diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000..dbbe355815 --- /dev/null +++ b/LICENSE @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. diff --git a/README.md b/README.md index be6c6ee903..39d916276c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,12 @@ +> [!NOTE] +> On 29 June 2023, Mobius Software LTD signed an agreement with Mavenir to assume development and support of the RestcommOne on prem products. For more details regarding open source / commercial differentiation, roadmap, licensing and other details please visit the [Mobius Website](https://www.mobius-software.com/telestaxannouncement). + + RestComm Sip Servlets ============ [![Join the chat at https://gitter.im/RestComm/sip-servlets](https://badges.gitter.im/RestComm/sip-servlets.svg)](https://gitter.im/RestComm/sip-servlets?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2FRestComm%2Fsip-servlets.svg?type=shield)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2FRestComm%2Fsip-servlets?ref=badge_shield) RestComm SIP Servlets is a SIP, IMS and WebRTC Application Server. RestComm SIP Servlets facilitates the shift towards Cloud Communications by enabling deployment and autoscaling of real time SIP Servlets applications across all major IaaS (Infrastructure as a Service) providers or on premises. @@ -23,40 +28,3 @@ RestComm SIP Servlets implements the latest SIP Servlet v1.1 (JSR 289) standard. ![](https://raw.githubusercontent.com/wiki/RestComm/sip-servlets/images/RestComm-SIP-Servlets-Stack.png) -Downloads -======== -[Get the latest stable release!](https://github.com/RestComm/sip-servlets/releases/latest) or -[Snapshot Releases for 3.x](https://mobicents.ci.cloudbees.com/job/RestcommSipServlets-Release/lastSuccessfulBuild/artifact/ ) or [Snapshot Releases for 4.x](https://mobicents.ci.cloudbees.com/job/RestcommSipServlets-4.X-Release/lastSuccessfulBuild/artifact/) - - It only takes a few minutes to set it up and running. - -Documentation -======== -Read the [Online SIP Servlets Documentation](http://docs.telestax.com/sip-servlets-homepage/) or it is also contained in the download binary - -Want to Contribute ? -======== -[See our Contributors Guide](https://github.com/RestComm/sip-servlets/wiki/Contribute-to-RestComm-SIP-Servlets) - -Issue Tracking and Roadmap -======== -[Issue Tracker](https://github.com/RestComm/sip-servlets/issues) - -Questions ? -======== -Please ask your question on [StackOverflow](http://stackoverflow.com/questions/tagged/restcomm) or the Google [public forum](http://groups.google.com/group/restcomm) - -License -======== - -RestComm SIP Servlets is lead by [TeleStax](http://www.telestax.com/), Inc. and developed collaboratively by a community of individual and enterprise contributors. - -RestComm SIP Servlets is licensed under dual license policy. The default license is the Free Open Source GNU Affero GPL v3.0. Alternatively a commercial license can be obtained from Telestax ([contact form](http://www.telestax.com/contactus/#InquiryForm)) - -Continuous Integration and Delivery -======== -[![RestComm SIP Servlets Continuous Job](http://www.cloudbees.com/sites/default/files/Button-Built-on-CB-1.png)](https://mobicents.ci.cloudbees.com/job/RestcommSipServlets-Release/) - -Acknowledgements -======== -[See who has been contributing to RestComm](http://www.telestax.com/opensource/acknowledgments/) diff --git a/build/jsr289-tck/pom.xml b/build/jsr289-tck/pom.xml new file mode 100644 index 0000000000..8ce6835daf --- /dev/null +++ b/build/jsr289-tck/pom.xml @@ -0,0 +1,92 @@ + + 4.0.0 + org.sipservlets.tck + tck + 1.1.0-SNAPSHOT + jar + + + + + + com.bea.sipservlet.tck + tck-unit + test + 1.1 + + + + com.bea.sipservlet.tck + sipunit + 1.1 + test + + + + com.bea.sipservlet.tck + sigtest + 1.1 + + + + + javax.servlet + servlet-api + 2.5 + provided + + + + + + org.mobicents.servlet.sip + sip-servlets-spec + 3.2.0-105 + + + + javax.annotation + javax.annotation-api + 1.2 + + + javax.sip + jain-sip-api + 1.2.0 + + + + javax.sip + jain-sip-ri + 1.3.0-91 + + + + + + + log4j + log4j + 1.2.8 + + + + + junit + junit + 3.8.1 + + + + tck/src + + + tck + false + + + + + + + diff --git a/build/jsr289-tck/sipunit/pom.xml b/build/jsr289-tck/sipunit/pom.xml new file mode 100644 index 0000000000..537e66a3f7 --- /dev/null +++ b/build/jsr289-tck/sipunit/pom.xml @@ -0,0 +1,44 @@ + + 4.0.0 + org.sipservlets.tck + sipunit + 1.1.0-SNAPSHOT + jar + + + + + + + + javax.sip + jain-sip-api + 1.2.0 + + + + javax.sip + jain-sip-ri + 1.3.0-91 + + + + log4j + log4j + 1.2.8 + + + + + junit + junit + 3.8.1 + + + + src + + + + + diff --git a/build/jsr289-tck/tck/applications/spectestapps/ar-continue/pom.xml b/build/jsr289-tck/tck/applications/spectestapps/ar-continue/pom.xml new file mode 100644 index 0000000000..ae87c59a12 --- /dev/null +++ b/build/jsr289-tck/tck/applications/spectestapps/ar-continue/pom.xml @@ -0,0 +1,51 @@ + + 4.0.0 + org.sipservlets.tck + ar-continue + 1.1.0-SNAPSHOT + war + + + + + + + + javax.servlet + servlet-api + 2.5 + provided + + + + + + org.mobicents.servlet.sip + sip-servlets-spec + 3.2.0-105 + + + + javax.annotation + javax.annotation-api + 1.2 + + + + + + + + log4j + log4j + 1.2.8 + + + + + src + + + + + diff --git a/build/jsr289-tck/tck/applications/spectestapps/b2bua/pom.xml b/build/jsr289-tck/tck/applications/spectestapps/b2bua/pom.xml new file mode 100644 index 0000000000..fc058015c2 --- /dev/null +++ b/build/jsr289-tck/tck/applications/spectestapps/b2bua/pom.xml @@ -0,0 +1,51 @@ + + 4.0.0 + org.sipservlets.tck + b2bua + 1.1.0-SNAPSHOT + war + + + + + + + + javax.servlet + servlet-api + 2.5 + provided + + + + + + org.mobicents.servlet.sip + sip-servlets-spec + 3.2.0-105 + + + + javax.annotation + javax.annotation-api + 1.2 + + + + + + + + log4j + log4j + 1.2.8 + + + + + src + + + + + diff --git a/build/jsr289-tck/tck/build.xml b/build/jsr289-tck/tck/build.xml new file mode 100644 index 0000000000..ff2b6bace7 --- /dev/null +++ b/build/jsr289-tck/tck/build.xml @@ -0,0 +1,471 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/jsr289-tck/tck/pom.xml b/build/jsr289-tck/tck/pom.xml new file mode 100644 index 0000000000..0114ab9282 --- /dev/null +++ b/build/jsr289-tck/tck/pom.xml @@ -0,0 +1,100 @@ + + 4.0.0 + org.sipservlets.tck + tck + 1.1.0-SNAPSHOT + jar + + + + + + com.bea.sipservlet.tck + tck-unit + test + 1.1 + + + + com.bea.sipservlet.tck + sipunit + 1.1 + test + + + + com.bea.sipservlet.tck + sigtest + 1.1 + test + + + + + javax.servlet + servlet-api + 2.5 + provided + + + + + + org.mobicents.servlet.sip + sip-servlets-spec + 3.2.0-105 + test + + + + javax.annotation + javax.annotation-api + 1.2 + test + + + com.bea.sipservlet.tck + jain-sip-api + 1.1 + test + + + + com.bea.sipservlet.tck + jain-sip-ri + 1.1 + test + + + + com.bea.sipservlet.tck + concurrent + 1.1 + test + + + + + + + log4j + log4j + 1.2.8 + test + + + + + junit + junit + 3.8.1 + test + + + + src + + + + + diff --git a/build/jsr289-tck/tck/tck-junit/pom.xml b/build/jsr289-tck/tck/tck-junit/pom.xml new file mode 100644 index 0000000000..cf79f2a13c --- /dev/null +++ b/build/jsr289-tck/tck/tck-junit/pom.xml @@ -0,0 +1,19 @@ + + 4.0.0 + org.restcomm.servlet.sip + tck-unit + 1.0.0-SNAPSHOT + jar + + + + + + + + src + + + + + diff --git a/build/release/build.xml b/build/release/build.xml index 491eb86b9b..c9f75299e5 100644 --- a/build/release/build.xml +++ b/build/release/build.xml @@ -24,7 +24,7 @@ - + diff --git a/build/release/steps.drop-in.wildfly-10.release.sh b/build/release/steps.drop-in.wildfly-10.release.sh index 66f59fe095..ac59eefa27 100755 --- a/build/release/steps.drop-in.wildfly-10.release.sh +++ b/build/release/steps.drop-in.wildfly-10.release.sh @@ -22,7 +22,7 @@ mkdir -p $CHECKOUT_DIR # get JBoss AS 10 release cd $CHECKOUT_DIR -wget http://download.jboss.org/wildfly/10.0.0.Final/wildfly-10.0.0.Final.zip +wget http://download.jboss.org/wildfly/10.0.0.Final/wildfly-10.0.0.Final.zip unzip wildfly-10.0.0.Final.zip cd ../../../.. @@ -42,7 +42,8 @@ mvn clean install war:inplace -f ./sip-servlets-examples/media-jsr309-servlet/po cp -pr ./sip-servlets-examples/media-jsr309-servlet/target/media-jsr309-servlet.war $BUILD_DIR/$MSS_FINAL_NAME/standalone/deployments/media-jsr309-servlet.war mvn clean install war:inplace -f ./management/sip-servlets-management/pom.xml cp -pr ./management/sip-servlets-management/target/sip-servlets-management.war $BUILD_DIR/$MSS_FINAL_NAME/standalone/deployments/sip-servlets-management.war -wget -nc http://labs.consol.de/maven/repository/org/jolokia/jolokia-war/1.1.0/jolokia-war-1.1.0.war -O $BUILD_DIR/$MSS_FINAL_NAME/standalone/deployments/jolokia.war +wget --no-check-certificate http://labs.consol.de/maven/repository/org/jolokia/jolokia-war/1.1.0/jolokia-war-1.1.0.war -O $BUILD_DIR/$MSS_FINAL_NAME/standalone/deployments/jolokia.war +#read -n1 -r -p "Press space to continue..." key mkdir -p $BUILD_DIR/$MSS_FINAL_NAME/standalone/configuration/dars mkdir -p $BUILD_DIR/$MSS_FINAL_NAME/domain/configuration/dars cp -vprf $BUILD_DIR/../../../../sip-servlets-examples/websocket-b2bua/websocket-dar.properties $BUILD_DIR/$MSS_FINAL_NAME/standalone/configuration/dars/mobicents-dar.properties diff --git a/containers/sip-servlets-as10-drop-in/build-restcomm-modules/build.xml b/containers/sip-servlets-as10-drop-in/build-restcomm-modules/build.xml index 44fb2a01d2..94b38b3a6a 100644 --- a/containers/sip-servlets-as10-drop-in/build-restcomm-modules/build.xml +++ b/containers/sip-servlets-as10-drop-in/build-restcomm-modules/build.xml @@ -63,9 +63,17 @@ - + + + + + + + + + diff --git a/containers/sip-servlets-as10-drop-in/build-restcomm-modules/pom.xml b/containers/sip-servlets-as10-drop-in/build-restcomm-modules/pom.xml index c80d03af20..f1a9b57a75 100644 --- a/containers/sip-servlets-as10-drop-in/build-restcomm-modules/pom.xml +++ b/containers/sip-servlets-as10-drop-in/build-restcomm-modules/pom.xml @@ -205,11 +205,35 @@ - org.mobicents.commons + org.restcomm.commons commons-congestion ${restcomm.commons.version} + + + org.restcomm.commons + restcomm-statistics + ${restcomm.commons.version} + + + + io.dropwizard.metrics + metrics-core + ${metrics.version} + + + + org.slf4j + slf4j-api + ${slf4j.version} + + + org.slf4j + slf4j-simple + ${slf4j.version} + + javolution javolution diff --git a/containers/sip-servlets-as10-drop-in/build-restcomm-modules/src/main/resources/modules/org/mobicents/libs/main/module.xml b/containers/sip-servlets-as10-drop-in/build-restcomm-modules/src/main/resources/modules/org/mobicents/libs/main/module.xml index d35810ad27..0a7f12beae 100644 --- a/containers/sip-servlets-as10-drop-in/build-restcomm-modules/src/main/resources/modules/org/mobicents/libs/main/module.xml +++ b/containers/sip-servlets-as10-drop-in/build-restcomm-modules/src/main/resources/modules/org/mobicents/libs/main/module.xml @@ -54,6 +54,12 @@ + + + + + + diff --git a/containers/sip-servlets-as10-drop-in/build-restcomm-modules/src/main/resources/modules/system/layers/base/org/mobicents/libs/main/module.xml b/containers/sip-servlets-as10-drop-in/build-restcomm-modules/src/main/resources/modules/system/layers/base/org/mobicents/libs/main/module.xml index 9822211e07..8f80836594 100644 --- a/containers/sip-servlets-as10-drop-in/build-restcomm-modules/src/main/resources/modules/system/layers/base/org/mobicents/libs/main/module.xml +++ b/containers/sip-servlets-as10-drop-in/build-restcomm-modules/src/main/resources/modules/system/layers/base/org/mobicents/libs/main/module.xml @@ -54,6 +54,12 @@ + + + + + + diff --git a/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/Attribute.java b/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/Attribute.java index 1a34cfd502..59a7b0d28d 100644 --- a/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/Attribute.java +++ b/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/Attribute.java @@ -54,6 +54,7 @@ enum Attribute { DEFAULT_WEB_MODULE(Constants.DEFAULT_WEB_MODULE), DEVELOPMENT(Constants.DEVELOPMENT), GATHER_STATISTICS(Constants.GATHER_STATISTICS), + GRACEFUL_INTERVAL(Constants.GRACEFUL_INTERVAL), DIALOG_PENDING_REQUEST_CHECKING(Constants.DIALOG_PENDING_REQUEST_CHECKING), DNS_SERVER_LOCATOR_CLASS(Constants.DNS_SERVER_LOCATOR_CLASS), DNS_TIMEOUT(Constants.DNS_TIMEOUT), diff --git a/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/Constants.java b/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/Constants.java index a7cb6b04d8..c84463a71d 100644 --- a/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/Constants.java +++ b/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/Constants.java @@ -75,6 +75,7 @@ public interface Constants { String FLAGS = "flags"; String GATHER_STATISTICS = "gather-statistics"; String GENERATE_STRINGS_AS_CHAR_ARRAYS = "generate-strings-as-char-arrays"; + String GRACEFUL_INTERVAL = "graceful-interval"; String INSTANCE_ID = "instance-id"; String JAVA_ENCODING = "java-encoding"; String JSP_CONFIGURATION = "jsp-configuration"; diff --git a/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/SipConnectorService.java b/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/SipConnectorService.java index 0c9e246949..ca406bff83 100644 --- a/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/SipConnectorService.java +++ b/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/SipConnectorService.java @@ -146,6 +146,8 @@ public synchronized void start(StartContext context) throws StartException { } // Register the binding after the connector is started binding.getSocketBindings().getNamedRegistry().registerBinding(new ConnectorBinding(binding)); + //notify SipServer only when connector has already been added/started + getSipServer().connectorAdded(connector); } /** {@inheritDoc} */ diff --git a/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/SipDefinition.java b/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/SipDefinition.java index 19500c2a78..042c594f0f 100644 --- a/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/SipDefinition.java +++ b/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/SipDefinition.java @@ -182,7 +182,7 @@ public class SipDefinition extends SimpleResourceDefinition { .setAllowExpression(true) .setXmlName(Constants.GATHER_STATISTICS) .setFlags(AttributeAccess.Flag.RESTART_ALL_SERVICES) - .setDefaultValue(new ModelNode(false)) + .setDefaultValue(new ModelNode(true)) .build(); protected static final SimpleAttributeDefinition DNS_SERVER_LOCATOR_CLASS = new SimpleAttributeDefinitionBuilder(Constants.DNS_SERVER_LOCATOR_CLASS, ModelType.STRING, true) @@ -247,6 +247,13 @@ public class SipDefinition extends SimpleResourceDefinition { .setFlags(AttributeAccess.Flag.RESTART_ALL_SERVICES) .setDefaultValue(null) .build(); + protected static final SimpleAttributeDefinition GRACEFUL_INTERVAL = + new SimpleAttributeDefinitionBuilder(Constants.GRACEFUL_INTERVAL, ModelType.LONG, true) + .setAllowExpression(true) + .setXmlName(Constants.GRACEFUL_INTERVAL) + .setFlags(AttributeAccess.Flag.RESTART_ALL_SERVICES) + .setDefaultValue(new ModelNode(30000)) + .build(); private SipDefinition() { super(PathElement.pathElement(ModelDescriptionConstants.SUBSYSTEM, SipExtension.SUBSYSTEM_NAME), SipExtension @@ -304,6 +311,8 @@ public void registerAttributes(ManagementResourceRegistration registration) { registration.registerReadWriteAttribute(BACK_TO_NORMAL_MEMORY_THRESHOLD, null, new ReloadRequiredWriteAttributeHandler( BACK_TO_NORMAL_MEMORY_THRESHOLD)); registration.registerReadWriteAttribute(OUTBOUND_PROXY, null, new ReloadRequiredWriteAttributeHandler(OUTBOUND_PROXY)); + registration.registerReadWriteAttribute(GRACEFUL_INTERVAL, null, new ReloadRequiredWriteAttributeHandler(GRACEFUL_INTERVAL)); + for (SipStackStat stat : SipStackStat.values()) { registration.registerMetric(stat.definition, SipStackStatsHandler.getInstance()); } diff --git a/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/SipServer.java b/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/SipServer.java index 9d687a7a71..e012b9070e 100644 --- a/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/SipServer.java +++ b/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/SipServer.java @@ -72,5 +72,7 @@ public interface SipServer { * return the service (StandardService) */ SipStandardService getService(); + + void connectorAdded(SipConnectorListener connector); } diff --git a/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/SipServerService.java b/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/SipServerService.java index ae87452ee0..8aba6c9164 100644 --- a/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/SipServerService.java +++ b/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/SipServerService.java @@ -18,6 +18,7 @@ */ package org.mobicents.as10; +import java.util.concurrent.atomic.AtomicInteger; import static org.mobicents.as10.SipMessages.MESSAGES; import javax.management.MBeanServer; @@ -58,6 +59,7 @@ class SipServerService implements SipServer, Service { final String sipAppDispatcherClass; final String additionalParameterableHeaders; final String proxyTimerServiceImplementationType; + final boolean gatherStatistics; final String sasTimerServiceImplementationType; final int sipCongestionControlInterval; final String congestionControlPolicy; @@ -77,6 +79,7 @@ class SipServerService implements SipServer, Service { final int memoryThreshold; final int backToNormalMemoryThreshold; final String outboundProxy; + private long gracefulInterval=30000; private final String instanceId; @@ -100,6 +103,7 @@ public SipServerService( String additionalParameterableHeaders, String proxyTimerServiceImplementationType, String sasTimerServiceImplementationType, + boolean gatherStatistics, int sipCongestionControlInterval, String congestionControlPolicy, String sipConcurrencyControlMode, @@ -130,6 +134,7 @@ public SipServerService( this.additionalParameterableHeaders = additionalParameterableHeaders; this.proxyTimerServiceImplementationType = proxyTimerServiceImplementationType; this.sasTimerServiceImplementationType = sasTimerServiceImplementationType; + this.gatherStatistics = gatherStatistics; this.sipCongestionControlInterval = sipCongestionControlInterval; this.congestionControlPolicy = congestionControlPolicy; this.sipConcurrencyControlMode = sipConcurrencyControlMode; @@ -225,7 +230,7 @@ public synchronized void start(StartContext context) throws StartException { sipService.setProxyTimerServiceImplementationType(proxyTimerServiceImplementationType); sipService.setSasTimerServiceImplementationType(sasTimerServiceImplementationType); - + sipService.setGatherStatistics(gatherStatistics); sipService.setCongestionControlCheckingInterval(sipCongestionControlInterval); sipService.setUsePrettyEncoding(usePrettyEncoding); @@ -249,6 +254,7 @@ public synchronized void start(StartContext context) throws StartException { sipService.setCongestionControlPolicy(congestionControlPolicy); sipService.setOutboundProxy(outboundProxy); sipService.setName(JBOSS_SIP); + sipService.setGracefulInterval(gracefulInterval); // FIXME: kakonyii // sipService.setServer(server); @@ -293,6 +299,8 @@ public synchronized void stop(StopContext context) { public synchronized SipServer getValue() throws IllegalStateException { return this; } + + private AtomicInteger addedConnectors = new AtomicInteger(0); /** {@inheritDoc} */ public synchronized void addConnector(SipConnectorListener connector) { @@ -301,6 +309,17 @@ public synchronized void addConnector(SipConnectorListener connector) { sipService.addConnector(connector.getProtocolHandler()); } } + + public synchronized void connectorAdded(SipConnectorListener connector) { + if (connector.getProtocolHandler() instanceof SipProtocolHandler) { + int currentConnectors = addedConnectors.incrementAndGet(); + if (currentConnectors >= SipSubsystemParser.getInstance().parsedConnectors.get()) { + logger.debug("Time to put dispatcher in service."); + sipService.getSipApplicationDispatcher().putInService(); + + } + } + } /** {@inheritDoc} */ public synchronized void removeConnector(SipConnectorListener connector) { @@ -355,4 +374,7 @@ public SipStandardService getService() { return sipService; } + public void setGracefulInterval(long gracefulInterval) { + this.gracefulInterval = gracefulInterval; + } } diff --git a/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/SipSubsystemAdd.java b/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/SipSubsystemAdd.java index 3f0e1129ca..76480ddb73 100644 --- a/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/SipSubsystemAdd.java +++ b/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/SipSubsystemAdd.java @@ -121,6 +121,7 @@ protected void populateModel(ModelNode operation, ModelNode model) throws Operat SipDefinition.MEMORY_THRESHOLD.validateAndSet(operation, model); SipDefinition.BACK_TO_NORMAL_MEMORY_THRESHOLD.validateAndSet(operation, model); SipDefinition.OUTBOUND_PROXY.validateAndSet(operation, model); + SipDefinition.GRACEFUL_INTERVAL.validateAndSet(operation, model); } @Override @@ -194,7 +195,7 @@ protected void performBoottime(OperationContext context, ModelNode operation, Mo final int timerDInterval = timerDIntervalModel.isDefined() ? timerDIntervalModel.asInt() : 32000; final ModelNode gatherStatisticsModel = SipDefinition.GATHER_STATISTICS.resolveModelAttribute(context, fullModel); - final boolean gatherStatistics = gatherStatisticsModel.isDefined() ? gatherStatisticsModel.asBoolean() : false; + final boolean gatherStatistics = gatherStatisticsModel.isDefined() ? gatherStatisticsModel.asBoolean() : true; final ModelNode dialogPendingRequestCheckingModel = SipDefinition.DIALOG_PENDING_REQUEST_CHECKING .resolveModelAttribute(context, fullModel); @@ -233,6 +234,9 @@ protected void performBoottime(OperationContext context, ModelNode operation, Mo final ModelNode outboundProxyModel = SipDefinition.OUTBOUND_PROXY.resolveModelAttribute(context, fullModel); final String outboundProxy = outboundProxyModel.isDefined() ? outboundProxyModel.asString() : null; + + final ModelNode gracefulIntervalModel = SipDefinition.GRACEFUL_INTERVAL.resolveModelAttribute(context, fullModel); + final Long gracefulInterval = gracefulIntervalModel.isDefined() ? gracefulIntervalModel.asLong(): null; // final String instanceId = operation.hasDefined(Constants.INSTANCE_ID) ? // operation.get(Constants.INSTANCE_ID).asString() : null; @@ -261,11 +265,12 @@ protected void performBoottime(OperationContext context, ModelNode operation, Mo } final SipServerService service = new SipServerService(sipAppRouterFile, sipStackPropertiesFile, sipPathName, - sipAppDispatcherClass, additionalParameterableHeaders, proxyTimerServiceImplementationType, sasTimerServiceImplementationType, sipCongestionControlInterval, congestionControlPolicy, + sipAppDispatcherClass, additionalParameterableHeaders, proxyTimerServiceImplementationType, sasTimerServiceImplementationType, gatherStatistics, sipCongestionControlInterval, congestionControlPolicy, sipConcurrencyControlMode, usePrettyEncoding, baseTimerInterval, t2Interval, t4Interval, timerDInterval, dialogPendingRequestChecking, dnsServerLocatorClass, dnsTimeout, dnsResolverClass, callIdMaxLength, tagHashMaxLength, canceledTimerTasksPurgePeriod, memoryThreshold, backToNormalMemoryThreshold, outboundProxy, instanceId); + service.setGracefulInterval(gracefulInterval); newControllers.add(context .getServiceTarget() .addService(SipSubsystemServices.JBOSS_SIP, service) diff --git a/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/SipSubsystemParser.java b/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/SipSubsystemParser.java index c4c1a8e115..a5dfde5c52 100644 --- a/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/SipSubsystemParser.java +++ b/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as10/SipSubsystemParser.java @@ -31,6 +31,7 @@ import java.util.Collections; import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; @@ -62,6 +63,7 @@ class SipSubsystemParser implements XMLStreamConstants, XMLElementReader { private static final SipSubsystemParser INSTANCE = new SipSubsystemParser(); + AtomicInteger parsedConnectors = new AtomicInteger(0); static SipSubsystemParser getInstance() { return INSTANCE; @@ -103,6 +105,7 @@ public void writeContent(XMLExtendedStreamWriter writer, SubsystemMarshallingCon SipDefinition.MEMORY_THRESHOLD.marshallAsAttribute(node, false, writer); SipDefinition.BACK_TO_NORMAL_MEMORY_THRESHOLD.marshallAsAttribute(node, false, writer); SipDefinition.OUTBOUND_PROXY.marshallAsAttribute(node, false, writer); + SipDefinition.GRACEFUL_INTERVAL.marshallAsAttribute(node, false, writer); if (node.hasDefined(CONNECTOR)) { for (final Property connector : node.get(CONNECTOR).asPropertyList()) { final ModelNode config = connector.getValue(); @@ -158,6 +161,7 @@ public void readElement(XMLExtendedStreamReader reader, List list) th case OUTBOUND_PROXY: case CONCURRENCY_CONTROL_MODE: case USE_PRETTY_ENCODING: + case GRACEFUL_INTERVAL: subsystem.get(attribute.getLocalName()).set(value); break; default: @@ -264,6 +268,7 @@ static void parseConnector(XMLExtendedStreamReader reader, PathAddress parent, L PathAddress address = PathAddress.pathAddress(parent, PathElement.pathElement(CONNECTOR, name)); connector.get(OP_ADDR).set(address.toModelNode()); list.add(connector); + getInstance().parsedConnectors.incrementAndGet(); while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { switch (Namespace.forUri(reader.getNamespaceURI())) { diff --git a/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/servlet/sip/startup/jboss/SipJBossContextConfig.java b/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/servlet/sip/startup/jboss/SipJBossContextConfig.java index b8600c773b..bf0f39ced0 100644 --- a/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/servlet/sip/startup/jboss/SipJBossContextConfig.java +++ b/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/servlet/sip/startup/jboss/SipJBossContextConfig.java @@ -365,6 +365,7 @@ public void processSipMetaData(JBossConvergedSipMetaData convergedMetaData, SipC SipServletImpl wrapper = new SipServletImpl(servletInfo, convergedContext.getServletContext()); wrapper.setupMultipart(convergedContext.getServletContext().getDelegatedContext()); wrapper.setServletName(value.getServletName()); + wrapper.getServletInfo().setLoadOnStartup(value.getLoadOnStartupInt()); convergedContext.getDeploymentInfoFacade().addSipServlets(servletInfo); convergedContext.addChild(wrapper); diff --git a/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/resources/org/mobicents/as10/LocalDescriptions.properties b/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/resources/org/mobicents/as10/LocalDescriptions.properties index b02053a732..32f7f912b6 100644 --- a/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/resources/org/mobicents/as10/LocalDescriptions.properties +++ b/containers/sip-servlets-as10-drop-in/jboss-as-restcomm/src/main/resources/org/mobicents/as10/LocalDescriptions.properties @@ -145,3 +145,6 @@ sip.deployment.sip-application-session-avg-alive-time=Average time (in seconds) sip.deployment.sip-session-max-alive-time=The longest time (in seconds) that an expired sip session had been alive sip.deployment.sip-application-session-max-alive-time=The longest time (in seconds) that an expired sip application session had been alive +sip.gracefulShutdown=Graceful Shutdown operation +sip.gracefulShutdown.timeToWait=Time to wait for a graceful shutdown +sip.graceful-interval=Interval of checks for timeout of Graceful Shutdown \ No newline at end of file diff --git a/containers/sip-servlets-as10/src/main/java/org/mobicents/io/undertow/servlet/spec/ConvergedSessionDelegate.java b/containers/sip-servlets-as10/src/main/java/org/mobicents/io/undertow/servlet/spec/ConvergedSessionDelegate.java index 4bb585ff39..240910ccc1 100644 --- a/containers/sip-servlets-as10/src/main/java/org/mobicents/io/undertow/servlet/spec/ConvergedSessionDelegate.java +++ b/containers/sip-servlets-as10/src/main/java/org/mobicents/io/undertow/servlet/spec/ConvergedSessionDelegate.java @@ -140,7 +140,8 @@ public String encodeURL(String relativePath, String scheme) { if (scheme != null && ("http".equalsIgnoreCase(scheme) || "https".equalsIgnoreCase(scheme)) && listener instanceof HttpListenerService) { if (listener.getBinding().getValue() != null) { - port = listener.getBinding().getValue().getPort(); + //use absolute port to support offset configuration + port = listener.getBinding().getValue().getAbsolutePort(); if (listener.getBinding().getValue().getAddress() != null) { hostname = listener.getBinding().getValue().getAddress().getHostName(); } diff --git a/containers/sip-servlets-as10/src/main/java/org/mobicents/servlet/sip/undertow/ContextGracefulStopTask.java b/containers/sip-servlets-as10/src/main/java/org/mobicents/servlet/sip/undertow/ContextGracefulStopTask.java index cff113a782..1d75d63aec 100644 --- a/containers/sip-servlets-as10/src/main/java/org/mobicents/servlet/sip/undertow/ContextGracefulStopTask.java +++ b/containers/sip-servlets-as10/src/main/java/org/mobicents/servlet/sip/undertow/ContextGracefulStopTask.java @@ -21,9 +21,10 @@ */ package org.mobicents.servlet.sip.undertow; -import javax.servlet.ServletException; import org.apache.log4j.Logger; +import org.mobicents.javax.servlet.ContainerListener; +import org.mobicents.javax.servlet.GracefulShutdownCheckEvent; import org.mobicents.servlet.sip.core.SipContext; /** @@ -31,35 +32,67 @@ * */ public class ContextGracefulStopTask implements Runnable { - private static final Logger logger = Logger.getLogger(ContextGracefulStopTask.class); + + private static final Logger logger = Logger.getLogger(ContextGracefulStopTask.class); SipContext sipContext; - long timeToWait; - long startTime; + long timeToWait; + long startTime; public ContextGracefulStopTask(SipContext context, long timeToWait) { - sipContext = context; - this.timeToWait = timeToWait; - startTime = System.currentTimeMillis(); - } + sipContext = context; + this.timeToWait = timeToWait; + startTime = System.currentTimeMillis(); + } + + private static final String PREVENT_PREMATURE_SHUTDOWN = "org.mobicents.servlet.sip.PREVENT_PREMATURE_SHUTDOWN"; - public void run() { + @Override + public void run() { int numberOfActiveSipApplicationSessions = sipContext.getSipManager().getActiveSipApplicationSessions(); int numberOfActiveHttpSessions = ((UndertowSipManager) ((SipContextImpl)sipContext).getSessionManager()).getActiveSessions().size(); - if(logger.isTraceEnabled()) { - logger.trace("ContextGracefulStopTask running for context " + sipContext.getApplicationName() + ", number of Sip Application Sessions still active " + numberOfActiveSipApplicationSessions + " number of HTTP Sessions still active " + numberOfActiveHttpSessions); - } - boolean stopPrematuraly = false; - long currentTime = System.currentTimeMillis(); - // if timeToWait is positive, then we check the time since the task started, if the time is greater than timeToWait we can safely stop the context - if(timeToWait > 0 && ((currentTime - startTime) > timeToWait)) { - stopPrematuraly = true; - } - if((numberOfActiveSipApplicationSessions <= 0 && numberOfActiveHttpSessions <= 0) || stopPrematuraly) { - try { - ((SipContextImpl)sipContext).stop(); - } catch (ServletException e) { - logger.error("Couldn't gracefully stop context " + sipContext.getApplicationName(), e); - } - } - } + if (logger.isTraceEnabled()) { + logger.trace("ContextGracefulStopTask running for context " + sipContext.getApplicationName() + ", number of Sip Application Sessions still active " + numberOfActiveSipApplicationSessions + " number of HTTP Sessions still active " + numberOfActiveHttpSessions); + } + + boolean stopPrematuraly = false; + long currentTime = System.currentTimeMillis(); + // if timeToWait is positive, then we check the time since the task started, if the time is greater than timeToWait we can safely stop the context + long elapsedTime = currentTime - startTime; + if (timeToWait > 0 && (elapsedTime > timeToWait)) { + logger.info("Graceful TimeToWait Consumed."); + stopContext(); + } + if (logger.isDebugEnabled()) { + logger.debug("ContextGracefulStopTask running for context " + sipContext.getApplicationName() + + ", number of Sip Application Sessions still active " + numberOfActiveSipApplicationSessions + + " number of HTTP Sessions still active " + numberOfActiveHttpSessions + + ", stopPrematurely " + stopPrematuraly); + } + if (numberOfActiveSipApplicationSessions <= 0 + && numberOfActiveHttpSessions <= 0) { + logger.info("No more active sessions, lets check with service"); + boolean servicePremature = true; + ContainerListener containerListener = ((SipContext) sipContext).getListeners().getContainerListener(); + if (containerListener != null) { + GracefulShutdownCheckEvent event = new GracefulShutdownCheckEvent(elapsedTime, timeToWait); + ((SipContext) sipContext).getListeners().callbackContainerListener(event); + servicePremature = sipContext.getServletContext().getAttribute(PREVENT_PREMATURE_SHUTDOWN) == null; + logger.info("servicePremature=" + servicePremature); + } + if (servicePremature) { + stopContext(); + } + + } + } + + private void stopContext() { + try { + logger.info("About to stop the context."); + ((SipContextImpl) sipContext).stop(); + } catch (Exception e) { + logger.error("Couldn't gracefully stop context " + sipContext.getApplicationName(), e); + } + } + } diff --git a/containers/sip-servlets-as10/src/main/java/org/mobicents/servlet/sip/undertow/SipContextImpl.java b/containers/sip-servlets-as10/src/main/java/org/mobicents/servlet/sip/undertow/SipContextImpl.java index a92f96d34c..5ea47dcd0a 100644 --- a/containers/sip-servlets-as10/src/main/java/org/mobicents/servlet/sip/undertow/SipContextImpl.java +++ b/containers/sip-servlets-as10/src/main/java/org/mobicents/servlet/sip/undertow/SipContextImpl.java @@ -29,6 +29,8 @@ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.LinkedList; import java.util.List; @@ -50,6 +52,7 @@ import org.apache.log4j.Logger; import org.mobicents.io.undertow.servlet.api.DeploymentInfoFacade; +import org.mobicents.javax.servlet.GracefulShutdownStartedEvent; import org.mobicents.servlet.sip.SipConnector; import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; import org.mobicents.servlet.sip.core.MobicentsSipServlet; @@ -139,7 +142,7 @@ public class SipContextImpl implements SipContext { // http://code.google.com/p/sipservlets/issues/detail?id=195 private ScheduledFuture gracefulStopFuture; - + // default constructor: public SipContextImpl() { } @@ -236,6 +239,10 @@ public synchronized void start() throws ServletException { Integer loadOnStartupNumber = servlet.getServletInfo().getLoadOnStartup(); if (loadOnStartupNumber != null) { + if (logger.isDebugEnabled()) { + String msg = String.format("Servlet %s load on startup %s", servlet.getName(), loadOnStartupNumber); + logger.debug(msg); + } if (loadOnStartupNumber < 0) { continue; } @@ -721,6 +728,15 @@ public boolean notifySipContextListeners(SipContextEvent event) { logger.debug(this.deploymentInfoFacade.getSipServlets().size() + " container to notify of " + event.getEventType()); } if (event.getEventType() == SipContextEventType.SERVLET_INITIALIZED) { + //fixes https://github.com/RestComm/sip-servlets/issues/165 + //now the SipService is totally ready/started, we prepare + //the context again just in case some att was not properly + //initiated + try { + prepareServletContext(); + } catch (Exception e) { + logger.warn("Couldnt prepare context", e); + } if (!timerService.isStarted()) { timerService.start(); } @@ -735,12 +751,14 @@ public boolean notifySipContextListeners(SipContextEvent event) { // if(this.available) { enterSipApp(null, null, false, true); boolean batchStarted = enterSipAppHa(true); - try { - for (String servletName : this.deploymentInfoFacade.getSipServlets().keySet()) { - SipServletImpl managedServlet = (SipServletImpl) this.getChildrenMap().get(servletName); + List sipServlets = new ArrayList(getChildrenMap().values()); + Collections.sort(sipServlets, new SipServletLoadOnStartupComparator()); + + try { + for (MobicentsSipServlet managedServlet : sipServlets) { if (logger.isDebugEnabled()) { - logger.debug("managedServlet " + managedServlet.getServletInfo().getName() + ", class : " + logger.debug("managedServlet " + managedServlet.getName() + ", class : " + managedServlet.getClass().getName()); } try { @@ -754,13 +772,13 @@ public boolean notifySipContextListeners(SipContextEvent event) { // in wildfly we use threadSetupAction from the deployment object for that purpose: bindThreadBindingListener(); - Servlet sipServlet = managedServlet.getServlet().getInstance(); + Servlet sipServlet = managedServlet.allocate(); if (sipServlet instanceof SipServlet) { // Fix for issue 1086 (http://code.google.com/p/mobicents/issues/detail?id=1086) : // Cannot send a request in SipServletListener.initialize() for servlet-selection applications boolean servletHandlerWasNull = false; if (this.getServletHandler() == null) { - this.setServletHandler(managedServlet.getServletInfo().getName()); + this.setServletHandler(managedServlet.getName()); servletHandlerWasNull = true; } @@ -826,10 +844,6 @@ public boolean notifySipContextListeners(SipContextEvent event) { unbindThreadBindingListener(); Thread.currentThread().setContextClassLoader(oldClassLoader); } - } catch (ServletException e) { - logger.error("Cannot allocate the servlet " + managedServlet.getClass() + " for notifying the listener " - + " of the event " + event.getEventType(), e); - ok = false; } catch (Throwable e) { logger.error("An error occured when notifying the servlet " + managedServlet.getClass() + " of the event " + event.getEventType(), e); @@ -857,6 +871,23 @@ public boolean notifySipContextListeners(SipContextEvent event) { return ok; } + protected class SipServletLoadOnStartupComparator implements Comparator { + + @Override + public int compare(MobicentsSipServlet o1, MobicentsSipServlet o2) { + if(o1 != null && o2 != null) { + if(o1.getLoadOnStartup() > o2.getLoadOnStartup()) { + return 1; + } else if(o1.getLoadOnStartup() == o2.getLoadOnStartup()) { + return 0; + } else { + return -1; + } + } + return 0; + } + } + @Override public void enterSipApp(MobicentsSipApplicationSession sipApplicationSession, MobicentsSipSession sipSession, boolean checkIsManagedThread, boolean isContainerManaged) { @@ -1154,13 +1185,17 @@ public enum TimerServiceType{ DEFAULT; } - @Override + private long gracefulInterval = 30000; + + @Override public void stopGracefully(long timeToWait) { - // http://code.google.com/p/sipservlets/issues/detail?id=195 + // http://code.google.com/p/sipservlets/issues/detail?id=195 // Support for Graceful Shutdown of SIP Applications and Overall Server if(logger.isInfoEnabled()) { logger.info("Stopping the Context " + getApplicationName() + " Gracefully in " + timeToWait + " ms"); } + GracefulShutdownStartedEvent startEvent = new GracefulShutdownStartedEvent(timeToWait); + getListeners().callbackContainerListener(startEvent); // Guarantees that the application won't be routed any initial requests anymore but will still handle subsequent requests List applicationsUndeployed = new ArrayList(); applicationsUndeployed.add(getApplicationName()); @@ -1175,16 +1210,15 @@ public void stopGracefully(long timeToWait) { } catch (ServletException e) { logger.error("The server couldn't be stopped", e); } - } else { - long gracefulStopTaskInterval = 30000; - if(timeToWait > 0 && timeToWait < gracefulStopTaskInterval) { + } else { + if(timeToWait > 0 && timeToWait < gracefulInterval) { // if the time to Wait is positive and < to the gracefulStopTaskInterval then we schedule the task directly once to the time to wait - gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().schedule(new ContextGracefulStopTask(this, timeToWait), timeToWait, TimeUnit.MILLISECONDS); + gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().schedule(new ContextGracefulStopTask(this, timeToWait), timeToWait, TimeUnit.MILLISECONDS); } else { // if the time to Wait is > to the gracefulStopTaskInterval or infinite (negative value) then we schedule the task to run every gracefulStopTaskInterval, not needed to be exactly precise on the timeToWait in this case - gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().scheduleWithFixedDelay(new ContextGracefulStopTask(this, timeToWait), gracefulStopTaskInterval, gracefulStopTaskInterval, TimeUnit.MILLISECONDS); + gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().scheduleWithFixedDelay(new ContextGracefulStopTask(this, timeToWait), 0, gracefulInterval, TimeUnit.MILLISECONDS); } - } + } } @Override @@ -1194,4 +1228,8 @@ public boolean isStoppingGracefully() { return false; } + public void setGracefulInterval(long gracefulInterval) { + this.gracefulInterval = gracefulInterval; + } + } diff --git a/containers/sip-servlets-as10/src/main/java/org/mobicents/servlet/sip/undertow/SipStandardService.java b/containers/sip-servlets-as10/src/main/java/org/mobicents/servlet/sip/undertow/SipStandardService.java index 32d52626bc..6384d35eab 100644 --- a/containers/sip-servlets-as10/src/main/java/org/mobicents/servlet/sip/undertow/SipStandardService.java +++ b/containers/sip-servlets-as10/src/main/java/org/mobicents/servlet/sip/undertow/SipStandardService.java @@ -127,6 +127,7 @@ public class SipStandardService implements SipService { protected boolean dialogPendingRequestChecking = false; protected int callIdMaxLength; protected int tagHashMaxLength; + private long gracefulInterval = 30000; protected boolean httpFollowsSip = false; protected String jvmRoute; @@ -582,7 +583,7 @@ protected void initSipStack() throws Exception { } // Create SipStack object sipStack = sipApplicationDispatcher.getSipFactory().getJainSipFactory().createSipStack(sipStackProperties); - + LoadBalancerHeartBeatingService loadBalancerHeartBeatingService = null; if (sipStack instanceof ClusteredSipStack) { loadBalancerHeartBeatingService = ((ClusteredSipStack) sipStack).getLoadBalancerHeartBeatingService(); @@ -735,7 +736,7 @@ private SipProtocolHandler findSipConnector(String ipAddress, int port, String t SipConnector connectorToRemove = null; for (SipProtocolHandler protocolHandler : connectors) { if (protocolHandler.getIpAddress().equals(ipAddress) && protocolHandler.getPort() == port - && protocolHandler.getSignalingTransport().equals(transport)) { + && protocolHandler.getSignalingTransport().equalsIgnoreCase(transport)) { connectorToRemove = protocolHandler.getSipConnector(); return protocolHandler; } @@ -1122,7 +1123,7 @@ public String getSasTimerServiceImplementationType() { public void setSasTimerServiceImplementationType(String sasTimerServiceImplementationType) { this.sasTimerServiceImplementationType = sasTimerServiceImplementationType; } - + protected void shutdownServer() throws MalformedObjectNameException, NullPointerException, InstanceNotFoundException, MBeanException, ReflectionException, IOException{ MBeanServerConnection mbeanServerConnection = ManagementFactory.getPlatformMBeanServer(); ObjectName mbeanName = new ObjectName("jboss.as:management-root=server"); @@ -1130,7 +1131,7 @@ protected void shutdownServer() throws MalformedObjectNameException, NullPointer String[] sigs = {"java.lang.Boolean"}; mbeanServerConnection.invoke(mbeanName, "shutdown", args, sigs); } - + @Override public void stopGracefully(long timeToWait) { if(logger.isInfoEnabled()) { @@ -1152,13 +1153,14 @@ public void stopGracefully(long timeToWait) { Iterator sipContexts = sipApplicationDispatcher.findSipApplications(); while (sipContexts.hasNext()) { SipContext sipContext = sipContexts.next(); + sipContext.setGracefulInterval(gracefulInterval); sipContext.stopGracefully(timeToWait); } - gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().scheduleWithFixedDelay(new ServiceGracefulStopTask(this), 30000, 30000, TimeUnit.MILLISECONDS); + gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().scheduleWithFixedDelay(new ServiceGracefulStopTask(this), gracefulInterval, gracefulInterval, TimeUnit.MILLISECONDS); if(timeToWait > 0) { gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().schedule( new Runnable() { - public void run() { + public void run() { gracefulStopFuture.cancel(false); try { stop(); @@ -1170,6 +1172,10 @@ public void run() { } , timeToWait, TimeUnit.MILLISECONDS); } - } + } } + + public void setGracefulInterval(long gracefulStopTaskInterval) { + this.gracefulInterval = gracefulStopTaskInterval; + } } \ No newline at end of file diff --git a/containers/sip-servlets-as7-drop-in/build-restcomm-modules/build.xml b/containers/sip-servlets-as7-drop-in/build-restcomm-modules/build.xml index ef3a789def..3c40a3074a 100644 --- a/containers/sip-servlets-as7-drop-in/build-restcomm-modules/build.xml +++ b/containers/sip-servlets-as7-drop-in/build-restcomm-modules/build.xml @@ -63,9 +63,17 @@ - + + + + + + + + + diff --git a/containers/sip-servlets-as7-drop-in/build-restcomm-modules/pom.xml b/containers/sip-servlets-as7-drop-in/build-restcomm-modules/pom.xml index 99e2e0c3d1..4cb399559a 100644 --- a/containers/sip-servlets-as7-drop-in/build-restcomm-modules/pom.xml +++ b/containers/sip-servlets-as7-drop-in/build-restcomm-modules/pom.xml @@ -206,11 +206,35 @@ - org.mobicents.commons + org.restcomm.commons commons-congestion ${restcomm.commons.version} + + + + org.restcomm.commons + restcomm-statistics + ${restcomm.commons.version} + + io.dropwizard.metrics + metrics-core + ${metrics.version} + + + + org.slf4j + slf4j-api + ${slf4j.version} + + + + org.slf4j + slf4j-simple + ${slf4j.version} + + javolution javolution diff --git a/containers/sip-servlets-as7-drop-in/build-restcomm-modules/src/main/resources/modules/org/mobicents/libs/main/module.xml b/containers/sip-servlets-as7-drop-in/build-restcomm-modules/src/main/resources/modules/org/mobicents/libs/main/module.xml index 43cc3b7a5c..ecfdeef51d 100644 --- a/containers/sip-servlets-as7-drop-in/build-restcomm-modules/src/main/resources/modules/org/mobicents/libs/main/module.xml +++ b/containers/sip-servlets-as7-drop-in/build-restcomm-modules/src/main/resources/modules/org/mobicents/libs/main/module.xml @@ -41,6 +41,12 @@ + + + + + + diff --git a/containers/sip-servlets-as7-drop-in/build-restcomm-modules/src/main/resources/modules/system/layers/base/org/mobicents/libs/main/module.xml b/containers/sip-servlets-as7-drop-in/build-restcomm-modules/src/main/resources/modules/system/layers/base/org/mobicents/libs/main/module.xml index 43cc3b7a5c..ecfdeef51d 100644 --- a/containers/sip-servlets-as7-drop-in/build-restcomm-modules/src/main/resources/modules/system/layers/base/org/mobicents/libs/main/module.xml +++ b/containers/sip-servlets-as7-drop-in/build-restcomm-modules/src/main/resources/modules/system/layers/base/org/mobicents/libs/main/module.xml @@ -41,6 +41,12 @@ + + + + + + diff --git a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/.classpath b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/.classpath new file mode 100644 index 0000000000..2031d401fe --- /dev/null +++ b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/.classpath @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/.project b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/.project index 9791fa9a23..69e6bb5eac 100644 --- a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/.project +++ b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/.project @@ -1,7 +1,7 @@ - jboss-as7-restcomm - >JBoss Application Server: Restcomm Sip Servlets Adaptation Layer. NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse. + jboss-as7-mobicents + >JBoss Application Server: Mobicents Sip Servlets Adaptation Layer. NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse. sip-servlets-impl sip-servlets-spec diff --git a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/Attribute.java b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/Attribute.java index 4c45f12365..4d67f2346c 100644 --- a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/Attribute.java +++ b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/Attribute.java @@ -86,6 +86,7 @@ enum Attribute { NAME(Constants.NAME), NATIVE(Constants.NATIVE), OUTBOUND_PROXY(Constants.OUTBOUND_PROXY), + GRACEFUL_INTERVAL(Constants.GRACEFUL_INTERVAL), PASSWORD(Constants.PASSWORD), PATH(Constants.PATH), PATTERN(Constants.PATTERN), diff --git a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/Constants.java b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/Constants.java index b87e662962..3e4b3b6352 100644 --- a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/Constants.java +++ b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/Constants.java @@ -156,6 +156,7 @@ interface Constants { String WEBDAV = "webdav"; String WELCOME_FILE = "welcome-file"; String X_POWERED_BY = "x-powered-by"; + String GRACEFUL_INTERVAL = "graceful-interval"; /* Connect stats attributes */ String BYTES_SENT = "bytesSent"; diff --git a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/MobicentsContextGracefulShutdownOperationHandler.java b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/MobicentsContextGracefulShutdownOperationHandler.java new file mode 100644 index 0000000000..53176627dd --- /dev/null +++ b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/MobicentsContextGracefulShutdownOperationHandler.java @@ -0,0 +1,89 @@ +package org.mobicents.as7; + +import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.DESCRIPTION; +import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.NILLABLE; +import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OPERATION_NAME; +import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.REPLY_PROPERTIES; +import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.REQUEST_PROPERTIES; +import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.REQUIRED; +import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.TYPE; + +import java.util.Locale; + +import org.jboss.as.controller.OperationContext; +import org.jboss.as.controller.OperationFailedException; +import org.jboss.as.controller.OperationStepHandler; +import org.jboss.as.controller.descriptions.DescriptionProvider; +import org.jboss.as.controller.operations.validation.ModelTypeValidator; +import org.jboss.as.controller.operations.validation.ParametersValidator; +import org.jboss.dmr.ModelNode; +import org.jboss.dmr.ModelType; +import org.mobicents.servlet.sip.core.SipContext; +import org.mobicents.servlet.sip.startup.StaticServiceHolder; + +/** + * @author gvagenas + */ + +public class MobicentsContextGracefulShutdownOperationHandler implements OperationStepHandler , DescriptionProvider { + + public static final MobicentsContextGracefulShutdownOperationHandler INSTANCE = new MobicentsContextGracefulShutdownOperationHandler(); + private final ParametersValidator validator = new ParametersValidator(); + private String operationName = "contextGracefulShutdown"; + private String timeToWaitParamName = "timeToWait"; + private String sipAppParamName = "sipApp"; + + protected MobicentsContextGracefulShutdownOperationHandler(){ + validator.registerValidator("sipApp", new ModelTypeValidator(ModelType.STRING, true)); + validator.registerValidator("timeToWait", new ModelTypeValidator(ModelType.LONG, true)); + } + + @Override + public void execute(OperationContext context, ModelNode operation) + throws OperationFailedException { + + validator.validate(operation); + + String sipApp = operation.require("sipApp").asString(); + Long timeToWait = operation.require("timeToWait").asLong(); + if(context.isNormalServer()){ + SipContext sipContext = StaticServiceHolder.sipStandardService.getSipApplicationDispatcher().findSipApplication(sipApp); + + if(sipContext != null){ + sipContext.stopGracefully(timeToWait); + } else { + throw new OperationFailedException("Sip Application with name: "+sipApp+" doesn't exists"); + } + } else { + throw new OperationFailedException(new ModelNode().set("Operation available only for Standalone mode")); + } + + + context.completeStep(); + + } + + @Override + public ModelNode getModelDescription(Locale locale) { + final ModelNode node = new ModelNode(); + node.get(OPERATION_NAME).set(operationName); + node.get(DESCRIPTION).set("Gracefuly shutdown a SIP Application"); + + final ModelNode sipAppParam = node.get(REQUEST_PROPERTIES, sipAppParamName); + sipAppParam.get(DESCRIPTION).set("SIP Application to shutdown" + "." + sipAppParamName); + sipAppParam.get(TYPE).set(ModelType.STRING); + sipAppParam.get(REQUIRED).set(true); + sipAppParam.get(NILLABLE).set(false); + + final ModelNode timeToWaitparam = node.get(REQUEST_PROPERTIES, timeToWaitParamName); + timeToWaitparam.get(DESCRIPTION).set("Time to wait before shutdown" + "." + timeToWaitParamName); + timeToWaitparam.get(TYPE).set(ModelType.LONG); + timeToWaitparam.get(REQUIRED).set(true); + timeToWaitparam.get(NILLABLE).set(false); + + node.get(REPLY_PROPERTIES).setEmptyObject(); + + return node; + } + +} diff --git a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/MobicentsGracefulShutdownOperationHandler.java b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/MobicentsGracefulShutdownOperationHandler.java new file mode 100644 index 0000000000..5fb7f4441a --- /dev/null +++ b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/MobicentsGracefulShutdownOperationHandler.java @@ -0,0 +1,50 @@ +package org.mobicents.as7; + +import java.util.Locale; +import java.util.ResourceBundle; + +import org.jboss.as.controller.OperationContext; +import org.jboss.as.controller.OperationFailedException; +import org.jboss.as.controller.OperationStepHandler; +import org.jboss.as.controller.descriptions.DescriptionProvider; +import org.jboss.as.controller.descriptions.common.CommonDescriptions; +import org.jboss.as.controller.operations.validation.ModelTypeValidator; +import org.jboss.as.controller.operations.validation.ParametersValidator; +import org.jboss.dmr.ModelNode; +import org.jboss.dmr.ModelType; +import org.mobicents.servlet.sip.startup.StaticServiceHolder; + +/** + * @author gvagenas + */ + +public class MobicentsGracefulShutdownOperationHandler implements OperationStepHandler , DescriptionProvider { + + public static final MobicentsGracefulShutdownOperationHandler INSTANCE = new MobicentsGracefulShutdownOperationHandler(); + private final ParametersValidator validator = new ParametersValidator(); + + protected MobicentsGracefulShutdownOperationHandler(){ + validator.registerValidator("timeToWait", new ModelTypeValidator(ModelType.LONG, true)); + } + + @Override + public void execute(OperationContext context, ModelNode operation) + throws OperationFailedException { + validator.validate(operation); + Long timeToWait = operation.require("timeToWait").asLong(); + if(context.isNormalServer()){ + StaticServiceHolder.sipStandardService.stopGracefully(timeToWait); + } else { + throw new OperationFailedException(new ModelNode().set("Operation available only for Standalone mode")); + } + + context.completeStep(); + } + + @Override + public ModelNode getModelDescription(Locale locale) { + final ResourceBundle bundle = ResourceBundle.getBundle(MobicentsGracefulShutdownOperationHandler.class.getPackage().getName()+".LocalDescriptions"); + return CommonDescriptions.getSingleParamOnlyOperation(bundle, "gracefulShutdown", "sip", "timeToWait", ModelType.LONG, false); + } + +} diff --git a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/MobicentsListApplicationsOperationHandler.java b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/MobicentsListApplicationsOperationHandler.java new file mode 100644 index 0000000000..b5f711e5bf --- /dev/null +++ b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/MobicentsListApplicationsOperationHandler.java @@ -0,0 +1,64 @@ +package org.mobicents.as7; + +import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.DESCRIPTION; +import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OPERATION_NAME; +import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.REPLY_PROPERTIES; +import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.TYPE; +import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.VALUE_TYPE; + +import java.util.Iterator; +import java.util.Locale; + +import org.jboss.as.controller.OperationContext; +import org.jboss.as.controller.OperationFailedException; +import org.jboss.as.controller.OperationStepHandler; +import org.jboss.as.controller.descriptions.DescriptionProvider; +import org.jboss.dmr.ModelNode; +import org.jboss.dmr.ModelType; +import org.mobicents.servlet.sip.core.SipApplicationDispatcher; +import org.mobicents.servlet.sip.core.SipContext; +import org.mobicents.servlet.sip.startup.StaticServiceHolder; + +/** + * @author gvagenas + */ + +public class MobicentsListApplicationsOperationHandler implements OperationStepHandler , DescriptionProvider { + + public static final MobicentsListApplicationsOperationHandler INSTANCE = new MobicentsListApplicationsOperationHandler(); + + private String operationName = "listSipAppplications"; + private String description = "Get a list of deployed applications"; + + @Override + public ModelNode getModelDescription(Locale locale) { + final ModelNode result = new ModelNode(); + result.get(OPERATION_NAME).set(operationName); + result.get(DESCRIPTION).set(description); + + result.get(REPLY_PROPERTIES, TYPE).set(ModelType.OBJECT); + result.get(REPLY_PROPERTIES, VALUE_TYPE, "AppName").get(TYPE).set(ModelType.LIST); + result.get(REPLY_PROPERTIES, VALUE_TYPE, "AppName").get(VALUE_TYPE).set(ModelType.STRING); + return result; + } + + @Override + public void execute(OperationContext context, ModelNode operation) + throws OperationFailedException { + + ModelNode result = context.getResult(); + result.get("AppName").setEmptyList(); + if(context.isNormalServer()){ + SipApplicationDispatcher sipApplicationDispatcher = StaticServiceHolder.sipStandardService.getSipApplicationDispatcher(); + Iterator sipApps = sipApplicationDispatcher.findSipApplications(); + + while(sipApps.hasNext()){ + result.get("AppName").add(sipApps.next().getApplicationName()); + } + } else { + throw new OperationFailedException(new ModelNode().set("Operation available only for Standalone mode")); + } + context.completeStep(); + } + +} diff --git a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/SipConnectorService.java b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/SipConnectorService.java index 3a1d3b2be2..df465334c4 100644 --- a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/SipConnectorService.java +++ b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/SipConnectorService.java @@ -150,7 +150,8 @@ public synchronized void start(StartContext context) throws StartException { // TODO set Executor on ProtocolHandler // TODO use server socket factory - or integrate with {@code ManagedBinding} - getSipServer().addConnector(connector); + getSipServer().addConnector(connector); + connector.init(); connector.start(); this.connector = connector; @@ -159,6 +160,8 @@ public synchronized void start(StartContext context) throws StartException { } // Register the binding after the connector is started binding.getSocketBindings().getNamedRegistry().registerBinding(new ConnectorBinding(binding)); + //notify SipServer only when connector has already been added/started + getSipServer().connectorAdded(connector); } /** {@inheritDoc} */ diff --git a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/SipDefinition.java b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/SipDefinition.java index 50d70c1227..a12da5584f 100644 --- a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/SipDefinition.java +++ b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/SipDefinition.java @@ -188,7 +188,7 @@ public class SipDefinition extends SimpleResourceDefinition { .setAllowExpression(true) .setXmlName(Constants.GATHER_STATISTICS) .setFlags(AttributeAccess.Flag.RESTART_ALL_SERVICES) - .setDefaultValue(new ModelNode(false)) + .setDefaultValue(new ModelNode(true)) .build(); protected static final SimpleAttributeDefinition DIALOG_PENDING_REQUEST_CHECKING = new SimpleAttributeDefinitionBuilder(Constants.DIALOG_PENDING_REQUEST_CHECKING, ModelType.BOOLEAN, true) @@ -260,6 +260,13 @@ public class SipDefinition extends SimpleResourceDefinition { .setFlags(AttributeAccess.Flag.RESTART_ALL_SERVICES) .setDefaultValue(null) .build(); + protected static final SimpleAttributeDefinition GRACEFUL_INTERVAL = + new SimpleAttributeDefinitionBuilder(Constants.GRACEFUL_INTERVAL, ModelType.LONG, true) + .setAllowExpression(true) + .setXmlName(Constants.GRACEFUL_INTERVAL) + .setFlags(AttributeAccess.Flag.RESTART_ALL_SERVICES) + .setDefaultValue(new ModelNode(30000)) + .build(); private SipDefinition() { @@ -306,6 +313,7 @@ public void registerAttributes(ManagementResourceRegistration registration) { registration.registerReadWriteAttribute(MEMORY_THRESHOLD, null, new ReloadRequiredWriteAttributeHandler(MEMORY_THRESHOLD)); registration.registerReadWriteAttribute(BACK_TO_NORMAL_MEMORY_THRESHOLD, null, new ReloadRequiredWriteAttributeHandler(BACK_TO_NORMAL_MEMORY_THRESHOLD)); registration.registerReadWriteAttribute(OUTBOUND_PROXY, null, new ReloadRequiredWriteAttributeHandler(OUTBOUND_PROXY)); + registration.registerReadWriteAttribute(GRACEFUL_INTERVAL, null, new ReloadRequiredWriteAttributeHandler(GRACEFUL_INTERVAL)); for (SipStackStat stat : SipStackStat.values()) { registration.registerMetric(stat.definition, SipStackStatsHandler.getInstance()); } diff --git a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/SipExtension.java b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/SipExtension.java index 940b9575b9..26ab4d895f 100644 --- a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/SipExtension.java +++ b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/SipExtension.java @@ -62,6 +62,11 @@ public void initialize(ExtensionContext context) { final SubsystemRegistration subsystem = context.registerSubsystem(SUBSYSTEM_NAME, MANAGEMENT_API_MAJOR_VERSION, MANAGEMENT_API_MINOR_VERSION); final ManagementResourceRegistration registration = subsystem.registerSubsystemModel(SipDefinition.INSTANCE); registration.registerOperationHandler(DESCRIBE, GenericSubsystemDescribeHandler.INSTANCE, GenericSubsystemDescribeHandler.INSTANCE, false, OperationEntry.EntryType.PRIVATE); + + registration.registerOperationHandler("gracefulShutdown", MobicentsGracefulShutdownOperationHandler.INSTANCE, MobicentsGracefulShutdownOperationHandler.INSTANCE); + registration.registerOperationHandler("contextGracefulShutdown", MobicentsContextGracefulShutdownOperationHandler.INSTANCE, MobicentsContextGracefulShutdownOperationHandler.INSTANCE); + registration.registerOperationHandler("listSipAppplications", MobicentsListApplicationsOperationHandler.INSTANCE, MobicentsListApplicationsOperationHandler.INSTANCE); + //final ManagementResourceRegistration registration = subsystem.registerSubsystemModel(SipSubsystemDescriptionProviders.SUBSYSTEM); //registration.registerOperationHandler(ADD, SipSubsystemAdd.INSTANCE, SipSubsystemAdd.INSTANCE, false); //registration.registerOperationHandler(DESCRIBE, SipSubsystemDescribe.INSTANCE, SipSubsystemDescribe.INSTANCE, false, OperationEntry.EntryType.PRIVATE); diff --git a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/SipServer.java b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/SipServer.java index 8c2516a922..fea9cef7d7 100644 --- a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/SipServer.java +++ b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/SipServer.java @@ -73,5 +73,7 @@ public interface SipServer { * return the service (StandardService) */ StandardService getService(); + + void connectorAdded(Connector connector); } diff --git a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/SipServerService.java b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/SipServerService.java index 28b28d1b4b..844b461584 100644 --- a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/SipServerService.java +++ b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/SipServerService.java @@ -21,6 +21,7 @@ */ package org.mobicents.as7; +import java.util.concurrent.atomic.AtomicInteger; import static org.mobicents.as7.SipMessages.MESSAGES; import javax.management.MBeanServer; @@ -64,6 +65,7 @@ class SipServerService implements SipServer, Service { final String additionalParameterableHeaders; final String proxyTimerServiceImplementationType; final String sasTimerServiceImplementationType; + final boolean gatherStatistics; final int sipCongestionControlInterval; final String congestionControlPolicy; final String sipConcurrencyControlMode; @@ -83,6 +85,7 @@ class SipServerService implements SipServer, Service { final int memoryThreshold; final int backToNormalMemoryThreshold; final String outboundProxy; + private long gracefulInterval; private final String instanceId; @@ -104,6 +107,7 @@ public SipServerService( String additionalParameterableHeaders, String proxyTimerServiceImplementationType, String sasTimerServiceImplementationType, + boolean gatherStatistics, int sipCongestionControlInterval, String congestionControlPolicy, String sipConcurrencyControlMode, @@ -132,6 +136,7 @@ public SipServerService( this.additionalParameterableHeaders = additionalParameterableHeaders; this.proxyTimerServiceImplementationType = proxyTimerServiceImplementationType; this.sasTimerServiceImplementationType = sasTimerServiceImplementationType; + this.gatherStatistics = gatherStatistics; this.sipCongestionControlInterval = sipCongestionControlInterval; this.congestionControlPolicy = congestionControlPolicy; this.sipConcurrencyControlMode = sipConcurrencyControlMode; @@ -227,6 +232,7 @@ public synchronized void start(StartContext context) throws StartException { sipService.setProxyTimerServiceImplementationType(proxyTimerServiceImplementationType); sipService.setSasTimerServiceImplementationType(sasTimerServiceImplementationType); + sipService.setGatherStatistics(gatherStatistics); // sipService.setCongestionControlCheckingInterval(sipCongestionControlInterval); // @@ -252,6 +258,7 @@ public synchronized void start(StartContext context) throws StartException { sipService.setOutboundProxy(outboundProxy); sipService.setName(JBOSS_SIP); sipService.setServer(server); + sipService.setGracefulInterval(gracefulInterval); sipEngine = new SipStandardEngine(); sipEngine.setName(JBOSS_SIP); @@ -288,6 +295,8 @@ public synchronized void stop(StopContext context) { public synchronized SipServer getValue() throws IllegalStateException { return this; } + + private AtomicInteger addedConnectors = new AtomicInteger(0); /** {@inheritDoc} */ public synchronized void addConnector(Connector connector) { @@ -296,6 +305,17 @@ public synchronized void addConnector(Connector connector) { sipService.addConnector(connector); } } + + public synchronized void connectorAdded(Connector connector) { + if (connector.getProtocolHandler() instanceof SipProtocolHandler) { + int currentConnectors = addedConnectors.incrementAndGet(); + if (currentConnectors >= SipSubsystemParser.getInstance().parsedConnectors.get()) { + logger.debug("Time to put dispatcher in service."); + sipService.getSipApplicationDispatcher().putInService(); + + } + } + } /** {@inheritDoc} */ public synchronized void removeConnector(Connector connector) { @@ -341,4 +361,8 @@ public SipStandardService getSipService() { return sipService; } + public void setGracefulInterval(long gracefulInterval) { + this.gracefulInterval = gracefulInterval; + } + } diff --git a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/SipSubsystemAdd.java b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/SipSubsystemAdd.java index f7b1ed4d34..d72d515ffd 100644 --- a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/SipSubsystemAdd.java +++ b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/SipSubsystemAdd.java @@ -1,5 +1,5 @@ /* - * TeleStax, Open Source Cloud Communications Copyright 2012. + * TeleStax, Open Source Cloud Communications Copyright 2012. * and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. @@ -62,7 +62,7 @@ * @author josemrecio@gmail.com */ class SipSubsystemAdd extends AbstractBoottimeAddStepHandler { - private static final Logger logger = Logger.getLogger(SipServerService.class); + private static final Logger logger = Logger.getLogger(SipSubsystemAdd.class); // FIXME: these priorities should be substituted by values from with org.jboss.as.server.deployment.Phase // aligned with those used by web subsystem static int PARSE_SIP_DEPLOYMENT_PRIORITY = 0x4000; @@ -74,7 +74,7 @@ class SipSubsystemAdd extends AbstractBoottimeAddStepHandler { // private static final boolean DEFAULT_NATIVE = true; private SipSubsystemAdd() { - // + // } // @Override @@ -84,6 +84,10 @@ private SipSubsystemAdd() { @Override protected void populateModel(ModelNode operation, ModelNode model) throws OperationFailedException { + if(logger.isDebugEnabled()) { + logger.debug("populateModel"); + } + SipDefinition.INSTANCE_ID.validateAndSet(operation, model); SipDefinition.APPLICATION_ROUTER.validateAndSet(operation, model); SipDefinition.SIP_STACK_PROPS.validateAndSet(operation, model); @@ -111,12 +115,16 @@ protected void populateModel(ModelNode operation, ModelNode model) throws Operat SipDefinition.MEMORY_THRESHOLD.validateAndSet(operation, model); SipDefinition.BACK_TO_NORMAL_MEMORY_THRESHOLD.validateAndSet(operation, model); SipDefinition.OUTBOUND_PROXY.validateAndSet(operation, model); + SipDefinition.GRACEFUL_INTERVAL.validateAndSet(operation, model); } @Override protected void performBoottime(OperationContext context, ModelNode operation, ModelNode model, ServiceVerificationHandler verificationHandler, List> newControllers) throws OperationFailedException { + if(logger.isDebugEnabled()) { + logger.debug("performBoottime"); + } ModelNode fullModel = Resource.Tools.readModel(context.readResource(PathAddress.EMPTY_ADDRESS)); final ModelNode instanceIdModel = SipDefinition.INSTANCE_ID.resolveModelAttribute(context, fullModel); @@ -133,10 +141,10 @@ protected void performBoottime(OperationContext context, ModelNode operation, Mo final ModelNode sipAppDispatcherClassModel = SipDefinition.SIP_APP_DISPATCHER_CLASS.resolveModelAttribute(context, fullModel); final String sipAppDispatcherClass = sipAppDispatcherClassModel.isDefined() ? sipAppDispatcherClassModel.asString() : null; - + final ModelNode usePrettyEncodingModel = SipDefinition.USE_PRETTY_ENCODING.resolveModelAttribute(context, fullModel); final boolean usePrettyEncoding = usePrettyEncodingModel.isDefined() ? usePrettyEncodingModel.asBoolean() : true; - + final ModelNode additionalParameterableHeadersModel = SipDefinition.ADDITIONAL_PARAMETERABLE_HEADERS.resolveModelAttribute(context, fullModel); final String additionalParameterableHeaders = additionalParameterableHeadersModel.isDefined() ? additionalParameterableHeadersModel.asString() : null; @@ -145,61 +153,64 @@ protected void performBoottime(OperationContext context, ModelNode operation, Mo final ModelNode sasTimerServiceImplementationTypeModel = SipDefinition.SAS_TIMER_SERVICE_IMPEMENTATION_TYPE.resolveModelAttribute(context, fullModel); final String sasTimerServiceImplementationType = sasTimerServiceImplementationTypeModel.isDefined() ? sasTimerServiceImplementationTypeModel.asString() : Constants.STANDARD; - + final ModelNode sipCongestionControlIntervalModel = SipDefinition.CONGESTION_CONTROL_INTERVAL.resolveModelAttribute(context, fullModel); final int sipCongestionControlInterval = sipCongestionControlIntervalModel.isDefined() ? sipCongestionControlIntervalModel.asInt() : -1; final ModelNode congestionControlPolicyModel = SipDefinition.CONGESTION_CONTROL_POLICY.resolveModelAttribute(context, fullModel); final String congestionControlPolicy = congestionControlPolicyModel.isDefined() ? congestionControlPolicyModel.asString() : "ErrorResponse"; - + final ModelNode sipConcurrencyControlModeModel = SipDefinition.CONCURRENCY_CONTROL_MODE.resolveModelAttribute(context, fullModel); final String sipConcurrencyControlMode = sipConcurrencyControlModeModel.isDefined() ? sipConcurrencyControlModeModel.asString() : null; final ModelNode baseTimerIntervalModel = SipDefinition.BASE_TIMER_INTERVAL.resolveModelAttribute(context, fullModel); final int baseTimerInterval = baseTimerIntervalModel.isDefined() ? baseTimerIntervalModel.asInt() : 500; - + final ModelNode t2IntervalModel = SipDefinition.T2_INTERVAL.resolveModelAttribute(context, fullModel); final int t2Interval = t2IntervalModel.isDefined() ? t2IntervalModel.asInt() : 4000; - + final ModelNode t4IntervalModel = SipDefinition.T4_INTERVAL.resolveModelAttribute(context, fullModel); final int t4Interval = t4IntervalModel.isDefined() ? t4IntervalModel.asInt() : 5000; - + final ModelNode timerDIntervalModel = SipDefinition.TIMER_D_INTERVAL.resolveModelAttribute(context, fullModel); final int timerDInterval = timerDIntervalModel.isDefined() ? timerDIntervalModel.asInt() : 32000; - + final ModelNode gatherStatisticsModel = SipDefinition.GATHER_STATISTICS.resolveModelAttribute(context, fullModel); - final boolean gatherStatistics = gatherStatisticsModel.isDefined() ? gatherStatisticsModel.asBoolean() : false; - + final boolean gatherStatistics = gatherStatisticsModel.isDefined() ? gatherStatisticsModel.asBoolean() : true; + final ModelNode dialogPendingRequestCheckingModel = SipDefinition.DIALOG_PENDING_REQUEST_CHECKING.resolveModelAttribute(context, fullModel); final boolean dialogPendingRequestChecking = dialogPendingRequestCheckingModel.isDefined() ? dialogPendingRequestCheckingModel.asBoolean() : false; - + final ModelNode dnsServerLocatorClassModel = SipDefinition.DNS_SERVER_LOCATOR_CLASS.resolveModelAttribute(context, fullModel); final String dnsServerLocatorClass = dnsServerLocatorClassModel.isDefined() ? dnsServerLocatorClassModel.asString() : DefaultDNSServerLocator.class.getName(); - + final ModelNode dnsTimeoutModel = SipDefinition.DNS_TIMEOUT.resolveModelAttribute(context, fullModel); final int dnsTimeout = dnsTimeoutModel.isDefined() ? dnsTimeoutModel.asInt() : null; - + final ModelNode dnsResolverClassModel = SipDefinition.DNS_RESOLVER_CLASS.resolveModelAttribute(context, fullModel); final String dnsResolverClass = dnsResolverClassModel.isDefined() ? dnsResolverClassModel.asString() : null; - + final ModelNode callIdMaxLengthModel = SipDefinition.CALL_ID_MAX_LENGTH.resolveModelAttribute(context, fullModel); final int callIdMaxLength = callIdMaxLengthModel.isDefined() ? callIdMaxLengthModel.asInt() : -1; - + final ModelNode tagHashMaxLengthModel = SipDefinition.TAG_HASH_MAX_LENGTH.resolveModelAttribute(context, fullModel); final int tagHashMaxLength = tagHashMaxLengthModel.isDefined() ? tagHashMaxLengthModel.asInt() : -1; - + final ModelNode canceledTimerTasksPurgePeriodModel = SipDefinition.CANCELED_TIMER_TASKS_PURGE_PERIOD.resolveModelAttribute(context, fullModel); final int canceledTimerTasksPurgePeriod = canceledTimerTasksPurgePeriodModel.isDefined() ? canceledTimerTasksPurgePeriodModel.asInt() : -1; - + final ModelNode memoryThresholdModel = SipDefinition.MEMORY_THRESHOLD.resolveModelAttribute(context, fullModel); final int memoryThreshold = memoryThresholdModel.isDefined() ? memoryThresholdModel.asInt() : -1; - + final ModelNode backToNormalMemoryThresholdModel = SipDefinition.BACK_TO_NORMAL_MEMORY_THRESHOLD.resolveModelAttribute(context, fullModel); final int backToNormalMemoryThreshold = backToNormalMemoryThresholdModel.isDefined() ? backToNormalMemoryThresholdModel.asInt() : -1; - + final ModelNode outboundProxyModel = SipDefinition.OUTBOUND_PROXY.resolveModelAttribute(context, fullModel); final String outboundProxy = outboundProxyModel.isDefined() ? outboundProxyModel.asString() : null; - + + final ModelNode gracefulIntervalModel = SipDefinition.GRACEFUL_INTERVAL.resolveModelAttribute(context, fullModel); + final Long gracefulInterval = gracefulIntervalModel.isDefined() ? gracefulIntervalModel.asLong() : null; + // final String instanceId = operation.hasDefined(Constants.INSTANCE_ID) ? operation.get(Constants.INSTANCE_ID).asString() : null; // final String sipAppRouterFile = operation.hasDefined(Constants.APPLICATION_ROUTER) ? operation.get(Constants.APPLICATION_ROUTER).asString() : null; // final String sipStackPropertiesFile = operation.hasDefined(Constants.SIP_STACK_PROPS) ? operation.get(Constants.SIP_STACK_PROPS).asString() : null; @@ -217,34 +228,36 @@ protected void performBoottime(OperationContext context, ModelNode operation, Mo !Constants.DEFAULT.equalsIgnoreCase(proxyTimerServiceImplementationType) && !Constants.STANDARD.equalsIgnoreCase(proxyTimerServiceImplementationType)) { throw new OperationFailedException("Invalid value is set for "+Constants.PROXY_TIMER_SERVICE_IMPEMENTATION_TYPE+" property: "+proxyTimerServiceImplementationType+"! Valid values are: "+Constants.DEFAULT +", "+Constants.STANDARD+"."); } - + final SipServerService service = new SipServerService( - sipAppRouterFile, - sipStackPropertiesFile, - sipPathName, - sipAppDispatcherClass, - additionalParameterableHeaders, - proxyTimerServiceImplementationType, - sasTimerServiceImplementationType, + sipAppRouterFile, + sipStackPropertiesFile, + sipPathName, + sipAppDispatcherClass, + additionalParameterableHeaders, + proxyTimerServiceImplementationType, + sasTimerServiceImplementationType, + gatherStatistics, sipCongestionControlInterval, congestionControlPolicy, - sipConcurrencyControlMode, - usePrettyEncoding, - baseTimerInterval, - t2Interval, - t4Interval, - timerDInterval, + sipConcurrencyControlMode, + usePrettyEncoding, + baseTimerInterval, + t2Interval, + t4Interval, + timerDInterval, dialogPendingRequestChecking, dnsServerLocatorClass, dnsTimeout, dnsResolverClass, callIdMaxLength, tagHashMaxLength, - canceledTimerTasksPurgePeriod, + canceledTimerTasksPurgePeriod, memoryThreshold, backToNormalMemoryThreshold, outboundProxy, instanceId); + service.setGracefulInterval(gracefulInterval); newControllers.add(context.getServiceTarget().addService(SipSubsystemServices.JBOSS_SIP, service) .addDependency(PathManagerService.SERVICE_NAME, PathManager.class, service.getPathManagerInjector()) .addDependency(DependencyType.OPTIONAL, ServiceName.JBOSS.append("mbean", "server"), MBeanServer.class, service.getMbeanServer()) @@ -310,9 +323,9 @@ protected void execute(DeploymentProcessorTarget processorTarget) { .setInitialMode(Mode.ON_DEMAND) .install()); newControllers.addAll(factory.installServices(target)); - } + } + - } @Override diff --git a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/SipSubsystemParser.java b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/SipSubsystemParser.java index 33030dc3b7..1bce58ffa1 100644 --- a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/SipSubsystemParser.java +++ b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/SipSubsystemParser.java @@ -31,6 +31,7 @@ import java.util.Collections; import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; @@ -57,6 +58,7 @@ class SipSubsystemParser implements XMLStreamConstants, XMLElementReader>, XMLElementWriter { private static final SipSubsystemParser INSTANCE = new SipSubsystemParser(); + AtomicInteger parsedConnectors = new AtomicInteger(0); static SipSubsystemParser getInstance() { return INSTANCE; @@ -98,6 +100,7 @@ public void writeContent(XMLExtendedStreamWriter writer, SubsystemMarshallingCon SipDefinition.MEMORY_THRESHOLD.marshallAsAttribute(node, false, writer); SipDefinition.BACK_TO_NORMAL_MEMORY_THRESHOLD.marshallAsAttribute(node, false, writer); SipDefinition.OUTBOUND_PROXY.marshallAsAttribute(node, false, writer); + SipDefinition.GRACEFUL_INTERVAL.marshallAsAttribute(node, false, writer); if(node.hasDefined(CONNECTOR)) { for(final Property connector : node.get(CONNECTOR).asPropertyList()) { final ModelNode config = connector.getValue(); @@ -154,6 +157,7 @@ public void readElement(XMLExtendedStreamReader reader, List list) th case OUTBOUND_PROXY: case CONCURRENCY_CONTROL_MODE: case USE_PRETTY_ENCODING: + case GRACEFUL_INTERVAL: subsystem.get(attribute.getLocalName()).set(value); break; default: @@ -258,6 +262,7 @@ static void parseConnector(XMLExtendedStreamReader reader, PathAddress parent, L PathAddress address = PathAddress.pathAddress(parent, PathElement.pathElement(CONNECTOR, name)); connector.get(OP_ADDR).set(address.toModelNode()); list.add(connector); + getInstance().parsedConnectors.incrementAndGet(); while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { switch (Namespace.forUri(reader.getNamespaceURI())) { diff --git a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/clustering/sip/MockDistributedCacheManager.java b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/clustering/sip/MockDistributedCacheManager.java index 8f44ace0d5..ac44d4f0db 100644 --- a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/clustering/sip/MockDistributedCacheManager.java +++ b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/clustering/sip/MockDistributedCacheManager.java @@ -36,12 +36,15 @@ * */ public class MockDistributedCacheManager implements DistributedCacheManager { + public static final MockDistributedCacheManager INSTANCE = new MockDistributedCacheManager(); + @Override public void evictSession(String realId) { // no-op } + @Override public void evictSession(String realId, String dataOwner) { // no-op } @@ -58,22 +61,27 @@ public Map getAttributes(String realId) { return Collections.emptyMap(); } + @Override public BatchingManager getBatchingManager() { return MockBatchingManager.INSTANCE; } + @Override public IncomingDistributableSessionData getSessionData(String realId, boolean initialLoad) { return null; } + @Override public IncomingDistributableSessionData getSessionData(String realId, String dataOwner, boolean includeAttributes) { return null; } + @Override public Map getSessionIds() { return Collections.emptyMap(); } + @Override public boolean isPassivationEnabled() { return false; } @@ -102,22 +110,27 @@ public void removeAttributesLocal(String realId) { // no-op } + @Override public void removeSession(String realId) { // no-op } + @Override public void removeSessionLocal(String realId) { // no-op } + @Override public void removeSessionLocal(String realId, String dataOwner) { // no-op } + @Override public void start() { // no-op } + @Override public void stop() { // no-op } @@ -126,22 +139,27 @@ public boolean getSupportsAttributeOperations() { return true; } + @Override public void sessionCreated(String realId) { // no-op } + @Override public void storeSessionData(OutgoingDistributableSessionData sessionData) { // no-op } + @Override public void setForceSynchronous(boolean forceSynchronous) { // no-op } + @Override public SessionOwnershipSupport getSessionOwnershipSupport() { return null; } + @Override public boolean isLocal(String realId) { return false; } diff --git a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/deployment/SipParsingDeploymentProcessor.java b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/deployment/SipParsingDeploymentProcessor.java index 38bbf96d78..b4620d6787 100644 --- a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/deployment/SipParsingDeploymentProcessor.java +++ b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/as7/deployment/SipParsingDeploymentProcessor.java @@ -35,8 +35,10 @@ import org.jboss.as.server.deployment.DeploymentUnit; import org.jboss.as.server.deployment.DeploymentUnitProcessingException; import org.jboss.as.server.deployment.DeploymentUnitProcessor; +import org.jboss.logging.Logger; import org.jboss.metadata.parser.util.MetaDataElementParser; import org.jboss.vfs.VirtualFile; +import org.mobicents.metadata.sip.parser.SipCommonMetaDataParser; import org.mobicents.metadata.sip.parser.SipMetaDataParser; import org.mobicents.metadata.sip.spec.SipMetaData; @@ -47,6 +49,8 @@ */ public class SipParsingDeploymentProcessor implements DeploymentUnitProcessor { + private static transient Logger logger = Logger.getLogger(SipParsingDeploymentProcessor.class); + protected static final String SIP_XML = "WEB-INF/sip.xml"; private final boolean schemaValidation = true; @@ -95,6 +99,9 @@ public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitPro MetaDataElementParser.DTDInfo dtdInfo = new MetaDataElementParser.DTDInfo(); inputFactory.setXMLResolver(dtdInfo); final XMLStreamReader xmlReader = inputFactory.createXMLStreamReader(is); + if (logger.isDebugEnabled()){ + logger.debug("deploy - parse xml"); + } SipMetaData sipMetaData = SipMetaDataParser.parse(xmlReader, dtdInfo); deploymentUnit.putAttachment(SipMetaData.ATTACHMENT_KEY, sipMetaData); } catch (XMLStreamException e) { diff --git a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/metadata/sip/spec/SipMetaData.java b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/metadata/sip/spec/SipMetaData.java index 6165adad7f..5fd2c8538e 100644 --- a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/metadata/sip/spec/SipMetaData.java +++ b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/java/org/mobicents/metadata/sip/spec/SipMetaData.java @@ -1,5 +1,5 @@ /* - * TeleStax, Open Source Cloud Communications Copyright 2012. + * TeleStax, Open Source Cloud Communications Copyright 2012. * and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. @@ -62,7 +62,7 @@ public abstract class SipMetaData extends WebMetaData implements Environment { // private MessageDestinationsMetaData messageDestinations; // AS7 isolated class loading does not allow to fetch Method, - // so processors fill SipApplicationKeyMethodInfo and Method is fetched afterwards + // so processors fill SipApplicationKeyMethodInfo and Method is fetched afterwards // private Method sipApplicationKeyMethod; private SipApplicationKeyMethodInfo sipApplicationKeyMethodInfo; private ConcurrencyControlMode concurrencyControlMode; diff --git a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/resources/org/mobicents/as7/LocalDescriptions.properties b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/resources/org/mobicents/as7/LocalDescriptions.properties index 90fa5a8dd5..4e7c61bffd 100644 --- a/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/resources/org/mobicents/as7/LocalDescriptions.properties +++ b/containers/sip-servlets-as7-drop-in/jboss-as-mobicents/src/main/resources/org/mobicents/as7/LocalDescriptions.properties @@ -141,3 +141,7 @@ sip.deployment.sip-session-avg-alive-time=Average time (in seconds) that expired sip.deployment.sip-application-session-avg-alive-time=Average time (in seconds) that expired sip application sessions had been alive sip.deployment.sip-session-max-alive-time=The longest time (in seconds) that an expired sip session had been alive sip.deployment.sip-application-session-max-alive-time=The longest time (in seconds) that an expired sip application session had been alive + +sip.gracefulShutdown=Graceful Shutdown operation +sip.gracefulShutdown.timeToWait=Time to wait for a graceful shutdown +sip.graceful-interval=Interval of checks for timeout of Graceful Shutdown \ No newline at end of file diff --git a/containers/sip-servlets-as7/.classpath b/containers/sip-servlets-as7/.classpath index 20026b077c..d36a3875f7 100644 --- a/containers/sip-servlets-as7/.classpath +++ b/containers/sip-servlets-as7/.classpath @@ -1,115 +1,131 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/containers/sip-servlets-as7/src/main/java/org/mobicents/servlet/sip/catalina/ContextGracefulStopTask.java b/containers/sip-servlets-as7/src/main/java/org/mobicents/servlet/sip/catalina/ContextGracefulStopTask.java index 1d854e838e..350067e85a 100644 --- a/containers/sip-servlets-as7/src/main/java/org/mobicents/servlet/sip/catalina/ContextGracefulStopTask.java +++ b/containers/sip-servlets-as7/src/main/java/org/mobicents/servlet/sip/catalina/ContextGracefulStopTask.java @@ -22,9 +22,10 @@ package org.mobicents.servlet.sip.catalina; import org.apache.catalina.Context; -import org.apache.catalina.LifecycleException; import org.apache.catalina.core.StandardContext; import org.apache.log4j.Logger; +import org.mobicents.javax.servlet.ContainerListener; +import org.mobicents.javax.servlet.GracefulShutdownCheckEvent; import org.mobicents.servlet.sip.core.SipContext; /** @@ -32,35 +33,67 @@ * */ public class ContextGracefulStopTask implements Runnable { - private static final Logger logger = Logger.getLogger(ContextGracefulStopTask.class); - Context sipContext; - long timeToWait; - long startTime; - public ContextGracefulStopTask(Context context, long timeToWait) { - sipContext = context; - this.timeToWait = timeToWait; - startTime = System.currentTimeMillis(); - } + private static final Logger logger = Logger.getLogger(ContextGracefulStopTask.class); + Context sipContext; + long timeToWait; + long startTime; + + public ContextGracefulStopTask(Context context, long timeToWait) { + sipContext = context; + this.timeToWait = timeToWait; + startTime = System.currentTimeMillis(); + } + + private static final String PREVENT_PREMATURE_SHUTDOWN = "org.mobicents.servlet.sip.PREVENT_PREMATURE_SHUTDOWN"; + + @Override + public void run() { + int numberOfActiveSipApplicationSessions = ((SipContext) sipContext).getSipManager().getActiveSipApplicationSessions(); + int numberOfActiveHttpSessions = sipContext.getManager().getActiveSessions(); + if (logger.isTraceEnabled()) { + logger.trace("ContextGracefulStopTask running for context " + sipContext.getName() + ", number of Sip Application Sessions still active " + numberOfActiveSipApplicationSessions + " number of HTTP Sessions still active " + numberOfActiveHttpSessions); + } + + boolean stopPrematuraly = false; + long currentTime = System.currentTimeMillis(); + // if timeToWait is positive, then we check the time since the task started, if the time is greater than timeToWait we can safely stop the context + long elapsedTime = currentTime - startTime; + if (timeToWait > 0 && (elapsedTime > timeToWait)) { + logger.info("Graceful TimeToWait Consumed."); + stopContext(); + } + if (logger.isDebugEnabled()) { + logger.debug("ContextGracefulStopTask running for context " + sipContext.getName() + + ", number of Sip Application Sessions still active " + numberOfActiveSipApplicationSessions + + " number of HTTP Sessions still active " + numberOfActiveHttpSessions + + ", stopPrematurely " + stopPrematuraly); + } + if (numberOfActiveSipApplicationSessions <= 0 + && numberOfActiveHttpSessions <= 0) { + logger.info("No more active sessions, lets check with service"); + boolean servicePremature = true; + ContainerListener containerListener = ((SipContext) sipContext).getListeners().getContainerListener(); + if (containerListener != null) { + GracefulShutdownCheckEvent event = new GracefulShutdownCheckEvent(elapsedTime, timeToWait); + ((SipContext) sipContext).getListeners().callbackContainerListener(event); + servicePremature = sipContext.getServletContext().getAttribute(PREVENT_PREMATURE_SHUTDOWN) == null; + logger.info("servicePremature=" + servicePremature); + } + if (servicePremature) { + stopContext(); + } + + } + } + + private void stopContext() { + try { + logger.info("About to stop the context."); + ((StandardContext) sipContext).stop(); + } catch (Exception e) { + logger.error("Couldn't gracefully stop context " + sipContext.getName(), e); + } + } - public void run() { - int numberOfActiveSipApplicationSessions = ((SipContext)sipContext).getSipManager().getActiveSipApplicationSessions(); - int numberOfActiveHttpSessions = sipContext.getManager().getActiveSessions(); - if(logger.isTraceEnabled()) { - logger.trace("ContextGracefulStopTask running for context " + sipContext.getName() + ", number of Sip Application Sessions still active " + numberOfActiveSipApplicationSessions + " number of HTTP Sessions still active " + numberOfActiveHttpSessions); - } - boolean stopPrematuraly = false; - long currentTime = System.currentTimeMillis(); - // if timeToWait is positive, then we check the time since the task started, if the time is greater than timeToWait we can safely stop the context - if(timeToWait > 0 && ((currentTime - startTime) > timeToWait)) { - stopPrematuraly = true; - } - if((numberOfActiveSipApplicationSessions <= 0 && numberOfActiveHttpSessions <= 0) || stopPrematuraly) { - try { - ((StandardContext)sipContext).stop(); - } catch (LifecycleException e) { - logger.error("Couldn't gracefully stop context " + sipContext.getName(), e); - } - } - } } diff --git a/containers/sip-servlets-as7/src/main/java/org/mobicents/servlet/sip/catalina/ServiceGracefulStopTask.java b/containers/sip-servlets-as7/src/main/java/org/mobicents/servlet/sip/catalina/ServiceGracefulStopTask.java index c8152e3505..4fef8c1a19 100644 --- a/containers/sip-servlets-as7/src/main/java/org/mobicents/servlet/sip/catalina/ServiceGracefulStopTask.java +++ b/containers/sip-servlets-as7/src/main/java/org/mobicents/servlet/sip/catalina/ServiceGracefulStopTask.java @@ -36,17 +36,28 @@ public class ServiceGracefulStopTask implements Runnable { private static final Logger logger = Logger.getLogger(ServiceGracefulStopTask.class); StandardService sipService; + long timeToWait; + long startTime; - public ServiceGracefulStopTask(StandardService sipService) { + public ServiceGracefulStopTask(StandardService sipService, long timeToWait) { this.sipService = sipService; + this.timeToWait = timeToWait; + startTime = System.currentTimeMillis(); } public void run() { int numberOfSipApplicationsDeployed = ((SipService)sipService).getSipApplicationDispatcher().findInstalledSipApplications().length; - if(logger.isTraceEnabled()) { - logger.trace("ServiceGracefulStopTask running, number of Sip Application still running " + numberOfSipApplicationsDeployed); + boolean stopPrematuraly = false; + long currentTime = System.currentTimeMillis(); + // if timeToWait is positive, then we check the time since the task started, if the time is greater than timeToWait we can safely stop the context + if(timeToWait > 0 && ((currentTime - startTime) > timeToWait)) { + stopPrematuraly = true; } - if(numberOfSipApplicationsDeployed <= 0) { + if(logger.isDebugEnabled()) { + logger.debug("ServiceGracefulStopTask running, number of Sip Application still running " + numberOfSipApplicationsDeployed + + ", stopPrematurely " + stopPrematuraly); + } + if(numberOfSipApplicationsDeployed <= 0 || stopPrematuraly) { try { sipService.stop(); ((SipStandardService)sipService).shutdownServer(); diff --git a/containers/sip-servlets-as7/src/main/java/org/mobicents/servlet/sip/catalina/SipStandardService.java b/containers/sip-servlets-as7/src/main/java/org/mobicents/servlet/sip/catalina/SipStandardService.java index fe900e7bdd..d80a71b87a 100644 --- a/containers/sip-servlets-as7/src/main/java/org/mobicents/servlet/sip/catalina/SipStandardService.java +++ b/containers/sip-servlets-as7/src/main/java/org/mobicents/servlet/sip/catalina/SipStandardService.java @@ -1,1411 +1,1450 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.catalina; - - -import gov.nist.core.net.AddressResolver; -import gov.nist.javax.sip.SipStackExt; -import gov.nist.javax.sip.message.MessageFactoryExt; -import gov.nist.javax.sip.stack.SIPTransactionStack; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.lang.management.ManagementFactory; -import java.lang.reflect.Constructor; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Properties; -import java.util.StringTokenizer; -import java.util.TooManyListenersException; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; - -import javax.management.InstanceNotFoundException; -import javax.management.MBeanException; -import javax.management.MBeanServerConnection; -import javax.management.MalformedObjectNameException; -import javax.management.ObjectName; -import javax.management.ReflectionException; -import javax.sip.PeerUnavailableException; -import javax.sip.SipStack; -import javax.sip.header.ServerHeader; -import javax.sip.header.UserAgentHeader; - -import org.apache.catalina.Engine; -import org.apache.catalina.LifecycleException; -import org.apache.catalina.connector.Connector; -import org.apache.catalina.core.StandardService; -import org.apache.coyote.ProtocolHandler; -import org.apache.log4j.Logger; -import org.apache.tomcat.util.modeler.Registry; -import org.mobicents.ext.javax.sip.dns.DNSAwareRouter; -import org.mobicents.ext.javax.sip.dns.DNSServerLocator; -import org.mobicents.ext.javax.sip.dns.DefaultDNSServerLocator; -import org.mobicents.ha.javax.sip.ClusteredSipStack; -import org.mobicents.ha.javax.sip.LoadBalancerHeartBeatingListener; -import org.mobicents.ha.javax.sip.LoadBalancerHeartBeatingService; -import org.mobicents.ha.javax.sip.LoadBalancerHeartBeatingServiceImpl; -import org.mobicents.ha.javax.sip.ReplicationStrategy; -import org.mobicents.javax.servlet.CongestionControlPolicy; -import org.mobicents.servlet.sip.JainSipUtils; -import org.mobicents.servlet.sip.SipConnector; -import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; -import org.mobicents.servlet.sip.core.ExtendedListeningPoint; -import org.mobicents.servlet.sip.core.MobicentsExtendedListeningPoint; -import org.mobicents.servlet.sip.core.SipApplicationDispatcher; -import org.mobicents.servlet.sip.core.SipContext; -import org.mobicents.servlet.sip.core.message.OutboundProxy; -import org.mobicents.servlet.sip.dns.MobicentsDNSResolver; -import org.mobicents.servlet.sip.message.Servlet3SipServletMessageFactory; -import org.mobicents.servlet.sip.startup.StaticServiceHolder; - -/** - * Sip Servlet implementation of the SipService interface. - * This class inherits from the Tomcat StandardService. It adds a SipApplicationDispatcher - * that will be listen for sip messages received by the sip stacks started by - * the sip connectors associated with this context. - * This has one attribute which is the sipApplicationDispatcherClassName allowing one - * to specify the class name of the sipApplicationDispacther to easily replace - * the default sipApplicationDispatcher with a custom one. - * - * @author Jean Deruelle - */ -public class SipStandardService extends StandardService implements CatalinaSipService { - //the logger - private static final Logger logger = Logger.getLogger(SipStandardService.class); - public static final String DEFAULT_SIP_PATH_NAME = "gov.nist"; - public static final String PASS_INVITE_NON_2XX_ACK_TO_LISTENER = "gov.nist.javax.sip.PASS_INVITE_NON_2XX_ACK_TO_LISTENER"; - public static final String TCP_POST_PARSING_THREAD_POOL_SIZE = "gov.nist.javax.sip.TCP_POST_PARSING_THREAD_POOL_SIZE"; - public static final String AUTOMATIC_DIALOG_SUPPORT_STACK_PROP = "javax.sip.AUTOMATIC_DIALOG_SUPPORT"; - public static final String LOOSE_DIALOG_VALIDATION = "gov.nist.javax.sip.LOOSE_DIALOG_VALIDATION"; - public static final String SERVER_LOG_STACK_PROP = "gov.nist.javax.sip.SERVER_LOG"; - public static final String DEBUG_LOG_STACK_PROP = "gov.nist.javax.sip.DEBUG_LOG"; - public static final String SERVER_HEADER = "org.mobicents.servlet.sip.SERVER_HEADER"; - public static final String USER_AGENT_HEADER = "org.mobicents.servlet.sip.USER_AGENT_HEADER"; - public static final String JVM_ROUTE = "jvmRoute"; - /** - * The descriptive information string for this implementation. - */ - private static final String INFO = - "org.mobicents.servlet.sip.startup.SipStandardService/1.0"; - //the sip application dispatcher class name defined in the server.xml - protected String sipApplicationDispatcherClassName; - //instatiated class from the sipApplicationDispatcherClassName of the sip application dispatcher - protected SipApplicationDispatcher sipApplicationDispatcher; - private boolean gatherStatistics = true; - protected int sipMessageQueueSize = 1500; - private int backToNormalSipMessageQueueSize = 1300; - protected int memoryThreshold = 95; - private int backToNormalMemoryThreshold = 90; - protected OutboundProxy outboundProxy; - protected String proxyTimerServiceImplementationType; - protected String sasTimerServiceImplementationType; - protected long congestionControlCheckingInterval = 30000; - private int canceledTimerTasksPurgePeriod = 0; - // base timer interval for jain sip tx - private int baseTimerInterval = 500; - private int t2Interval = 4000; - private int t4Interval = 5000; - private int timerDInterval = 32000; - protected int dispatcherThreadPoolSize = 15; - private boolean md5ContactUserPart = false; - - protected String concurrencyControlMode = ConcurrencyControlMode.SipApplicationSession.toString(); - protected String congestionControlPolicy = CongestionControlPolicy.ErrorResponse.toString(); - protected String additionalParameterableHeaders; - protected boolean bypassResponseExecutor = true; - protected boolean bypassRequestExecutor = true; - //this should be made available to the application router as a system prop - protected String darConfigurationFileLocation; - protected boolean connectorsStartedExternally = false; - protected boolean dialogPendingRequestChecking = false; - protected int callIdMaxLength; - protected int tagHashMaxLength; - - protected boolean httpFollowsSip = false; - protected String jvmRoute; - protected ReplicationStrategy replicationStrategy; - - /** - * the sip stack path name. Since the sip factory is per classloader it should be set here for all underlying stacks - */ - private String sipPathName; - /** - * use Pretty Encoding - */ - private boolean usePrettyEncoding = true; - - private SipStack sipStack; - // defining sip stack properties - private Properties sipStackProperties; - private String sipStackPropertiesFileLocation; - @Deprecated - private String addressResolverClass = null; - private String dnsServerLocatorClass = DefaultDNSServerLocator.class.getName(); - private int dnsTimeout = 1; - private String dnsResolverClass = MobicentsDNSResolver.class.getName(); - private String mobicentsSipServletMessageFactoryClassName = Servlet3SipServletMessageFactory.class.getName(); - - //the balancers to send heartbeat to and our health info - @Deprecated - private String balancers; - // - private ScheduledFuture gracefulStopFuture; - - @Override - public String getInfo() { - return (INFO); - } - - @Override - public void addConnector(Connector connector) { - if (initialized) { - MobicentsExtendedListeningPoint extendedListeningPoint = null; - if (connector.getProtocolHandler() instanceof SipProtocolHandler) { - extendedListeningPoint = (MobicentsExtendedListeningPoint) - ((SipProtocolHandler)connector.getProtocolHandler()).getAttribute(ExtendedListeningPoint.class.getSimpleName());} - if(extendedListeningPoint != null) { - try { - extendedListeningPoint.getSipProvider().addSipListener(sipApplicationDispatcher); - sipApplicationDispatcher.getSipNetworkInterfaceManager().addExtendedListeningPoint(extendedListeningPoint); - } catch (TooManyListenersException e) { - logger.error("Connector.initialize", e); - } - } - ProtocolHandler protocolHandler = connector.getProtocolHandler(); - if(protocolHandler instanceof SipProtocolHandler) { - connector.setPort(((SipProtocolHandler)protocolHandler).getPort()); - ((SipProtocolHandler)protocolHandler).setSipStack(sipStack); - ((SipProtocolHandler)protocolHandler).setAttribute(SipApplicationDispatcher.class.getSimpleName(), sipApplicationDispatcher); - registerSipConnector(connector); - } - } - else { - } - super.addConnector(connector); - } - - /** - * Register the sip connector under a different name than HTTP Connector and we add the transport to avoid clashing with 2 connectors having the same port and address - * @param connector connector to register - */ - protected void registerSipConnector(Connector connector) { - try { - - ObjectName objectName = createSipConnectorObjectName(connector, getName(), "SipConnector"); - Registry.getRegistry(null, null) - .registerComponent(connector, objectName, null); -//TODO connector.setController(objectName); - } catch (Exception e) { - logger.error( "Error registering connector ", e); - } - if(logger.isDebugEnabled()) - logger.debug("Creating name for connector " + getObjectName()); - } - - @Override - public void removeConnector(Connector connector) { - MobicentsExtendedListeningPoint extendedListeningPoint = null; - if (connector.getProtocolHandler() instanceof SipProtocolHandler){ - extendedListeningPoint = (MobicentsExtendedListeningPoint) - ((SipProtocolHandler)connector.getProtocolHandler()).getAttribute(ExtendedListeningPoint.class.getSimpleName());} - if(extendedListeningPoint != null) { - extendedListeningPoint.getSipProvider().removeSipListener(sipApplicationDispatcher); - sipApplicationDispatcher.getSipNetworkInterfaceManager().removeExtendedListeningPoint(extendedListeningPoint); - } - super.removeConnector(connector); - } - - @Override - public void initialize() throws LifecycleException { - //load the sip application disptacher from the class name specified in the server.xml file - //and initializes it - StaticServiceHolder.sipStandardService = this; - try { - sipApplicationDispatcher = (SipApplicationDispatcher) - Class.forName(sipApplicationDispatcherClassName).newInstance(); - } catch (InstantiationException e) { - throw new LifecycleException("Impossible to load the Sip Application Dispatcher",e); - } catch (IllegalAccessException e) { - throw new LifecycleException("Impossible to load the Sip Application Dispatcher",e); - } catch (ClassNotFoundException e) { - throw new LifecycleException("Impossible to load the Sip Application Dispatcher",e); - } catch (ClassCastException e) { - throw new LifecycleException("Sip Application Dispatcher defined does not implement " + SipApplicationDispatcher.class.getName(),e); - } - if(logger.isInfoEnabled()) { - logger.info("Pretty encoding of headers enabled ? " + usePrettyEncoding); - } - if(sipPathName == null) { - sipPathName = DEFAULT_SIP_PATH_NAME; - } - if(logger.isInfoEnabled()) { - logger.info("Sip Stack path name : " + sipPathName); - } - sipApplicationDispatcher.setSipService(this); - sipApplicationDispatcher.getSipFactory().initialize(sipPathName, usePrettyEncoding); - - String catalinaBase = getCatalinaBase(); - if(darConfigurationFileLocation != null) { - if(!darConfigurationFileLocation.startsWith("file:///")) { - darConfigurationFileLocation = "file:///" + catalinaBase.replace(File.separatorChar, '/') + "/" + darConfigurationFileLocation; - } - System.setProperty("javax.servlet.sip.dar", darConfigurationFileLocation); - } - super.initialize(); - sipApplicationDispatcher.setDomain(this.getName()); - if(baseTimerInterval < 1) { - throw new LifecycleException("It's forbidden to set the Base Timer Interval to a non positive value"); - } - initSipStack(); - sipApplicationDispatcher.setBaseTimerInterval(baseTimerInterval); - sipApplicationDispatcher.setT2Interval(t2Interval); - sipApplicationDispatcher.setT4Interval(t4Interval); - sipApplicationDispatcher.setTimerDInterval(timerDInterval); - sipApplicationDispatcher.setMemoryThreshold(getMemoryThreshold()); - sipApplicationDispatcher.setBackToNormalMemoryThreshold(backToNormalMemoryThreshold); - sipApplicationDispatcher.setCongestionControlCheckingInterval(getCongestionControlCheckingInterval()); - sipApplicationDispatcher.setCongestionControlPolicyByName(getCongestionControlPolicy()); - sipApplicationDispatcher.setQueueSize(getSipMessageQueueSize()); - sipApplicationDispatcher.setBackToNormalQueueSize(backToNormalSipMessageQueueSize); - sipApplicationDispatcher.setGatherStatistics(gatherStatistics); - sipApplicationDispatcher.setConcurrencyControlMode(ConcurrencyControlMode.valueOf(getConcurrencyControlMode())); - sipApplicationDispatcher.setBypassRequestExecutor(bypassRequestExecutor); - sipApplicationDispatcher.setBypassResponseExecutor(bypassResponseExecutor); - sipApplicationDispatcher.setSipStack(sipStack); - sipApplicationDispatcher.init(); - // Tomcat specific loading case where the connectors are added even before the service is initialized - // so we need to set the sip stack before it starts - synchronized (connectors) { - for (Connector connector : connectors) { - ProtocolHandler protocolHandler = connector.getProtocolHandler(); - if(protocolHandler instanceof SipProtocolHandler) { - connector.setPort(((SipProtocolHandler)protocolHandler).getPort()); - ((SipProtocolHandler)protocolHandler).setSipStack(sipStack); - ((SipProtocolHandler)protocolHandler).setAttribute(SipApplicationDispatcher.class.getSimpleName(), sipApplicationDispatcher); - registerSipConnector(connector); - } - } - } - } - - @Override - public void start() throws LifecycleException { - super.start(); - synchronized (connectors) { - for (Connector connector : connectors) { - final ProtocolHandler protocolHandler = connector.getProtocolHandler(); - //Jboss sepcific loading case - Boolean isSipConnector = false; - if (protocolHandler instanceof SipProtocolHandler) - isSipConnector = (Boolean) ((SipProtocolHandler)protocolHandler).getAttribute(SipProtocolHandler.IS_SIP_CONNECTOR); - if(isSipConnector != null && isSipConnector) { - if(logger.isDebugEnabled()) { - logger.debug("Attaching the sip application dispatcher " + - "as a sip listener to connector listening on port " + - connector.getPort()); - } - ((SipProtocolHandler)protocolHandler).setAttribute(SipApplicationDispatcher.class.getSimpleName(), sipApplicationDispatcher); - ((SipProtocolHandler)protocolHandler).setSipStack(sipStack); - connectorsStartedExternally = true; - } - //Tomcat specific loading case - MobicentsExtendedListeningPoint extendedListeningPoint = null; - if (protocolHandler instanceof SipProtocolHandler) { - extendedListeningPoint = (MobicentsExtendedListeningPoint) - ((SipProtocolHandler)protocolHandler).getAttribute(ExtendedListeningPoint.class.getSimpleName());} - if(extendedListeningPoint != null && sipStack != null) { - try { - extendedListeningPoint.getSipProvider().addSipListener(sipApplicationDispatcher); - sipApplicationDispatcher.getSipNetworkInterfaceManager().addExtendedListeningPoint(extendedListeningPoint); - connectorsStartedExternally = false; - } catch (TooManyListenersException e) { - throw new LifecycleException("Couldn't add the sip application dispatcher " - + sipApplicationDispatcher + " as a listener to the following listening point provider " + extendedListeningPoint, e); - } - } - } - } - if(!connectorsStartedExternally) { - sipApplicationDispatcher.start(); - } - - if(this.getSipMessageQueueSize() <= 0) - throw new LifecycleException("Message queue size can not be 0 or less"); - - if(logger.isDebugEnabled()) { - logger.debug("SIP Standard Service Started."); - } - } - - public String getJvmRoute() { - return this.jvmRoute; - } - - public void setJvmRoute(String jvmRoute) { - this.jvmRoute = jvmRoute; - } - - protected void initSipStack() throws LifecycleException { - try { - if(logger.isDebugEnabled()) { - logger.debug("Initializing SIP stack"); - } - - // This simply puts HTTP and SSL port numbers in JVM properties menat to be read by jsip ha when sending heart beats with Node description. - initializeSystemPortProperties(); - - String catalinaBase = getCatalinaBase(); - if(sipStackPropertiesFileLocation != null && !sipStackPropertiesFileLocation.startsWith("file:///")) { - sipStackPropertiesFileLocation = "file:///" + catalinaBase.replace(File.separatorChar, '/') + "/" + sipStackPropertiesFileLocation; - } - boolean isPropsLoaded = false; - if(sipStackProperties == null) { - sipStackProperties = new Properties(); - } else { - isPropsLoaded = true; - } - - if (logger.isDebugEnabled()) { - logger.debug("Loading SIP stack properties from following file : " + sipStackPropertiesFileLocation); - } - if(sipStackPropertiesFileLocation != null) { - //hack to get around space char in path see http://weblogs.java.net/blog/kohsuke/archive/2007/04/how_to_convert.html, - // we create a URL since it's permissive enough - File sipStackPropertiesFile = null; - URL url = null; - try { - url = new URL(sipStackPropertiesFileLocation); - } catch (MalformedURLException e) { - logger.fatal("Cannot find the sip stack properties file ! ",e); - throw new IllegalArgumentException("The Default Application Router file Location : "+sipStackPropertiesFileLocation+" is not valid ! ",e); - } - try { - sipStackPropertiesFile = new File(new URI(sipStackPropertiesFileLocation)); - } catch (URISyntaxException e) { - //if the uri contains space this will fail, so getting the path will work - sipStackPropertiesFile = new File(url.getPath()); - } - FileInputStream sipStackPropertiesInputStream = null; - try { - sipStackPropertiesInputStream = new FileInputStream(sipStackPropertiesFile); - sipStackProperties.load(sipStackPropertiesInputStream); - } catch (Exception e) { - logger.warn("Could not find or problem when loading the sip stack properties file : " + sipStackPropertiesFileLocation, e); - } finally { - if(sipStackPropertiesInputStream != null) { - try { - sipStackPropertiesInputStream.close(); - } catch (IOException e) { - logger.error("fail to close the following file " + sipStackPropertiesFile.getAbsolutePath(), e); - } - } - } - - String debugLog = sipStackProperties.getProperty(DEBUG_LOG_STACK_PROP); - if(debugLog != null && debugLog.length() > 0 && !debugLog.startsWith("file:///")) { - sipStackProperties.setProperty(DEBUG_LOG_STACK_PROP, - catalinaBase + "/" + debugLog); - } - String serverLog = sipStackProperties.getProperty(SERVER_LOG_STACK_PROP); - if(serverLog != null && serverLog.length() > 0 && !serverLog.startsWith("file:///")) { - sipStackProperties.setProperty(SERVER_LOG_STACK_PROP, - catalinaBase + "/" + serverLog); - } - // The whole MSS is built upon those assumptions, so those properties are not overrideable - if (sipStackProperties.getProperty(AUTOMATIC_DIALOG_SUPPORT_STACK_PROP) == null) { - //https://github.com/RestComm/sip-servlets/issues/143 - //set off if user didnt provided any value. - sipStackProperties.setProperty(AUTOMATIC_DIALOG_SUPPORT_STACK_PROP, "off"); - } - sipStackProperties.setProperty(LOOSE_DIALOG_VALIDATION, "true"); - sipStackProperties.setProperty(PASS_INVITE_NON_2XX_ACK_TO_LISTENER, "true"); - isPropsLoaded = true; - } else { - logger.warn("no sip stack properties file defined "); - } - if(!isPropsLoaded) { - logger.warn("loading default Mobicents Sip Servlets sip stack properties"); - // Silently set default values - sipStackProperties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", - "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", - "LOG4J"); - sipStackProperties.setProperty(DEBUG_LOG_STACK_PROP, - catalinaBase + "/" + "mss-jsip-" + getName() +"-debug.txt"); - sipStackProperties.setProperty(SERVER_LOG_STACK_PROP, - catalinaBase + "/" + "mss-jsip-" + getName() +"-messages.xml"); - sipStackProperties.setProperty("javax.sip.STACK_NAME", "mss-" + getName()); - sipStackProperties.setProperty(AUTOMATIC_DIALOG_SUPPORT_STACK_PROP, "off"); - sipStackProperties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.THREAD_POOL_SIZE", "64"); - sipStackProperties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.MAX_FORK_TIME_SECONDS", "0"); - sipStackProperties.setProperty(LOOSE_DIALOG_VALIDATION, "true"); - sipStackProperties.setProperty(PASS_INVITE_NON_2XX_ACK_TO_LISTENER, "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.AUTOMATIC_DIALOG_ERROR_HANDLING", "false"); - sipStackProperties.setProperty("gov.nist.javax.sip.AGGRESSIVE_CLEANUP", "true"); - } - - if(sipStackProperties.get(TCP_POST_PARSING_THREAD_POOL_SIZE) == null) { - sipStackProperties.setProperty(TCP_POST_PARSING_THREAD_POOL_SIZE, "30"); - } - - // set the DNSServerLocator allowing to support RFC 3263 and do DNS lookups to resolve uris - if(dnsServerLocatorClass != null && dnsServerLocatorClass.trim().length() > 0) { - if(logger.isDebugEnabled()) { - logger.debug("Sip Stack " + sipStackProperties.getProperty("javax.sip.STACK_NAME") +" will be using " + dnsServerLocatorClass + " as DNSServerLocator"); - } - try { - // create parameters argument to identify constructor - Class[] paramTypes = new Class[0]; - // get constructor of AddressResolver in order to instantiate - Constructor dnsServerLocatorConstructor = Class.forName(dnsServerLocatorClass).getConstructor( - paramTypes); - // Wrap properties object in order to pass to constructor of AddressResolver - Object[] conArgs = new Object[0]; - // Creates a new instance of AddressResolver Class with the supplied sipApplicationDispatcher. - DNSServerLocator dnsServerLocator = (DNSServerLocator) dnsServerLocatorConstructor.newInstance(conArgs); - sipApplicationDispatcher.setDNSServerLocator(dnsServerLocator); - sipApplicationDispatcher.setDNSTimeout(dnsTimeout); - if(sipStackProperties.getProperty("javax.sip.ROUTER_PATH") == null) { - sipStackProperties.setProperty("javax.sip.ROUTER_PATH", DNSAwareRouter.class.getCanonicalName()); - } - } catch (Exception e) { - logger.error("Couldn't set the AddressResolver " + addressResolverClass, e); - throw e; - } - } else { - if(logger.isInfoEnabled()) { - logger.info("no DNSServerLocator will be used since none has been specified."); - } - } - - String serverHeaderValue = sipStackProperties.getProperty(SERVER_HEADER); - if(serverHeaderValue != null) { - List serverHeaderList = new ArrayList(); - StringTokenizer stringTokenizer = new StringTokenizer(serverHeaderValue, ","); - while(stringTokenizer.hasMoreTokens()) { - serverHeaderList.add(stringTokenizer.nextToken()); - } - ServerHeader serverHeader = sipApplicationDispatcher.getSipFactory().getHeaderFactory().createServerHeader(serverHeaderList); - ((MessageFactoryExt)sipApplicationDispatcher.getSipFactory().getMessageFactory()).setDefaultServerHeader(serverHeader); - } - String userAgent = sipStackProperties.getProperty(USER_AGENT_HEADER); - if(userAgent != null) { - List userAgentList = new ArrayList(); - StringTokenizer stringTokenizer = new StringTokenizer(userAgent, ","); - while(stringTokenizer.hasMoreTokens()) { - userAgentList.add(stringTokenizer.nextToken()); - } - UserAgentHeader userAgentHeader = sipApplicationDispatcher.getSipFactory().getHeaderFactory().createUserAgentHeader(userAgentList); - ((MessageFactoryExt)sipApplicationDispatcher.getSipFactory().getMessageFactory()).setDefaultUserAgentHeader(userAgentHeader); - } - if(balancers != null) { - if(sipStackProperties.get(LoadBalancerHeartBeatingService.LB_HB_SERVICE_CLASS_NAME) == null) { - sipStackProperties.put(LoadBalancerHeartBeatingService.LB_HB_SERVICE_CLASS_NAME, LoadBalancerHeartBeatingServiceImpl.class.getCanonicalName()); - } - if(sipStackProperties.get(LoadBalancerHeartBeatingService.BALANCERS) == null) { - sipStackProperties.put(LoadBalancerHeartBeatingService.BALANCERS, balancers); - } - } - String replicationStrategyString = sipStackProperties.getProperty(ClusteredSipStack.REPLICATION_STRATEGY_PROPERTY); - if(replicationStrategyString == null) { - replicationStrategyString = ReplicationStrategy.ConfirmedDialog.toString(); - } - boolean replicateApplicationData = false; - if(replicationStrategyString.equals(ReplicationStrategy.EarlyDialog.toString())) { - replicateApplicationData = true; - } - if(replicationStrategyString != null) { - replicationStrategy = ReplicationStrategy.valueOf(replicationStrategyString); - } - sipStackProperties.put(ClusteredSipStack.REPLICATION_STRATEGY_PROPERTY, replicationStrategyString); - sipStackProperties.put(ClusteredSipStack.REPLICATE_APPLICATION_DATA, Boolean.valueOf(replicateApplicationData).toString()); - if(logger.isInfoEnabled()) { - logger.info("Mobicents Sip Servlets sip stack properties : " + sipStackProperties); - } - // Create SipStack object - sipStack = sipApplicationDispatcher.getSipFactory().getJainSipFactory().createSipStack(sipStackProperties); - LoadBalancerHeartBeatingService loadBalancerHeartBeatingService = null; - if(sipStack instanceof ClusteredSipStack) { - loadBalancerHeartBeatingService = ((ClusteredSipStack) sipStack).getLoadBalancerHeartBeatingService(); - if ((this.container != null) && (this.container instanceof Engine) && ((Engine)container).getJvmRoute() != null) { - final String jvmRoute = ((Engine)container).getJvmRoute(); - if(jvmRoute != null) { - loadBalancerHeartBeatingService.setJvmRoute(jvmRoute); - setJvmRoute(jvmRoute); - } - } - } - if(sipApplicationDispatcher != null && loadBalancerHeartBeatingService != null && sipApplicationDispatcher instanceof LoadBalancerHeartBeatingListener) { - loadBalancerHeartBeatingService.addLoadBalancerHeartBeatingListener((LoadBalancerHeartBeatingListener)sipApplicationDispatcher); - } - // for nist sip stack set the DNS Address resolver allowing to make DNS SRV lookups - if(sipStack instanceof SipStackExt && addressResolverClass != null && addressResolverClass.trim().length() > 0) { - if(logger.isDebugEnabled()) { - logger.debug("Sip Stack " + sipStack.getStackName() +" will be using " + addressResolverClass + " as AddressResolver"); - } - try { - // create parameters argument to identify constructor - Class[] paramTypes = new Class[1]; - paramTypes[0] = SipApplicationDispatcher.class; - // get constructor of AddressResolver in order to instantiate - Constructor addressResolverConstructor = Class.forName(addressResolverClass).getConstructor( - paramTypes); - // Wrap properties object in order to pass to constructor of AddressResolver - Object[] conArgs = new Object[1]; - conArgs[0] = sipApplicationDispatcher; - // Creates a new instance of AddressResolver Class with the supplied sipApplicationDispatcher. - AddressResolver addressResolver = (AddressResolver) addressResolverConstructor.newInstance(conArgs); - ((SipStackExt) sipStack).setAddressResolver(addressResolver); - } catch (Exception e) { - logger.error("Couldn't set the AddressResolver " + addressResolverClass, e); - throw e; - } - } else { - if(logger.isInfoEnabled()) { - logger.info("no AddressResolver will be used since none has been specified."); - } - } - if(logger.isInfoEnabled()) { - logger.info("SIP stack initialized"); - } - } catch (Exception ex) { - if(ex instanceof PeerUnavailableException) { - logger.error("the SIP Stack couldn't be started because of " + ex.getCause()); - ex.getCause().printStackTrace(); - } - throw new LifecycleException("A problem occured while initializing the SIP Stack", ex); - } - } - - @Override - public void stop() throws LifecycleException { - // Tomcat specific unloading case - // Issue 1411 http://code.google.com/p/mobicents/issues/detail?id=1411 - // Sip Connectors should be removed after removing all Sip Servlets to allow them to send BYE to terminate cleanly - synchronized (connectors) { - for (Connector connector : connectors) { - MobicentsExtendedListeningPoint extendedListeningPoint = null; - if (connector.getProtocolHandler() instanceof SipProtocolHandler) { - extendedListeningPoint = (MobicentsExtendedListeningPoint) - ((SipProtocolHandler)connector.getProtocolHandler()).getAttribute(ExtendedListeningPoint.class.getSimpleName()); - } - if(extendedListeningPoint != null) { - extendedListeningPoint.getSipProvider().removeSipListener(sipApplicationDispatcher); - sipApplicationDispatcher.getSipNetworkInterfaceManager().removeExtendedListeningPoint(extendedListeningPoint); - } - } - } - if(!connectorsStartedExternally) { - sipApplicationDispatcher.stop(); - } - super.stop(); - if(logger.isDebugEnabled()) { - logger.debug("SIP Standard Service Stopped."); - } -// setState(LifecycleState.STOPPING); - } - - /** - * Retrieve the sip application dispatcher class name - * @return the sip application dispatcher class name - */ - public String getSipApplicationDispatcherClassName() { - return sipApplicationDispatcherClassName; - } - - /** - * Set the sip application dispatcher class name - * @param sipApplicationDispatcherClassName the sip application dispatcher class name to be set - */ - public void setSipApplicationDispatcherClassName(String sipApplicationDispatcherName) { - this.sipApplicationDispatcherClassName = sipApplicationDispatcherName; - } - - /** - * @return the sipApplicationDispatcher - */ - public SipApplicationDispatcher getSipApplicationDispatcher() { - return sipApplicationDispatcher; - } - - /** - * @param sipApplicationDispatcher the sipApplicationDispatcher to set - */ - public void setSipApplicationDispatcher( - SipApplicationDispatcher sipApplicationDispatcher) { - this.sipApplicationDispatcher = sipApplicationDispatcher; - } - - /** - * @return the darConfigurationFileLocation - */ - public String getDarConfigurationFileLocation() { - return darConfigurationFileLocation; - } - - /** - * @param darConfigurationFileLocation the darConfigurationFileLocation to set - */ - public void setDarConfigurationFileLocation(String darConfigurationFileLocation) { - this.darConfigurationFileLocation = darConfigurationFileLocation; - } - - /** - * Message queue size. If the number of pending requests exceeds this number they are rejected. - * - * @return - */ - public int getSipMessageQueueSize() { - return sipMessageQueueSize; - } - - /** - * Message queue size. If the number of pending requests exceeds this number they are rejected. - * - * @return - */ - public void setSipMessageQueueSize(int sipMessageQueueSize) { - this.sipMessageQueueSize = sipMessageQueueSize; - } - - /** - * ConcurrencyControl control mode is SipSession, AppSession or None - * Specifies the isolation level of concurrently executing requests. - * - * @return - */ - public String getConcurrencyControlMode() { - return concurrencyControlMode; - } - - /** - * ConcurrencyControl control mode is SipSession, AppSession or None - * Specifies the isolation level of concurrently executing requests. - * - * @return - */ - public void setConcurrencyControlMode(String concurrencyControlMode) { - this.concurrencyControlMode = concurrencyControlMode; - } - - - /** - * @param memoryThreshold the memoryThreshold to set - */ - public void setMemoryThreshold(int memoryThreshold) { - this.memoryThreshold = memoryThreshold; - } - - - /** - * @return the memoryThreshold - */ - public int getMemoryThreshold() { - return memoryThreshold; - } - - /** - * @param skipStatistics the skipStatistics to set - */ - public void setGatherStatistics(boolean skipStatistics) { - this.gatherStatistics = skipStatistics; - if(logger.isInfoEnabled()) { - logger.info("Gathering Statistics set to " + skipStatistics); - } - } - - /** - * @return the skipStatistics - */ - public boolean isGatherStatistics() { - return gatherStatistics; - } - - /** - * PRESENT TO ACCOMODATE JOPR. NEED TO FILE A BUG ON THIS - * @return the skipStatistics - */ - public boolean getGatherStatistics() { - return gatherStatistics; - } - - /** - * @param backToNormalPercentageOfMemoryUsed the backToNormalPercentageOfMemoryUsed to set - */ - public void setBackToNormalMemoryThreshold( - int backToNormalMemoryThreshold) { - this.backToNormalMemoryThreshold = backToNormalMemoryThreshold; - } - - /** - * @return the backToNormalPercentageOfMemoryUsed - */ - public int getBackToNormalMemoryThreshold() { - return backToNormalMemoryThreshold; - } - - /** - * @param backToNormalQueueSize the backToNormalQueueSize to set - */ - public void setBackToNormalSipMessageQueueSize(int backToNormalSipMessageQueueSize) { - this.backToNormalSipMessageQueueSize = backToNormalSipMessageQueueSize; - } - - /** - * @return the backToNormalQueueSize - */ - public int getBackToNormalSipMessageQueueSize() { - return backToNormalSipMessageQueueSize; - } - - - /** - * @param congestionControlPolicy the congestionControlPolicy to set - */ - public void setCongestionControlPolicy(String congestionControlPolicy) { - this.congestionControlPolicy = congestionControlPolicy; - } - - - /** - * @return the congestionControlPolicy - */ - public String getCongestionControlPolicy() { - return congestionControlPolicy; - } - - - /** - * @param congestionControlCheckingInterval the congestionControlCheckingInterval to set - */ - public void setCongestionControlCheckingInterval( - long congestionControlCheckingInterval) { - this.congestionControlCheckingInterval = congestionControlCheckingInterval; - } - - - /** - * @return the congestionControlCheckingInterval - */ - public long getCongestionControlCheckingInterval() { - return congestionControlCheckingInterval; - } - - - public String getAdditionalParameterableHeaders() { - return additionalParameterableHeaders; - } - - - public void setAdditionalParameterableHeaders( - String additionalParameterableHeaders) { - this.additionalParameterableHeaders = additionalParameterableHeaders; - String[] headers = additionalParameterableHeaders.split(","); - for(String header : headers) { - if(header != null && header.length()>0) { - JainSipUtils.PARAMETERABLE_HEADER_NAMES.add(header); - } - } - } - - - /** - * @return the bypassResponseExecutor - */ - public boolean isBypassResponseExecutor() { - return bypassResponseExecutor; - } - - - /** - * @param bypassResponseExecutor the bypassResponseExecutor to set - */ - public void setBypassResponseExecutor(boolean bypassResponseExecutor) { - this.bypassResponseExecutor = bypassResponseExecutor; - } - - - /** - * @return the bypassRequestExecutor - */ - public boolean isBypassRequestExecutor() { - return bypassRequestExecutor; - } - - - /** - * @param bypassRequestExecutor the bypassRequestExecutor to set - */ - public void setBypassRequestExecutor(boolean bypassRequestExecutor) { - this.bypassRequestExecutor = bypassRequestExecutor; - } - - public boolean isMd5ContactUserPart() { - return md5ContactUserPart; - } - - - public void setMd5ContactUserPart(boolean md5ContactUserPart) { - this.md5ContactUserPart = md5ContactUserPart; - } - - - /** - * @param usePrettyEncoding the usePrettyEncoding to set - */ - public void setUsePrettyEncoding(boolean usePrettyEncoding) { - this.usePrettyEncoding = usePrettyEncoding; - } - - /** - * @return the usePrettyEncoding - */ - public boolean isUsePrettyEncoding() { - return usePrettyEncoding; - } - - /** - * @param sipPathName the sipPathName to set - */ - public void setSipPathName(String sipPathName) { - this.sipPathName = sipPathName; - } - - /** - * @return the sipPathName - */ - public String getSipPathName() { - return sipPathName; - } - - - /** - * @param baseTimerInterval the baseTimerInterval to set - */ - public void setBaseTimerInterval(int baseTimerInterval) { - this.baseTimerInterval = baseTimerInterval; - } - - - /** - * @return the baseTimerInterval - */ - public int getBaseTimerInterval() { - return baseTimerInterval; - } - - - public OutboundProxy getOutboundProxy() { - return outboundProxy; - } - - - public void setOutboundProxy(String outboundProxy) { - if(outboundProxy != null) { - this.outboundProxy = new OutboundProxy(outboundProxy); - } else { - this.outboundProxy = null; - } - if(logger.isDebugEnabled()) { - logger.debug("Outbound Proxy : " + outboundProxy); - } - } - - public int getDispatcherThreadPoolSize() { - return dispatcherThreadPoolSize; - } - - - public void setDispatcherThreadPoolSize(int dispatcherThreadPoolSize) { - this.dispatcherThreadPoolSize = dispatcherThreadPoolSize; - } - - public int getCanceledTimerTasksPurgePeriod() { - return canceledTimerTasksPurgePeriod; - } - - public void setCanceledTimerTasksPurgePeriod(int purgePeriod) { - this.canceledTimerTasksPurgePeriod = purgePeriod; - } - - /** - * @deprecated - * @param balancers the balancers to set - */ - public void setBalancers(String balancers) { - this.balancers = balancers; - } - - public boolean addSipConnector(SipConnector sipConnector) throws Exception { - if(sipConnector == null) { - throw new IllegalArgumentException("The sip connector passed is null"); - } - Connector connectorToAdd = findSipConnector(sipConnector.getIpAddress(), sipConnector.getPort(), - sipConnector.getTransport()); - if(connectorToAdd == null) { - Connector connector = new Connector( - SipProtocolHandler.class.getName()); - SipProtocolHandler sipProtocolHandler = (SipProtocolHandler) connector - .getProtocolHandler(); - sipProtocolHandler.setSipConnector(sipConnector); - sipProtocolHandler.setSipStack(sipStack); - connector.setService(this); -//TODO connector.setContainer(container); - connector.init(); - addConnector(connector); - MobicentsExtendedListeningPoint extendedListeningPoint = (MobicentsExtendedListeningPoint) - sipProtocolHandler.getAttribute(ExtendedListeningPoint.class.getSimpleName()); - if(extendedListeningPoint != null) { - try { - extendedListeningPoint.getSipProvider().addSipListener(sipApplicationDispatcher); - sipApplicationDispatcher.getSipNetworkInterfaceManager().addExtendedListeningPoint(extendedListeningPoint); - } catch (TooManyListenersException e) { - logger.error("Connector.initialize", e); - removeConnector(connector); - return false; - } - } - if(!sipProtocolHandler.isStarted()) { - if(logger.isDebugEnabled()) { - logger.debug("Sip Connector couldn't be started, removing it automatically"); - } - removeConnector(connector); - } - return sipProtocolHandler.isStarted(); - } - return false; - } - - public boolean removeSipConnector(String ipAddress, int port, String transport) throws Exception { - Connector connectorToRemove = findSipConnector(ipAddress, port, - transport); - if(connectorToRemove != null) { - removeConnector(connectorToRemove); - return true; - } - return false; - } - - - /** - * Find a sip Connector by it's ip address, port and transport - * @param ipAddress ip address of the connector to find - * @param port port of the connector to find - * @param transport transport of the connector to find - * @return the found sip connector or null if noting found - */ - private Connector findSipConnector(String ipAddress, int port, - String transport) { - Connector connectorToRemove = null; - for (Connector connector : connectors) { - final ProtocolHandler protocolHandler = connector.getProtocolHandler(); - if(protocolHandler instanceof SipProtocolHandler) { - final SipProtocolHandler sipProtocolHandler = (SipProtocolHandler) protocolHandler; - if(sipProtocolHandler.getIpAddress().equals(ipAddress) && sipProtocolHandler.getPort() == port && sipProtocolHandler.getSignalingTransport().equals(transport)) { -// connector.destroy(); - connectorToRemove = connector; - break; - } - } - } - return connectorToRemove; - } - - public SipConnector findSipConnector(String transport) { - List sipConnectors = new ArrayList(); - for (Connector connector : connectors) { - final ProtocolHandler protocolHandler = connector.getProtocolHandler(); - if(protocolHandler instanceof SipProtocolHandler) { - SipConnector sc = (((SipProtocolHandler)protocolHandler).getSipConnector()); - if(sc.getTransport().equalsIgnoreCase(transport)) return sc; - } - } - return null; - } - - public SipConnector[] findSipConnectors() { - List sipConnectors = new ArrayList(); - for (Connector connector : connectors) { - final ProtocolHandler protocolHandler = connector.getProtocolHandler(); - if(protocolHandler instanceof SipProtocolHandler) { - sipConnectors.add(((SipProtocolHandler)protocolHandler).getSipConnector()); - } - } - return sipConnectors.toArray(new SipConnector[sipConnectors.size()]); - } - - /** - * This method simply makes the HTTP and SSL ports avaialble everywhere in the JVM in order jsip ha to read them for - * balancer description purposes. There is no other good way to communicate the properies to jsip ha without adding - * more dependencies. - */ - public void initializeSystemPortProperties() { - for (Connector connector : connectors) { - if(connector.getProtocol().contains("HTTP")) { - if(connector.getSecure()) { - System.setProperty("org.mobicents.properties.sslPort", Integer.toString(connector.getPort())); - } else { - System.setProperty("org.mobicents.properties.httpPort", Integer.toString(connector.getPort())); - } - } - } - } - - protected ObjectName createSipConnectorObjectName(Connector connector, String domain, String type) - throws MalformedObjectNameException { - String encodedAddr = null; - if (connector.getProperty("address") != null) { - encodedAddr = URLEncoder.encode(connector.getProperty("address").toString()); - } - String addSuffix = (connector.getProperty("address") == null) ? "" : ",address=" - + encodedAddr; - ObjectName _oname = new ObjectName(domain + ":type=" + type + ",port=" - + connector.getPort() + ",transport=" + connector.getProperty("transport") + addSuffix); - return _oname; - } - - - /** - * @param t2Interval the t2Interval to set - */ - public void setT2Interval(int t2Interval) { - this.t2Interval = t2Interval; - } - - - /** - * @return the t2Interval - */ - public int getT2Interval() { - return t2Interval; - } - - - /** - * @param t4Interval the t4Interval to set - */ - public void setT4Interval(int t4Interval) { - this.t4Interval = t4Interval; - } - - - /** - * @return the t4Interval - */ - public int getT4Interval() { - return t4Interval; - } - - - /** - * @param timerDInterval the timerDInterval to set - */ - public void setTimerDInterval(int timerDInterval) { - this.timerDInterval = timerDInterval; - } - - - /** - * @return the timerDInterval - */ - public int getTimerDInterval() { - return timerDInterval; - } - - /** - * @param sipStackPropertiesFile the sipStackPropertiesFile to set - */ - public void setSipStackPropertiesFile(String sipStackPropertiesFile) { - sipStackPropertiesFileLocation = sipStackPropertiesFile; - } - - /** - * @return the sipStackProperties - */ - public Properties getSipStackProperties() { - return sipStackProperties; - } - - /** - * @param sipStackProperties the sipStackProperties to set - */ - public void setSipStackProperties(Properties sipStackProperties) { - this.sipStackProperties = sipStackProperties; - } - - /** - * @return the sipStackPropertiesFile - */ - public String getSipStackPropertiesFile() { - return sipStackPropertiesFileLocation; - } - - /** - * @param dnsAddressResolverClass the dnsAddressResolverClass to set - */ - @Deprecated - public void setAddressResolverClass(String dnsAddressResolverClass) { - this.addressResolverClass = dnsAddressResolverClass; - } - - /** - * @return the dnsAddressResolverClass - */ - @Deprecated - public String getAddressResolverClass() { - return addressResolverClass; - } - - /** - * Whether we check for pending requests and return 491 response if there are any - * - * @return the flag value - */ - public boolean isDialogPendingRequestChecking() { - return dialogPendingRequestChecking; - } - - /** - * - * Whether we check for pending requests and return 491 response if there are any - * - * @param dialogPendingRequestChecking - */ - public void setDialogPendingRequestChecking(boolean dialogPendingRequestChecking) { - this.dialogPendingRequestChecking = dialogPendingRequestChecking; - } - - - public boolean isHttpFollowsSip() { - return httpFollowsSip; - } - - - public void setHttpFollowsSip(boolean httpFollowsSip) { - this.httpFollowsSip = httpFollowsSip; - } - - /** - * @return the tagHashMaxLength - */ - public int getTagHashMaxLength() { - return tagHashMaxLength; - } - - /** - * @param tagHashMaxLength the tagHashMaxLength to set - */ - public void setTagHashMaxLength(int tagHashMaxLength) { - this.tagHashMaxLength = tagHashMaxLength; - } - - /** - * @return the callIdMaxLength - */ - public int getCallIdMaxLength() { - return callIdMaxLength; - } - - /** - * @param callIdMaxLength the callIdMaxLength to set - */ - public void setCallIdMaxLength(int callIdMaxLength) { - this.callIdMaxLength = callIdMaxLength; - } - - /** - * @return the sipStack - */ - public SipStack getSipStack() { - return sipStack; - } - - /** - * @param dnsServerLocatorClass the dnsServerLocatorClass to set - */ - public void setDnsServerLocatorClass(String dnsServerLocatorClass) { - this.dnsServerLocatorClass = dnsServerLocatorClass; - } - - /** - * @return the dnsServerLocatorClass - */ - public String getDnsServerLocatorClass() { - return dnsServerLocatorClass; - } - - /** - * @param dnsResolverClass the dnsResolverClass to set - */ - public void setDnsResolverClass(String dnsResolverClass) { - this.dnsResolverClass = dnsResolverClass; - } - - /** - * @return the dnsResolverClass - */ - public String getDnsResolverClass() { - return dnsResolverClass; - } - - /** - * Returns first the catalina.base if it is defined then the catalina.home if it is defined - * then the current dir if none is specified - */ - protected String getCatalinaBase() { - String catalinaBase = System.getProperty("catalina.base"); - if (catalinaBase == null) { - catalinaBase = System.getProperty("catalina.home"); - } - if(catalinaBase == null) { - catalinaBase = "."; - } - return catalinaBase; - } - - public ReplicationStrategy getReplicationStrategy() { - return replicationStrategy; - } - - @Override - public String getMobicentsSipServletMessageFactoryClassName() { - return mobicentsSipServletMessageFactoryClassName; - } - - @Override - public void setMobicentsSipServletMessageFactoryClassName( - String mobicentsSipServletMessageFactoryClassName) { - this.mobicentsSipServletMessageFactoryClassName = mobicentsSipServletMessageFactoryClassName; - } - - public void sendHeartBeat(String localAddress, int localPort, String transport, String remoteIpAddress, int remotePort) throws IOException { - MobicentsExtendedListeningPoint extendedListeningPoint = sipApplicationDispatcher.getSipNetworkInterfaceManager().findMatchingListeningPoint(localAddress, localPort, transport); - if(extendedListeningPoint != null) { - extendedListeningPoint.getListeningPoint().sendHeartbeat(remoteIpAddress, remotePort); - } - } - - public boolean setKeepAliveTimeout(SipConnector sipConnector, String clientAddress, int clientPort, long timeout) { - SIPTransactionStack sipStack = ((SIPTransactionStack) sipApplicationDispatcher.getSipStack()); - - return sipStack.setKeepAliveTimeout(sipConnector.getIpAddress(), sipConnector.getPort(), sipConnector.getTransport(), - clientAddress, clientPort, timeout); - } - - public void closeReliableConnection(SipConnector sipConnector, String clientAddress, int clientPort) { - SIPTransactionStack sipStack = ((SIPTransactionStack) sipApplicationDispatcher.getSipStack()); - - sipStack.closeReliableConnection(sipConnector.getIpAddress(),sipConnector.getPort(), sipConnector.getTransport(), - clientAddress, clientPort); - } - - @Override - public void stopGracefully(long timeToWait) { - if(logger.isInfoEnabled()) { - logger.info("Stopping the Server Gracefully in " + timeToWait + " ms"); - } - if(timeToWait == 0) { - if(gracefulStopFuture != null) { - gracefulStopFuture.cancel(false); - } - try { - stop(); - shutdownServer(); - } catch (Exception e){ - logger.error("The server couldn't be stopped", e); - } - - } else { - sipApplicationDispatcher.setGracefulShutdown(true); - Iterator sipContexts = sipApplicationDispatcher.findSipApplications(); - while (sipContexts.hasNext()) { - SipContext sipContext = sipContexts.next(); - sipContext.stopGracefully(timeToWait); - } - gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().scheduleWithFixedDelay(new ServiceGracefulStopTask(this), 30000, 30000, TimeUnit.MILLISECONDS); - if(timeToWait > 0) { - gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().schedule( - new Runnable() { - public void run() { - gracefulStopFuture.cancel(false); - try { - stop(); - shutdownServer(); - } catch (Exception e) { - logger.error("The server couldn't be stopped", e); - } - } - } - , timeToWait, TimeUnit.MILLISECONDS); - } - } - } - - protected void shutdownServer() throws MalformedObjectNameException, NullPointerException, InstanceNotFoundException, MBeanException, ReflectionException, IOException{ - MBeanServerConnection mbeanServerConnection = ManagementFactory.getPlatformMBeanServer(); - ObjectName mbeanName = new ObjectName("jboss.as:management-root=server"); - Object[] args = {false}; - String[] sigs = {"java.lang.Boolean"}; - mbeanServerConnection.invoke(mbeanName, "shutdown", args, sigs); - } - - /** - * @return the dnsTimeout - */ - public int getDnsTimeout() { - return dnsTimeout; - } - - /** - * @param dnsTimeout the dnsTimeout to set - */ - public void setDnsTimeout(int dnsTimeout) { - this.dnsTimeout = dnsTimeout; - } - - public String getProxyTimerServiceImplementationType() { - return proxyTimerServiceImplementationType; - } - - public void setProxyTimerServiceImplementationType(String proxyTimerServiceImplementationType) { - this.proxyTimerServiceImplementationType = proxyTimerServiceImplementationType; - } - - public String getSasTimerServiceImplementationType() { - return sasTimerServiceImplementationType; - } - - public void setSasTimerServiceImplementationType(String sasTimerServiceImplementationType) { - this.sasTimerServiceImplementationType = sasTimerServiceImplementationType; - } -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.catalina; + + +import gov.nist.core.net.AddressResolver; +import gov.nist.javax.sip.SipStackExt; +import gov.nist.javax.sip.message.MessageFactoryExt; +import gov.nist.javax.sip.stack.SIPTransactionStack; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.lang.management.ManagementFactory; +import java.lang.reflect.Constructor; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; +import java.util.StringTokenizer; +import java.util.TooManyListenersException; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import javax.management.InstanceNotFoundException; +import javax.management.MBeanException; +import javax.management.MBeanServerConnection; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; +import javax.management.ReflectionException; +import javax.sip.PeerUnavailableException; +import javax.sip.SipStack; +import javax.sip.header.ServerHeader; +import javax.sip.header.UserAgentHeader; + +import org.apache.catalina.Engine; +import org.apache.catalina.LifecycleException; +import org.apache.catalina.connector.Connector; +import org.apache.catalina.core.StandardService; +import org.apache.coyote.ProtocolHandler; +import org.apache.log4j.Logger; +import org.apache.tomcat.util.modeler.Registry; +import org.mobicents.ext.javax.sip.dns.DNSAwareRouter; +import org.mobicents.ext.javax.sip.dns.DNSServerLocator; +import org.mobicents.ext.javax.sip.dns.DefaultDNSServerLocator; +import org.mobicents.ha.javax.sip.ClusteredSipStack; +import org.mobicents.ha.javax.sip.LoadBalancerHeartBeatingListener; +import org.mobicents.ha.javax.sip.LoadBalancerHeartBeatingService; +import org.mobicents.ha.javax.sip.LoadBalancerHeartBeatingServiceImpl; +import org.mobicents.ha.javax.sip.ReplicationStrategy; +import org.mobicents.javax.servlet.CongestionControlPolicy; +import org.mobicents.servlet.sip.JainSipUtils; +import org.mobicents.servlet.sip.SipConnector; +import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; +import org.mobicents.servlet.sip.core.ExtendedListeningPoint; +import org.mobicents.servlet.sip.core.MobicentsExtendedListeningPoint; +import org.mobicents.servlet.sip.core.SipApplicationDispatcher; +import org.mobicents.servlet.sip.core.SipContext; +import org.mobicents.servlet.sip.core.message.OutboundProxy; +import org.mobicents.servlet.sip.dns.MobicentsDNSResolver; +import org.mobicents.servlet.sip.message.Servlet3SipServletMessageFactory; +import org.mobicents.servlet.sip.startup.StaticServiceHolder; + +/** + * Sip Servlet implementation of the SipService interface. + * This class inherits from the Tomcat StandardService. It adds a SipApplicationDispatcher + * that will be listen for sip messages received by the sip stacks started by + * the sip connectors associated with this context. + * This has one attribute which is the sipApplicationDispatcherClassName allowing one + * to specify the class name of the sipApplicationDispacther to easily replace + * the default sipApplicationDispatcher with a custom one. + * + * @author Jean Deruelle + */ +public class SipStandardService extends StandardService implements CatalinaSipService { + //the logger + private static final Logger logger = Logger.getLogger(SipStandardService.class); + public static final String DEFAULT_SIP_PATH_NAME = "gov.nist"; + public static final String PASS_INVITE_NON_2XX_ACK_TO_LISTENER = "gov.nist.javax.sip.PASS_INVITE_NON_2XX_ACK_TO_LISTENER"; + public static final String TCP_POST_PARSING_THREAD_POOL_SIZE = "gov.nist.javax.sip.TCP_POST_PARSING_THREAD_POOL_SIZE"; + public static final String AUTOMATIC_DIALOG_SUPPORT_STACK_PROP = "javax.sip.AUTOMATIC_DIALOG_SUPPORT"; + public static final String LOOSE_DIALOG_VALIDATION = "gov.nist.javax.sip.LOOSE_DIALOG_VALIDATION"; + public static final String SERVER_LOG_STACK_PROP = "gov.nist.javax.sip.SERVER_LOG"; + public static final String DEBUG_LOG_STACK_PROP = "gov.nist.javax.sip.DEBUG_LOG"; + public static final String SERVER_HEADER = "org.mobicents.servlet.sip.SERVER_HEADER"; + public static final String USER_AGENT_HEADER = "org.mobicents.servlet.sip.USER_AGENT_HEADER"; + public static final String JVM_ROUTE = "jvmRoute"; + /** + * The descriptive information string for this implementation. + */ + private static final String INFO = + "org.mobicents.servlet.sip.startup.SipStandardService/1.0"; + //the sip application dispatcher class name defined in the server.xml + protected String sipApplicationDispatcherClassName; + //instatiated class from the sipApplicationDispatcherClassName of the sip application dispatcher + protected SipApplicationDispatcher sipApplicationDispatcher; + private boolean gatherStatistics = true; + protected int sipMessageQueueSize = 1500; + private int backToNormalSipMessageQueueSize = 1300; + protected int memoryThreshold = 95; + private int backToNormalMemoryThreshold = 90; + protected OutboundProxy outboundProxy; + protected String proxyTimerServiceImplementationType; + protected String sasTimerServiceImplementationType; + protected long congestionControlCheckingInterval = 30000; + private int canceledTimerTasksPurgePeriod = 0; + // base timer interval for jain sip tx + private int baseTimerInterval = 500; + private int t2Interval = 4000; + private int t4Interval = 5000; + private int timerDInterval = 32000; + protected int dispatcherThreadPoolSize = 15; + private boolean md5ContactUserPart = false; + + protected String concurrencyControlMode = ConcurrencyControlMode.SipApplicationSession.toString(); + protected String congestionControlPolicy = CongestionControlPolicy.ErrorResponse.toString(); + protected String additionalParameterableHeaders; + protected boolean bypassResponseExecutor = true; + protected boolean bypassRequestExecutor = true; + //this should be made available to the application router as a system prop + protected String darConfigurationFileLocation; + protected boolean connectorsStartedExternally = false; + protected boolean dialogPendingRequestChecking = false; + protected int callIdMaxLength; + protected int tagHashMaxLength; + private long gracefulInterval = 30000; + + protected boolean httpFollowsSip = false; + protected String jvmRoute; + protected ReplicationStrategy replicationStrategy; + + /** + * the sip stack path name. Since the sip factory is per classloader it should be set here for all underlying stacks + */ + private String sipPathName; + /** + * use Pretty Encoding + */ + private boolean usePrettyEncoding = true; + + private SipStack sipStack; + // defining sip stack properties + private Properties sipStackProperties; + private String sipStackPropertiesFileLocation; + @Deprecated + private String addressResolverClass = null; + private String dnsServerLocatorClass = DefaultDNSServerLocator.class.getName(); + private int dnsTimeout = 1; + private String dnsResolverClass = MobicentsDNSResolver.class.getName(); + private String mobicentsSipServletMessageFactoryClassName = Servlet3SipServletMessageFactory.class.getName(); + + //the balancers to send heartbeat to and our health info + @Deprecated + private String balancers; + // + private ScheduledFuture gracefulStopFuture; + + @Override + public String getInfo() { + return (INFO); + } + + @Override + public void addConnector(Connector connector) { + if (initialized) { + MobicentsExtendedListeningPoint extendedListeningPoint = null; + if (connector.getProtocolHandler() instanceof SipProtocolHandler) { + extendedListeningPoint = (MobicentsExtendedListeningPoint) + ((SipProtocolHandler)connector.getProtocolHandler()).getAttribute(ExtendedListeningPoint.class.getSimpleName());} + if(extendedListeningPoint != null) { + try { + extendedListeningPoint.getSipProvider().addSipListener(sipApplicationDispatcher); + sipApplicationDispatcher.getSipNetworkInterfaceManager().addExtendedListeningPoint(extendedListeningPoint); + } catch (TooManyListenersException e) { + logger.error("Connector.initialize", e); + } + } + ProtocolHandler protocolHandler = connector.getProtocolHandler(); + if(protocolHandler instanceof SipProtocolHandler) { + connector.setPort(((SipProtocolHandler)protocolHandler).getPort()); + ((SipProtocolHandler)protocolHandler).setSipStack(sipStack); + ((SipProtocolHandler)protocolHandler).setAttribute(SipApplicationDispatcher.class.getSimpleName(), sipApplicationDispatcher); + registerSipConnector(connector); + } + } + else { + } + super.addConnector(connector); + } + + /** + * Register the sip connector under a different name than HTTP Connector and we add the transport to avoid clashing with 2 connectors having the same port and address + * @param connector connector to register + */ + protected void registerSipConnector(Connector connector) { + try { + ObjectName objectName = createSipConnectorObjectName(connector, getName(), "SipConnector"); + if(logger.isDebugEnabled()) { + logger.debug("registering sip connector : " + objectName); + } + Registry.getRegistry(null, null) + .registerComponent(connector, objectName, null); +//TODO connector.setController(objectName); + } catch (Exception e) { + logger.error( "Error registering connector ", e); + } + if(logger.isDebugEnabled()) + logger.debug("Creating name for connector " + getObjectName()); + } + + /** + * Register the sip connector under a different name than HTTP Connector and we add the transport to avoid clashing with 2 connectors having the same port and address + * @param connector connector to register + */ + protected void unregisterSipConnector(Connector connector) { + try { + + ObjectName objectName = createSipConnectorObjectName(connector, getName(), "SipConnector"); + if(logger.isDebugEnabled()) { + logger.debug("unregistering sip connector : " + objectName); + } + Registry.getRegistry(null, null) + .unregisterComponent(objectName); + } catch (Exception e) { + logger.error( "Error registering connector ", e); + } + if(logger.isDebugEnabled()) + logger.debug("Creating name for connector " + getObjectName()); + } + + @Override + public void removeConnector(Connector connector) { + MobicentsExtendedListeningPoint extendedListeningPoint = null; + if (connector.getProtocolHandler() instanceof SipProtocolHandler) { + extendedListeningPoint = (MobicentsExtendedListeningPoint) + ((SipProtocolHandler)connector.getProtocolHandler()).getAttribute(ExtendedListeningPoint.class.getSimpleName()); + unregisterSipConnector(connector); + } + if(extendedListeningPoint != null) { + extendedListeningPoint.getSipProvider().removeSipListener(sipApplicationDispatcher); + sipApplicationDispatcher.getSipNetworkInterfaceManager().removeExtendedListeningPoint(extendedListeningPoint); + } + super.removeConnector(connector); + } + + @Override + public void initialize() throws LifecycleException { + //load the sip application disptacher from the class name specified in the server.xml file + //and initializes it + StaticServiceHolder.sipStandardService = this; + try { + sipApplicationDispatcher = (SipApplicationDispatcher) + Class.forName(sipApplicationDispatcherClassName).newInstance(); + } catch (InstantiationException e) { + throw new LifecycleException("Impossible to load the Sip Application Dispatcher",e); + } catch (IllegalAccessException e) { + throw new LifecycleException("Impossible to load the Sip Application Dispatcher",e); + } catch (ClassNotFoundException e) { + throw new LifecycleException("Impossible to load the Sip Application Dispatcher",e); + } catch (ClassCastException e) { + throw new LifecycleException("Sip Application Dispatcher defined does not implement " + SipApplicationDispatcher.class.getName(),e); + } + if(logger.isInfoEnabled()) { + logger.info("Pretty encoding of headers enabled ? " + usePrettyEncoding); + } + if(sipPathName == null) { + sipPathName = DEFAULT_SIP_PATH_NAME; + } + if(logger.isInfoEnabled()) { + logger.info("Sip Stack path name : " + sipPathName); + } + sipApplicationDispatcher.setSipService(this); + sipApplicationDispatcher.getSipFactory().initialize(sipPathName, usePrettyEncoding); + + String catalinaBase = getCatalinaBase(); + if(darConfigurationFileLocation != null) { + if(!darConfigurationFileLocation.startsWith("file:///")) { + darConfigurationFileLocation = "file:///" + catalinaBase.replace(File.separatorChar, '/') + "/" + darConfigurationFileLocation; + } + System.setProperty("javax.servlet.sip.dar", darConfigurationFileLocation); + } + super.initialize(); + sipApplicationDispatcher.setDomain(this.getName()); + if(baseTimerInterval < 1) { + throw new LifecycleException("It's forbidden to set the Base Timer Interval to a non positive value"); + } + initSipStack(); + sipApplicationDispatcher.setBaseTimerInterval(baseTimerInterval); + sipApplicationDispatcher.setT2Interval(t2Interval); + sipApplicationDispatcher.setT4Interval(t4Interval); + sipApplicationDispatcher.setTimerDInterval(timerDInterval); + sipApplicationDispatcher.setMemoryThreshold(getMemoryThreshold()); + sipApplicationDispatcher.setBackToNormalMemoryThreshold(backToNormalMemoryThreshold); + sipApplicationDispatcher.setCongestionControlCheckingInterval(getCongestionControlCheckingInterval()); + sipApplicationDispatcher.setCongestionControlPolicyByName(getCongestionControlPolicy()); + sipApplicationDispatcher.setQueueSize(getSipMessageQueueSize()); + sipApplicationDispatcher.setBackToNormalQueueSize(backToNormalSipMessageQueueSize); + sipApplicationDispatcher.setGatherStatistics(gatherStatistics); + sipApplicationDispatcher.setConcurrencyControlMode(ConcurrencyControlMode.valueOf(getConcurrencyControlMode())); + sipApplicationDispatcher.setBypassRequestExecutor(bypassRequestExecutor); + sipApplicationDispatcher.setBypassResponseExecutor(bypassResponseExecutor); + sipApplicationDispatcher.setSipStack(sipStack); + sipApplicationDispatcher.init(); + // Tomcat specific loading case where the connectors are added even before the service is initialized + // so we need to set the sip stack before it starts + synchronized (connectors) { + for (Connector connector : connectors) { + ProtocolHandler protocolHandler = connector.getProtocolHandler(); + if(protocolHandler instanceof SipProtocolHandler) { + connector.setPort(((SipProtocolHandler)protocolHandler).getPort()); + ((SipProtocolHandler)protocolHandler).setSipStack(sipStack); + ((SipProtocolHandler)protocolHandler).setAttribute(SipApplicationDispatcher.class.getSimpleName(), sipApplicationDispatcher); + registerSipConnector(connector); + } + } + } + } + + @Override + public void start() throws LifecycleException { + super.start(); + synchronized (connectors) { + for (Connector connector : connectors) { + final ProtocolHandler protocolHandler = connector.getProtocolHandler(); + //Jboss sepcific loading case + Boolean isSipConnector = false; + if (protocolHandler instanceof SipProtocolHandler) + isSipConnector = (Boolean) ((SipProtocolHandler)protocolHandler).getAttribute(SipProtocolHandler.IS_SIP_CONNECTOR); + if(isSipConnector != null && isSipConnector) { + if(logger.isDebugEnabled()) { + logger.debug("Attaching the sip application dispatcher " + + "as a sip listener to connector listening on port " + + connector.getPort()); + } + ((SipProtocolHandler)protocolHandler).setAttribute(SipApplicationDispatcher.class.getSimpleName(), sipApplicationDispatcher); + ((SipProtocolHandler)protocolHandler).setSipStack(sipStack); + connectorsStartedExternally = true; + } + //Tomcat specific loading case + MobicentsExtendedListeningPoint extendedListeningPoint = null; + if (protocolHandler instanceof SipProtocolHandler) { + extendedListeningPoint = (MobicentsExtendedListeningPoint) + ((SipProtocolHandler)protocolHandler).getAttribute(ExtendedListeningPoint.class.getSimpleName());} + if(extendedListeningPoint != null && sipStack != null) { + try { + extendedListeningPoint.getSipProvider().addSipListener(sipApplicationDispatcher); + sipApplicationDispatcher.getSipNetworkInterfaceManager().addExtendedListeningPoint(extendedListeningPoint); + connectorsStartedExternally = false; + } catch (TooManyListenersException e) { + throw new LifecycleException("Couldn't add the sip application dispatcher " + + sipApplicationDispatcher + " as a listener to the following listening point provider " + extendedListeningPoint, e); + } + } + } + } + if(!connectorsStartedExternally) { + sipApplicationDispatcher.start(); + } + + if(this.getSipMessageQueueSize() <= 0) + throw new LifecycleException("Message queue size can not be 0 or less"); + + if(logger.isDebugEnabled()) { + logger.debug("SIP Standard Service Started."); + } + } + + public String getJvmRoute() { + return this.jvmRoute; + } + + public void setJvmRoute(String jvmRoute) { + this.jvmRoute = jvmRoute; + } + + protected void initSipStack() throws LifecycleException { + try { + if(logger.isDebugEnabled()) { + logger.debug("Initializing SIP stack"); + } + + // This simply puts HTTP and SSL port numbers in JVM properties menat to be read by jsip ha when sending heart beats with Node description. + initializeSystemPortProperties(); + + String catalinaBase = getCatalinaBase(); + if(sipStackPropertiesFileLocation != null && !sipStackPropertiesFileLocation.startsWith("file:///")) { + sipStackPropertiesFileLocation = "file:///" + catalinaBase.replace(File.separatorChar, '/') + "/" + sipStackPropertiesFileLocation; + } + boolean isPropsLoaded = false; + if(sipStackProperties == null) { + sipStackProperties = new Properties(); + } else { + isPropsLoaded = true; + } + + if (logger.isDebugEnabled()) { + logger.debug("Loading SIP stack properties from following file : " + sipStackPropertiesFileLocation); + } + if(sipStackPropertiesFileLocation != null) { + //hack to get around space char in path see http://weblogs.java.net/blog/kohsuke/archive/2007/04/how_to_convert.html, + // we create a URL since it's permissive enough + File sipStackPropertiesFile = null; + URL url = null; + try { + url = new URL(sipStackPropertiesFileLocation); + } catch (MalformedURLException e) { + logger.fatal("Cannot find the sip stack properties file ! ",e); + throw new IllegalArgumentException("The Default Application Router file Location : "+sipStackPropertiesFileLocation+" is not valid ! ",e); + } + try { + sipStackPropertiesFile = new File(new URI(sipStackPropertiesFileLocation)); + } catch (URISyntaxException e) { + //if the uri contains space this will fail, so getting the path will work + sipStackPropertiesFile = new File(url.getPath()); + } + FileInputStream sipStackPropertiesInputStream = null; + try { + sipStackPropertiesInputStream = new FileInputStream(sipStackPropertiesFile); + sipStackProperties.load(sipStackPropertiesInputStream); + } catch (Exception e) { + logger.warn("Could not find or problem when loading the sip stack properties file : " + sipStackPropertiesFileLocation, e); + } finally { + if(sipStackPropertiesInputStream != null) { + try { + sipStackPropertiesInputStream.close(); + } catch (IOException e) { + logger.error("fail to close the following file " + sipStackPropertiesFile.getAbsolutePath(), e); + } + } + } + + String debugLog = sipStackProperties.getProperty(DEBUG_LOG_STACK_PROP); + if(debugLog != null && debugLog.length() > 0 && !debugLog.startsWith("file:///")) { + sipStackProperties.setProperty(DEBUG_LOG_STACK_PROP, + catalinaBase + "/" + debugLog); + } + String serverLog = sipStackProperties.getProperty(SERVER_LOG_STACK_PROP); + if(serverLog != null && serverLog.length() > 0 && !serverLog.startsWith("file:///")) { + sipStackProperties.setProperty(SERVER_LOG_STACK_PROP, + catalinaBase + "/" + serverLog); + } + // The whole MSS is built upon those assumptions, so those properties are not overrideable + if (sipStackProperties.getProperty(AUTOMATIC_DIALOG_SUPPORT_STACK_PROP) == null) { + //https://github.com/RestComm/sip-servlets/issues/143 + //set off if user didnt provided any value. + sipStackProperties.setProperty(AUTOMATIC_DIALOG_SUPPORT_STACK_PROP, "off"); + } + sipStackProperties.setProperty(LOOSE_DIALOG_VALIDATION, "true"); + sipStackProperties.setProperty(PASS_INVITE_NON_2XX_ACK_TO_LISTENER, "true"); + isPropsLoaded = true; + } else { + logger.warn("no sip stack properties file defined "); + } + if(!isPropsLoaded) { + logger.warn("loading default Mobicents Sip Servlets sip stack properties"); + // Silently set default values + sipStackProperties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", + "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", + "LOG4J"); + sipStackProperties.setProperty(DEBUG_LOG_STACK_PROP, + catalinaBase + "/" + "mss-jsip-" + getName() +"-debug.txt"); + sipStackProperties.setProperty(SERVER_LOG_STACK_PROP, + catalinaBase + "/" + "mss-jsip-" + getName() +"-messages.xml"); + sipStackProperties.setProperty("javax.sip.STACK_NAME", "mss-" + getName()); + sipStackProperties.setProperty(AUTOMATIC_DIALOG_SUPPORT_STACK_PROP, "off"); + sipStackProperties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.THREAD_POOL_SIZE", "64"); + sipStackProperties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.MAX_FORK_TIME_SECONDS", "0"); + sipStackProperties.setProperty(LOOSE_DIALOG_VALIDATION, "true"); + sipStackProperties.setProperty(PASS_INVITE_NON_2XX_ACK_TO_LISTENER, "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.AUTOMATIC_DIALOG_ERROR_HANDLING", "false"); + sipStackProperties.setProperty("gov.nist.javax.sip.AGGRESSIVE_CLEANUP", "true"); + } + + if(sipStackProperties.get(TCP_POST_PARSING_THREAD_POOL_SIZE) == null) { + sipStackProperties.setProperty(TCP_POST_PARSING_THREAD_POOL_SIZE, "30"); + } + + // set the DNSServerLocator allowing to support RFC 3263 and do DNS lookups to resolve uris + if(dnsServerLocatorClass != null && dnsServerLocatorClass.trim().length() > 0) { + if(logger.isDebugEnabled()) { + logger.debug("Sip Stack " + sipStackProperties.getProperty("javax.sip.STACK_NAME") +" will be using " + dnsServerLocatorClass + " as DNSServerLocator"); + } + try { + // create parameters argument to identify constructor + Class[] paramTypes = new Class[0]; + // get constructor of AddressResolver in order to instantiate + Constructor dnsServerLocatorConstructor = Class.forName(dnsServerLocatorClass).getConstructor( + paramTypes); + // Wrap properties object in order to pass to constructor of AddressResolver + Object[] conArgs = new Object[0]; + // Creates a new instance of AddressResolver Class with the supplied sipApplicationDispatcher. + DNSServerLocator dnsServerLocator = (DNSServerLocator) dnsServerLocatorConstructor.newInstance(conArgs); + sipApplicationDispatcher.setDNSServerLocator(dnsServerLocator); + sipApplicationDispatcher.setDNSTimeout(dnsTimeout); + if(sipStackProperties.getProperty("javax.sip.ROUTER_PATH") == null) { + sipStackProperties.setProperty("javax.sip.ROUTER_PATH", DNSAwareRouter.class.getCanonicalName()); + } + } catch (Exception e) { + logger.error("Couldn't set the AddressResolver " + addressResolverClass, e); + throw e; + } + } else { + if(logger.isInfoEnabled()) { + logger.info("no DNSServerLocator will be used since none has been specified."); + } + } + + String serverHeaderValue = sipStackProperties.getProperty(SERVER_HEADER); + if(serverHeaderValue != null) { + List serverHeaderList = new ArrayList(); + StringTokenizer stringTokenizer = new StringTokenizer(serverHeaderValue, ","); + while(stringTokenizer.hasMoreTokens()) { + serverHeaderList.add(stringTokenizer.nextToken()); + } + ServerHeader serverHeader = sipApplicationDispatcher.getSipFactory().getHeaderFactory().createServerHeader(serverHeaderList); + ((MessageFactoryExt)sipApplicationDispatcher.getSipFactory().getMessageFactory()).setDefaultServerHeader(serverHeader); + } + String userAgent = sipStackProperties.getProperty(USER_AGENT_HEADER); + if(userAgent != null) { + List userAgentList = new ArrayList(); + StringTokenizer stringTokenizer = new StringTokenizer(userAgent, ","); + while(stringTokenizer.hasMoreTokens()) { + userAgentList.add(stringTokenizer.nextToken()); + } + UserAgentHeader userAgentHeader = sipApplicationDispatcher.getSipFactory().getHeaderFactory().createUserAgentHeader(userAgentList); + ((MessageFactoryExt)sipApplicationDispatcher.getSipFactory().getMessageFactory()).setDefaultUserAgentHeader(userAgentHeader); + } + if(balancers != null) { + if(sipStackProperties.get(LoadBalancerHeartBeatingService.LB_HB_SERVICE_CLASS_NAME) == null) { + sipStackProperties.put(LoadBalancerHeartBeatingService.LB_HB_SERVICE_CLASS_NAME, LoadBalancerHeartBeatingServiceImpl.class.getCanonicalName()); + } + if(sipStackProperties.get(LoadBalancerHeartBeatingService.BALANCERS) == null) { + sipStackProperties.put(LoadBalancerHeartBeatingService.BALANCERS, balancers); + } + } + String replicationStrategyString = sipStackProperties.getProperty(ClusteredSipStack.REPLICATION_STRATEGY_PROPERTY); + if(replicationStrategyString == null) { + replicationStrategyString = ReplicationStrategy.ConfirmedDialog.toString(); + } + boolean replicateApplicationData = false; + if(replicationStrategyString.equals(ReplicationStrategy.EarlyDialog.toString())) { + replicateApplicationData = true; + } + if(replicationStrategyString != null) { + replicationStrategy = ReplicationStrategy.valueOf(replicationStrategyString); + } + sipStackProperties.put(ClusteredSipStack.REPLICATION_STRATEGY_PROPERTY, replicationStrategyString); + sipStackProperties.put(ClusteredSipStack.REPLICATE_APPLICATION_DATA, Boolean.valueOf(replicateApplicationData).toString()); + if(logger.isInfoEnabled()) { + logger.info("Mobicents Sip Servlets sip stack properties : " + sipStackProperties); + } + // Create SipStack object + sipStack = sipApplicationDispatcher.getSipFactory().getJainSipFactory().createSipStack(sipStackProperties); + LoadBalancerHeartBeatingService loadBalancerHeartBeatingService = null; + if(sipStack instanceof ClusteredSipStack) { + loadBalancerHeartBeatingService = ((ClusteredSipStack) sipStack).getLoadBalancerHeartBeatingService(); + if ((this.container != null) && (this.container instanceof Engine) && ((Engine)container).getJvmRoute() != null) { + final String jvmRoute = ((Engine)container).getJvmRoute(); + if(jvmRoute != null) { + loadBalancerHeartBeatingService.setJvmRoute(jvmRoute); + setJvmRoute(jvmRoute); + } + } + } + if(sipApplicationDispatcher != null && loadBalancerHeartBeatingService != null && sipApplicationDispatcher instanceof LoadBalancerHeartBeatingListener) { + loadBalancerHeartBeatingService.addLoadBalancerHeartBeatingListener((LoadBalancerHeartBeatingListener)sipApplicationDispatcher); + } + // for nist sip stack set the DNS Address resolver allowing to make DNS SRV lookups + if(sipStack instanceof SipStackExt && addressResolverClass != null && addressResolverClass.trim().length() > 0) { + if(logger.isDebugEnabled()) { + logger.debug("Sip Stack " + sipStack.getStackName() +" will be using " + addressResolverClass + " as AddressResolver"); + } + try { + // create parameters argument to identify constructor + Class[] paramTypes = new Class[1]; + paramTypes[0] = SipApplicationDispatcher.class; + // get constructor of AddressResolver in order to instantiate + Constructor addressResolverConstructor = Class.forName(addressResolverClass).getConstructor( + paramTypes); + // Wrap properties object in order to pass to constructor of AddressResolver + Object[] conArgs = new Object[1]; + conArgs[0] = sipApplicationDispatcher; + // Creates a new instance of AddressResolver Class with the supplied sipApplicationDispatcher. + AddressResolver addressResolver = (AddressResolver) addressResolverConstructor.newInstance(conArgs); + ((SipStackExt) sipStack).setAddressResolver(addressResolver); + } catch (Exception e) { + logger.error("Couldn't set the AddressResolver " + addressResolverClass, e); + throw e; + } + } else { + if(logger.isInfoEnabled()) { + logger.info("no AddressResolver will be used since none has been specified."); + } + } + if(logger.isInfoEnabled()) { + logger.info("SIP stack initialized"); + } + } catch (Exception ex) { + if(ex instanceof PeerUnavailableException) { + logger.error("the SIP Stack couldn't be started because of " + ex.getCause()); + ex.getCause().printStackTrace(); + } + throw new LifecycleException("A problem occured while initializing the SIP Stack", ex); + } + } + + @Override + public void stop() throws LifecycleException { + // Tomcat specific unloading case + // Issue 1411 http://code.google.com/p/mobicents/issues/detail?id=1411 + // Sip Connectors should be removed after removing all Sip Servlets to allow them to send BYE to terminate cleanly + synchronized (connectors) { + for (Connector connector : connectors) { + MobicentsExtendedListeningPoint extendedListeningPoint = null; + if (connector.getProtocolHandler() instanceof SipProtocolHandler) { + extendedListeningPoint = (MobicentsExtendedListeningPoint) + ((SipProtocolHandler)connector.getProtocolHandler()).getAttribute(ExtendedListeningPoint.class.getSimpleName()); + } + if(extendedListeningPoint != null) { + extendedListeningPoint.getSipProvider().removeSipListener(sipApplicationDispatcher); + sipApplicationDispatcher.getSipNetworkInterfaceManager().removeExtendedListeningPoint(extendedListeningPoint); + } + } + } + if(!connectorsStartedExternally) { + sipApplicationDispatcher.stop(); + } + super.stop(); + if(logger.isDebugEnabled()) { + logger.debug("SIP Standard Service Stopped."); + } +// setState(LifecycleState.STOPPING); + } + + /** + * Retrieve the sip application dispatcher class name + * @return the sip application dispatcher class name + */ + public String getSipApplicationDispatcherClassName() { + return sipApplicationDispatcherClassName; + } + + /** + * Set the sip application dispatcher class name + * @param sipApplicationDispatcherClassName the sip application dispatcher class name to be set + */ + public void setSipApplicationDispatcherClassName(String sipApplicationDispatcherName) { + this.sipApplicationDispatcherClassName = sipApplicationDispatcherName; + } + + /** + * @return the sipApplicationDispatcher + */ + public SipApplicationDispatcher getSipApplicationDispatcher() { + return sipApplicationDispatcher; + } + + /** + * @param sipApplicationDispatcher the sipApplicationDispatcher to set + */ + public void setSipApplicationDispatcher( + SipApplicationDispatcher sipApplicationDispatcher) { + this.sipApplicationDispatcher = sipApplicationDispatcher; + } + + /** + * @return the darConfigurationFileLocation + */ + public String getDarConfigurationFileLocation() { + return darConfigurationFileLocation; + } + + /** + * @param darConfigurationFileLocation the darConfigurationFileLocation to set + */ + public void setDarConfigurationFileLocation(String darConfigurationFileLocation) { + this.darConfigurationFileLocation = darConfigurationFileLocation; + } + + /** + * Message queue size. If the number of pending requests exceeds this number they are rejected. + * + * @return + */ + public int getSipMessageQueueSize() { + return sipMessageQueueSize; + } + + /** + * Message queue size. If the number of pending requests exceeds this number they are rejected. + * + * @return + */ + public void setSipMessageQueueSize(int sipMessageQueueSize) { + this.sipMessageQueueSize = sipMessageQueueSize; + } + + /** + * ConcurrencyControl control mode is SipSession, AppSession or None + * Specifies the isolation level of concurrently executing requests. + * + * @return + */ + public String getConcurrencyControlMode() { + return concurrencyControlMode; + } + + /** + * ConcurrencyControl control mode is SipSession, AppSession or None + * Specifies the isolation level of concurrently executing requests. + * + * @return + */ + public void setConcurrencyControlMode(String concurrencyControlMode) { + this.concurrencyControlMode = concurrencyControlMode; + } + + + /** + * @param memoryThreshold the memoryThreshold to set + */ + public void setMemoryThreshold(int memoryThreshold) { + this.memoryThreshold = memoryThreshold; + } + + + /** + * @return the memoryThreshold + */ + public int getMemoryThreshold() { + return memoryThreshold; + } + + /** + * @param gatherStatistics the skipStatistics to set + */ + public void setGatherStatistics(boolean gatherStatistics) { + this.gatherStatistics = gatherStatistics; + if(logger.isInfoEnabled()) { + logger.info("Gathering Statistics set to " + gatherStatistics); + } + } + + /** + * @return the skipStatistics + */ + public boolean isGatherStatistics() { + return gatherStatistics; + } + + /** + * PRESENT TO ACCOMODATE JOPR. NEED TO FILE A BUG ON THIS + * @return the skipStatistics + */ + public boolean getGatherStatistics() { + return gatherStatistics; + } + + /** + * @param backToNormalPercentageOfMemoryUsed the backToNormalPercentageOfMemoryUsed to set + */ + public void setBackToNormalMemoryThreshold( + int backToNormalMemoryThreshold) { + this.backToNormalMemoryThreshold = backToNormalMemoryThreshold; + } + + /** + * @return the backToNormalPercentageOfMemoryUsed + */ + public int getBackToNormalMemoryThreshold() { + return backToNormalMemoryThreshold; + } + + /** + * @param backToNormalQueueSize the backToNormalQueueSize to set + */ + public void setBackToNormalSipMessageQueueSize(int backToNormalSipMessageQueueSize) { + this.backToNormalSipMessageQueueSize = backToNormalSipMessageQueueSize; + } + + /** + * @return the backToNormalQueueSize + */ + public int getBackToNormalSipMessageQueueSize() { + return backToNormalSipMessageQueueSize; + } + + + /** + * @param congestionControlPolicy the congestionControlPolicy to set + */ + public void setCongestionControlPolicy(String congestionControlPolicy) { + this.congestionControlPolicy = congestionControlPolicy; + } + + + /** + * @return the congestionControlPolicy + */ + public String getCongestionControlPolicy() { + return congestionControlPolicy; + } + + + /** + * @param congestionControlCheckingInterval the congestionControlCheckingInterval to set + */ + public void setCongestionControlCheckingInterval( + long congestionControlCheckingInterval) { + this.congestionControlCheckingInterval = congestionControlCheckingInterval; + } + + + /** + * @return the congestionControlCheckingInterval + */ + public long getCongestionControlCheckingInterval() { + return congestionControlCheckingInterval; + } + + + public String getAdditionalParameterableHeaders() { + return additionalParameterableHeaders; + } + + + public void setAdditionalParameterableHeaders( + String additionalParameterableHeaders) { + this.additionalParameterableHeaders = additionalParameterableHeaders; + String[] headers = additionalParameterableHeaders.split(","); + for(String header : headers) { + if(header != null && header.length()>0) { + JainSipUtils.PARAMETERABLE_HEADER_NAMES.add(header); + } + } + } + + + /** + * @return the bypassResponseExecutor + */ + public boolean isBypassResponseExecutor() { + return bypassResponseExecutor; + } + + + /** + * @param bypassResponseExecutor the bypassResponseExecutor to set + */ + public void setBypassResponseExecutor(boolean bypassResponseExecutor) { + this.bypassResponseExecutor = bypassResponseExecutor; + } + + + /** + * @return the bypassRequestExecutor + */ + public boolean isBypassRequestExecutor() { + return bypassRequestExecutor; + } + + + /** + * @param bypassRequestExecutor the bypassRequestExecutor to set + */ + public void setBypassRequestExecutor(boolean bypassRequestExecutor) { + this.bypassRequestExecutor = bypassRequestExecutor; + } + + public boolean isMd5ContactUserPart() { + return md5ContactUserPart; + } + + + public void setMd5ContactUserPart(boolean md5ContactUserPart) { + this.md5ContactUserPart = md5ContactUserPart; + } + + + /** + * @param usePrettyEncoding the usePrettyEncoding to set + */ + public void setUsePrettyEncoding(boolean usePrettyEncoding) { + this.usePrettyEncoding = usePrettyEncoding; + } + + /** + * @return the usePrettyEncoding + */ + public boolean isUsePrettyEncoding() { + return usePrettyEncoding; + } + + /** + * @param sipPathName the sipPathName to set + */ + public void setSipPathName(String sipPathName) { + this.sipPathName = sipPathName; + } + + /** + * @return the sipPathName + */ + public String getSipPathName() { + return sipPathName; + } + + + /** + * @param baseTimerInterval the baseTimerInterval to set + */ + public void setBaseTimerInterval(int baseTimerInterval) { + this.baseTimerInterval = baseTimerInterval; + } + + + /** + * @return the baseTimerInterval + */ + public int getBaseTimerInterval() { + return baseTimerInterval; + } + + + public OutboundProxy getOutboundProxy() { + return outboundProxy; + } + + + public void setOutboundProxy(String outboundProxy) { + if(outboundProxy != null) { + this.outboundProxy = new OutboundProxy(outboundProxy); + } else { + this.outboundProxy = null; + } + if(logger.isDebugEnabled()) { + logger.debug("Outbound Proxy : " + outboundProxy); + } + } + + public int getDispatcherThreadPoolSize() { + return dispatcherThreadPoolSize; + } + + + public void setDispatcherThreadPoolSize(int dispatcherThreadPoolSize) { + this.dispatcherThreadPoolSize = dispatcherThreadPoolSize; + } + + public int getCanceledTimerTasksPurgePeriod() { + return canceledTimerTasksPurgePeriod; + } + + public void setCanceledTimerTasksPurgePeriod(int purgePeriod) { + this.canceledTimerTasksPurgePeriod = purgePeriod; + } + + /** + * @deprecated + * @param balancers the balancers to set + */ + public void setBalancers(String balancers) { + this.balancers = balancers; + } + + public boolean addSipConnector(SipConnector sipConnector) throws Exception { + if(sipConnector == null) { + throw new IllegalArgumentException("The sip connector passed is null"); + } + Connector connectorToAdd = findSipConnector(sipConnector.getIpAddress(), sipConnector.getPort(), + sipConnector.getTransport()); + if(connectorToAdd == null) { + Connector connector = new Connector( + SipProtocolHandler.class.getName()); + SipProtocolHandler sipProtocolHandler = (SipProtocolHandler) connector + .getProtocolHandler(); + sipProtocolHandler.setSipConnector(sipConnector); + sipProtocolHandler.setSipStack(sipStack); + connector.setService(this); +//TODO connector.setContainer(container); + connector.init(); + addConnector(connector); + MobicentsExtendedListeningPoint extendedListeningPoint = (MobicentsExtendedListeningPoint) + sipProtocolHandler.getAttribute(ExtendedListeningPoint.class.getSimpleName()); + if(extendedListeningPoint != null) { + try { + extendedListeningPoint.getSipProvider().addSipListener(sipApplicationDispatcher); + sipApplicationDispatcher.getSipNetworkInterfaceManager().addExtendedListeningPoint(extendedListeningPoint); + } catch (TooManyListenersException e) { + logger.error("Connector.initialize", e); + removeConnector(connector); + return false; + } + } + if(!sipProtocolHandler.isStarted()) { + if(logger.isDebugEnabled()) { + logger.debug("Sip Connector couldn't be started, removing it automatically"); + } + removeConnector(connector); + } + return sipProtocolHandler.isStarted(); + } + return false; + } + + public boolean removeSipConnector(String ipAddress, int port, String transport) throws Exception { + Connector connectorToRemove = findSipConnector(ipAddress, port, + transport); + if(connectorToRemove != null) { + removeConnector(connectorToRemove); + return true; + } + return false; + } + + + /** + * Find a sip Connector by it's ip address, port and transport + * @param ipAddress ip address of the connector to find + * @param port port of the connector to find + * @param transport transport of the connector to find + * @return the found sip connector or null if noting found + */ + private Connector findSipConnector(String ipAddress, int port, + String transport) { + Connector connectorToRemove = null; + for (Connector connector : connectors) { + final ProtocolHandler protocolHandler = connector.getProtocolHandler(); + if(protocolHandler instanceof SipProtocolHandler) { + final SipProtocolHandler sipProtocolHandler = (SipProtocolHandler) protocolHandler; + if(sipProtocolHandler.getIpAddress().equals(ipAddress) && sipProtocolHandler.getPort() == port && sipProtocolHandler.getSignalingTransport().equalsIgnoreCase(transport)) { +// connector.destroy(); + connectorToRemove = connector; + break; + } + } + } + return connectorToRemove; + } + + public SipConnector findSipConnector(String transport) { + List sipConnectors = new ArrayList(); + for (Connector connector : connectors) { + final ProtocolHandler protocolHandler = connector.getProtocolHandler(); + if(protocolHandler instanceof SipProtocolHandler) { + SipConnector sc = (((SipProtocolHandler)protocolHandler).getSipConnector()); + if(sc.getTransport().equalsIgnoreCase(transport)) return sc; + } + } + return null; + } + + public SipConnector[] findSipConnectors() { + List sipConnectors = new ArrayList(); + for (Connector connector : connectors) { + final ProtocolHandler protocolHandler = connector.getProtocolHandler(); + if(protocolHandler instanceof SipProtocolHandler) { + sipConnectors.add(((SipProtocolHandler)protocolHandler).getSipConnector()); + } + } + return sipConnectors.toArray(new SipConnector[sipConnectors.size()]); + } + + /** + * This method simply makes the HTTP and SSL ports avaialble everywhere in the JVM in order jsip ha to read them for + * balancer description purposes. There is no other good way to communicate the properies to jsip ha without adding + * more dependencies. + */ + public void initializeSystemPortProperties() { + for (Connector connector : connectors) { + if(connector.getProtocol().contains("HTTP")) { + if(connector.getSecure()) { + System.setProperty("org.mobicents.properties.sslPort", Integer.toString(connector.getPort())); + } else { + System.setProperty("org.mobicents.properties.httpPort", Integer.toString(connector.getPort())); + } + } + } + } + + protected ObjectName createSipConnectorObjectName(Connector connector, String domain, String type) + throws MalformedObjectNameException { + String encodedAddr = null; + if (connector.getProperty("address") != null) { + encodedAddr = URLEncoder.encode(connector.getProperty("address").toString()); + } + String addSuffix = (connector.getProperty("address") == null) ? "" : ",address=" + + encodedAddr; + ObjectName _oname = new ObjectName(domain + ":type=" + type + ",port=" + + connector.getPort() + ",transport=" + connector.getProperty("transport") + addSuffix); + return _oname; + } + + + /** + * @param t2Interval the t2Interval to set + */ + public void setT2Interval(int t2Interval) { + this.t2Interval = t2Interval; + } + + + /** + * @return the t2Interval + */ + public int getT2Interval() { + return t2Interval; + } + + + /** + * @param t4Interval the t4Interval to set + */ + public void setT4Interval(int t4Interval) { + this.t4Interval = t4Interval; + } + + + /** + * @return the t4Interval + */ + public int getT4Interval() { + return t4Interval; + } + + + /** + * @param timerDInterval the timerDInterval to set + */ + public void setTimerDInterval(int timerDInterval) { + this.timerDInterval = timerDInterval; + } + + + /** + * @return the timerDInterval + */ + public int getTimerDInterval() { + return timerDInterval; + } + + /** + * @param sipStackPropertiesFile the sipStackPropertiesFile to set + */ + public void setSipStackPropertiesFile(String sipStackPropertiesFile) { + sipStackPropertiesFileLocation = sipStackPropertiesFile; + } + + /** + * @return the sipStackProperties + */ + public Properties getSipStackProperties() { + return sipStackProperties; + } + + /** + * @param sipStackProperties the sipStackProperties to set + */ + public void setSipStackProperties(Properties sipStackProperties) { + this.sipStackProperties = sipStackProperties; + } + + /** + * @return the sipStackPropertiesFile + */ + public String getSipStackPropertiesFile() { + return sipStackPropertiesFileLocation; + } + + /** + * @param dnsAddressResolverClass the dnsAddressResolverClass to set + */ + @Deprecated + public void setAddressResolverClass(String dnsAddressResolverClass) { + this.addressResolverClass = dnsAddressResolverClass; + } + + /** + * @return the dnsAddressResolverClass + */ + @Deprecated + public String getAddressResolverClass() { + return addressResolverClass; + } + + /** + * Whether we check for pending requests and return 491 response if there are any + * + * @return the flag value + */ + public boolean isDialogPendingRequestChecking() { + return dialogPendingRequestChecking; + } + + /** + * + * Whether we check for pending requests and return 491 response if there are any + * + * @param dialogPendingRequestChecking + */ + public void setDialogPendingRequestChecking(boolean dialogPendingRequestChecking) { + this.dialogPendingRequestChecking = dialogPendingRequestChecking; + } + + + public boolean isHttpFollowsSip() { + return httpFollowsSip; + } + + + public void setHttpFollowsSip(boolean httpFollowsSip) { + this.httpFollowsSip = httpFollowsSip; + } + + /** + * @return the tagHashMaxLength + */ + public int getTagHashMaxLength() { + return tagHashMaxLength; + } + + /** + * @param tagHashMaxLength the tagHashMaxLength to set + */ + public void setTagHashMaxLength(int tagHashMaxLength) { + this.tagHashMaxLength = tagHashMaxLength; + } + + /** + * @return the callIdMaxLength + */ + public int getCallIdMaxLength() { + return callIdMaxLength; + } + + /** + * @param callIdMaxLength the callIdMaxLength to set + */ + public void setCallIdMaxLength(int callIdMaxLength) { + this.callIdMaxLength = callIdMaxLength; + } + + /** + * @return the sipStack + */ + public SipStack getSipStack() { + return sipStack; + } + + /** + * @param dnsServerLocatorClass the dnsServerLocatorClass to set + */ + public void setDnsServerLocatorClass(String dnsServerLocatorClass) { + this.dnsServerLocatorClass = dnsServerLocatorClass; + } + + /** + * @return the dnsServerLocatorClass + */ + public String getDnsServerLocatorClass() { + return dnsServerLocatorClass; + } + + /** + * @param dnsResolverClass the dnsResolverClass to set + */ + public void setDnsResolverClass(String dnsResolverClass) { + this.dnsResolverClass = dnsResolverClass; + } + + /** + * @return the dnsResolverClass + */ + public String getDnsResolverClass() { + return dnsResolverClass; + } + + /** + * Returns first the catalina.base if it is defined then the catalina.home if it is defined + * then the current dir if none is specified + */ + protected String getCatalinaBase() { + String catalinaBase = System.getProperty("catalina.base"); + if (catalinaBase == null) { + catalinaBase = System.getProperty("catalina.home"); + } + if(catalinaBase == null) { + catalinaBase = "."; + } + return catalinaBase; + } + + public ReplicationStrategy getReplicationStrategy() { + return replicationStrategy; + } + + @Override + public String getMobicentsSipServletMessageFactoryClassName() { + return mobicentsSipServletMessageFactoryClassName; + } + + @Override + public void setMobicentsSipServletMessageFactoryClassName( + String mobicentsSipServletMessageFactoryClassName) { + this.mobicentsSipServletMessageFactoryClassName = mobicentsSipServletMessageFactoryClassName; + } + + public void sendHeartBeat(String localAddress, int localPort, String transport, String remoteIpAddress, int remotePort) throws IOException { + MobicentsExtendedListeningPoint extendedListeningPoint = sipApplicationDispatcher.getSipNetworkInterfaceManager().findMatchingListeningPoint(localAddress, localPort, transport); + if(extendedListeningPoint != null) { + extendedListeningPoint.getListeningPoint().sendHeartbeat(remoteIpAddress, remotePort); + } + } + + public boolean setKeepAliveTimeout(SipConnector sipConnector, String clientAddress, int clientPort, long timeout) { + SIPTransactionStack sipStack = ((SIPTransactionStack) sipApplicationDispatcher.getSipStack()); + + return sipStack.setKeepAliveTimeout(sipConnector.getIpAddress(), sipConnector.getPort(), sipConnector.getTransport(), + clientAddress, clientPort, timeout); + } + + public void closeReliableConnection(SipConnector sipConnector, String clientAddress, int clientPort) { + SIPTransactionStack sipStack = ((SIPTransactionStack) sipApplicationDispatcher.getSipStack()); + + sipStack.closeReliableConnection(sipConnector.getIpAddress(),sipConnector.getPort(), sipConnector.getTransport(), + clientAddress, clientPort); + } + + @Override + public void stopGracefully(long timeToWait) { + if(logger.isInfoEnabled()) { + logger.info("Stopping the Server Gracefully in " + timeToWait + " ms"); + } + if(timeToWait == 0) { + if(gracefulStopFuture != null) { + gracefulStopFuture.cancel(false); + } + try { + stop(); + shutdownServer(); + } catch (Exception e){ + logger.error("The server couldn't be stopped", e); + } + + } else { + sipApplicationDispatcher.setGracefulShutdown(true); + Iterator sipContexts = sipApplicationDispatcher.findSipApplications(); + while (sipContexts.hasNext()) { + SipContext sipContext = sipContexts.next(); + sipContext.setGracefulInterval(gracefulInterval); + sipContext.stopGracefully(timeToWait); + } + + if(timeToWait > 0 && timeToWait < gracefulInterval) { + // if the time to Wait is positive and < to the gracefulStopTaskInterval then we schedule the task directly once to the time to wait + gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().schedule(new ServiceGracefulStopTask(this, timeToWait), timeToWait, TimeUnit.MILLISECONDS); + } else { + // if the time to Wait is > to the gracefulStopTaskInterval or infinite (negative value) then we schedule the task to run every gracefulStopTaskInterval, not needed to be exactly precise on the timeToWait in this case + gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().scheduleWithFixedDelay(new ServiceGracefulStopTask(this, timeToWait), gracefulInterval, gracefulInterval, TimeUnit.MILLISECONDS); + } +// gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().scheduleWithFixedDelay(new ServiceGracefulStopTask(this), 30000, 30000, TimeUnit.MILLISECONDS); +// if(timeToWait > 0) { +// gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().schedule( +// new Runnable() { +// public void run() { +// gracefulStopFuture.cancel(false); +// try { +// stop(); +// shutdownServer(); +// } catch (Exception e) { +// logger.error("The server couldn't be stopped", e); +// } +// } +// } +// , timeToWait, TimeUnit.MILLISECONDS); +// } + } + } + + protected void shutdownServer() throws MalformedObjectNameException, NullPointerException, InstanceNotFoundException, MBeanException, ReflectionException, IOException{ + MBeanServerConnection mbeanServerConnection = ManagementFactory.getPlatformMBeanServer(); + ObjectName mbeanName = new ObjectName("jboss.as:management-root=server"); + Object[] args = {false}; + String[] sigs = {"java.lang.Boolean"}; + mbeanServerConnection.invoke(mbeanName, "shutdown", args, sigs); + } + + /** + * @return the dnsTimeout + */ + public int getDnsTimeout() { + return dnsTimeout; + } + + /** + * @param dnsTimeout the dnsTimeout to set + */ + public void setDnsTimeout(int dnsTimeout) { + this.dnsTimeout = dnsTimeout; + } + + public String getProxyTimerServiceImplementationType() { + return proxyTimerServiceImplementationType; + } + + public void setProxyTimerServiceImplementationType(String proxyTimerServiceImplementationType) { + this.proxyTimerServiceImplementationType = proxyTimerServiceImplementationType; + } + + public String getSasTimerServiceImplementationType() { + return sasTimerServiceImplementationType; + } + + public void setSasTimerServiceImplementationType(String sasTimerServiceImplementationType) { + this.sasTimerServiceImplementationType = sasTimerServiceImplementationType; + } + + public void setGracefulInterval(long gracefulStopTaskInterval) { + this.gracefulInterval = gracefulStopTaskInterval; + } + +} diff --git a/containers/sip-servlets-as7/src/main/java/org/mobicents/servlet/sip/startup/SipStandardContext.java b/containers/sip-servlets-as7/src/main/java/org/mobicents/servlet/sip/startup/SipStandardContext.java index e00ec81a44..e5e5def3f2 100644 --- a/containers/sip-servlets-as7/src/main/java/org/mobicents/servlet/sip/startup/SipStandardContext.java +++ b/containers/sip-servlets-as7/src/main/java/org/mobicents/servlet/sip/startup/SipStandardContext.java @@ -30,6 +30,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.Stack; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.ScheduledFuture; @@ -59,6 +60,7 @@ import org.apache.catalina.security.SecurityUtil; import org.apache.log4j.Logger; import org.apache.tomcat.InstanceManager; +import org.mobicents.javax.servlet.GracefulShutdownStartedEvent; import org.mobicents.servlet.sip.SipConnector; import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; import org.mobicents.servlet.sip.catalina.CatalinaSipContext; @@ -75,6 +77,7 @@ import org.mobicents.servlet.sip.catalina.security.authentication.DigestAuthenticator; import org.mobicents.servlet.sip.core.MobicentsSipServlet; import org.mobicents.servlet.sip.core.SipApplicationDispatcher; +import org.mobicents.servlet.sip.core.SipContext; import org.mobicents.servlet.sip.core.SipContextEvent; import org.mobicents.servlet.sip.core.SipContextEventType; import org.mobicents.servlet.sip.core.SipListeners; @@ -107,12 +110,12 @@ * Sip implementation of the Context interface extending the standard * tomcat context to allow deployment of converged applications (sip & web apps) * as well as standalone sip servlets applications. - * + * * @author Jean Deruelle - * + * */ public class SipStandardContext extends StandardContext implements CatalinaSipContext { - + private static final long serialVersionUID = 1L; // the logger private static final Logger logger = Logger.getLogger(SipStandardContext.class); @@ -123,31 +126,34 @@ public class SipStandardContext extends StandardContext implements CatalinaSipCo */ private static final String info = "org.mobicents.servlet.sip.startup.SipStandardContext/1.0"; - - // as mentionned per JSR 289 Section 6.1.2.1 default lifetime for an + + // as mentionned per JSR 289 Section 6.1.2.1 default lifetime for an // application session is 3 minutes private static int DEFAULT_LIFETIME = 3; - + + // The key to get configurable timer serive pool size + private static final String TIMER_SERVICE_POOL_SIZE = "org.restcomm.servlets.sip.TIMER_SERVICE_THREADS"; + protected String applicationName; protected String smallIcon; protected String largeIcon; protected String description; protected int proxyTimeout; protected int sipApplicationSessionTimeout; - protected transient SipListeners sipListeners; - protected transient SipFactoryFacade sipFactoryFacade; + protected transient SipListeners sipListeners; + protected transient SipFactoryFacade sipFactoryFacade; protected transient SipSessionsUtilImpl sipSessionsUtil; protected transient MobicentsSipLoginConfig sipLoginConfig; protected transient SipSecurityUtils sipSecurityUtils; protected transient SipDigestAuthenticator sipDigestAuthenticator; protected transient String securityDomain; - + protected boolean hasDistributableManager; - + protected String namingContextName; - + protected transient Method sipApplicationKeyMethod; - protected ConcurrencyControlMode concurrencyControlMode; + protected ConcurrencyControlMode concurrencyControlMode; /** * The set of sip application listener class names configured for this * application, in the order they were encountered in the sip.xml file. @@ -163,9 +169,9 @@ public class SipStandardContext extends StandardContext implements CatalinaSipCo * application. */ protected transient List sipServletMappings = new ArrayList(); - + protected transient SipApplicationDispatcher sipApplicationDispatcher = null; - + protected transient Map childrenMap; protected transient Map childrenMapByClassName; @@ -174,18 +180,20 @@ public class SipStandardContext extends StandardContext implements CatalinaSipCo // timer service used to schedule sip servlet originated timer tasks protected transient SipServletTimerService timerService = null; // timer service used to schedule proxy timer tasks - protected transient ProxyTimerService proxyTimerService = null; - // http://code.google.com/p/mobicents/issues/detail?id=2450 - private transient ThreadLocal sipApplicationSessionsAccessedThreadLocal = new ThreadLocal(); + protected transient ProxyTimerService proxyTimerService = null; + // http://code.google.com/p/mobicents/issues/detail?id=2534 && http://code.google.com/p/mobicents/issues/detail?id=2526 private transient ThreadLocal isManagedThread = new ThreadLocal(); // http://code.google.com/p/sipservlets/issues/detail?id=195 private ScheduledFuture gracefulStopFuture; /** - * + * */ public SipStandardContext() { super(); + if(logger.isDebugEnabled()) { + logger.debug("SipStandardContext constructor"); + } sipApplicationSessionTimeout = DEFAULT_LIFETIME; pipeline.setBasic(new SipStandardContextValve()); sipListeners = new CatalinaSipListenersHolder(this); @@ -206,90 +214,122 @@ public void init() throws Exception { // if (this.getParent() != null) { // // Add the main configuration listener for sip applications // LifecycleListener sipConfigurationListener = new SipContextConfig(); -// this.addLifecycleListener(sipConfigurationListener); +// this.addLifecycleListener(sipConfigurationListener); // setDelegate(true); -// } +// } // call the super method to correctly initialize the context and fire // up the // init event on the new registered SipContextConfig, so that the // standardcontextconfig // is correctly initialized too super.init(); - - prepareServletContext(); - + + initInternalApplicationComponents(); + if(logger.isDebugEnabled()) { logger.debug("sip context Initialized"); - } + } } - protected void prepareServletContext() throws LifecycleException { - if(sipApplicationDispatcher == null) { - setApplicationDispatcher(); - } - if(sipFactoryFacade == null) { - sipFactoryFacade = new SipFactoryFacade((SipFactoryImpl)sipApplicationDispatcher.getSipFactory(), this); - } - if(sipSessionsUtil == null) { - sipSessionsUtil = new SipSessionsUtilImpl(this); - } - //needed when restarting applications through the tomcat manager - this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.SIP_FACTORY, - sipFactoryFacade); - if(timerService == null) { -// FIXME: distributable not supported -// if(getDistributable() && hasDistributableManager) { -// if(logger.isInfoEnabled()) { -// logger.info("Using the Fault Tolerant Timer Service to schedule fault tolerant timers in a distributed environment"); -// } -// timerService = new FaultTolerantTimerServiceImpl((DistributableSipManager)getSipManager()); -// } else { -// timerService = new TimerServiceImpl(); -// } - timerService = new TimerServiceImpl(sipApplicationDispatcher.getSipService(), applicationName); - } - if(proxyTimerService == null) { - String proxyTimerServiceType = sipApplicationDispatcher.getSipService().getProxyTimerServiceImplementationType(); - if(proxyTimerServiceType != null && proxyTimerServiceType.equalsIgnoreCase("Standard")) { - proxyTimerService = new ProxyTimerServiceImpl(applicationName); - } else if(proxyTimerServiceType != null && proxyTimerServiceType.equalsIgnoreCase("Default")) { - proxyTimerService = new DefaultProxyTimerService(applicationName); - } else { - proxyTimerService = new ProxyTimerServiceImpl(applicationName); + /** + * This function is to prepare basic servlet context attributes before the underlying + * context is really ready. + * + * The method is designed to be idempotent, so we may call it as many times as + * required to actually initiate all possible structures/atts. + * + * @throws LifecycleException + */ + protected void initInternalApplicationComponents() throws LifecycleException { + if (sipApplicationDispatcher == null) { + setApplicationDispatcher(); + } + if (sipFactoryFacade == null) { + sipFactoryFacade = new SipFactoryFacade((SipFactoryImpl) sipApplicationDispatcher.getSipFactory(), this); + } + if (sipSessionsUtil == null) { + sipSessionsUtil = new SipSessionsUtilImpl(this); + } + + // needed when restarting applications through the tomcat manager + this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.SIP_FACTORY, sipFactoryFacade); + this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.TIMER_SERVICE, timerService); + this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.SUPPORTED, + Arrays.asList(sipApplicationDispatcher.getExtensionsSupported())); + this.getServletContext().setAttribute("javax.servlet.sip.100rel", Boolean.TRUE); + this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.SUPPORTED_RFCs, + Arrays.asList(sipApplicationDispatcher.getRfcSupported())); + this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.SIP_SESSIONS_UTIL, sipSessionsUtil); + this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.OUTBOUND_INTERFACES, + sipApplicationDispatcher.getOutboundInterfaces()); + this.getServletContext().setAttribute("org.mobicents.servlet.sip.SIP_CONNECTORS", + sipApplicationDispatcher.getSipService().findSipConnectors()); + this.getServletContext().setAttribute("org.mobicents.servlet.sip.DNS_RESOLVER", + sipApplicationDispatcher.getDNSResolver()); + + if (timerService == null || !timerService.isStarted()) { + // Distributable + if (logger.isDebugEnabled()) { + logger.debug("prepareServletContext - timerService is null" + getName()); + logger.debug("prepareServletContext - getDistributable: " + getDistributable() + ", hasDistributableManager: " + hasDistributableManager); } - } - if(sasTimerService == null || !sasTimerService.isStarted()) { + // FIXME: distributable not supported -//distributable if(getDistributable() && hasDistributableManager) { -// sasTimerService = new FaultTolerantSasTimerService((DistributableSipManager)getSipManager(), 4); -// } else { -// sasTimerService = new StandardSipApplicationSessionTimerService(); -// } - String sasTimerServiceType = sipApplicationDispatcher.getSipService().getSasTimerServiceImplementationType(); - if(sasTimerServiceType != null && sasTimerServiceType.equalsIgnoreCase("Standard")) { +// if(getDistributable() && hasDistributableManager) { +// if(logger.isInfoEnabled()) { +// logger.info("Using the Fault Tolerant Timer Service to schedule fault tolerant timers in a distributed environment"); +// } +// timerService = new FaultTolerantTimerServiceImpl((DistributableSipManager)getSipManager()); +// } else { +// timerService = new TimerServiceImpl(); +// } + timerService = new TimerServiceImpl(sipApplicationDispatcher.getSipService(), applicationName); + } + this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.TIMER_SERVICE, timerService); + + if (sasTimerService == null || !sasTimerService.isStarted()) { + // FIXME: distributable not supported + // distributable if(getDistributable() && hasDistributableManager) { + // sasTimerService = new + // FaultTolerantSasTimerService((DistributableSipManager)getSipManager(), + // 4); + // } else { + // sasTimerService = new + // StandardSipApplicationSessionTimerService(); + // } + String sasTimerServiceType = sipApplicationDispatcher.getSipService() + .getSasTimerServiceImplementationType(); + if (sasTimerServiceType != null && sasTimerServiceType.equalsIgnoreCase("Standard")) { sasTimerService = new StandardSipApplicationSessionTimerService(applicationName); } else if (sasTimerServiceType != null && sasTimerServiceType.equalsIgnoreCase("Default")) { sasTimerService = new DefaultSipApplicationSessionTimerService(applicationName); } else { sasTimerService = new StandardSipApplicationSessionTimerService(applicationName); } - } - this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.TIMER_SERVICE, - timerService); - this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.SUPPORTED, - Arrays.asList(sipApplicationDispatcher.getExtensionsSupported())); - this.getServletContext().setAttribute("javax.servlet.sip.100rel", Boolean.TRUE); - this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.SUPPORTED_RFCs, - Arrays.asList(sipApplicationDispatcher.getRfcSupported())); - this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.SIP_SESSIONS_UTIL, - sipSessionsUtil); - this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.OUTBOUND_INTERFACES, - sipApplicationDispatcher.getOutboundInterfaces()); - this.getServletContext().setAttribute("org.mobicents.servlet.sip.SIP_CONNECTORS", - sipApplicationDispatcher.getSipService().findSipConnectors()); - this.getServletContext().setAttribute("org.mobicents.servlet.sip.DNS_RESOLVER", - sipApplicationDispatcher.getDNSResolver()); - } + } + + if (proxyTimerService == null) { + String proxyTimerServiceType = sipApplicationDispatcher.getSipService().getProxyTimerServiceImplementationType(); + if (proxyTimerServiceType != null && proxyTimerServiceType.equalsIgnoreCase("Standard")) { + proxyTimerService = new ProxyTimerServiceImpl(applicationName); + } else if (proxyTimerServiceType != null && proxyTimerServiceType.equalsIgnoreCase("Default")) { + String strCorePoolSize = this.getServletContext().getInitParameter(TIMER_SERVICE_POOL_SIZE); + if (strCorePoolSize != null && !strCorePoolSize.isEmpty()) { + try { + int CorePoolSize = Integer.parseInt(strCorePoolSize); + proxyTimerService = new DefaultProxyTimerService(applicationName, CorePoolSize); + } catch (NumberFormatException ex) { + logger.warn("Failed to parse timer service pool size with string value [" + strCorePoolSize + "], use default value."); + proxyTimerService = new DefaultProxyTimerService(applicationName); + } + } else { + proxyTimerService = new DefaultProxyTimerService(applicationName); + } + } else { + proxyTimerService = new ProxyTimerServiceImpl(applicationName); + } + } + } /** * @throws Exception @@ -299,7 +339,7 @@ protected void setApplicationDispatcher() throws LifecycleException { if(container instanceof Engine) { Service service = ((Engine)container).getService(); if(service instanceof SipService) { - sipApplicationDispatcher = + sipApplicationDispatcher = ((SipService)service).getSipApplicationDispatcher(); } } @@ -313,16 +353,16 @@ public synchronized void start() throws LifecycleException { if(logger.isDebugEnabled()) { logger.debug("Starting the sip context " + getName()); } - if( initialized ) { - prepareServletContext(); - } + if( initialized ) { + initInternalApplicationComponents(); + } // Add missing components as necessary if (getResources() == null) { // (1) Required by Loader if (logger.isDebugEnabled()) logger.debug("Configuring default Resources"); try { if ((getDocBase() != null) && (getDocBase().endsWith(".sar")) && (!(new File(getBasePath())).isDirectory())) - setResources(new SARDirContext()); + setResources(new SARDirContext()); } catch (IllegalArgumentException e) { logger.error("Error initializing resources: " + e.getMessage()); // ok = false; @@ -330,7 +370,14 @@ public synchronized void start() throws LifecycleException { } // Configure default manager if none was specified if (manager == null) { + if(logger.isDebugEnabled()) { + logger.debug("start - Configure default manager (as none was specified)" + getName()); + } + if ((getCluster() != null) && getDistributable()) { + if(logger.isDebugEnabled()) { + logger.debug("start - try to create clustered manager" + getName()); + } try { manager = getCluster().createManager(getName()); } catch (Exception ex) { @@ -338,8 +385,15 @@ public synchronized void start() throws LifecycleException { // ok = false; } } else { + if(logger.isDebugEnabled()) { + logger.debug("start - calling setManager wit a new instance of SipStandardManager"); + } setManager(new SipStandardManager()); } + } else { + if(logger.isDebugEnabled()) { + logger.debug("start - manager is not null"); + } } //JSR 289 Section 2.1.1 Step 1.Deploy the application. @@ -349,25 +403,25 @@ public synchronized void start() throws LifecycleException { if(manager instanceof DistributableSipManager) { // due to refactoring on http://code.google.com/p/mobicents/issues/detail?id=2794 // we set the container on the manager right before the start and after the context have been init-ed - hasDistributableManager = true; + hasDistributableManager = true; if(logger.isDebugEnabled()) { - logger.debug("this context contains a manager that allows applications to work in a distributed environment"); - } + logger.debug("start1 - this context contains a manager that allows applications to work in a distributed environment"); + } ((SipManager)getManager()).setMobicentsSipFactory( (sipApplicationDispatcher.getSipFactory())); - ((CatalinaSipManager)manager).setContainer(this); + ((CatalinaSipManager)manager).setContainer(this); } - super.start(); - - if(getAvailable()) { + super.start(); + + if(getAvailable()) { //set the session manager on the specific sipstandardmanager to handle converged http sessions if(!(getManager() instanceof DistributableSipManager) && getManager() instanceof CatalinaSipManager) { ((SipManager)getManager()).setMobicentsSipFactory( (sipApplicationDispatcher.getSipFactory())); - ((CatalinaSipManager)manager).setContainer(this); + ((CatalinaSipManager)manager).setContainer(this); } // JSR 289 16.2 Servlet Selection - // When using this mechanism (the main-servlet) for servlet selection, + // When using this mechanism (the main-servlet) for servlet selection, // if there is only one servlet in the application then this // declaration is optional and the lone servlet becomes the main servlet if((mainServlet == null || mainServlet.length() < 1) && childrenMap.size() == 1) { @@ -377,21 +431,21 @@ public synchronized void start() throws LifecycleException { sipDigestAuthenticator = new DigestAuthenticator(sipApplicationDispatcher.getSipFactory().getHeaderFactory()); //JSR 289 Section 2.1.1 Step 3.Invoke SipApplicationRouter.applicationDeployed() for this application. //called implicitly within sipApplicationDispatcher.addSipApplication - sipApplicationDispatcher.addSipApplication(applicationName, this); + sipApplicationDispatcher.addSipApplication(applicationName, this); if(manager instanceof DistributableSipManager) { // only call the setContainer on the manager when it has been fully initialized - hasDistributableManager = true; + hasDistributableManager = true; if(logger.isDebugEnabled()) { - logger.debug("this context contains a manager that allows applications to work in a distributed environment"); + logger.debug("start2 - this context contains a manager that allows applications to work in a distributed environment"); } ((SipManager)getManager()).setMobicentsSipFactory( (sipApplicationDispatcher.getSipFactory())); - ((CatalinaSipManager)manager).setContainer(this); + ((CatalinaSipManager)manager).setContainer(this); } if(logger.isDebugEnabled()) { logger.debug("sip application session timeout for this context is " + sipApplicationSessionTimeout + " minutes"); } - + if(logger.isDebugEnabled()) { logger.debug("http session timeout for this context is " + getSessionTimeout() + " minutes"); } @@ -403,11 +457,11 @@ public synchronized void start() throws LifecycleException { logger.info("sip context " + getName() + " didn't started due to errors"); } } - + } @Override - public ServletContext getServletContext() { + public ServletContext getServletContext() { if (context == null) { context = new ConvergedApplicationContext(getBasePath(), this); if (getAltDDName() != null) @@ -441,10 +495,10 @@ public boolean contextListenerStart() { if (servletContextListeners != null) { ServletContextEvent event = new ServletContextEvent(getServletContext()); - for (ServletContextListener servletContextListener : servletContextListeners) { + for (ServletContextListener servletContextListener : servletContextListeners) { if (servletContextListener == null) continue; - + try { fireContainerEvent("beforeContextInitialized", servletContextListener); servletContextListener.contextInitialized(event); @@ -458,8 +512,8 @@ public boolean contextListenerStart() { (MESSAGES.errorSendingContextInitializedEvent(servletContextListener.getClass().getName()), t); ok = false; } - - // TODO Annotation processing + + // TODO Annotation processing } } @@ -485,15 +539,15 @@ public boolean listenerStop() { boolean ok = super.listenerStop(); if (logger.isDebugEnabled()) logger.debug("Sending application stop events"); - + List servletContextListeners = sipListeners.getServletContextListeners(); if (servletContextListeners != null) { ServletContextEvent event = new ServletContextEvent(getServletContext()); - for (ServletContextListener servletContextListener : servletContextListeners) { + for (ServletContextListener servletContextListener : servletContextListeners) { if (servletContextListener == null) continue; - + try { fireContainerEvent("beforeContextDestroyed", servletContextListener); servletContextListener.contextDestroyed(event); @@ -504,16 +558,16 @@ public boolean listenerStop() { // (sm.getString("standardContext.listenerStop", // servletContextListener.getClass().getName()), t); getLogger().error - (MESSAGES.errorSendingContextDestroyedEvent(servletContextListener.getClass().getName()), t); + (MESSAGES.errorSendingContextDestroyedEvent(servletContextListener.getClass().getName()), t); ok = false; } - - // TODO Annotation processing + + // TODO Annotation processing } } // TODO Annotation processing check super class on tomcat 6 - + sipListeners.clean(); return ok; @@ -547,7 +601,7 @@ public String getBasePath() { } return docBase; } - + @Override public synchronized void stop() throws LifecycleException { if(logger.isInfoEnabled()) { @@ -556,9 +610,9 @@ public synchronized void stop() throws LifecycleException { if(manager instanceof SipManager) { ((SipManager)manager).dumpSipSessions(); ((SipManager)manager).dumpSipApplicationSessions(); - logger.warn("number of active sip sessions : " + ((SipManager)manager).getActiveSipSessions()); + logger.warn("number of active sip sessions : " + ((SipManager)manager).getActiveSipSessions()); logger.warn("number of active sip application sessions : " + ((SipManager)manager).getActiveSipApplicationSessions()); - } + } super.stop(); // this should happen after so that applications can still do some processing // in destroy methods to notify that context is getting destroyed and app removed @@ -573,9 +627,9 @@ public synchronized void stop() throws LifecycleException { } else { logger.error("the application name is null for the following context : " + name); } - } + } if(sasTimerService != null && sasTimerService.isStarted()) { - sasTimerService.stop(); + sasTimerService.stop(); } // Issue 1478 : nullify the ref to avoid reusing it sasTimerService = null; @@ -583,7 +637,7 @@ public synchronized void stop() throws LifecycleException { // of tomcat hang if(timerService != null) { timerService.stop(); - } + } if(proxyTimerService != null) { proxyTimerService.stop(); } @@ -604,15 +658,15 @@ public synchronized void stop() throws LifecycleException { } @Override - public void loadOnStartup(Container[] containers) { - super.loadOnStartup(containers); + public void loadOnStartup(Container[] containers) { + super.loadOnStartup(containers); } @Override - public Wrapper createWrapper() { + public Wrapper createWrapper() { return super.createWrapper(); - } - + } + @Override public void addChild(Container container) { if(container instanceof Wrapper) { @@ -620,7 +674,7 @@ public void addChild(Container container) { Wrapper wrapper = (Wrapper) container; SipServletImpl sipServletImpl = (SipServletImpl) childrenMap.get(container.getName()); if(sipServletImpl != null && !sipServletImpl.getServletClass().equals(wrapper.getServletClass())) { - throw new SipDeploymentException("Trying to add a servlet with name " + container.getName() + " and servlet class " + wrapper.getServletClass() + + throw new SipDeploymentException("Trying to add a servlet with name " + container.getName() + " and servlet class " + wrapper.getServletClass() + " while there is already a SIP Servlet with the same name and a different servlet class " + sipServletImpl.getServletClass()); } } @@ -632,10 +686,10 @@ public void addChild(Container container) { } } } - + public void addChild(SipServletImpl sipServletImpl) { - SipServletImpl existingServlet = (SipServletImpl) childrenMap.get(sipServletImpl.getName()); - if(existingServlet != null) { + SipServletImpl existingServlet = (SipServletImpl) childrenMap.get(sipServletImpl.getName()); + if(existingServlet != null) { logger.warn(sipServletImpl.getName() + " servlet already present, removing the previous one. " + "This might be due to the fact that the definition of the servlet " + "is present both in annotations and in sip.xml"); @@ -647,22 +701,22 @@ public void addChild(SipServletImpl sipServletImpl) { } childrenMap.put(sipServletImpl.getName(), sipServletImpl); childrenMapByClassName.put(sipServletImpl.getServletClass(), sipServletImpl); - super.addChild(sipServletImpl); + super.addChild(sipServletImpl); } - + public void removeChild(SipServletImpl sipServletImpl) { super.removeChild(sipServletImpl); childrenMap.remove(sipServletImpl.getName()); childrenMapByClassName.remove(sipServletImpl.getServletClass()); } - + /** * {@inheritDoc} */ - public Map getChildrenMap() { + public Map getChildrenMap() { return childrenMap; } - + /** * {@inheritDoc} */ @@ -671,7 +725,7 @@ public MobicentsSipServlet findSipServletByName(String name) { return (null); return childrenMap.get(name); } - + /** * {@inheritDoc} */ @@ -770,25 +824,25 @@ public int getProxyTimeout() { public void setProxyTimeout(int proxyTimeout) { this.proxyTimeout = proxyTimeout; } - - public void addConstraint(SipSecurityConstraint securityConstraint) { + + public void addConstraint(SipSecurityConstraint securityConstraint) { super.addConstraint(securityConstraint); } - + public void removeConstraint(SipSecurityConstraint securityConstraint) { super.removeConstraint(securityConstraint); } - + public void setSecurityDomain(String securityDomain) { this.securityDomain = securityDomain; } - + public String getSecurityDomain() { return securityDomain; } - + /* (non-Javadoc) * @see org.mobicents.servlet.sip.startup.SipContext#getSmallIcon() */ @@ -801,21 +855,21 @@ public String getSmallIcon() { public void setSmallIcon(String smallIcon) { this.smallIcon = smallIcon; } - + @Override - public void setLoginConfig(LoginConfig config) { + public void setLoginConfig(LoginConfig config) { super.setLoginConfig(config); } - + @Override - public LoginConfig getLoginConfig() { + public LoginConfig getLoginConfig() { return super.getLoginConfig(); } - + public void setSipLoginConfig(MobicentsSipLoginConfig config) { this.sipLoginConfig = config; } - + public MobicentsSipLoginConfig getSipLoginConfig() { return this.sipLoginConfig; } @@ -826,6 +880,9 @@ public MobicentsSipLoginConfig getSipLoginConfig() { * @param listener Java class name of a listener class */ public void addSipApplicationListener(String listener) { + if(logger.isDebugEnabled()) { + logger.debug("addSipApplicationListener " + getName()); + } sipApplicationListeners.add(listener); fireContainerEvent("addSipApplicationListener", listener); @@ -833,7 +890,7 @@ public void addSipApplicationListener(String listener) { // FIXME - add instance if already started? } - + /** * Remove the specified application listener class from the set of * listeners for this application. @@ -850,7 +907,7 @@ public void removeSipApplicationListener(String listener) { // FIXME - behavior if already started? } - + /** * Return the set of sip application listener class names configured * for this application. @@ -871,33 +928,33 @@ public SipApplicationDispatcher getSipApplicationDispatcher() { */ public SipFactoryFacade getSipFactoryFacade() { return sipFactoryFacade; - } - + } + /** * @return the sipSessionsUtil */ public SipSessionsUtilImpl getSipSessionsUtil() { return sipSessionsUtil; } - + /** * @return the timerService */ public TimerService getTimerService() { return timerService; } - + /** * @return the proxyTimerService */ public ProxyTimerService getProxyTimerService() { return proxyTimerService; } - + /** * Get naming context full name. */ - private String getNamingContextName() { + private String getNamingContextName() { if (namingContextName == null) { Container parent = getParent(); if (parent == null) { @@ -918,35 +975,44 @@ private String getNamingContextName() { } return namingContextName; } - + @Override public synchronized void setManager(Manager manager) { + if(logger.isInfoEnabled()) { + logger.info("setManager - getName()=" + getName()); + } if(getManager() != null && !manager.equals(getManager())) { // http://code.google.com/p/mobicents/issues/detail?id=2794 : TimerService object from JDNI lookup or injection is never HATimerService. This means that timers scheduled using that object will not survive across cluster changes. - // Avoid the DistributableSipManager set by TomcatConvergedDeployment to be overriden by JBossContextConfig.processContextConfig that reset the distributable manager. + // Avoid the DistributableSipManager set by TomcatConvergedDeployment to be overriden by JBossContextConfig.processContextConfig that reset the distributable manager. if(logger.isInfoEnabled()) { logger.info("this context already contains a manager " + getManager() + " not setting new manager " + manager); - } + } return; } if(manager instanceof CatalinaSipManager && sipApplicationDispatcher != null) { ((SipManager)manager).setMobicentsSipFactory( - sipApplicationDispatcher.getSipFactory()); + sipApplicationDispatcher.getSipFactory()); + if(logger.isInfoEnabled()) { + logger.info("setManager - calling setContainer"); + } ((CatalinaSipManager)manager).setContainer(this); - } + } super.setManager(manager); + if(logger.isInfoEnabled()) { + logger.info("setManager - check if manager is distributable" + getName()); + } if(manager instanceof DistributableSipManager) { hasDistributableManager = true; // if the logic comes unitl here, distributable is true, we set it to be able to start the FT timer services correctly on init setDistributable(true); if(logger.isInfoEnabled()) { - logger.info("this context contains a manager that allows applications to work in a distributed environment"); - } - } + logger.info("this context contains a manager that allows applications to work in a distributed environment" + getName()); + } + } } - + @Override - public Manager getManager() { + public Manager getManager() { return super.getManager(); } @@ -961,7 +1027,7 @@ public int getSipApplicationSessionTimeout() { * @param sipApplicationSessionTimeout the sipApplicationSessionTimeout to set in minutes */ public void setSipApplicationSessionTimeout(int sipApplicationSessionTimeout) { - this.sipApplicationSessionTimeout = sipApplicationSessionTimeout; + this.sipApplicationSessionTimeout = sipApplicationSessionTimeout; } public Method getSipApplicationKeyMethod() { @@ -971,7 +1037,7 @@ public Method getSipApplicationKeyMethod() { public void setSipApplicationKeyMethod(Method sipApplicationKeyMethod) { this.sipApplicationKeyMethod = sipApplicationKeyMethod; } - + public String getJbossBasePath() { return getBasePath(); } @@ -992,7 +1058,7 @@ public void addSipServletMapping(MobicentsSipServletMapping sipServletMapping) { public List findSipServletMappings() { return sipServletMappings; } - + /** * {@inheritDoc} */ @@ -1004,14 +1070,14 @@ public MobicentsSipServletMapping findSipServletMappings(SipServletRequest sipSe if(sipServletMapping.getMatchingRule().matches(sipServletRequest)) { return sipServletMapping; } else { - logger.debug("Following mapping rule didn't match : servletName => " + - sipServletMapping.getServletName() + " | expression = "+ + logger.debug("Following mapping rule didn't match : servletName => " + + sipServletMapping.getServletName() + " | expression = "+ sipServletMapping.getMatchingRule().getExpression()); } } return null; } - + /** * {@inheritDoc} */ @@ -1025,7 +1091,7 @@ public void removeSipServletMapping(MobicentsSipServletMapping sipServletMapping public final SipManager getSipManager() { return (SipManager)manager; } - + @Override public String getInfo() { return info; @@ -1035,10 +1101,10 @@ public String getInfo() { // // TODO Auto-generated method stub // return new DummyAnnotationProcessor(); // } - + // ----------------------------------------------- DummyAnnotationProcessor Inner Class - - + + // protected class DummyAnnotationProcessor implements AnnotationProcessor { // // public void postConstruct(Object instance) @@ -1056,34 +1122,37 @@ public String getInfo() { // NamingException { // getInstanceManager().newInstance(instance); // } -// +// // } /* * (non-Javadoc) * @see org.mobicents.servlet.sip.core.SipContext#enterSipApp(org.mobicents.servlet.sip.core.session.MobicentsSipApplicationSession, org.mobicents.servlet.sip.core.session.MobicentsSipSession, boolean, boolean) */ - public void enterSipApp(MobicentsSipApplicationSession sipApplicationSession, MobicentsSipSession sipSession, boolean checkIsManagedThread, boolean isContainerManaged) { + public void enterSipApp(MobicentsSipApplicationSession sipApplicationSession, MobicentsSipSession sipSession, boolean checkIsManagedThread, boolean isContainerManaged) { + if(logger.isDebugEnabled()) { + logger.debug("enterSipApp " + getName()); + } switch (concurrencyControlMode) { - case SipSession: + case SipSession: if(sipSession != null) { - sipSession.acquire(); - } + sipSession.acquire(); + } break; case SipApplicationSession: if(logger.isDebugEnabled()) { logger.debug("checkIsManagedThread " + checkIsManagedThread + " , isManagedThread " + isManagedThread.get() + ", isContainerManaged " + isContainerManaged); } - // http://code.google.com/p/mobicents/issues/detail?id=2534 && http://code.google.com/p/mobicents/issues/detail?id=2526 + // http://code.google.com/p/mobicents/issues/detail?id=2534 && http://code.google.com/p/mobicents/issues/detail?id=2526 if(!checkIsManagedThread || (checkIsManagedThread && Boolean.TRUE.equals(isManagedThread.get()))) { if(isManagedThread.get() == null) { isManagedThread.set(Boolean.TRUE); } - if(sipApplicationSession != null) { - SipApplicationSessionCreationThreadLocal sipApplicationSessionCreationThreadLocal = sipApplicationSessionsAccessedThreadLocal.get(); + if(sipApplicationSession != null) { + SipApplicationSessionCreationThreadLocal sipApplicationSessionCreationThreadLocal = SipApplicationSessionCreationThreadLocal.getTHRef().get(); if(sipApplicationSessionCreationThreadLocal == null) { sipApplicationSessionCreationThreadLocal = new SipApplicationSessionCreationThreadLocal(); - sipApplicationSessionsAccessedThreadLocal.set(sipApplicationSessionCreationThreadLocal); + SipApplicationSessionCreationThreadLocal.getTHRef().set(sipApplicationSessionCreationThreadLocal); } boolean notPresent = sipApplicationSessionCreationThreadLocal.getSipApplicationSessions().add(sipApplicationSession); if(notPresent && isContainerManaged) { @@ -1111,14 +1180,17 @@ public void enterSipApp(MobicentsSipApplicationSession sipApplicationSession, Mo break; case None: break; - } - } - + } + } + /* * (non-Javadoc) * @see org.mobicents.servlet.sip.startup.SipContext#exitSipApp(org.mobicents.servlet.sip.core.session.MobicentsSipApplicationSession, org.mobicents.servlet.sip.core.session.MobicentsSipSession) */ public void exitSipApp(MobicentsSipApplicationSession sipApplicationSession, MobicentsSipSession sipSession) { + if(logger.isDebugEnabled()) { + logger.debug("exitSipApp " + getName()); + } switch (concurrencyControlMode) { case SipSession: if(sipSession != null) { @@ -1132,17 +1204,17 @@ public void exitSipApp(MobicentsSipApplicationSession sipApplicationSession, Mob break; case SipApplicationSession: boolean wasSessionReleased = false; - SipApplicationSessionCreationThreadLocal sipApplicationSessionCreationThreadLocal = sipApplicationSessionsAccessedThreadLocal.get(); - if(sipApplicationSessionCreationThreadLocal != null) { - for(MobicentsSipApplicationSession sipApplicationSessionAccessed : sipApplicationSessionsAccessedThreadLocal.get().getSipApplicationSessions()) { + SipApplicationSessionCreationThreadLocal sipApplicationSessionCreationThreadLocal = SipApplicationSessionCreationThreadLocal.getTHRef().get(); + if(sipApplicationSessionCreationThreadLocal != null) { + for(MobicentsSipApplicationSession sipApplicationSessionAccessed : SipApplicationSessionCreationThreadLocal.getTHRef().get().getSipApplicationSessions()) { sipApplicationSessionAccessed.release(); if(sipApplicationSessionAccessed.equals(sipApplicationSession)) { wasSessionReleased = true; } - } - sipApplicationSessionsAccessedThreadLocal.get().getSipApplicationSessions().clear(); - sipApplicationSessionsAccessedThreadLocal.set(null); - sipApplicationSessionsAccessedThreadLocal.remove(); + } + SipApplicationSessionCreationThreadLocal.getTHRef().get().getSipApplicationSessions().clear(); + SipApplicationSessionCreationThreadLocal.getTHRef().set(null); + SipApplicationSessionCreationThreadLocal.getTHRef().remove(); } isManagedThread.set(null); isManagedThread.remove(); @@ -1159,14 +1231,17 @@ public void exitSipApp(MobicentsSipApplicationSession sipApplicationSession, Mob break; case None: break; - } - } - + } + } + /* * (non-Javadoc) * @see org.mobicents.servlet.sip.startup.SipContext#enterSipAppHa(boolean) */ public boolean enterSipAppHa(boolean startCacheActivity) { + if(logger.isDebugEnabled()) { + logger.debug("enterSipAppHa " + getName()); + } boolean batchStarted = false; // FIXME: distributable not supported // if(getDistributable() && hasDistributableManager) { @@ -1180,12 +1255,12 @@ public boolean enterSipAppHa(boolean startCacheActivity) { // } return batchStarted; } - + /* * (non-Javadoc) * @see org.mobicents.servlet.sip.startup.SipContext#exitSipAppHa(org.mobicents.servlet.sip.message.SipServletRequestImpl, org.mobicents.servlet.sip.message.SipServletResponseImpl, boolean) */ - public void exitSipAppHa(MobicentsSipServletRequest request, MobicentsSipServletResponse response, boolean batchStarted) { + public void exitSipAppHa(MobicentsSipServletRequest request, MobicentsSipServletResponse response, boolean batchStarted) { // FIXME: distributable not supported // if (getDistributable() && hasDistributableManager) { // if(logger.isInfoEnabled()) { @@ -1214,7 +1289,7 @@ public void exitSipAppHa(MobicentsSipServletRequest request, MobicentsSipServlet // for (ClusteredSipApplicationSession clusteredSipApplicationSession : sipApplicationSessions) { // snapshotSipManager.snapshot(clusteredSipApplicationSession); // } -// } +// } // } catch (Throwable e) { // logger.error("A problem occured while replicating", e); // // no need to rethrow an exception here as this is not recoverable and this could mess up the concurrency release of the semaphore on the session @@ -1232,7 +1307,7 @@ public void exitSipAppHa(MobicentsSipServletRequest request, MobicentsSipServlet // } // } } - + // FIXME: distributable not supported // private boolean startBatchTransaction() { // DistributedCacheConvergedSipManager distributedConvergedManager = ((ClusteredSipManager) manager) @@ -1253,7 +1328,7 @@ public void exitSipAppHa(MobicentsSipServletRequest request, MobicentsSipServlet // // return started; // } - + // FIXME: distributable not supported // private void endBatchTransaction(boolean wasStarted) { // DistributedCacheConvergedSipManager distributedConvergedManager = ((ClusteredSipManager) manager) @@ -1268,22 +1343,26 @@ public void exitSipAppHa(MobicentsSipServletRequest request, MobicentsSipServlet // // no need to rethrow an exception here as this is not recoverable and this could mess up the concurrency release of the semaphore on the session // } // } - + public boolean notifySipContextListeners(SipContextEvent event) { + if(logger.isDebugEnabled()) { + logger.debug("notifySipContextListeners " + getName()); + } + boolean ok = true; if(logger.isDebugEnabled()) { logger.debug(childrenMap.size() + " container to notify of " + event.getEventType()); } if(event.getEventType() == SipContextEventType.SERVLET_INITIALIZED) { //fixes https://github.com/RestComm/sip-servlets/issues/165 - //now the SipService is totally ready/started, we prepare + //now the SipService is totally ready/started, we prepare //the context again just in case some att was not properly //initiated try { - prepareServletContext(); + initInternalApplicationComponents(); } catch (Exception e) { logger.warn("Couldnt prepare context", e); - } + } if(!timerService.isStarted()) { timerService.start(); } @@ -1294,26 +1373,30 @@ public boolean notifySipContextListeners(SipContextEvent event) { sasTimerService.start(); } } - + if(this.available) { + if(logger.isDebugEnabled()) { + logger.debug("notifySipContextListeners - available " + getName()); + } + enterSipApp(null, null, false, true); boolean batchStarted = enterSipAppHa(true); // https://github.com/Mobicents/sip-servlets/issues/52 List sipServlets = new ArrayList(childrenMap.values()); Collections.sort(sipServlets, new SipServletLoadOnStartupComparator()); - + try { for (MobicentsSipServlet container : sipServlets) { if(logger.isDebugEnabled()) { logger.debug("container " + container.getName() + ", class : " + container.getClass().getName() + ", load-on-startup : " + container.getLoadOnStartup()); } - if(container instanceof Wrapper) { + if(container instanceof Wrapper) { Wrapper wrapper = (Wrapper) container; Servlet sipServlet = null; try { sipServlet = wrapper.allocate(); if(sipServlet instanceof SipServlet) { - // Fix for issue 1086 (http://code.google.com/p/mobicents/issues/detail?id=1086) : + // Fix for issue 1086 (http://code.google.com/p/mobicents/issues/detail?id=1086) : // Cannot send a request in SipServletListener.initialize() for servlet-selection applications boolean servletHandlerWasNull = false; if(servletHandler == null) { @@ -1326,34 +1409,34 @@ public boolean notifySipContextListeners(SipContextEvent event) { Thread.currentThread().setContextClassLoader(cl); // http://code.google.com/p/sipservlets/issues/detail?id=135 bindThreadBindingListener(); - + switch(event.getEventType()) { case SERVLET_INITIALIZED : { - SipServletContextEvent sipServletContextEvent = + SipServletContextEvent sipServletContextEvent = new SipServletContextEvent(getServletContext(), (SipServlet)sipServlet); List sipServletListeners = sipListeners.getSipServletsListeners(); if(logger.isDebugEnabled()) { logger.debug(sipServletListeners.size() + " SipServletListener to notify of servlet initialization"); } - for (SipServletListener sipServletListener : sipServletListeners) { - sipServletListener.servletInitialized(sipServletContextEvent); + for (SipServletListener sipServletListener : sipServletListeners) { + sipServletListener.servletInitialized(sipServletContextEvent); } break; } case SIP_CONNECTOR_ADDED : { // reload the outbound interfaces if they have changed this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.OUTBOUND_INTERFACES, - sipApplicationDispatcher.getOutboundInterfaces()); + sipApplicationDispatcher.getOutboundInterfaces()); // https://code.google.com/p/sipservlets/issues/detail?id=246 this.getServletContext().setAttribute("org.mobicents.servlet.sip.SIP_CONNECTORS", sipApplicationDispatcher.getSipService().findSipConnectors()); - + List sipConnectorListeners = sipListeners.getSipConnectorListeners(); if(logger.isDebugEnabled()) { logger.debug(sipConnectorListeners.size() + " SipConnectorListener to notify of sip connector addition"); } - for (SipConnectorListener sipConnectorListener : sipConnectorListeners) { - sipConnectorListener.sipConnectorAdded((SipConnector)event.getEventObject()); + for (SipConnectorListener sipConnectorListener : sipConnectorListeners) { + sipConnectorListener.sipConnectorAdded((SipConnector)event.getEventObject()); } break; } @@ -1364,16 +1447,16 @@ public boolean notifySipContextListeners(SipContextEvent event) { // https://code.google.com/p/sipservlets/issues/detail?id=246 this.getServletContext().setAttribute("org.mobicents.servlet.sip.SIP_CONNECTORS", sipApplicationDispatcher.getSipService().findSipConnectors()); - + List sipConnectorListeners = sipListeners.getSipConnectorListeners(); if(logger.isDebugEnabled()) { logger.debug(sipConnectorListeners.size() + " SipConnectorListener to notify of sip connector removal"); } - for (SipConnectorListener sipConnectorListener : sipConnectorListeners) { - sipConnectorListener.sipConnectorRemoved((SipConnector)event.getEventObject()); + for (SipConnectorListener sipConnectorListener : sipConnectorListeners) { + sipConnectorListener.sipConnectorRemoved((SipConnector)event.getEventObject()); } break; - } + } } if(servletHandlerWasNull) { servletHandler = null; @@ -1383,16 +1466,16 @@ public boolean notifySipContextListeners(SipContextEvent event) { unbindThreadBindingListener(); Thread.currentThread().setContextClassLoader(oldClassLoader); } - } + } } catch (ServletException e) { logger.error("Cannot allocate the servlet "+ wrapper.getServletClass() +" for notifying the listener " + " of the event " + event.getEventType(), e); - ok = false; + ok = false; } catch (Throwable e) { logger.error("An error occured when notifying the servlet " + wrapper.getServletClass() + " of the event " + event.getEventType(), e); - ok = false; - } + ok = false; + } try { if(sipServlet != null) { wrapper.deallocate(sipServlet); @@ -1408,13 +1491,13 @@ public boolean notifySipContextListeners(SipContextEvent event) { } } finally { exitSipAppHa(null, null, batchStarted); - exitSipApp(null, null); + exitSipApp(null, null); } } return ok; } - public ConcurrencyControlMode getConcurrencyControlMode() { + public ConcurrencyControlMode getConcurrencyControlMode() { return concurrencyControlMode; } @@ -1424,7 +1507,7 @@ public void setConcurrencyControlMode(ConcurrencyControlMode mode) { logger.debug("Concurrency Control set to " + concurrencyControlMode.toString() + " for application " + applicationName); } } - + public SipRubyController getSipRubyController() { return rubyController; } @@ -1432,10 +1515,10 @@ public SipRubyController getSipRubyController() { public void setSipRubyController(SipRubyController sipRubyController) { this.rubyController = sipRubyController; } - + public SipApplicationSessionTimerService getSipApplicationSessionTimerService() { return sasTimerService; - } + } /** * @return the hasDistributableManager @@ -1443,7 +1526,7 @@ public SipApplicationSessionTimerService getSipApplicationSessionTimerService() public boolean hasDistributableManager() { return hasDistributableManager; } - + /** * @return the servletHandler */ @@ -1457,11 +1540,11 @@ public String getServletHandler() { public void setServletHandler(String servletHandler) { this.servletHandler = servletHandler; } - - public boolean isPackageProtectionEnabled() { + + public boolean isPackageProtectionEnabled() { return SecurityUtil.isPackageProtectionEnabled(); } - + public ClassLoader getSipContextClassLoader() { return getLoader().getClassLoader(); } @@ -1477,7 +1560,7 @@ public SipDigestAuthenticator getDigestAuthenticator() { public SipInstanceManager getSipInstanceManager() { return (SipInstanceManager) super.getInstanceManager(); } - + @Override public void setInstanceManager(InstanceManager instanceManager) { super.setInstanceManager(instanceManager); @@ -1506,14 +1589,17 @@ public void exitSipContext(ClassLoader oldClassLoader) { Thread.currentThread().setContextClassLoader(oldClassLoader); } + private long gracefulInterval = 30000; @Override public void stopGracefully(long timeToWait) { - // http://code.google.com/p/sipservlets/issues/detail?id=195 + // http://code.google.com/p/sipservlets/issues/detail?id=195 // Support for Graceful Shutdown of SIP Applications and Overall Server if(logger.isInfoEnabled()) { logger.info("Stopping the Context " + getName() + " Gracefully in " + timeToWait + " ms"); } + GracefulShutdownStartedEvent startEvent = new GracefulShutdownStartedEvent(timeToWait); + getListeners().callbackContainerListener(startEvent); // Guarantees that the application won't be routed any initial requests anymore but will still handle subsequent requests List applicationsUndeployed = new ArrayList(); applicationsUndeployed.add(applicationName); @@ -1528,16 +1614,15 @@ public void stopGracefully(long timeToWait) { } catch (LifecycleException e) { logger.error("The server couldn't be stopped", e); } - } else { - long gracefulStopTaskInterval = 30000; - if(timeToWait > 0 && timeToWait < gracefulStopTaskInterval) { + } else { + if(timeToWait > 0 && timeToWait < gracefulInterval) { // if the time to Wait is positive and < to the gracefulStopTaskInterval then we schedule the task directly once to the time to wait - gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().schedule(new ContextGracefulStopTask(this, timeToWait), timeToWait, TimeUnit.MILLISECONDS); + gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().schedule(new ContextGracefulStopTask(this, timeToWait), timeToWait, TimeUnit.MILLISECONDS); } else { // if the time to Wait is > to the gracefulStopTaskInterval or infinite (negative value) then we schedule the task to run every gracefulStopTaskInterval, not needed to be exactly precise on the timeToWait in this case - gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().scheduleWithFixedDelay(new ContextGracefulStopTask(this, timeToWait), gracefulStopTaskInterval, gracefulStopTaskInterval, TimeUnit.MILLISECONDS); + gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().scheduleWithFixedDelay(new ContextGracefulStopTask(this, timeToWait), 0, gracefulInterval, TimeUnit.MILLISECONDS); } - } + } } @Override @@ -1546,7 +1631,7 @@ public boolean isStoppingGracefully() { return true; return false; } - + // https://github.com/Mobicents/sip-servlets/issues/52 protected class SipServletLoadOnStartupComparator implements Comparator { @@ -1564,4 +1649,14 @@ public int compare(MobicentsSipServlet o1, MobicentsSipServlet o2) { return 0; } } + + public long getGracefulInterval() { + return gracefulInterval; + } + + public void setGracefulInterval(long gracefulInterval) { + this.gracefulInterval = gracefulInterval; + } + + } diff --git a/containers/sip-servlets-as7/src/main/java/org/mobicents/servlet/sip/startup/SipStandardContextValve.java b/containers/sip-servlets-as7/src/main/java/org/mobicents/servlet/sip/startup/SipStandardContextValve.java index e014ba9066..05353f951e 100644 --- a/containers/sip-servlets-as7/src/main/java/org/mobicents/servlet/sip/startup/SipStandardContextValve.java +++ b/containers/sip-servlets-as7/src/main/java/org/mobicents/servlet/sip/startup/SipStandardContextValve.java @@ -1,384 +1,394 @@ -/* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2014, Telestax Inc and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - */ - -package org.mobicents.servlet.sip.startup; - -import static org.jboss.web.CatalinaMessages.MESSAGES; - -import java.io.IOException; -import java.text.ParseException; - -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletRequestEvent; -import javax.servlet.ServletRequestListener; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.apache.catalina.Container; -import org.apache.catalina.Globals; -import org.apache.catalina.Wrapper; -import org.apache.catalina.connector.Request; -import org.apache.catalina.connector.Response; -import org.apache.catalina.core.Constants; -import org.apache.catalina.core.StandardContext; -//import org.apache.catalina.util.StringManager; -import org.apache.log4j.Logger; -import org.apache.tomcat.util.buf.MessageBytes; -import org.jboss.servlet.http.HttpEvent; -import org.mobicents.servlet.sip.core.SipManager; -import org.mobicents.servlet.sip.core.session.ConvergedSession; -import org.mobicents.servlet.sip.core.session.MobicentsSipApplicationSession; -import org.mobicents.servlet.sip.core.session.SessionManagerUtil; -import org.mobicents.servlet.sip.core.session.SipApplicationSessionKey; - - -/** - * Valve that implements the default basic behavior for the - * SipStandardContext container implementation. - *

- * USAGE CONSTRAINT: This implementation is likely to be useful only - * when processing HTTP requests. - * - * The code was copy pasted from tomcat 5.5.20 source and some specific code was added on invoke - * method to store the htpp session in the threadlocal of the sipfactoryfacade and check if the request - * has an application key associated with it - * - * @author Jean Deruelle - * - */ -final class SipStandardContextValve extends org.apache.catalina.valves.ValveBase { - - // ----------------------------------------------------- Instance Variables - - - /** - * The descriptive information related to this implementation. - */ - private static final String info = - "org.apache.catalina.core.StandardContextValve/1.0"; - - - /** - * The string manager for this package (not supported in AS-7.2.0) - */ -// private static final StringManager sm = -// StringManager.getManager(Constants.Package); - - - private static transient final Logger logger = Logger.getLogger(SipStandardContextValve.class); - - - private SipStandardContext context = null; - - - // ------------------------------------------------------------- Properties - - - /** - * Return descriptive information about this Valve implementation. - */ - public String getInfo() { - - return (info); - - } - - - // --------------------------------------------------------- Public Methods - - - /** - * Cast to a StandardContext right away, as it will be needed later. - * - * @see org.apache.catalina.Contained#setContainer(org.apache.catalina.Container) - */ - public void setContainer(Container container) { - super.setContainer(container); - context = (SipStandardContext) container; - } - - - /** - * Select the appropriate child Wrapper to process this request, - * based on the specified request URI. If no matching Wrapper can - * be found, return an appropriate HTTP error. - * - * @param request Request to be processed - * @param response Response to be produced - * @param valveContext Valve context used to forward to the next Valve - * - * @exception IOException if an input/output error occurred - * @exception ServletException if a servlet error occurred - */ - public final void invoke(Request request, Response response) - throws IOException, ServletException { - - // Disallow any direct access to resources under WEB-INF or META-INF - MessageBytes requestPathMB = request.getRequestPathMB(); - if ((requestPathMB.startsWithIgnoreCase("/META-INF/", 0)) - || (requestPathMB.equalsIgnoreCase("/META-INF")) - || (requestPathMB.startsWithIgnoreCase("/WEB-INF/", 0)) - || (requestPathMB.equalsIgnoreCase("/WEB-INF"))) { - notFound(response); - return; - } - - // Wait if we are reloading - boolean reloaded = false; - while (context.getPaused()) { - reloaded = true; - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - ; - } - } - - // Reloading will have stopped the old webappclassloader and - // created a new one - if (reloaded && - context.getLoader() != null && - context.getLoader().getClassLoader() != null) { - Thread.currentThread().setContextClassLoader( - context.getLoader().getClassLoader()); - } - - // Select the Wrapper to be used for this Request - Wrapper wrapper = request.getWrapper(); - if (wrapper == null) { - notFound(response); - return; - } else if (wrapper.isUnavailable()) { - // May be as a result of a reload, try and find the new wrapper - wrapper = (Wrapper) container.findChild(wrapper.getName()); - if (wrapper == null) { - notFound(response); - return; - } - } - - // Normal request processing - Object instances[] = context.getApplicationEventListeners(); - - ServletRequestEvent event = null; - - if ((instances != null) - && (instances.length > 0)) { - event = new ServletRequestEvent - (((StandardContext) container).getServletContext(), - request.getRequest()); - // create pre-service event - for (int i = 0; i < instances.length; i++) { - if (instances[i] == null) - continue; - if (!(instances[i] instanceof ServletRequestListener)) - continue; - ServletRequestListener listener = - (ServletRequestListener) instances[i]; - try { - listener.requestInitialized(event); - } catch (Throwable t) { - container.getLogger().error(MESSAGES.requestListenerInitException(instances[i].getClass().getName()), t); - ServletRequest sreq = request.getRequest(); - sreq.setAttribute(RequestDispatcher.ERROR_EXCEPTION,t); - return; - } - } - } - boolean batchStarted = context.enterSipAppHa(false); - - //the line below was replaced by the whole bunch of code because getting the parameter from the request is causing - //JRuby-Rails persistence to fail, go figure... -// String sipApplicationKey = request.getParameter(MobicentsSipApplicationSession.SIP_APPLICATION_KEY_PARAM_NAME); - - String sipApplicationKey = null; - String queryString = request.getQueryString(); - if(queryString != null) { - int indexOfSipAppKey = queryString.indexOf(MobicentsSipApplicationSession.SIP_APPLICATION_KEY_PARAM_NAME); - - if(indexOfSipAppKey != -1) { - // +1 to remove the = sign also - String sipAppKeyParam = queryString.substring(indexOfSipAppKey + MobicentsSipApplicationSession.SIP_APPLICATION_KEY_PARAM_NAME.length() + 1); - int indexOfPoundSign = sipAppKeyParam.indexOf("&"); - if(indexOfPoundSign != -1) { - sipAppKeyParam = sipAppKeyParam.substring(0, indexOfPoundSign); - } - sipApplicationKey = sipAppKeyParam; - } - } - - MobicentsSipApplicationSession sipApplicationSessionImpl = null; - if(sipApplicationKey != null && sipApplicationKey.length() > 0) { - try { - SipApplicationSessionKey sipApplicationSessionKey = - SessionManagerUtil.parseSipApplicationSessionKey(sipApplicationKey); - sipApplicationSessionImpl = - ((SipManager)context.getManager()).getSipApplicationSession(sipApplicationSessionKey, false); - sipApplicationSessionImpl.addHttpSession(request.getSession()); - } catch (ParseException pe) { - logger.error("Unexpected exception while parsing the sip application session key" + sipApplicationKey, pe); - } - } else { - // Fix for Issue 882 : HTTP requests to a SIP application always create an HTTP session, even for static resources - // Don't create an http session if not already created - final HttpSession httpSession = request.getSession(false); - if(httpSession != null) { - context.getSipFactoryFacade().storeHttpSession(httpSession); - ConvergedSession convergedSession = (ConvergedSession) httpSession; - sipApplicationSessionImpl = convergedSession.getApplicationSession(false); - } - } - // Fix for http://code.google.com/p/mobicents/issues/detail?id=1386 : - // Ensure SipApplicationSession concurrency control on converged HTTP apps - context.enterSipApp(sipApplicationSessionImpl, null, false, true); - try { - wrapper.getPipeline().getFirst().invoke(request, response); - } finally { - context.exitSipApp(sipApplicationSessionImpl, null); - context.exitSipAppHa(null, null, batchStarted); - } - // Fix for Issue 882 :remove the http session from the thread local to avoid any leaking of the session - context.getSipFactoryFacade().removeHttpSession(); - - if ((instances !=null ) && - (instances.length > 0)) { - // create post-service event - for (int i = 0; i < instances.length; i++) { - if (instances[i] == null) - continue; - if (!(instances[i] instanceof ServletRequestListener)) - continue; - ServletRequestListener listener = - (ServletRequestListener) instances[i]; - try { - listener.requestDestroyed(event); - } catch (Throwable t) { - container.getLogger().error(MESSAGES.requestListenerDestroyException(instances[i].getClass().getName()), t); - ServletRequest sreq = request.getRequest(); - sreq.setAttribute(RequestDispatcher.ERROR_EXCEPTION,t); - } - } - } - - } - - /** - * Select the appropriate child Wrapper to process this request, - * based on the specified request URI. If no matching Wrapper can - * be found, return an appropriate HTTP error. - * - * @param request Request to be processed - * @param response Response to be produced - * @param valveContext Valve context used to forward to the next Valve - * - * @exception IOException if an input/output error occurred - * @exception ServletException if a servlet error occurred - */ - public final void event(Request request, Response response, HttpEvent event) - throws IOException, ServletException { - - // Select the Wrapper to be used for this Request - Wrapper wrapper = request.getWrapper(); - - // Normal request processing - // FIXME: This could be an addition to the core API too - /* - Object instances[] = context.getApplicationEventListeners(); - - ServletRequestEvent event = null; - - if ((instances != null) - && (instances.length > 0)) { - event = new ServletRequestEvent - (((StandardContext) container).getServletContext(), - request.getRequest()); - // create pre-service event - for (int i = 0; i < instances.length; i++) { - if (instances[i] == null) - continue; - if (!(instances[i] instanceof ServletRequestListener)) - continue; - ServletRequestListener listener = - (ServletRequestListener) instances[i]; - try { - listener.requestInitialized(event); - } catch (Throwable t) { - container.getLogger().error(sm.getString("requestListenerValve.requestInit", - instances[i].getClass().getName()), t); - ServletRequest sreq = request.getRequest(); - sreq.setAttribute(Globals.EXCEPTION_ATTR,t); - return; - } - } - } - */ - - wrapper.getPipeline().getFirst().event(request, response, event); - - /* - if ((instances !=null ) && - (instances.length > 0)) { - // create post-service event - for (int i = 0; i < instances.length; i++) { - if (instances[i] == null) - continue; - if (!(instances[i] instanceof ServletRequestListener)) - continue; - ServletRequestListener listener = - (ServletRequestListener) instances[i]; - try { - listener.requestDestroyed(event); - } catch (Throwable t) { - container.getLogger().error(sm.getString("requestListenerValve.requestDestroy", - instances[i].getClass().getName()), t); - ServletRequest sreq = request.getRequest(); - sreq.setAttribute(Globals.EXCEPTION_ATTR,t); - } - } - } - */ - - } - - // -------------------------------------------------------- Private Methods - - - - /** - * Report a "not found" error for the specified resource. FIXME: We - * should really be using the error reporting settings for this web - * application, but currently that code runs at the wrapper level rather - * than the context level. - * - * @param response The response we are creating - */ - protected void notFound(HttpServletResponse response) { - - try { - response.sendError(HttpServletResponse.SC_NOT_FOUND); - } catch (IllegalStateException e) { - ; - } catch (IOException e) { - ; - } - - } -} +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2014, Telestax Inc and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + */ + +package org.mobicents.servlet.sip.startup; + +import static org.jboss.web.CatalinaMessages.MESSAGES; + +import java.io.IOException; +import java.text.ParseException; + +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletRequestEvent; +import javax.servlet.ServletRequestListener; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.catalina.Container; +import org.apache.catalina.Globals; +import org.apache.catalina.Wrapper; +import org.apache.catalina.connector.Request; +import org.apache.catalina.connector.Response; +import org.apache.catalina.core.Constants; +import org.apache.catalina.core.StandardContext; +//import org.apache.catalina.util.StringManager; +import org.apache.log4j.Logger; +import org.apache.tomcat.util.buf.MessageBytes; +import org.jboss.servlet.http.HttpEvent; +import org.mobicents.servlet.sip.core.SipManager; +import org.mobicents.servlet.sip.core.session.ConvergedSession; +import org.mobicents.servlet.sip.core.session.MobicentsSipApplicationSession; +import org.mobicents.servlet.sip.core.session.SessionManagerUtil; +import org.mobicents.servlet.sip.core.session.SipApplicationSessionKey; + + +/** + * Valve that implements the default basic behavior for the + * SipStandardContext container implementation. + *

+ * USAGE CONSTRAINT: This implementation is likely to be useful only + * when processing HTTP requests. + * + * The code was copy pasted from tomcat 5.5.20 source and some specific code was added on invoke + * method to store the htpp session in the threadlocal of the sipfactoryfacade and check if the request + * has an application key associated with it + * + * @author Jean Deruelle + * + */ +final class SipStandardContextValve extends org.apache.catalina.valves.ValveBase { + + // ----------------------------------------------------- Instance Variables + + + /** + * The descriptive information related to this implementation. + */ + private static final String info = + "org.apache.catalina.core.StandardContextValve/1.0"; + + + /** + * The string manager for this package (not supported in AS-7.2.0) + */ +// private static final StringManager sm = +// StringManager.getManager(Constants.Package); + + + private static transient final Logger logger = Logger.getLogger(SipStandardContextValve.class); + + + private SipStandardContext context = null; + + + // ------------------------------------------------------------- Properties + + + /** + * Return descriptive information about this Valve implementation. + */ + public String getInfo() { + + return (info); + + } + + + // --------------------------------------------------------- Public Methods + + + /** + * Cast to a StandardContext right away, as it will be needed later. + * + * @see org.apache.catalina.Contained#setContainer(org.apache.catalina.Container) + */ + public void setContainer(Container container) { + super.setContainer(container); + context = (SipStandardContext) container; + } + + + /** + * Select the appropriate child Wrapper to process this request, + * based on the specified request URI. If no matching Wrapper can + * be found, return an appropriate HTTP error. + * + * @param request Request to be processed + * @param response Response to be produced + * @param valveContext Valve context used to forward to the next Valve + * + * @exception IOException if an input/output error occurred + * @exception ServletException if a servlet error occurred + */ + public final void invoke(Request request, Response response) + throws IOException, ServletException { + + // Disallow any direct access to resources under WEB-INF or META-INF + MessageBytes requestPathMB = request.getRequestPathMB(); + if ((requestPathMB.startsWithIgnoreCase("/META-INF/", 0)) + || (requestPathMB.equalsIgnoreCase("/META-INF")) + || (requestPathMB.startsWithIgnoreCase("/WEB-INF/", 0)) + || (requestPathMB.equalsIgnoreCase("/WEB-INF"))) { + notFound(response); + return; + } + + // Wait if we are reloading + boolean reloaded = false; + while (context.getPaused()) { + reloaded = true; + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + ; + } + } + + // Reloading will have stopped the old webappclassloader and + // created a new one + if (reloaded && + context.getLoader() != null && + context.getLoader().getClassLoader() != null) { + Thread.currentThread().setContextClassLoader( + context.getLoader().getClassLoader()); + } + + // Select the Wrapper to be used for this Request + Wrapper wrapper = request.getWrapper(); + if (wrapper == null) { + notFound(response); + return; + } else if (wrapper.isUnavailable()) { + // May be as a result of a reload, try and find the new wrapper + wrapper = (Wrapper) container.findChild(wrapper.getName()); + if (wrapper == null) { + notFound(response); + return; + } + } + + // Acknowledge the request + try { + response.sendAcknowledgement(); + } catch (IOException ioe) { + container.getLogger().error(MESSAGES.errorAcknowledgingRequest("standardContextValve.acknowledgeException"), ioe); + request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, ioe); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + return; + } + + // Normal request processing + Object instances[] = context.getApplicationEventListeners(); + + ServletRequestEvent event = null; + + if ((instances != null) + && (instances.length > 0)) { + event = new ServletRequestEvent + (((StandardContext) container).getServletContext(), + request.getRequest()); + // create pre-service event + for (int i = 0; i < instances.length; i++) { + if (instances[i] == null) + continue; + if (!(instances[i] instanceof ServletRequestListener)) + continue; + ServletRequestListener listener = + (ServletRequestListener) instances[i]; + try { + listener.requestInitialized(event); + } catch (Throwable t) { + container.getLogger().error(MESSAGES.requestListenerInitException(instances[i].getClass().getName()), t); + ServletRequest sreq = request.getRequest(); + sreq.setAttribute(RequestDispatcher.ERROR_EXCEPTION,t); + return; + } + } + } + boolean batchStarted = context.enterSipAppHa(false); + + //the line below was replaced by the whole bunch of code because getting the parameter from the request is causing + //JRuby-Rails persistence to fail, go figure... +// String sipApplicationKey = request.getParameter(MobicentsSipApplicationSession.SIP_APPLICATION_KEY_PARAM_NAME); + + String sipApplicationKey = null; + String queryString = request.getQueryString(); + if(queryString != null) { + int indexOfSipAppKey = queryString.indexOf(MobicentsSipApplicationSession.SIP_APPLICATION_KEY_PARAM_NAME); + + if(indexOfSipAppKey != -1) { + // +1 to remove the = sign also + String sipAppKeyParam = queryString.substring(indexOfSipAppKey + MobicentsSipApplicationSession.SIP_APPLICATION_KEY_PARAM_NAME.length() + 1); + int indexOfPoundSign = sipAppKeyParam.indexOf("&"); + if(indexOfPoundSign != -1) { + sipAppKeyParam = sipAppKeyParam.substring(0, indexOfPoundSign); + } + sipApplicationKey = sipAppKeyParam; + } + } + + MobicentsSipApplicationSession sipApplicationSessionImpl = null; + if(sipApplicationKey != null && sipApplicationKey.length() > 0) { + try { + SipApplicationSessionKey sipApplicationSessionKey = + SessionManagerUtil.parseSipApplicationSessionKey(sipApplicationKey); + sipApplicationSessionImpl = + ((SipManager)context.getManager()).getSipApplicationSession(sipApplicationSessionKey, false); + sipApplicationSessionImpl.addHttpSession(request.getSession()); + } catch (ParseException pe) { + logger.error("Unexpected exception while parsing the sip application session key" + sipApplicationKey, pe); + } + } else { + // Fix for Issue 882 : HTTP requests to a SIP application always create an HTTP session, even for static resources + // Don't create an http session if not already created + final HttpSession httpSession = request.getSession(false); + if(httpSession != null) { + context.getSipFactoryFacade().storeHttpSession(httpSession); + ConvergedSession convergedSession = (ConvergedSession) httpSession; + sipApplicationSessionImpl = convergedSession.getApplicationSession(false); + } + } + // Fix for http://code.google.com/p/mobicents/issues/detail?id=1386 : + // Ensure SipApplicationSession concurrency control on converged HTTP apps + context.enterSipApp(sipApplicationSessionImpl, null, false, true); + try { + wrapper.getPipeline().getFirst().invoke(request, response); + } finally { + context.exitSipApp(sipApplicationSessionImpl, null); + context.exitSipAppHa(null, null, batchStarted); + } + // Fix for Issue 882 :remove the http session from the thread local to avoid any leaking of the session + context.getSipFactoryFacade().removeHttpSession(); + + if ((instances !=null ) && + (instances.length > 0)) { + // create post-service event + for (int i = 0; i < instances.length; i++) { + if (instances[i] == null) + continue; + if (!(instances[i] instanceof ServletRequestListener)) + continue; + ServletRequestListener listener = + (ServletRequestListener) instances[i]; + try { + listener.requestDestroyed(event); + } catch (Throwable t) { + container.getLogger().error(MESSAGES.requestListenerDestroyException(instances[i].getClass().getName()), t); + ServletRequest sreq = request.getRequest(); + sreq.setAttribute(RequestDispatcher.ERROR_EXCEPTION,t); + } + } + } + + } + + /** + * Select the appropriate child Wrapper to process this request, + * based on the specified request URI. If no matching Wrapper can + * be found, return an appropriate HTTP error. + * + * @param request Request to be processed + * @param response Response to be produced + * @param valveContext Valve context used to forward to the next Valve + * + * @exception IOException if an input/output error occurred + * @exception ServletException if a servlet error occurred + */ + public final void event(Request request, Response response, HttpEvent event) + throws IOException, ServletException { + + // Select the Wrapper to be used for this Request + Wrapper wrapper = request.getWrapper(); + + // Normal request processing + // FIXME: This could be an addition to the core API too + /* + Object instances[] = context.getApplicationEventListeners(); + + ServletRequestEvent event = null; + + if ((instances != null) + && (instances.length > 0)) { + event = new ServletRequestEvent + (((StandardContext) container).getServletContext(), + request.getRequest()); + // create pre-service event + for (int i = 0; i < instances.length; i++) { + if (instances[i] == null) + continue; + if (!(instances[i] instanceof ServletRequestListener)) + continue; + ServletRequestListener listener = + (ServletRequestListener) instances[i]; + try { + listener.requestInitialized(event); + } catch (Throwable t) { + container.getLogger().error(sm.getString("requestListenerValve.requestInit", + instances[i].getClass().getName()), t); + ServletRequest sreq = request.getRequest(); + sreq.setAttribute(Globals.EXCEPTION_ATTR,t); + return; + } + } + } + */ + + wrapper.getPipeline().getFirst().event(request, response, event); + + /* + if ((instances !=null ) && + (instances.length > 0)) { + // create post-service event + for (int i = 0; i < instances.length; i++) { + if (instances[i] == null) + continue; + if (!(instances[i] instanceof ServletRequestListener)) + continue; + ServletRequestListener listener = + (ServletRequestListener) instances[i]; + try { + listener.requestDestroyed(event); + } catch (Throwable t) { + container.getLogger().error(sm.getString("requestListenerValve.requestDestroy", + instances[i].getClass().getName()), t); + ServletRequest sreq = request.getRequest(); + sreq.setAttribute(Globals.EXCEPTION_ATTR,t); + } + } + } + */ + + } + + // -------------------------------------------------------- Private Methods + + + + /** + * Report a "not found" error for the specified resource. FIXME: We + * should really be using the error reporting settings for this web + * application, but currently that code runs at the wrapper level rather + * than the context level. + * + * @param response The response we are creating + */ + protected void notFound(HttpServletResponse response) { + + try { + response.sendError(HttpServletResponse.SC_NOT_FOUND); + } catch (IllegalStateException e) { + ; + } catch (IOException e) { + ; + } + + } +} diff --git a/containers/sip-servlets-as8-drop-in/build-restcomm-modules/build.xml b/containers/sip-servlets-as8-drop-in/build-restcomm-modules/build.xml index 32920fed3c..bf8140c49a 100644 --- a/containers/sip-servlets-as8-drop-in/build-restcomm-modules/build.xml +++ b/containers/sip-servlets-as8-drop-in/build-restcomm-modules/build.xml @@ -63,9 +63,17 @@ - + + + + + + + + + diff --git a/containers/sip-servlets-as8-drop-in/build-restcomm-modules/pom.xml b/containers/sip-servlets-as8-drop-in/build-restcomm-modules/pom.xml index 33e38c81b6..87fd79d7aa 100644 --- a/containers/sip-servlets-as8-drop-in/build-restcomm-modules/pom.xml +++ b/containers/sip-servlets-as8-drop-in/build-restcomm-modules/pom.xml @@ -205,11 +205,35 @@ - org.mobicents.commons + org.restcomm.commons commons-congestion ${restcomm.commons.version} + + + + org.restcomm.commons + restcomm-statistics + ${restcomm.commons.version} + + + io.dropwizard.metrics + metrics-core + ${metrics.version} + + + org.slf4j + slf4j-api + ${slf4j.version} + + + + org.slf4j + slf4j-simple + ${slf4j.version} + + javolution javolution diff --git a/containers/sip-servlets-as8-drop-in/build-restcomm-modules/src/main/resources/modules/org/mobicents/libs/main/module.xml b/containers/sip-servlets-as8-drop-in/build-restcomm-modules/src/main/resources/modules/org/mobicents/libs/main/module.xml index d35810ad27..0a7f12beae 100644 --- a/containers/sip-servlets-as8-drop-in/build-restcomm-modules/src/main/resources/modules/org/mobicents/libs/main/module.xml +++ b/containers/sip-servlets-as8-drop-in/build-restcomm-modules/src/main/resources/modules/org/mobicents/libs/main/module.xml @@ -54,6 +54,12 @@ + + + + + + diff --git a/containers/sip-servlets-as8-drop-in/build-restcomm-modules/src/main/resources/modules/system/layers/base/org/mobicents/libs/main/module.xml b/containers/sip-servlets-as8-drop-in/build-restcomm-modules/src/main/resources/modules/system/layers/base/org/mobicents/libs/main/module.xml index 9822211e07..8f80836594 100644 --- a/containers/sip-servlets-as8-drop-in/build-restcomm-modules/src/main/resources/modules/system/layers/base/org/mobicents/libs/main/module.xml +++ b/containers/sip-servlets-as8-drop-in/build-restcomm-modules/src/main/resources/modules/system/layers/base/org/mobicents/libs/main/module.xml @@ -54,6 +54,12 @@ + + + + + + diff --git a/containers/sip-servlets-as8-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as8/SipDefinition.java b/containers/sip-servlets-as8-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as8/SipDefinition.java index b498db46c5..64b0d0ab97 100644 --- a/containers/sip-servlets-as8-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as8/SipDefinition.java +++ b/containers/sip-servlets-as8-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as8/SipDefinition.java @@ -190,7 +190,7 @@ public class SipDefinition extends SimpleResourceDefinition { .setAllowExpression(true) .setXmlName(Constants.GATHER_STATISTICS) .setFlags(AttributeAccess.Flag.RESTART_ALL_SERVICES) - .setDefaultValue(new ModelNode(false)) + .setDefaultValue(new ModelNode(true)) .build(); protected static final SimpleAttributeDefinition DNS_SERVER_LOCATOR_CLASS = new SimpleAttributeDefinitionBuilder(Constants.DNS_SERVER_LOCATOR_CLASS, ModelType.STRING, true) diff --git a/containers/sip-servlets-as8-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as8/SipServerService.java b/containers/sip-servlets-as8-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as8/SipServerService.java index e427c2d222..cba2cd1e7a 100644 --- a/containers/sip-servlets-as8-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as8/SipServerService.java +++ b/containers/sip-servlets-as8-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as8/SipServerService.java @@ -59,6 +59,7 @@ class SipServerService implements SipServer, Service { final String additionalParameterableHeaders; final String proxyTimerServiceImplementationType; final String sasTimerServiceImplementationType; + final boolean gatherStatistics; final int sipCongestionControlInterval; final String congestionControlPolicy; final String sipConcurrencyControlMode; @@ -100,6 +101,7 @@ public SipServerService( String additionalParameterableHeaders, String proxyTimerServiceImplementationType, String sasTimerServiceImplementationType, + boolean gatherStatistics, int sipCongestionControlInterval, String congestionControlPolicy, String sipConcurrencyControlMode, @@ -130,6 +132,7 @@ public SipServerService( this.additionalParameterableHeaders = additionalParameterableHeaders; this.proxyTimerServiceImplementationType = proxyTimerServiceImplementationType; this.sasTimerServiceImplementationType = sasTimerServiceImplementationType; + this.gatherStatistics = gatherStatistics; this.sipCongestionControlInterval = sipCongestionControlInterval; this.congestionControlPolicy = congestionControlPolicy; this.sipConcurrencyControlMode = sipConcurrencyControlMode; @@ -225,7 +228,7 @@ public synchronized void start(StartContext context) throws StartException { sipService.setProxyTimerServiceImplementationType(proxyTimerServiceImplementationType); sipService.setSasTimerServiceImplementationType(sasTimerServiceImplementationType); - + sipService.setGatherStatistics(gatherStatistics); sipService.setCongestionControlCheckingInterval(sipCongestionControlInterval); sipService.setUsePrettyEncoding(usePrettyEncoding); diff --git a/containers/sip-servlets-as8-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as8/SipSubsystemAdd.java b/containers/sip-servlets-as8-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as8/SipSubsystemAdd.java index 459cf372b8..2711f3e68f 100644 --- a/containers/sip-servlets-as8-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as8/SipSubsystemAdd.java +++ b/containers/sip-servlets-as8-drop-in/jboss-as-restcomm/src/main/java/org/mobicents/as8/SipSubsystemAdd.java @@ -195,7 +195,7 @@ protected void performBoottime(OperationContext context, ModelNode operation, Mo final int timerDInterval = timerDIntervalModel.isDefined() ? timerDIntervalModel.asInt() : 32000; final ModelNode gatherStatisticsModel = SipDefinition.GATHER_STATISTICS.resolveModelAttribute(context, fullModel); - final boolean gatherStatistics = gatherStatisticsModel.isDefined() ? gatherStatisticsModel.asBoolean() : false; + final boolean gatherStatistics = gatherStatisticsModel.isDefined() ? gatherStatisticsModel.asBoolean() : true; final ModelNode dialogPendingRequestCheckingModel = SipDefinition.DIALOG_PENDING_REQUEST_CHECKING .resolveModelAttribute(context, fullModel); @@ -262,7 +262,7 @@ protected void performBoottime(OperationContext context, ModelNode operation, Mo } final SipServerService service = new SipServerService(sipAppRouterFile, sipStackPropertiesFile, sipPathName, - sipAppDispatcherClass, additionalParameterableHeaders, proxyTimerServiceImplementationType, sasTimerServiceImplementationType, sipCongestionControlInterval, congestionControlPolicy, + sipAppDispatcherClass, additionalParameterableHeaders, proxyTimerServiceImplementationType, sasTimerServiceImplementationType, gatherStatistics, sipCongestionControlInterval, congestionControlPolicy, sipConcurrencyControlMode, usePrettyEncoding, baseTimerInterval, t2Interval, t4Interval, timerDInterval, dialogPendingRequestChecking, dnsServerLocatorClass, dnsTimeout, dnsResolverClass, callIdMaxLength, tagHashMaxLength, canceledTimerTasksPurgePeriod, memoryThreshold, backToNormalMemoryThreshold, outboundProxy, diff --git a/containers/sip-servlets-as8/src/main/java/org/mobicents/servlet/sip/undertow/SipStandardService.java b/containers/sip-servlets-as8/src/main/java/org/mobicents/servlet/sip/undertow/SipStandardService.java index 69ea52f7f8..a4cbbd38a3 100644 --- a/containers/sip-servlets-as8/src/main/java/org/mobicents/servlet/sip/undertow/SipStandardService.java +++ b/containers/sip-servlets-as8/src/main/java/org/mobicents/servlet/sip/undertow/SipStandardService.java @@ -734,7 +734,7 @@ private SipProtocolHandler findSipConnector(String ipAddress, int port, String t SipConnector connectorToRemove = null; for (SipProtocolHandler protocolHandler : connectors) { if (protocolHandler.getIpAddress().equals(ipAddress) && protocolHandler.getPort() == port - && protocolHandler.getSignalingTransport().equals(transport)) { + && protocolHandler.getSignalingTransport().equalsIgnoreCase(transport)) { connectorToRemove = protocolHandler.getSipConnector(); return protocolHandler; } diff --git a/containers/sip-servlets-catalina-7/.classpath b/containers/sip-servlets-catalina-7/.classpath index 09af9c9ef0..4f077f6b59 100644 --- a/containers/sip-servlets-catalina-7/.classpath +++ b/containers/sip-servlets-catalina-7/.classpath @@ -1,27 +1,47 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/containers/sip-servlets-catalina-7/src/main/java/org/mobicents/servlet/sip/catalina/ContextGracefulStopTask.java b/containers/sip-servlets-catalina-7/src/main/java/org/mobicents/servlet/sip/catalina/ContextGracefulStopTask.java index 1d854e838e..350067e85a 100644 --- a/containers/sip-servlets-catalina-7/src/main/java/org/mobicents/servlet/sip/catalina/ContextGracefulStopTask.java +++ b/containers/sip-servlets-catalina-7/src/main/java/org/mobicents/servlet/sip/catalina/ContextGracefulStopTask.java @@ -22,9 +22,10 @@ package org.mobicents.servlet.sip.catalina; import org.apache.catalina.Context; -import org.apache.catalina.LifecycleException; import org.apache.catalina.core.StandardContext; import org.apache.log4j.Logger; +import org.mobicents.javax.servlet.ContainerListener; +import org.mobicents.javax.servlet.GracefulShutdownCheckEvent; import org.mobicents.servlet.sip.core.SipContext; /** @@ -32,35 +33,67 @@ * */ public class ContextGracefulStopTask implements Runnable { - private static final Logger logger = Logger.getLogger(ContextGracefulStopTask.class); - Context sipContext; - long timeToWait; - long startTime; - public ContextGracefulStopTask(Context context, long timeToWait) { - sipContext = context; - this.timeToWait = timeToWait; - startTime = System.currentTimeMillis(); - } + private static final Logger logger = Logger.getLogger(ContextGracefulStopTask.class); + Context sipContext; + long timeToWait; + long startTime; + + public ContextGracefulStopTask(Context context, long timeToWait) { + sipContext = context; + this.timeToWait = timeToWait; + startTime = System.currentTimeMillis(); + } + + private static final String PREVENT_PREMATURE_SHUTDOWN = "org.mobicents.servlet.sip.PREVENT_PREMATURE_SHUTDOWN"; + + @Override + public void run() { + int numberOfActiveSipApplicationSessions = ((SipContext) sipContext).getSipManager().getActiveSipApplicationSessions(); + int numberOfActiveHttpSessions = sipContext.getManager().getActiveSessions(); + if (logger.isTraceEnabled()) { + logger.trace("ContextGracefulStopTask running for context " + sipContext.getName() + ", number of Sip Application Sessions still active " + numberOfActiveSipApplicationSessions + " number of HTTP Sessions still active " + numberOfActiveHttpSessions); + } + + boolean stopPrematuraly = false; + long currentTime = System.currentTimeMillis(); + // if timeToWait is positive, then we check the time since the task started, if the time is greater than timeToWait we can safely stop the context + long elapsedTime = currentTime - startTime; + if (timeToWait > 0 && (elapsedTime > timeToWait)) { + logger.info("Graceful TimeToWait Consumed."); + stopContext(); + } + if (logger.isDebugEnabled()) { + logger.debug("ContextGracefulStopTask running for context " + sipContext.getName() + + ", number of Sip Application Sessions still active " + numberOfActiveSipApplicationSessions + + " number of HTTP Sessions still active " + numberOfActiveHttpSessions + + ", stopPrematurely " + stopPrematuraly); + } + if (numberOfActiveSipApplicationSessions <= 0 + && numberOfActiveHttpSessions <= 0) { + logger.info("No more active sessions, lets check with service"); + boolean servicePremature = true; + ContainerListener containerListener = ((SipContext) sipContext).getListeners().getContainerListener(); + if (containerListener != null) { + GracefulShutdownCheckEvent event = new GracefulShutdownCheckEvent(elapsedTime, timeToWait); + ((SipContext) sipContext).getListeners().callbackContainerListener(event); + servicePremature = sipContext.getServletContext().getAttribute(PREVENT_PREMATURE_SHUTDOWN) == null; + logger.info("servicePremature=" + servicePremature); + } + if (servicePremature) { + stopContext(); + } + + } + } + + private void stopContext() { + try { + logger.info("About to stop the context."); + ((StandardContext) sipContext).stop(); + } catch (Exception e) { + logger.error("Couldn't gracefully stop context " + sipContext.getName(), e); + } + } - public void run() { - int numberOfActiveSipApplicationSessions = ((SipContext)sipContext).getSipManager().getActiveSipApplicationSessions(); - int numberOfActiveHttpSessions = sipContext.getManager().getActiveSessions(); - if(logger.isTraceEnabled()) { - logger.trace("ContextGracefulStopTask running for context " + sipContext.getName() + ", number of Sip Application Sessions still active " + numberOfActiveSipApplicationSessions + " number of HTTP Sessions still active " + numberOfActiveHttpSessions); - } - boolean stopPrematuraly = false; - long currentTime = System.currentTimeMillis(); - // if timeToWait is positive, then we check the time since the task started, if the time is greater than timeToWait we can safely stop the context - if(timeToWait > 0 && ((currentTime - startTime) > timeToWait)) { - stopPrematuraly = true; - } - if((numberOfActiveSipApplicationSessions <= 0 && numberOfActiveHttpSessions <= 0) || stopPrematuraly) { - try { - ((StandardContext)sipContext).stop(); - } catch (LifecycleException e) { - logger.error("Couldn't gracefully stop context " + sipContext.getName(), e); - } - } - } } diff --git a/containers/sip-servlets-catalina-7/src/main/java/org/mobicents/servlet/sip/catalina/SipProtocolHandler.java b/containers/sip-servlets-catalina-7/src/main/java/org/mobicents/servlet/sip/catalina/SipProtocolHandler.java index 4256d83d1b..818159cc51 100644 --- a/containers/sip-servlets-catalina-7/src/main/java/org/mobicents/servlet/sip/catalina/SipProtocolHandler.java +++ b/containers/sip-servlets-catalina-7/src/main/java/org/mobicents/servlet/sip/catalina/SipProtocolHandler.java @@ -535,6 +535,42 @@ public void setUseLoadBalancer(boolean useLoadBalancer) { sipConnector.setUseLoadBalancer(useLoadBalancer); } + public String getLoadBalancerAddress() { + return sipConnector.getLoadBalancerAddress(); + } + + /** + * @param loadBalancerAddress the loadBalancerAddress to set + */ + public void setLoadBalancerAddress(String loadBalancerAddress) { + sipConnector.setLoadBalancerAddress(loadBalancerAddress); + } + + /** + * @return the loadBalancerRmiPort + */ + public int getLoadBalancerRmiPort() { + return sipConnector.getLoadBalancerRmiPort(); + } + + /** + * @param loadBalancerRmiPort the loadBalancerRmiPort to set + */ + public void setLoadBalancerRmiPort(int loadBalancerRmiPort) { + sipConnector.setLoadBalancerRmiPort(loadBalancerRmiPort); + } + + public int getLoadBalancerSipPort() { + return sipConnector.getLoadBalancerSipPort(); + } + + /** + * @param loadBalancerSipPort the loadBalancerSipPort to set + */ + public void setLoadBalancerSipPort(int loadBalancerSipPort) { + sipConnector.setLoadBalancerSipPort(loadBalancerSipPort); + } + /** * @return the useStun */ diff --git a/containers/sip-servlets-catalina-7/src/main/java/org/mobicents/servlet/sip/catalina/SipStandardService.java b/containers/sip-servlets-catalina-7/src/main/java/org/mobicents/servlet/sip/catalina/SipStandardService.java index 171c877add..59eace4e69 100644 --- a/containers/sip-servlets-catalina-7/src/main/java/org/mobicents/servlet/sip/catalina/SipStandardService.java +++ b/containers/sip-servlets-catalina-7/src/main/java/org/mobicents/servlet/sip/catalina/SipStandardService.java @@ -1,1405 +1,1412 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.catalina; - - -import gov.nist.core.net.AddressResolver; -import gov.nist.javax.sip.SipStackExt; -import gov.nist.javax.sip.message.MessageFactoryExt; -import gov.nist.javax.sip.stack.SIPTransactionStack; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.lang.reflect.Constructor; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Properties; -import java.util.StringTokenizer; -import java.util.TooManyListenersException; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; - -import javax.management.MalformedObjectNameException; -import javax.management.ObjectName; -import javax.sip.SipStack; -import javax.sip.header.ServerHeader; -import javax.sip.header.UserAgentHeader; - -import org.apache.catalina.Engine; -import org.apache.catalina.LifecycleException; -import org.apache.catalina.connector.Connector; -import org.apache.catalina.core.StandardService; -import org.apache.coyote.ProtocolHandler; -import org.apache.log4j.Logger; -import org.apache.tomcat.util.modeler.Registry; -import org.mobicents.ext.javax.sip.dns.DNSAwareRouter; -import org.mobicents.ext.javax.sip.dns.DNSServerLocator; -import org.mobicents.ext.javax.sip.dns.DefaultDNSServerLocator; -import org.mobicents.ha.javax.sip.ClusteredSipStack; -import org.mobicents.ha.javax.sip.LoadBalancerHeartBeatingListener; -import org.mobicents.ha.javax.sip.LoadBalancerHeartBeatingService; -import org.mobicents.ha.javax.sip.LoadBalancerHeartBeatingServiceImpl; -import org.mobicents.ha.javax.sip.ReplicationStrategy; -import org.mobicents.javax.servlet.CongestionControlPolicy; -import org.mobicents.servlet.sip.JainSipUtils; -import org.mobicents.servlet.sip.SipConnector; -import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; -import org.mobicents.servlet.sip.core.ExtendedListeningPoint; -import org.mobicents.servlet.sip.core.MobicentsExtendedListeningPoint; -import org.mobicents.servlet.sip.core.SipApplicationDispatcher; -import org.mobicents.servlet.sip.core.SipContext; -import org.mobicents.servlet.sip.core.message.OutboundProxy; -import org.mobicents.servlet.sip.dns.MobicentsDNSResolver; -import org.mobicents.servlet.sip.message.Servlet3SipServletMessageFactory; -import org.mobicents.servlet.sip.startup.StaticServiceHolder; - -/** - * Sip Servlet implementation of the SipService interface. - * This class inherits from the Tomcat StandardService. It adds a SipApplicationDispatcher - * that will be listen for sip messages received by the sip stacks started by - * the sip connectors associated with this context. - * This has one attribute which is the sipApplicationDispatcherClassName allowing one - * to specify the class name of the sipApplicationDispacther to easily replace - * the default sipApplicationDispatcher with a custom one. - * - * @author Jean Deruelle - */ -public class SipStandardService extends StandardService implements CatalinaSipService { - //the logger - private static final Logger logger = Logger.getLogger(SipStandardService.class); - public static final String DEFAULT_SIP_PATH_NAME = "gov.nist"; - public static final String PASS_INVITE_NON_2XX_ACK_TO_LISTENER = "gov.nist.javax.sip.PASS_INVITE_NON_2XX_ACK_TO_LISTENER"; - public static final String TCP_POST_PARSING_THREAD_POOL_SIZE = "gov.nist.javax.sip.TCP_POST_PARSING_THREAD_POOL_SIZE"; - public static final String AUTOMATIC_DIALOG_SUPPORT_STACK_PROP = "javax.sip.AUTOMATIC_DIALOG_SUPPORT"; - public static final String LOOSE_DIALOG_VALIDATION = "gov.nist.javax.sip.LOOSE_DIALOG_VALIDATION"; - public static final String SERVER_LOG_STACK_PROP = "gov.nist.javax.sip.SERVER_LOG"; - public static final String DEBUG_LOG_STACK_PROP = "gov.nist.javax.sip.DEBUG_LOG"; - public static final String SERVER_HEADER = "org.mobicents.servlet.sip.SERVER_HEADER"; - public static final String USER_AGENT_HEADER = "org.mobicents.servlet.sip.USER_AGENT_HEADER"; - public static final String JVM_ROUTE = "jvmRoute"; - /** - * The descriptive information string for this implementation. - */ - private static final String INFO = - "org.mobicents.servlet.sip.startup.SipStandardService/1.0"; - //the sip application dispatcher class name defined in the server.xml - protected String sipApplicationDispatcherClassName; - //instatiated class from the sipApplicationDispatcherClassName of the sip application dispatcher - protected SipApplicationDispatcher sipApplicationDispatcher; - private boolean gatherStatistics = true; - protected int sipMessageQueueSize = 1500; - private int backToNormalSipMessageQueueSize = 1300; - protected int memoryThreshold = 95; - private int backToNormalMemoryThreshold = 90; - protected OutboundProxy outboundProxy; - protected String proxyTimerServiceImplementationType; - protected String sasTimerServiceImplementationType; - protected long congestionControlCheckingInterval = 30000; - private int canceledTimerTasksPurgePeriod = 0; - // base timer interval for jain sip tx - private int baseTimerInterval = 500; - private int t2Interval = 4000; - private int t4Interval = 5000; - private int timerDInterval = 32000; - protected int dispatcherThreadPoolSize = 15; - private boolean md5ContactUserPart = false; - - protected String concurrencyControlMode = ConcurrencyControlMode.SipApplicationSession.toString(); - protected String congestionControlPolicy = CongestionControlPolicy.ErrorResponse.toString(); - protected String additionalParameterableHeaders; - protected boolean bypassResponseExecutor = true; - protected boolean bypassRequestExecutor = true; - //this should be made available to the application router as a system prop - protected String darConfigurationFileLocation; - protected boolean connectorsStartedExternally = false; - protected boolean dialogPendingRequestChecking = false; - protected int callIdMaxLength; - protected int tagHashMaxLength; - - protected boolean httpFollowsSip = false; - protected String jvmRoute; - protected ReplicationStrategy replicationStrategy; - - /** - * the sip stack path name. Since the sip factory is per classloader it should be set here for all underlying stacks - */ - private String sipPathName; - /** - * use Pretty Encoding - */ - private boolean usePrettyEncoding = true; - - private SipStack sipStack; - // defining sip stack properties - private Properties sipStackProperties; - private String sipStackPropertiesFileLocation; - @Deprecated - private String addressResolverClass = null; - private String dnsServerLocatorClass = DefaultDNSServerLocator.class.getName(); - private int dnsTimeout = 1; - private String dnsResolverClass = MobicentsDNSResolver.class.getName(); - private String mobicentsSipServletMessageFactoryClassName = Servlet3SipServletMessageFactory.class.getName(); - - //the balancers to send heartbeat to and our health info - @Deprecated - private String balancers; - // - private ScheduledFuture gracefulStopFuture; - - @Override - public String getInfo() { - return (INFO); - } - - @Override - public void addConnector(Connector connector) { - MobicentsExtendedListeningPoint extendedListeningPoint = null; - if (connector.getProtocolHandler() instanceof SipProtocolHandler) { - extendedListeningPoint = (MobicentsExtendedListeningPoint) - ((SipProtocolHandler)connector.getProtocolHandler()).getAttribute(ExtendedListeningPoint.class.getSimpleName());} - if(extendedListeningPoint != null) { - try { - extendedListeningPoint.getSipProvider().addSipListener(sipApplicationDispatcher); - sipApplicationDispatcher.getSipNetworkInterfaceManager().addExtendedListeningPoint(extendedListeningPoint); - } catch (TooManyListenersException e) { - logger.error("Connector.initialize", e); - } - } - ProtocolHandler protocolHandler = connector.getProtocolHandler(); - if(protocolHandler instanceof SipProtocolHandler) { - connector.setPort(((SipProtocolHandler)protocolHandler).getPort()); - ((SipProtocolHandler)protocolHandler).setSipStack(sipStack); - ((SipProtocolHandler)protocolHandler).setAttribute(SipApplicationDispatcher.class.getSimpleName(), sipApplicationDispatcher); - registerSipConnector(connector); - } - super.addConnector(connector); - } - - /** - * Register the sip connector under a different name than HTTP Connector and we add the transport to avoid clashing with 2 connectors having the same port and address - * @param connector connector to register - */ - protected void registerSipConnector(Connector connector) { - try { - - ObjectName objectName = createSipConnectorObjectName(connector, getName(), "SipConnector"); - Registry.getRegistry(null, null) - .registerComponent(connector, objectName, null); -//TODO connector.setController(objectName); - } catch (Exception e) { - logger.error( "Error registering connector ", e); - } - if(logger.isDebugEnabled()) - logger.debug("Creating name for connector " + getObjectName()); - } - - @Override - public void removeConnector(Connector connector) { - MobicentsExtendedListeningPoint extendedListeningPoint = null; - if (connector.getProtocolHandler() instanceof SipProtocolHandler){ - extendedListeningPoint = (MobicentsExtendedListeningPoint) - ((SipProtocolHandler)connector.getProtocolHandler()).getAttribute(ExtendedListeningPoint.class.getSimpleName());} - if(extendedListeningPoint != null) { - extendedListeningPoint.getSipProvider().removeSipListener(sipApplicationDispatcher); - sipApplicationDispatcher.getSipNetworkInterfaceManager().removeExtendedListeningPoint(extendedListeningPoint); - } - super.removeConnector(connector); - } - - @Override - public void initInternal() throws LifecycleException { - //load the sip application disptacher from the class name specified in the server.xml file - //and initializes it - StaticServiceHolder.sipStandardService = this; - try { - sipApplicationDispatcher = (SipApplicationDispatcher) - Class.forName(sipApplicationDispatcherClassName).newInstance(); - } catch (InstantiationException e) { - throw new LifecycleException("Impossible to load the Sip Application Dispatcher",e); - } catch (IllegalAccessException e) { - throw new LifecycleException("Impossible to load the Sip Application Dispatcher",e); - } catch (ClassNotFoundException e) { - throw new LifecycleException("Impossible to load the Sip Application Dispatcher",e); - } catch (ClassCastException e) { - throw new LifecycleException("Sip Application Dispatcher defined does not implement " + SipApplicationDispatcher.class.getName(),e); - } - if(logger.isInfoEnabled()) { - logger.info("Pretty encoding of headers enabled ? " + usePrettyEncoding); - } - if(sipPathName == null) { - sipPathName = DEFAULT_SIP_PATH_NAME; - } - if(logger.isInfoEnabled()) { - logger.info("Sip Stack path name : " + sipPathName); - } - sipApplicationDispatcher.setSipService(this); - sipApplicationDispatcher.getSipFactory().initialize(sipPathName, usePrettyEncoding); - - String catalinaBase = getCatalinaBase(); - if(darConfigurationFileLocation != null) { - if(!darConfigurationFileLocation.startsWith("file:///")) { - darConfigurationFileLocation = "file:///" + catalinaBase.replace(File.separatorChar, '/') + "/" + darConfigurationFileLocation; - } - System.setProperty("javax.servlet.sip.dar", darConfigurationFileLocation); - } - super.initInternal(); - sipApplicationDispatcher.setDomain(this.getName()); - if(baseTimerInterval < 1) { - throw new LifecycleException("It's forbidden to set the Base Timer Interval to a non positive value"); - } - initSipStack(); - // https://telestax.atlassian.net/browse/MSS-148 make sure we have a default to bin direction for better out of the box experience - if(System.getProperty("telscale.license.dir") == null) { - System.setProperty("telscale.license.dir", getCatalinaBase() + File.separatorChar + "bin"); - if(logger.isDebugEnabled()) { - logger.debug("Setting telscale.license.dir directory to : " + getCatalinaBase() + File.separatorChar + "bin"); - } - } - if(System.getProperty("telscale.license.key.location") == null) { - System.setProperty("telscale.license.key.location", getCatalinaBase() + File.separatorChar + "bin"); - if(logger.isDebugEnabled()) { - logger.debug("Setting telscale.license.key.location directory to : " + getCatalinaBase() + File.separatorChar + "bin"); - } - } - - sipApplicationDispatcher.setBaseTimerInterval(baseTimerInterval); - sipApplicationDispatcher.setT2Interval(t2Interval); - sipApplicationDispatcher.setT4Interval(t4Interval); - sipApplicationDispatcher.setTimerDInterval(timerDInterval); - sipApplicationDispatcher.setMemoryThreshold(getMemoryThreshold()); - sipApplicationDispatcher.setBackToNormalMemoryThreshold(backToNormalMemoryThreshold); - sipApplicationDispatcher.setCongestionControlCheckingInterval(getCongestionControlCheckingInterval()); - sipApplicationDispatcher.setCongestionControlPolicyByName(getCongestionControlPolicy()); - sipApplicationDispatcher.setQueueSize(getSipMessageQueueSize()); - sipApplicationDispatcher.setBackToNormalQueueSize(backToNormalSipMessageQueueSize); - sipApplicationDispatcher.setGatherStatistics(gatherStatistics); - sipApplicationDispatcher.setConcurrencyControlMode(ConcurrencyControlMode.valueOf(getConcurrencyControlMode())); - sipApplicationDispatcher.setBypassRequestExecutor(bypassRequestExecutor); - sipApplicationDispatcher.setBypassResponseExecutor(bypassResponseExecutor); - sipApplicationDispatcher.setSipStack(sipStack); - sipApplicationDispatcher.init(); - // Tomcat specific loading case where the connectors are added even before the service is initialized - // so we need to set the sip stack before it starts - synchronized (connectors) { - for (Connector connector : connectors) { - ProtocolHandler protocolHandler = connector.getProtocolHandler(); - if(protocolHandler instanceof SipProtocolHandler) { - connector.setPort(((SipProtocolHandler)protocolHandler).getPort()); - ((SipProtocolHandler)protocolHandler).setSipStack(sipStack); - ((SipProtocolHandler)protocolHandler).setAttribute(SipApplicationDispatcher.class.getSimpleName(), sipApplicationDispatcher); - registerSipConnector(connector); - } - } - } - } - - @Override - public void startInternal() throws LifecycleException { - super.startInternal(); - synchronized (connectors) { - for (Connector connector : connectors) { - final ProtocolHandler protocolHandler = connector.getProtocolHandler(); - //Jboss sepcific loading case - Boolean isSipConnector = false; - if (protocolHandler instanceof SipProtocolHandler) - isSipConnector = (Boolean) ((SipProtocolHandler)protocolHandler).getAttribute(SipProtocolHandler.IS_SIP_CONNECTOR); - if(isSipConnector != null && isSipConnector) { - if(logger.isDebugEnabled()) { - logger.debug("Attaching the sip application dispatcher " + - "as a sip listener to connector listening on port " + - connector.getPort()); - } - ((SipProtocolHandler)protocolHandler).setAttribute(SipApplicationDispatcher.class.getSimpleName(), sipApplicationDispatcher); - ((SipProtocolHandler)protocolHandler).setSipStack(sipStack); - connectorsStartedExternally = true; - } - //Tomcat specific loading case - MobicentsExtendedListeningPoint extendedListeningPoint = null; - if (protocolHandler instanceof SipProtocolHandler) { - extendedListeningPoint = (MobicentsExtendedListeningPoint) - ((SipProtocolHandler)protocolHandler).getAttribute(ExtendedListeningPoint.class.getSimpleName());} - if(extendedListeningPoint != null && sipStack != null) { - try { - extendedListeningPoint.getSipProvider().addSipListener(sipApplicationDispatcher); - sipApplicationDispatcher.getSipNetworkInterfaceManager().addExtendedListeningPoint(extendedListeningPoint); - connectorsStartedExternally = false; - } catch (TooManyListenersException e) { - throw new LifecycleException("Couldn't add the sip application dispatcher " - + sipApplicationDispatcher + " as a listener to the following listening point provider " + extendedListeningPoint, e); - } - } - } - } - if(!connectorsStartedExternally) { - sipApplicationDispatcher.start(); - } - - if(this.getSipMessageQueueSize() <= 0) - throw new LifecycleException("Message queue size can not be 0 or less"); - - if(logger.isDebugEnabled()) { - logger.debug("SIP Standard Service Started."); - } - } - - public String getJvmRoute() { - return this.jvmRoute; - } - - public void setJvmRoute(String jvmRoute) { - this.jvmRoute = jvmRoute; - } - - protected void initSipStack() throws LifecycleException { - try { - if(logger.isDebugEnabled()) { - logger.debug("Initializing SIP stack"); - } - - // This simply puts HTTP and SSL port numbers in JVM properties menat to be read by jsip ha when sending heart beats with Node description. - initializeSystemPortProperties(); - - String catalinaBase = getCatalinaBase(); - if(sipStackPropertiesFileLocation != null && !sipStackPropertiesFileLocation.startsWith("file:///")) { - sipStackPropertiesFileLocation = "file:///" + catalinaBase.replace(File.separatorChar, '/') + "/" + sipStackPropertiesFileLocation; - } - boolean isPropsLoaded = false; - if(sipStackProperties == null) { - sipStackProperties = new Properties(); - } else { - isPropsLoaded = true; - } - - if (logger.isDebugEnabled()) { - logger.debug("Loading SIP stack properties from following file : " + sipStackPropertiesFileLocation); - } - if(sipStackPropertiesFileLocation != null) { - //hack to get around space char in path see http://weblogs.java.net/blog/kohsuke/archive/2007/04/how_to_convert.html, - // we create a URL since it's permissive enough - File sipStackPropertiesFile = null; - URL url = null; - try { - url = new URL(sipStackPropertiesFileLocation); - } catch (MalformedURLException e) { - logger.fatal("Cannot find the sip stack properties file ! ",e); - throw new IllegalArgumentException("The Default Application Router file Location : "+sipStackPropertiesFileLocation+" is not valid ! ",e); - } - try { - sipStackPropertiesFile = new File(new URI(sipStackPropertiesFileLocation)); - } catch (URISyntaxException e) { - //if the uri contains space this will fail, so getting the path will work - sipStackPropertiesFile = new File(url.getPath()); - } - FileInputStream sipStackPropertiesInputStream = null; - try { - sipStackPropertiesInputStream = new FileInputStream(sipStackPropertiesFile); - sipStackProperties.load(sipStackPropertiesInputStream); - } catch (Exception e) { - logger.warn("Could not find or problem when loading the sip stack properties file : " + sipStackPropertiesFileLocation, e); - } finally { - if(sipStackPropertiesInputStream != null) { - try { - sipStackPropertiesInputStream.close(); - } catch (IOException e) { - logger.error("fail to close the following file " + sipStackPropertiesFile.getAbsolutePath(), e); - } - } - } - - String debugLog = sipStackProperties.getProperty(DEBUG_LOG_STACK_PROP); - if(debugLog != null && debugLog.length() > 0 && !debugLog.startsWith("file:///")) { - sipStackProperties.setProperty(DEBUG_LOG_STACK_PROP, - catalinaBase + "/" + debugLog); - } - String serverLog = sipStackProperties.getProperty(SERVER_LOG_STACK_PROP); - if(serverLog != null && serverLog.length() > 0 && !serverLog.startsWith("file:///")) { - sipStackProperties.setProperty(SERVER_LOG_STACK_PROP, - catalinaBase + "/" + serverLog); - } - // The whole MSS is built upon those assumptions, so those properties are not overrideable - if (sipStackProperties.getProperty(AUTOMATIC_DIALOG_SUPPORT_STACK_PROP) == null) { - //https://github.com/RestComm/sip-servlets/issues/143 - //set off if user didnt provided any value. - sipStackProperties.setProperty(AUTOMATIC_DIALOG_SUPPORT_STACK_PROP, "off"); - } - sipStackProperties.setProperty(LOOSE_DIALOG_VALIDATION, "true"); - sipStackProperties.setProperty(PASS_INVITE_NON_2XX_ACK_TO_LISTENER, "true"); - isPropsLoaded = true; - } else { - logger.warn("no sip stack properties file defined "); - } - if(!isPropsLoaded) { - logger.warn("loading default Mobicents Sip Servlets sip stack properties"); - // Silently set default values - sipStackProperties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", - "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", - "32"); - sipStackProperties.setProperty(DEBUG_LOG_STACK_PROP, - catalinaBase + "/" + "mss-jsip-" + getName() +"-debug.txt"); - sipStackProperties.setProperty(SERVER_LOG_STACK_PROP, - catalinaBase + "/" + "mss-jsip-" + getName() +"-messages.xml"); - sipStackProperties.setProperty("javax.sip.STACK_NAME", "mss-" + getName()); - sipStackProperties.setProperty(AUTOMATIC_DIALOG_SUPPORT_STACK_PROP, "off"); - sipStackProperties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.THREAD_POOL_SIZE", "64"); - sipStackProperties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.MAX_FORK_TIME_SECONDS", "0"); - sipStackProperties.setProperty(LOOSE_DIALOG_VALIDATION, "true"); - sipStackProperties.setProperty(PASS_INVITE_NON_2XX_ACK_TO_LISTENER, "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.AUTOMATIC_DIALOG_ERROR_HANDLING", "false"); - sipStackProperties.setProperty("gov.nist.javax.sip.AGGRESSIVE_CLEANUP", "true"); - } - - if(sipStackProperties.get(TCP_POST_PARSING_THREAD_POOL_SIZE) == null) { - sipStackProperties.setProperty(TCP_POST_PARSING_THREAD_POOL_SIZE, "30"); - } - - // set the DNSServerLocator allowing to support RFC 3263 and do DNS lookups to resolve uris - if(dnsServerLocatorClass != null && dnsServerLocatorClass.trim().length() > 0) { - if(logger.isDebugEnabled()) { - logger.debug("Sip Stack " + sipStackProperties.getProperty("javax.sip.STACK_NAME") +" will be using " + dnsServerLocatorClass + " as DNSServerLocator"); - } - try { - // create parameters argument to identify constructor - Class[] paramTypes = new Class[0]; - // get constructor of AddressResolver in order to instantiate - Constructor dnsServerLocatorConstructor = Class.forName(dnsServerLocatorClass).getConstructor( - paramTypes); - // Wrap properties object in order to pass to constructor of AddressResolver - Object[] conArgs = new Object[0]; - // Creates a new instance of AddressResolver Class with the supplied sipApplicationDispatcher. - DNSServerLocator dnsServerLocator = (DNSServerLocator) dnsServerLocatorConstructor.newInstance(conArgs); - sipApplicationDispatcher.setDNSServerLocator(dnsServerLocator); - sipApplicationDispatcher.setDNSTimeout(dnsTimeout); - if(sipStackProperties.getProperty("javax.sip.ROUTER_PATH") == null) { - sipStackProperties.setProperty("javax.sip.ROUTER_PATH", DNSAwareRouter.class.getCanonicalName()); - } - } catch (Exception e) { - logger.error("Couldn't set the AddressResolver " + addressResolverClass, e); - throw e; - } - } else { - if(logger.isInfoEnabled()) { - logger.info("no DNSServerLocator will be used since none has been specified."); - } - } - - String serverHeaderValue = sipStackProperties.getProperty(SERVER_HEADER); - if(serverHeaderValue != null) { - List serverHeaderList = new ArrayList(); - StringTokenizer stringTokenizer = new StringTokenizer(serverHeaderValue, ","); - while(stringTokenizer.hasMoreTokens()) { - serverHeaderList.add(stringTokenizer.nextToken()); - } - ServerHeader serverHeader = sipApplicationDispatcher.getSipFactory().getHeaderFactory().createServerHeader(serverHeaderList); - ((MessageFactoryExt)sipApplicationDispatcher.getSipFactory().getMessageFactory()).setDefaultServerHeader(serverHeader); - } - String userAgent = sipStackProperties.getProperty(USER_AGENT_HEADER); - if(userAgent != null) { - List userAgentList = new ArrayList(); - StringTokenizer stringTokenizer = new StringTokenizer(userAgent, ","); - while(stringTokenizer.hasMoreTokens()) { - userAgentList.add(stringTokenizer.nextToken()); - } - UserAgentHeader userAgentHeader = sipApplicationDispatcher.getSipFactory().getHeaderFactory().createUserAgentHeader(userAgentList); - ((MessageFactoryExt)sipApplicationDispatcher.getSipFactory().getMessageFactory()).setDefaultUserAgentHeader(userAgentHeader); - } - if(balancers != null) { - if(sipStackProperties.get(LoadBalancerHeartBeatingService.LB_HB_SERVICE_CLASS_NAME) == null) { - sipStackProperties.put(LoadBalancerHeartBeatingService.LB_HB_SERVICE_CLASS_NAME, LoadBalancerHeartBeatingServiceImpl.class.getCanonicalName()); - } - if(sipStackProperties.get(LoadBalancerHeartBeatingService.BALANCERS) == null) { - sipStackProperties.put(LoadBalancerHeartBeatingService.BALANCERS, balancers); - } - } - String replicationStrategyString = sipStackProperties.getProperty(ClusteredSipStack.REPLICATION_STRATEGY_PROPERTY); - if(replicationStrategyString == null) { - replicationStrategyString = ReplicationStrategy.ConfirmedDialog.toString(); - } - boolean replicateApplicationData = false; - if(replicationStrategyString.equals(ReplicationStrategy.EarlyDialog.toString())) { - replicateApplicationData = true; - } - if(replicationStrategyString != null) { - replicationStrategy = ReplicationStrategy.valueOf(replicationStrategyString); - } - sipStackProperties.put(ClusteredSipStack.REPLICATION_STRATEGY_PROPERTY, replicationStrategyString); - sipStackProperties.put(ClusteredSipStack.REPLICATE_APPLICATION_DATA, Boolean.valueOf(replicateApplicationData).toString()); - if(logger.isInfoEnabled()) { - logger.info("Mobicents Sip Servlets sip stack properties : " + sipStackProperties); - } - // Create SipStack object - sipStack = sipApplicationDispatcher.getSipFactory().getJainSipFactory().createSipStack(sipStackProperties); - LoadBalancerHeartBeatingService loadBalancerHeartBeatingService = null; - if(sipStack instanceof ClusteredSipStack) { - loadBalancerHeartBeatingService = ((ClusteredSipStack) sipStack).getLoadBalancerHeartBeatingService(); - if ((this.container != null) && (this.container instanceof Engine) && ((Engine)container).getJvmRoute() != null) { - final String jvmRoute = ((Engine)container).getJvmRoute(); - if(jvmRoute != null) { - loadBalancerHeartBeatingService.setJvmRoute(jvmRoute); - setJvmRoute(jvmRoute); - } - } - } - if(sipApplicationDispatcher != null && loadBalancerHeartBeatingService != null && sipApplicationDispatcher instanceof LoadBalancerHeartBeatingListener) { - loadBalancerHeartBeatingService.addLoadBalancerHeartBeatingListener((LoadBalancerHeartBeatingListener)sipApplicationDispatcher); - } - // for nist sip stack set the DNS Address resolver allowing to make DNS SRV lookups - if(sipStack instanceof SipStackExt && addressResolverClass != null && addressResolverClass.trim().length() > 0) { - if(logger.isDebugEnabled()) { - logger.debug("Sip Stack " + sipStack.getStackName() +" will be using " + addressResolverClass + " as AddressResolver"); - } - try { - // create parameters argument to identify constructor - Class[] paramTypes = new Class[1]; - paramTypes[0] = SipApplicationDispatcher.class; - // get constructor of AddressResolver in order to instantiate - Constructor addressResolverConstructor = Class.forName(addressResolverClass).getConstructor( - paramTypes); - // Wrap properties object in order to pass to constructor of AddressResolver - Object[] conArgs = new Object[1]; - conArgs[0] = sipApplicationDispatcher; - // Creates a new instance of AddressResolver Class with the supplied sipApplicationDispatcher. - AddressResolver addressResolver = (AddressResolver) addressResolverConstructor.newInstance(conArgs); - ((SipStackExt) sipStack).setAddressResolver(addressResolver); - } catch (Exception e) { - logger.error("Couldn't set the AddressResolver " + addressResolverClass, e); - throw e; - } - } else { - if(logger.isInfoEnabled()) { - logger.info("no AddressResolver will be used since none has been specified."); - } - } - if(logger.isInfoEnabled()) { - logger.info("SIP stack initialized"); - } - } catch (Exception ex) { - throw new LifecycleException("A problem occured while initializing the SIP Stack", ex); - } - } - - @Override - public void stopInternal() throws LifecycleException { - // on Tomcat 7 super.stop needs to be called before for Issue 1411 http://code.google.com/p/mobicents/issues/detail?id=1411 - super.stopInternal(); - // Tomcat specific unloading case - // Issue 1411 http://code.google.com/p/mobicents/issues/detail?id=1411 - // Sip Connectors should be removed after removing all Sip Servlets to allow them to send BYE to terminate cleanly - synchronized (connectors) { - for (Connector connector : connectors) { - MobicentsExtendedListeningPoint extendedListeningPoint = null; - if (connector.getProtocolHandler() instanceof SipProtocolHandler) { - extendedListeningPoint = (MobicentsExtendedListeningPoint) - ((SipProtocolHandler)connector.getProtocolHandler()).getAttribute(ExtendedListeningPoint.class.getSimpleName()); - } - if(extendedListeningPoint != null) { - extendedListeningPoint.getSipProvider().removeSipListener(sipApplicationDispatcher); - sipApplicationDispatcher.getSipNetworkInterfaceManager().removeExtendedListeningPoint(extendedListeningPoint); - } - } - } - if(!connectorsStartedExternally) { - sipApplicationDispatcher.stop(); - } - if(logger.isDebugEnabled()) { - logger.debug("SIP Standard Service Stopped."); - } -// setState(LifecycleState.STOPPING); - } - - /** - * Retrieve the sip application dispatcher class name - * @return the sip application dispatcher class name - */ - public String getSipApplicationDispatcherClassName() { - return sipApplicationDispatcherClassName; - } - - /** - * Set the sip application dispatcher class name - * @param sipApplicationDispatcherClassName the sip application dispatcher class name to be set - */ - public void setSipApplicationDispatcherClassName(String sipApplicationDispatcherName) { - this.sipApplicationDispatcherClassName = sipApplicationDispatcherName; - } - - /** - * @return the sipApplicationDispatcher - */ - public SipApplicationDispatcher getSipApplicationDispatcher() { - return sipApplicationDispatcher; - } - - /** - * @param sipApplicationDispatcher the sipApplicationDispatcher to set - */ - public void setSipApplicationDispatcher( - SipApplicationDispatcher sipApplicationDispatcher) { - this.sipApplicationDispatcher = sipApplicationDispatcher; - } - - /** - * @return the darConfigurationFileLocation - */ - public String getDarConfigurationFileLocation() { - return darConfigurationFileLocation; - } - - /** - * @param darConfigurationFileLocation the darConfigurationFileLocation to set - */ - public void setDarConfigurationFileLocation(String darConfigurationFileLocation) { - this.darConfigurationFileLocation = darConfigurationFileLocation; - } - - /** - * Message queue size. If the number of pending requests exceeds this number they are rejected. - * - * @return - */ - public int getSipMessageQueueSize() { - return sipMessageQueueSize; - } - - /** - * Message queue size. If the number of pending requests exceeds this number they are rejected. - * - * @return - */ - public void setSipMessageQueueSize(int sipMessageQueueSize) { - this.sipMessageQueueSize = sipMessageQueueSize; - } - - /** - * ConcurrencyControl control mode is SipSession, AppSession or None - * Specifies the isolation level of concurrently executing requests. - * - * @return - */ - public String getConcurrencyControlMode() { - return concurrencyControlMode; - } - - /** - * ConcurrencyControl control mode is SipSession, AppSession or None - * Specifies the isolation level of concurrently executing requests. - * - * @return - */ - public void setConcurrencyControlMode(String concurrencyControlMode) { - this.concurrencyControlMode = concurrencyControlMode; - } - - - /** - * @param memoryThreshold the memoryThreshold to set - */ - public void setMemoryThreshold(int memoryThreshold) { - this.memoryThreshold = memoryThreshold; - } - - - /** - * @return the memoryThreshold - */ - public int getMemoryThreshold() { - return memoryThreshold; - } - - /** - * @param skipStatistics the skipStatistics to set - */ - public void setGatherStatistics(boolean skipStatistics) { - this.gatherStatistics = skipStatistics; - if(logger.isInfoEnabled()) { - logger.info("Gathering Statistics set to " + skipStatistics); - } - } - - /** - * @return the skipStatistics - */ - public boolean isGatherStatistics() { - return gatherStatistics; - } - - /** - * PRESENT TO ACCOMODATE JOPR. NEED TO FILE A BUG ON THIS - * @return the skipStatistics - */ - public boolean getGatherStatistics() { - return gatherStatistics; - } - - /** - * @param backToNormalPercentageOfMemoryUsed the backToNormalPercentageOfMemoryUsed to set - */ - public void setBackToNormalMemoryThreshold( - int backToNormalMemoryThreshold) { - this.backToNormalMemoryThreshold = backToNormalMemoryThreshold; - } - - /** - * @return the backToNormalPercentageOfMemoryUsed - */ - public int getBackToNormalMemoryThreshold() { - return backToNormalMemoryThreshold; - } - - /** - * @param backToNormalQueueSize the backToNormalQueueSize to set - */ - public void setBackToNormalSipMessageQueueSize(int backToNormalSipMessageQueueSize) { - this.backToNormalSipMessageQueueSize = backToNormalSipMessageQueueSize; - } - - /** - * @return the backToNormalQueueSize - */ - public int getBackToNormalSipMessageQueueSize() { - return backToNormalSipMessageQueueSize; - } - - - /** - * @param congestionControlPolicy the congestionControlPolicy to set - */ - public void setCongestionControlPolicy(String congestionControlPolicy) { - this.congestionControlPolicy = congestionControlPolicy; - } - - - /** - * @return the congestionControlPolicy - */ - public String getCongestionControlPolicy() { - return congestionControlPolicy; - } - - - /** - * @param congestionControlCheckingInterval the congestionControlCheckingInterval to set - */ - public void setCongestionControlCheckingInterval( - long congestionControlCheckingInterval) { - this.congestionControlCheckingInterval = congestionControlCheckingInterval; - } - - - /** - * @return the congestionControlCheckingInterval - */ - public long getCongestionControlCheckingInterval() { - return congestionControlCheckingInterval; - } - - - public String getAdditionalParameterableHeaders() { - return additionalParameterableHeaders; - } - - - public void setAdditionalParameterableHeaders( - String additionalParameterableHeaders) { - this.additionalParameterableHeaders = additionalParameterableHeaders; - String[] headers = additionalParameterableHeaders.split(","); - for(String header : headers) { - if(header != null && header.length()>0) { - JainSipUtils.PARAMETERABLE_HEADER_NAMES.add(header); - } - } - } - - - /** - * @return the bypassResponseExecutor - */ - public boolean isBypassResponseExecutor() { - return bypassResponseExecutor; - } - - - /** - * @param bypassResponseExecutor the bypassResponseExecutor to set - */ - public void setBypassResponseExecutor(boolean bypassResponseExecutor) { - this.bypassResponseExecutor = bypassResponseExecutor; - } - - - /** - * @return the bypassRequestExecutor - */ - public boolean isBypassRequestExecutor() { - return bypassRequestExecutor; - } - - - /** - * @param bypassRequestExecutor the bypassRequestExecutor to set - */ - public void setBypassRequestExecutor(boolean bypassRequestExecutor) { - this.bypassRequestExecutor = bypassRequestExecutor; - } - - public boolean isMd5ContactUserPart() { - return md5ContactUserPart; - } - - - public void setMd5ContactUserPart(boolean md5ContactUserPart) { - this.md5ContactUserPart = md5ContactUserPart; - } - - - /** - * @param usePrettyEncoding the usePrettyEncoding to set - */ - public void setUsePrettyEncoding(boolean usePrettyEncoding) { - this.usePrettyEncoding = usePrettyEncoding; - } - - /** - * @return the usePrettyEncoding - */ - public boolean isUsePrettyEncoding() { - return usePrettyEncoding; - } - - /** - * @param sipPathName the sipPathName to set - */ - public void setSipPathName(String sipPathName) { - this.sipPathName = sipPathName; - } - - /** - * @return the sipPathName - */ - public String getSipPathName() { - return sipPathName; - } - - - /** - * @param baseTimerInterval the baseTimerInterval to set - */ - public void setBaseTimerInterval(int baseTimerInterval) { - this.baseTimerInterval = baseTimerInterval; - } - - - /** - * @return the baseTimerInterval - */ - public int getBaseTimerInterval() { - return baseTimerInterval; - } - - - public OutboundProxy getOutboundProxy() { - return outboundProxy; - } - - - public void setOutboundProxy(String outboundProxy) { - if(outboundProxy != null) { - this.outboundProxy = new OutboundProxy(outboundProxy); - } else { - this.outboundProxy = null; - } - if(logger.isDebugEnabled()) { - logger.debug("Outbound Proxy : " + outboundProxy); - } - } - - public int getDispatcherThreadPoolSize() { - return dispatcherThreadPoolSize; - } - - - public void setDispatcherThreadPoolSize(int dispatcherThreadPoolSize) { - this.dispatcherThreadPoolSize = dispatcherThreadPoolSize; - } - - public int getCanceledTimerTasksPurgePeriod() { - return canceledTimerTasksPurgePeriod; - } - - public void setCanceledTimerTasksPurgePeriod(int purgePeriod) { - this.canceledTimerTasksPurgePeriod = purgePeriod; - } - - - /** - * @deprecated - * @param balancers the balancers to set - */ - public void setBalancers(String balancers) { - this.balancers = balancers; - } - - public boolean addSipConnector(SipConnector sipConnector) throws Exception { - if(sipConnector == null) { - throw new IllegalArgumentException("The sip connector passed is null"); - } - Connector connectorToAdd = findSipConnector(sipConnector.getIpAddress(), sipConnector.getPort(), - sipConnector.getTransport()); - if(connectorToAdd == null) { - Connector connector = new Connector( - SipProtocolHandler.class.getName()); - SipProtocolHandler sipProtocolHandler = (SipProtocolHandler) connector - .getProtocolHandler(); - sipProtocolHandler.setSipConnector(sipConnector); - sipProtocolHandler.setSipStack(sipStack); - connector.setService(this); -//TODO connector.setContainer(container); - connector.init(); - addConnector(connector); - MobicentsExtendedListeningPoint extendedListeningPoint = (MobicentsExtendedListeningPoint) - sipProtocolHandler.getAttribute(ExtendedListeningPoint.class.getSimpleName()); - if(extendedListeningPoint != null) { - try { - extendedListeningPoint.getSipProvider().addSipListener(sipApplicationDispatcher); - sipApplicationDispatcher.getSipNetworkInterfaceManager().addExtendedListeningPoint(extendedListeningPoint); - } catch (TooManyListenersException e) { - logger.error("Connector.initialize", e); - removeConnector(connector); - return false; - } - } - if(!sipProtocolHandler.isStarted()) { - if(logger.isDebugEnabled()) { - logger.debug("Sip Connector couldn't be started, removing it automatically"); - } - removeConnector(connector); - } - return sipProtocolHandler.isStarted(); - } - return false; - } - - public boolean removeSipConnector(String ipAddress, int port, String transport) throws Exception { - Connector connectorToRemove = findSipConnector(ipAddress, port, - transport); - if(connectorToRemove != null) { - removeConnector(connectorToRemove); - return true; - } - return false; - } - - - /** - * Find a sip Connector by it's ip address, port and transport - * @param ipAddress ip address of the connector to find - * @param port port of the connector to find - * @param transport transport of the connector to find - * @return the found sip connector or null if noting found - */ - private Connector findSipConnector(String ipAddress, int port, - String transport) { - Connector connectorToRemove = null; - for (Connector connector : connectors) { - final ProtocolHandler protocolHandler = connector.getProtocolHandler(); - if(protocolHandler instanceof SipProtocolHandler) { - final SipProtocolHandler sipProtocolHandler = (SipProtocolHandler) protocolHandler; - if(sipProtocolHandler.getIpAddress().equals(ipAddress) && sipProtocolHandler.getPort() == port && sipProtocolHandler.getSignalingTransport().equals(transport)) { -// connector.destroy(); - connectorToRemove = connector; - break; - } - } - } - return connectorToRemove; - } - - public SipConnector findSipConnector(String transport) { - List sipConnectors = new ArrayList(); - for (Connector connector : connectors) { - final ProtocolHandler protocolHandler = connector.getProtocolHandler(); - if(protocolHandler instanceof SipProtocolHandler) { - SipConnector sc = (((SipProtocolHandler)protocolHandler).getSipConnector()); - if(sc.getTransport().equalsIgnoreCase(transport)) return sc; - } - } - return null; - } - - public SipConnector[] findSipConnectors() { - List sipConnectors = new ArrayList(); - for (Connector connector : connectors) { - final ProtocolHandler protocolHandler = connector.getProtocolHandler(); - if(protocolHandler instanceof SipProtocolHandler) { - sipConnectors.add(((SipProtocolHandler)protocolHandler).getSipConnector()); - } - } - return sipConnectors.toArray(new SipConnector[sipConnectors.size()]); - } - - /** - * This method simply makes the HTTP and SSL ports avaialble everywhere in the JVM in order jsip ha to read them for - * balancer description purposes. There is no other good way to communicate the properies to jsip ha without adding - * more dependencies. - */ - public void initializeSystemPortProperties() { - for (Connector connector : connectors) { - if(connector.getProtocol().contains("HTTP")) { - if(connector.getSecure()) { - System.setProperty("org.mobicents.properties.sslPort", Integer.toString(connector.getPort())); - } else { - System.setProperty("org.mobicents.properties.httpPort", Integer.toString(connector.getPort())); - } - } - } - } - - protected ObjectName createSipConnectorObjectName(Connector connector, String domain, String type) - throws MalformedObjectNameException { - String encodedAddr = null; - if (connector.getProperty("address") != null) { - encodedAddr = URLEncoder.encode(connector.getProperty("address").toString()); - } - String addSuffix = (connector.getProperty("address") == null) ? "" : ",address=" - + encodedAddr; - ObjectName _oname = new ObjectName(domain + ":type=" + type + ",port=" - + connector.getPort() + ",transport=" + connector.getProperty("transport") + addSuffix); - return _oname; - } - - - /** - * @param t2Interval the t2Interval to set - */ - public void setT2Interval(int t2Interval) { - this.t2Interval = t2Interval; - } - - - /** - * @return the t2Interval - */ - public int getT2Interval() { - return t2Interval; - } - - - /** - * @param t4Interval the t4Interval to set - */ - public void setT4Interval(int t4Interval) { - this.t4Interval = t4Interval; - } - - - /** - * @return the t4Interval - */ - public int getT4Interval() { - return t4Interval; - } - - - /** - * @param timerDInterval the timerDInterval to set - */ - public void setTimerDInterval(int timerDInterval) { - this.timerDInterval = timerDInterval; - } - - - /** - * @return the timerDInterval - */ - public int getTimerDInterval() { - return timerDInterval; - } - - /** - * @param sipStackPropertiesFile the sipStackPropertiesFile to set - */ - public void setSipStackPropertiesFile(String sipStackPropertiesFile) { - sipStackPropertiesFileLocation = sipStackPropertiesFile; - } - - /** - * @return the sipStackProperties - */ - public Properties getSipStackProperties() { - return sipStackProperties; - } - - /** - * @param sipStackProperties the sipStackProperties to set - */ - public void setSipStackProperties(Properties sipStackProperties) { - this.sipStackProperties = sipStackProperties; - } - - /** - * @return the sipStackPropertiesFile - */ - public String getSipStackPropertiesFile() { - return sipStackPropertiesFileLocation; - } - - /** - * @param dnsAddressResolverClass the dnsAddressResolverClass to set - */ - @Deprecated - public void setAddressResolverClass(String dnsAddressResolverClass) { - this.addressResolverClass = dnsAddressResolverClass; - } - - /** - * @return the dnsAddressResolverClass - */ - @Deprecated - public String getAddressResolverClass() { - return addressResolverClass; - } - - /** - * Whether we check for pending requests and return 491 response if there are any - * - * @return the flag value - */ - public boolean isDialogPendingRequestChecking() { - return dialogPendingRequestChecking; - } - - /** - * - * Whether we check for pending requests and return 491 response if there are any - * - * @param dialogPendingRequestChecking - */ - public void setDialogPendingRequestChecking(boolean dialogPendingRequestChecking) { - this.dialogPendingRequestChecking = dialogPendingRequestChecking; - } - - - public boolean isHttpFollowsSip() { - return httpFollowsSip; - } - - - public void setHttpFollowsSip(boolean httpFollowsSip) { - this.httpFollowsSip = httpFollowsSip; - } - - /** - * @return the tagHashMaxLength - */ - public int getTagHashMaxLength() { - return tagHashMaxLength; - } - - /** - * @param tagHashMaxLength the tagHashMaxLength to set - */ - public void setTagHashMaxLength(int tagHashMaxLength) { - this.tagHashMaxLength = tagHashMaxLength; - } - - /** - * @return the callIdMaxLength - */ - public int getCallIdMaxLength() { - return callIdMaxLength; - } - - /** - * @param callIdMaxLength the callIdMaxLength to set - */ - public void setCallIdMaxLength(int callIdMaxLength) { - this.callIdMaxLength = callIdMaxLength; - } - - /** - * @return the sipStack - */ - public SipStack getSipStack() { - return sipStack; - } - - /** - * @param dnsServerLocatorClass the dnsServerLocatorClass to set - */ - public void setDnsServerLocatorClass(String dnsServerLocatorClass) { - this.dnsServerLocatorClass = dnsServerLocatorClass; - } - - /** - * @return the dnsServerLocatorClass - */ - public String getDnsServerLocatorClass() { - return dnsServerLocatorClass; - } - - /** - * @param dnsResolverClass the dnsResolverClass to set - */ - public void setDnsResolverClass(String dnsResolverClass) { - this.dnsResolverClass = dnsResolverClass; - } - - /** - * @return the dnsResolverClass - */ - public String getDnsResolverClass() { - return dnsResolverClass; - } - - /** - * Returns first the catalina.base if it is defined then the catalina.home if it is defined - * then the current dir if none is specified - */ - protected String getCatalinaBase() { - String catalinaBase = System.getProperty("catalina.base"); - if (catalinaBase == null) { - catalinaBase = System.getProperty("catalina.home"); - } - if(catalinaBase == null) { - catalinaBase = "."; - } - return catalinaBase; - } - - public ReplicationStrategy getReplicationStrategy() { - return replicationStrategy; - } - - @Override - public String getMobicentsSipServletMessageFactoryClassName() { - return mobicentsSipServletMessageFactoryClassName; - } - - @Override - public void setMobicentsSipServletMessageFactoryClassName( - String mobicentsSipServletMessageFactoryClassName) { - this.mobicentsSipServletMessageFactoryClassName = mobicentsSipServletMessageFactoryClassName; - } - - public void sendHeartBeat(String localAddress, int localPort, String transport, String remoteIpAddress, int remotePort) throws IOException { - MobicentsExtendedListeningPoint extendedListeningPoint = sipApplicationDispatcher.getSipNetworkInterfaceManager().findMatchingListeningPoint(localAddress, localPort, transport); - if(extendedListeningPoint != null) { - extendedListeningPoint.getListeningPoint().sendHeartbeat(remoteIpAddress, remotePort); - } - } - - public boolean setKeepAliveTimeout(SipConnector sipConnector, String clientAddress, int clientPort, long timeout) { - SIPTransactionStack sipStack = ((SIPTransactionStack) sipApplicationDispatcher.getSipStack()); - - return sipStack.setKeepAliveTimeout(sipConnector.getIpAddress(), sipConnector.getPort(), sipConnector.getTransport(), - clientAddress, clientPort, timeout); - } - - public void closeReliableConnection(SipConnector sipConnector, String clientAddress, int clientPort) { - SIPTransactionStack sipStack = ((SIPTransactionStack) sipApplicationDispatcher.getSipStack()); - - sipStack.closeReliableConnection(sipConnector.getIpAddress(),sipConnector.getPort(), sipConnector.getTransport(), - clientAddress, clientPort); - } - - /* - * (non-Javadoc) - * @see org.mobicents.servlet.sip.core.SipService#stopGracefully(long) - */ - public void stopGracefully(long timeToWait) { - if(logger.isInfoEnabled()) { - logger.info("Stopping the Server Gracefully in " + timeToWait + " ms"); - } - if(timeToWait == 0) { - if(gracefulStopFuture != null) { - gracefulStopFuture.cancel(false); - } - try { - getServer().stop(); - } catch (LifecycleException e) { - logger.error("The server couldn't be stopped", e); - } - } else { - sipApplicationDispatcher.setGracefulShutdown(true); - Iterator sipContexts = sipApplicationDispatcher.findSipApplications(); - while (sipContexts.hasNext()) { - SipContext sipContext = sipContexts.next(); - sipContext.stopGracefully(timeToWait); - } - gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().scheduleWithFixedDelay(new ServiceGracefulStopTask(this), 30000, 30000, TimeUnit.MILLISECONDS); - if(timeToWait > 0) { - gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().schedule( - new Runnable() { - public void run() { - gracefulStopFuture.cancel(false); - try { - getServer().stop(); - } catch (LifecycleException e) { - logger.error("The server couldn't be stopped", e); - } - } - } - , timeToWait, TimeUnit.MILLISECONDS); - } - } - } - - /** - * @return the dnsTimeout - */ - public int getDnsTimeout() { - return dnsTimeout; - } - - /** - * @param dnsTimeout the dnsTimeout to set - */ - public void setDnsTimeout(int dnsTimeout) { - this.dnsTimeout = dnsTimeout; - } - - public String getProxyTimerServiceImplementationType() { - return proxyTimerServiceImplementationType; - } - - public void setProxyTimerServiceImplementationType(String proxyTimerServiceImplementationType) { - this.proxyTimerServiceImplementationType = proxyTimerServiceImplementationType; - } - - public String getSasTimerServiceImplementationType() { - return sasTimerServiceImplementationType; - } - - public void setSasTimerServiceImplementationType(String sasTimerServiceImplementationType) { - this.sasTimerServiceImplementationType = sasTimerServiceImplementationType; - } -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.catalina; + + +import gov.nist.core.net.AddressResolver; +import gov.nist.javax.sip.SipStackExt; +import gov.nist.javax.sip.message.MessageFactoryExt; +import gov.nist.javax.sip.stack.SIPTransactionStack; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; +import java.util.StringTokenizer; +import java.util.TooManyListenersException; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; +import javax.sip.SipStack; +import javax.sip.header.ServerHeader; +import javax.sip.header.UserAgentHeader; + +import org.apache.catalina.Engine; +import org.apache.catalina.LifecycleException; +import org.apache.catalina.connector.Connector; +import org.apache.catalina.core.StandardService; +import org.apache.coyote.ProtocolHandler; +import org.apache.log4j.Logger; +import org.apache.tomcat.util.modeler.Registry; +import org.mobicents.ext.javax.sip.dns.DNSAwareRouter; +import org.mobicents.ext.javax.sip.dns.DNSServerLocator; +import org.mobicents.ext.javax.sip.dns.DefaultDNSServerLocator; +import org.mobicents.ha.javax.sip.ClusteredSipStack; +import org.mobicents.ha.javax.sip.LoadBalancerHeartBeatingListener; +import org.mobicents.ha.javax.sip.LoadBalancerHeartBeatingService; +import org.mobicents.ha.javax.sip.LoadBalancerHeartBeatingServiceImpl; +import org.mobicents.ha.javax.sip.ReplicationStrategy; +import org.mobicents.javax.servlet.CongestionControlPolicy; +import org.mobicents.servlet.sip.JainSipUtils; +import org.mobicents.servlet.sip.SipConnector; +import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; +import org.mobicents.servlet.sip.core.ExtendedListeningPoint; +import org.mobicents.servlet.sip.core.MobicentsExtendedListeningPoint; +import org.mobicents.servlet.sip.core.SipApplicationDispatcher; +import org.mobicents.servlet.sip.core.SipContext; +import org.mobicents.servlet.sip.core.message.OutboundProxy; +import org.mobicents.servlet.sip.dns.MobicentsDNSResolver; +import org.mobicents.servlet.sip.message.Servlet3SipServletMessageFactory; +import org.mobicents.servlet.sip.startup.StaticServiceHolder; + +/** + * Sip Servlet implementation of the SipService interface. + * This class inherits from the Tomcat StandardService. It adds a SipApplicationDispatcher + * that will be listen for sip messages received by the sip stacks started by + * the sip connectors associated with this context. + * This has one attribute which is the sipApplicationDispatcherClassName allowing one + * to specify the class name of the sipApplicationDispacther to easily replace + * the default sipApplicationDispatcher with a custom one. + * + * @author Jean Deruelle + */ +public class SipStandardService extends StandardService implements CatalinaSipService { + //the logger + private static final Logger logger = Logger.getLogger(SipStandardService.class); + public static final String DEFAULT_SIP_PATH_NAME = "gov.nist"; + public static final String PASS_INVITE_NON_2XX_ACK_TO_LISTENER = "gov.nist.javax.sip.PASS_INVITE_NON_2XX_ACK_TO_LISTENER"; + public static final String TCP_POST_PARSING_THREAD_POOL_SIZE = "gov.nist.javax.sip.TCP_POST_PARSING_THREAD_POOL_SIZE"; + public static final String AUTOMATIC_DIALOG_SUPPORT_STACK_PROP = "javax.sip.AUTOMATIC_DIALOG_SUPPORT"; + public static final String LOOSE_DIALOG_VALIDATION = "gov.nist.javax.sip.LOOSE_DIALOG_VALIDATION"; + public static final String SERVER_LOG_STACK_PROP = "gov.nist.javax.sip.SERVER_LOG"; + public static final String DEBUG_LOG_STACK_PROP = "gov.nist.javax.sip.DEBUG_LOG"; + public static final String SERVER_HEADER = "org.mobicents.servlet.sip.SERVER_HEADER"; + public static final String USER_AGENT_HEADER = "org.mobicents.servlet.sip.USER_AGENT_HEADER"; + public static final String JVM_ROUTE = "jvmRoute"; + /** + * The descriptive information string for this implementation. + */ + private static final String INFO = + "org.mobicents.servlet.sip.startup.SipStandardService/1.0"; + //the sip application dispatcher class name defined in the server.xml + protected String sipApplicationDispatcherClassName; + //instatiated class from the sipApplicationDispatcherClassName of the sip application dispatcher + protected SipApplicationDispatcher sipApplicationDispatcher; + private boolean gatherStatistics = true; + protected int sipMessageQueueSize = 1500; + private int backToNormalSipMessageQueueSize = 1300; + protected int memoryThreshold = 95; + private int backToNormalMemoryThreshold = 90; + protected OutboundProxy outboundProxy; + protected String proxyTimerServiceImplementationType; + protected String sasTimerServiceImplementationType; + protected long congestionControlCheckingInterval = 30000; + private int canceledTimerTasksPurgePeriod = 0; + // base timer interval for jain sip tx + private int baseTimerInterval = 500; + private int t2Interval = 4000; + private int t4Interval = 5000; + private int timerDInterval = 32000; + protected int dispatcherThreadPoolSize = 15; + private boolean md5ContactUserPart = false; + + protected String concurrencyControlMode = ConcurrencyControlMode.SipApplicationSession.toString(); + protected String congestionControlPolicy = CongestionControlPolicy.ErrorResponse.toString(); + protected String additionalParameterableHeaders; + protected boolean bypassResponseExecutor = true; + protected boolean bypassRequestExecutor = true; + //this should be made available to the application router as a system prop + protected String darConfigurationFileLocation; + protected boolean connectorsStartedExternally = false; + protected boolean dialogPendingRequestChecking = false; + protected int callIdMaxLength; + protected int tagHashMaxLength; + private long gracefulInterval = 30000; + + protected boolean httpFollowsSip = false; + protected String jvmRoute; + protected ReplicationStrategy replicationStrategy; + + /** + * the sip stack path name. Since the sip factory is per classloader it should be set here for all underlying stacks + */ + private String sipPathName; + /** + * use Pretty Encoding + */ + private boolean usePrettyEncoding = true; + + private SipStack sipStack; + // defining sip stack properties + private Properties sipStackProperties; + private String sipStackPropertiesFileLocation; + @Deprecated + private String addressResolverClass = null; + private String dnsServerLocatorClass = DefaultDNSServerLocator.class.getName(); + private int dnsTimeout = 1; + private String dnsResolverClass = MobicentsDNSResolver.class.getName(); + private String mobicentsSipServletMessageFactoryClassName = Servlet3SipServletMessageFactory.class.getName(); + + //the balancers to send heartbeat to and our health info + @Deprecated + private String balancers; + // + private ScheduledFuture gracefulStopFuture; + + @Override + public String getInfo() { + return (INFO); + } + + @Override + public void addConnector(Connector connector) { + MobicentsExtendedListeningPoint extendedListeningPoint = null; + if (connector.getProtocolHandler() instanceof SipProtocolHandler) { + extendedListeningPoint = (MobicentsExtendedListeningPoint) + ((SipProtocolHandler)connector.getProtocolHandler()).getAttribute(ExtendedListeningPoint.class.getSimpleName());} + if(extendedListeningPoint != null) { + try { + extendedListeningPoint.getSipProvider().addSipListener(sipApplicationDispatcher); + sipApplicationDispatcher.getSipNetworkInterfaceManager().addExtendedListeningPoint(extendedListeningPoint); + } catch (TooManyListenersException e) { + logger.error("Connector.initialize", e); + } + } + ProtocolHandler protocolHandler = connector.getProtocolHandler(); + if(protocolHandler instanceof SipProtocolHandler) { + connector.setPort(((SipProtocolHandler)protocolHandler).getPort()); + ((SipProtocolHandler)protocolHandler).setSipStack(sipStack); + ((SipProtocolHandler)protocolHandler).setAttribute(SipApplicationDispatcher.class.getSimpleName(), sipApplicationDispatcher); + registerSipConnector(connector); + } + super.addConnector(connector); + } + + /** + * Register the sip connector under a different name than HTTP Connector and we add the transport to avoid clashing with 2 connectors having the same port and address + * @param connector connector to register + */ + protected void registerSipConnector(Connector connector) { + try { + + ObjectName objectName = createSipConnectorObjectName(connector, getName(), "SipConnector"); + Registry.getRegistry(null, null) + .registerComponent(connector, objectName, null); +//TODO connector.setController(objectName); + } catch (Exception e) { + logger.error( "Error registering connector ", e); + } + if(logger.isDebugEnabled()) + logger.debug("Creating name for connector " + getObjectName()); + } + + @Override + public void removeConnector(Connector connector) { + MobicentsExtendedListeningPoint extendedListeningPoint = null; + if (connector.getProtocolHandler() instanceof SipProtocolHandler){ + extendedListeningPoint = (MobicentsExtendedListeningPoint) + ((SipProtocolHandler)connector.getProtocolHandler()).getAttribute(ExtendedListeningPoint.class.getSimpleName());} + if(extendedListeningPoint != null) { + extendedListeningPoint.getSipProvider().removeSipListener(sipApplicationDispatcher); + sipApplicationDispatcher.getSipNetworkInterfaceManager().removeExtendedListeningPoint(extendedListeningPoint); + } + super.removeConnector(connector); + } + + @Override + public void initInternal() throws LifecycleException { + //load the sip application disptacher from the class name specified in the server.xml file + //and initializes it + StaticServiceHolder.sipStandardService = this; + try { + sipApplicationDispatcher = (SipApplicationDispatcher) + Class.forName(sipApplicationDispatcherClassName).newInstance(); + } catch (InstantiationException e) { + throw new LifecycleException("Impossible to load the Sip Application Dispatcher",e); + } catch (IllegalAccessException e) { + throw new LifecycleException("Impossible to load the Sip Application Dispatcher",e); + } catch (ClassNotFoundException e) { + throw new LifecycleException("Impossible to load the Sip Application Dispatcher",e); + } catch (ClassCastException e) { + throw new LifecycleException("Sip Application Dispatcher defined does not implement " + SipApplicationDispatcher.class.getName(),e); + } + if(logger.isInfoEnabled()) { + logger.info("Pretty encoding of headers enabled ? " + usePrettyEncoding); + } + if(sipPathName == null) { + sipPathName = DEFAULT_SIP_PATH_NAME; + } + if(logger.isInfoEnabled()) { + logger.info("Sip Stack path name : " + sipPathName); + } + sipApplicationDispatcher.setSipService(this); + sipApplicationDispatcher.getSipFactory().initialize(sipPathName, usePrettyEncoding); + + String catalinaBase = getCatalinaBase(); + if(darConfigurationFileLocation != null) { + if(!darConfigurationFileLocation.startsWith("file:///")) { + darConfigurationFileLocation = "file:///" + catalinaBase.replace(File.separatorChar, '/') + "/" + darConfigurationFileLocation; + } + System.setProperty("javax.servlet.sip.dar", darConfigurationFileLocation); + } + super.initInternal(); + sipApplicationDispatcher.setDomain(this.getName()); + if(baseTimerInterval < 1) { + throw new LifecycleException("It's forbidden to set the Base Timer Interval to a non positive value"); + } + initSipStack(); + // https://telestax.atlassian.net/browse/MSS-148 make sure we have a default to bin direction for better out of the box experience + if(System.getProperty("telscale.license.dir") == null) { + System.setProperty("telscale.license.dir", getCatalinaBase() + File.separatorChar + "bin"); + if(logger.isDebugEnabled()) { + logger.debug("Setting telscale.license.dir directory to : " + getCatalinaBase() + File.separatorChar + "bin"); + } + } + if(System.getProperty("telscale.license.key.location") == null) { + System.setProperty("telscale.license.key.location", getCatalinaBase() + File.separatorChar + "bin"); + if(logger.isDebugEnabled()) { + logger.debug("Setting telscale.license.key.location directory to : " + getCatalinaBase() + File.separatorChar + "bin"); + } + } + + sipApplicationDispatcher.setBaseTimerInterval(baseTimerInterval); + sipApplicationDispatcher.setT2Interval(t2Interval); + sipApplicationDispatcher.setT4Interval(t4Interval); + sipApplicationDispatcher.setTimerDInterval(timerDInterval); + sipApplicationDispatcher.setMemoryThreshold(getMemoryThreshold()); + sipApplicationDispatcher.setBackToNormalMemoryThreshold(backToNormalMemoryThreshold); + sipApplicationDispatcher.setCongestionControlCheckingInterval(getCongestionControlCheckingInterval()); + sipApplicationDispatcher.setCongestionControlPolicyByName(getCongestionControlPolicy()); + sipApplicationDispatcher.setQueueSize(getSipMessageQueueSize()); + sipApplicationDispatcher.setBackToNormalQueueSize(backToNormalSipMessageQueueSize); + sipApplicationDispatcher.setGatherStatistics(gatherStatistics); + sipApplicationDispatcher.setConcurrencyControlMode(ConcurrencyControlMode.valueOf(getConcurrencyControlMode())); + sipApplicationDispatcher.setBypassRequestExecutor(bypassRequestExecutor); + sipApplicationDispatcher.setBypassResponseExecutor(bypassResponseExecutor); + sipApplicationDispatcher.setSipStack(sipStack); + sipApplicationDispatcher.init(); + // Tomcat specific loading case where the connectors are added even before the service is initialized + // so we need to set the sip stack before it starts + synchronized (connectors) { + for (Connector connector : connectors) { + ProtocolHandler protocolHandler = connector.getProtocolHandler(); + if(protocolHandler instanceof SipProtocolHandler) { + connector.setPort(((SipProtocolHandler)protocolHandler).getPort()); + ((SipProtocolHandler)protocolHandler).setSipStack(sipStack); + ((SipProtocolHandler)protocolHandler).setAttribute(SipApplicationDispatcher.class.getSimpleName(), sipApplicationDispatcher); + registerSipConnector(connector); + } + } + } + } + + @Override + public void startInternal() throws LifecycleException { + super.startInternal(); + synchronized (connectors) { + for (Connector connector : connectors) { + final ProtocolHandler protocolHandler = connector.getProtocolHandler(); + //Jboss sepcific loading case + Boolean isSipConnector = false; + if (protocolHandler instanceof SipProtocolHandler) + isSipConnector = (Boolean) ((SipProtocolHandler)protocolHandler).getAttribute(SipProtocolHandler.IS_SIP_CONNECTOR); + if(isSipConnector != null && isSipConnector) { + if(logger.isDebugEnabled()) { + logger.debug("Attaching the sip application dispatcher " + + "as a sip listener to connector listening on port " + + connector.getPort()); + } + ((SipProtocolHandler)protocolHandler).setAttribute(SipApplicationDispatcher.class.getSimpleName(), sipApplicationDispatcher); + ((SipProtocolHandler)protocolHandler).setSipStack(sipStack); + connectorsStartedExternally = true; + } + //Tomcat specific loading case + MobicentsExtendedListeningPoint extendedListeningPoint = null; + if (protocolHandler instanceof SipProtocolHandler) { + extendedListeningPoint = (MobicentsExtendedListeningPoint) + ((SipProtocolHandler)protocolHandler).getAttribute(ExtendedListeningPoint.class.getSimpleName());} + if(extendedListeningPoint != null && sipStack != null) { + try { + extendedListeningPoint.getSipProvider().addSipListener(sipApplicationDispatcher); + sipApplicationDispatcher.getSipNetworkInterfaceManager().addExtendedListeningPoint(extendedListeningPoint); + connectorsStartedExternally = false; + } catch (TooManyListenersException e) { + throw new LifecycleException("Couldn't add the sip application dispatcher " + + sipApplicationDispatcher + " as a listener to the following listening point provider " + extendedListeningPoint, e); + } + } + } + } + if(!connectorsStartedExternally) { + sipApplicationDispatcher.start(); + sipApplicationDispatcher.putInService(); + } + + if(this.getSipMessageQueueSize() <= 0) + throw new LifecycleException("Message queue size can not be 0 or less"); + + if(logger.isDebugEnabled()) { + logger.debug("SIP Standard Service Started."); + } + } + + public String getJvmRoute() { + return this.jvmRoute; + } + + public void setJvmRoute(String jvmRoute) { + this.jvmRoute = jvmRoute; + } + + protected void initSipStack() throws LifecycleException { + try { + if(logger.isDebugEnabled()) { + logger.debug("Initializing SIP stack"); + } + + // This simply puts HTTP and SSL port numbers in JVM properties menat to be read by jsip ha when sending heart beats with Node description. + initializeSystemPortProperties(); + + String catalinaBase = getCatalinaBase(); + if(sipStackPropertiesFileLocation != null && !sipStackPropertiesFileLocation.startsWith("file:///")) { + sipStackPropertiesFileLocation = "file:///" + catalinaBase.replace(File.separatorChar, '/') + "/" + sipStackPropertiesFileLocation; + } + boolean isPropsLoaded = false; + if(sipStackProperties == null) { + sipStackProperties = new Properties(); + } else { + isPropsLoaded = true; + } + + if (logger.isDebugEnabled()) { + logger.debug("Loading SIP stack properties from following file : " + sipStackPropertiesFileLocation); + } + if(sipStackPropertiesFileLocation != null) { + //hack to get around space char in path see http://weblogs.java.net/blog/kohsuke/archive/2007/04/how_to_convert.html, + // we create a URL since it's permissive enough + File sipStackPropertiesFile = null; + URL url = null; + try { + url = new URL(sipStackPropertiesFileLocation); + } catch (MalformedURLException e) { + logger.fatal("Cannot find the sip stack properties file ! ",e); + throw new IllegalArgumentException("The Default Application Router file Location : "+sipStackPropertiesFileLocation+" is not valid ! ",e); + } + try { + sipStackPropertiesFile = new File(new URI(sipStackPropertiesFileLocation)); + } catch (URISyntaxException e) { + //if the uri contains space this will fail, so getting the path will work + sipStackPropertiesFile = new File(url.getPath()); + } + FileInputStream sipStackPropertiesInputStream = null; + try { + sipStackPropertiesInputStream = new FileInputStream(sipStackPropertiesFile); + sipStackProperties.load(sipStackPropertiesInputStream); + } catch (Exception e) { + logger.warn("Could not find or problem when loading the sip stack properties file : " + sipStackPropertiesFileLocation, e); + } finally { + if(sipStackPropertiesInputStream != null) { + try { + sipStackPropertiesInputStream.close(); + } catch (IOException e) { + logger.error("fail to close the following file " + sipStackPropertiesFile.getAbsolutePath(), e); + } + } + } + + String debugLog = sipStackProperties.getProperty(DEBUG_LOG_STACK_PROP); + if(debugLog != null && debugLog.length() > 0 && !debugLog.startsWith("file:///")) { + sipStackProperties.setProperty(DEBUG_LOG_STACK_PROP, + catalinaBase + "/" + debugLog); + } + String serverLog = sipStackProperties.getProperty(SERVER_LOG_STACK_PROP); + if(serverLog != null && serverLog.length() > 0 && !serverLog.startsWith("file:///")) { + sipStackProperties.setProperty(SERVER_LOG_STACK_PROP, + catalinaBase + "/" + serverLog); + } + // The whole MSS is built upon those assumptions, so those properties are not overrideable + if (sipStackProperties.getProperty(AUTOMATIC_DIALOG_SUPPORT_STACK_PROP) == null) { + //https://github.com/RestComm/sip-servlets/issues/143 + //set off if user didnt provided any value. + sipStackProperties.setProperty(AUTOMATIC_DIALOG_SUPPORT_STACK_PROP, "off"); + } + sipStackProperties.setProperty(LOOSE_DIALOG_VALIDATION, "true"); + sipStackProperties.setProperty(PASS_INVITE_NON_2XX_ACK_TO_LISTENER, "true"); + isPropsLoaded = true; + } else { + logger.warn("no sip stack properties file defined "); + } + if(!isPropsLoaded) { + logger.warn("loading default Mobicents Sip Servlets sip stack properties"); + // Silently set default values + sipStackProperties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", + "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", + "32"); + sipStackProperties.setProperty(DEBUG_LOG_STACK_PROP, + catalinaBase + "/" + "mss-jsip-" + getName() +"-debug.txt"); + sipStackProperties.setProperty(SERVER_LOG_STACK_PROP, + catalinaBase + "/" + "mss-jsip-" + getName() +"-messages.xml"); + sipStackProperties.setProperty("javax.sip.STACK_NAME", "mss-" + getName()); + sipStackProperties.setProperty(AUTOMATIC_DIALOG_SUPPORT_STACK_PROP, "off"); + sipStackProperties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.THREAD_POOL_SIZE", "64"); + sipStackProperties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.MAX_FORK_TIME_SECONDS", "0"); + sipStackProperties.setProperty(LOOSE_DIALOG_VALIDATION, "true"); + sipStackProperties.setProperty(PASS_INVITE_NON_2XX_ACK_TO_LISTENER, "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.AUTOMATIC_DIALOG_ERROR_HANDLING", "false"); + sipStackProperties.setProperty("gov.nist.javax.sip.AGGRESSIVE_CLEANUP", "true"); + } + + if(sipStackProperties.get(TCP_POST_PARSING_THREAD_POOL_SIZE) == null) { + sipStackProperties.setProperty(TCP_POST_PARSING_THREAD_POOL_SIZE, "30"); + } + + // set the DNSServerLocator allowing to support RFC 3263 and do DNS lookups to resolve uris + if(dnsServerLocatorClass != null && dnsServerLocatorClass.trim().length() > 0) { + if(logger.isDebugEnabled()) { + logger.debug("Sip Stack " + sipStackProperties.getProperty("javax.sip.STACK_NAME") +" will be using " + dnsServerLocatorClass + " as DNSServerLocator"); + } + try { + // create parameters argument to identify constructor + Class[] paramTypes = new Class[0]; + // get constructor of AddressResolver in order to instantiate + Constructor dnsServerLocatorConstructor = Class.forName(dnsServerLocatorClass).getConstructor( + paramTypes); + // Wrap properties object in order to pass to constructor of AddressResolver + Object[] conArgs = new Object[0]; + // Creates a new instance of AddressResolver Class with the supplied sipApplicationDispatcher. + DNSServerLocator dnsServerLocator = (DNSServerLocator) dnsServerLocatorConstructor.newInstance(conArgs); + sipApplicationDispatcher.setDNSServerLocator(dnsServerLocator); + sipApplicationDispatcher.setDNSTimeout(dnsTimeout); + if(sipStackProperties.getProperty("javax.sip.ROUTER_PATH") == null) { + sipStackProperties.setProperty("javax.sip.ROUTER_PATH", DNSAwareRouter.class.getCanonicalName()); + } + } catch (Exception e) { + logger.error("Couldn't set the AddressResolver " + addressResolverClass, e); + throw e; + } + } else { + if(logger.isInfoEnabled()) { + logger.info("no DNSServerLocator will be used since none has been specified."); + } + } + + String serverHeaderValue = sipStackProperties.getProperty(SERVER_HEADER); + if(serverHeaderValue != null) { + List serverHeaderList = new ArrayList(); + StringTokenizer stringTokenizer = new StringTokenizer(serverHeaderValue, ","); + while(stringTokenizer.hasMoreTokens()) { + serverHeaderList.add(stringTokenizer.nextToken()); + } + ServerHeader serverHeader = sipApplicationDispatcher.getSipFactory().getHeaderFactory().createServerHeader(serverHeaderList); + ((MessageFactoryExt)sipApplicationDispatcher.getSipFactory().getMessageFactory()).setDefaultServerHeader(serverHeader); + } + String userAgent = sipStackProperties.getProperty(USER_AGENT_HEADER); + if(userAgent != null) { + List userAgentList = new ArrayList(); + StringTokenizer stringTokenizer = new StringTokenizer(userAgent, ","); + while(stringTokenizer.hasMoreTokens()) { + userAgentList.add(stringTokenizer.nextToken()); + } + UserAgentHeader userAgentHeader = sipApplicationDispatcher.getSipFactory().getHeaderFactory().createUserAgentHeader(userAgentList); + ((MessageFactoryExt)sipApplicationDispatcher.getSipFactory().getMessageFactory()).setDefaultUserAgentHeader(userAgentHeader); + } + if(balancers != null) { + if(sipStackProperties.get(LoadBalancerHeartBeatingService.LB_HB_SERVICE_CLASS_NAME) == null) { + sipStackProperties.put(LoadBalancerHeartBeatingService.LB_HB_SERVICE_CLASS_NAME, LoadBalancerHeartBeatingServiceImpl.class.getCanonicalName()); + } + if(sipStackProperties.get(LoadBalancerHeartBeatingService.BALANCERS) == null) { + sipStackProperties.put(LoadBalancerHeartBeatingService.BALANCERS, balancers); + } + } + String replicationStrategyString = sipStackProperties.getProperty(ClusteredSipStack.REPLICATION_STRATEGY_PROPERTY); + if(replicationStrategyString == null) { + replicationStrategyString = ReplicationStrategy.ConfirmedDialog.toString(); + } + boolean replicateApplicationData = false; + if(replicationStrategyString.equals(ReplicationStrategy.EarlyDialog.toString())) { + replicateApplicationData = true; + } + if(replicationStrategyString != null) { + replicationStrategy = ReplicationStrategy.valueOf(replicationStrategyString); + } + sipStackProperties.put(ClusteredSipStack.REPLICATION_STRATEGY_PROPERTY, replicationStrategyString); + sipStackProperties.put(ClusteredSipStack.REPLICATE_APPLICATION_DATA, Boolean.valueOf(replicateApplicationData).toString()); + if(logger.isInfoEnabled()) { + logger.info("Mobicents Sip Servlets sip stack properties : " + sipStackProperties); + } + // Create SipStack object + sipStack = sipApplicationDispatcher.getSipFactory().getJainSipFactory().createSipStack(sipStackProperties); + LoadBalancerHeartBeatingService loadBalancerHeartBeatingService = null; + if(sipStack instanceof ClusteredSipStack) { + loadBalancerHeartBeatingService = ((ClusteredSipStack) sipStack).getLoadBalancerHeartBeatingService(); + if ((this.container != null) && (this.container instanceof Engine) && ((Engine)container).getJvmRoute() != null) { + final String jvmRoute = ((Engine)container).getJvmRoute(); + if(jvmRoute != null) { + loadBalancerHeartBeatingService.setJvmRoute(jvmRoute); + setJvmRoute(jvmRoute); + } + } + } + if(sipApplicationDispatcher != null && loadBalancerHeartBeatingService != null && sipApplicationDispatcher instanceof LoadBalancerHeartBeatingListener) { + loadBalancerHeartBeatingService.addLoadBalancerHeartBeatingListener((LoadBalancerHeartBeatingListener)sipApplicationDispatcher); + } + // for nist sip stack set the DNS Address resolver allowing to make DNS SRV lookups + if(sipStack instanceof SipStackExt && addressResolverClass != null && addressResolverClass.trim().length() > 0) { + if(logger.isDebugEnabled()) { + logger.debug("Sip Stack " + sipStack.getStackName() +" will be using " + addressResolverClass + " as AddressResolver"); + } + try { + // create parameters argument to identify constructor + Class[] paramTypes = new Class[1]; + paramTypes[0] = SipApplicationDispatcher.class; + // get constructor of AddressResolver in order to instantiate + Constructor addressResolverConstructor = Class.forName(addressResolverClass).getConstructor( + paramTypes); + // Wrap properties object in order to pass to constructor of AddressResolver + Object[] conArgs = new Object[1]; + conArgs[0] = sipApplicationDispatcher; + // Creates a new instance of AddressResolver Class with the supplied sipApplicationDispatcher. + AddressResolver addressResolver = (AddressResolver) addressResolverConstructor.newInstance(conArgs); + ((SipStackExt) sipStack).setAddressResolver(addressResolver); + } catch (Exception e) { + logger.error("Couldn't set the AddressResolver " + addressResolverClass, e); + throw e; + } + } else { + if(logger.isInfoEnabled()) { + logger.info("no AddressResolver will be used since none has been specified."); + } + } + if(logger.isInfoEnabled()) { + logger.info("SIP stack initialized"); + } + } catch (Exception ex) { + throw new LifecycleException("A problem occured while initializing the SIP Stack", ex); + } + } + + @Override + public void stopInternal() throws LifecycleException { + // on Tomcat 7 super.stop needs to be called before for Issue 1411 http://code.google.com/p/mobicents/issues/detail?id=1411 + super.stopInternal(); + // Tomcat specific unloading case + // Issue 1411 http://code.google.com/p/mobicents/issues/detail?id=1411 + // Sip Connectors should be removed after removing all Sip Servlets to allow them to send BYE to terminate cleanly + synchronized (connectors) { + for (Connector connector : connectors) { + MobicentsExtendedListeningPoint extendedListeningPoint = null; + if (connector.getProtocolHandler() instanceof SipProtocolHandler) { + extendedListeningPoint = (MobicentsExtendedListeningPoint) + ((SipProtocolHandler)connector.getProtocolHandler()).getAttribute(ExtendedListeningPoint.class.getSimpleName()); + } + if(extendedListeningPoint != null) { + extendedListeningPoint.getSipProvider().removeSipListener(sipApplicationDispatcher); + sipApplicationDispatcher.getSipNetworkInterfaceManager().removeExtendedListeningPoint(extendedListeningPoint); + } + } + } + if(!connectorsStartedExternally) { + sipApplicationDispatcher.stop(); + } + if(logger.isDebugEnabled()) { + logger.debug("SIP Standard Service Stopped."); + } +// setState(LifecycleState.STOPPING); + } + + /** + * Retrieve the sip application dispatcher class name + * @return the sip application dispatcher class name + */ + public String getSipApplicationDispatcherClassName() { + return sipApplicationDispatcherClassName; + } + + /** + * Set the sip application dispatcher class name + * @param sipApplicationDispatcherClassName the sip application dispatcher class name to be set + */ + public void setSipApplicationDispatcherClassName(String sipApplicationDispatcherName) { + this.sipApplicationDispatcherClassName = sipApplicationDispatcherName; + } + + /** + * @return the sipApplicationDispatcher + */ + public SipApplicationDispatcher getSipApplicationDispatcher() { + return sipApplicationDispatcher; + } + + /** + * @param sipApplicationDispatcher the sipApplicationDispatcher to set + */ + public void setSipApplicationDispatcher( + SipApplicationDispatcher sipApplicationDispatcher) { + this.sipApplicationDispatcher = sipApplicationDispatcher; + } + + /** + * @return the darConfigurationFileLocation + */ + public String getDarConfigurationFileLocation() { + return darConfigurationFileLocation; + } + + /** + * @param darConfigurationFileLocation the darConfigurationFileLocation to set + */ + public void setDarConfigurationFileLocation(String darConfigurationFileLocation) { + this.darConfigurationFileLocation = darConfigurationFileLocation; + } + + /** + * Message queue size. If the number of pending requests exceeds this number they are rejected. + * + * @return + */ + public int getSipMessageQueueSize() { + return sipMessageQueueSize; + } + + /** + * Message queue size. If the number of pending requests exceeds this number they are rejected. + * + * @return + */ + public void setSipMessageQueueSize(int sipMessageQueueSize) { + this.sipMessageQueueSize = sipMessageQueueSize; + } + + /** + * ConcurrencyControl control mode is SipSession, AppSession or None + * Specifies the isolation level of concurrently executing requests. + * + * @return + */ + public String getConcurrencyControlMode() { + return concurrencyControlMode; + } + + /** + * ConcurrencyControl control mode is SipSession, AppSession or None + * Specifies the isolation level of concurrently executing requests. + * + * @return + */ + public void setConcurrencyControlMode(String concurrencyControlMode) { + this.concurrencyControlMode = concurrencyControlMode; + } + + + /** + * @param memoryThreshold the memoryThreshold to set + */ + public void setMemoryThreshold(int memoryThreshold) { + this.memoryThreshold = memoryThreshold; + } + + + /** + * @return the memoryThreshold + */ + public int getMemoryThreshold() { + return memoryThreshold; + } + + /** + * @param skipStatistics the skipStatistics to set + */ + public void setGatherStatistics(boolean skipStatistics) { + this.gatherStatistics = skipStatistics; + if(logger.isInfoEnabled()) { + logger.info("Gathering Statistics set to " + skipStatistics); + } + } + + /** + * @return the skipStatistics + */ + public boolean isGatherStatistics() { + return gatherStatistics; + } + + /** + * PRESENT TO ACCOMODATE JOPR. NEED TO FILE A BUG ON THIS + * @return the skipStatistics + */ + public boolean getGatherStatistics() { + return gatherStatistics; + } + + /** + * @param backToNormalPercentageOfMemoryUsed the backToNormalPercentageOfMemoryUsed to set + */ + public void setBackToNormalMemoryThreshold( + int backToNormalMemoryThreshold) { + this.backToNormalMemoryThreshold = backToNormalMemoryThreshold; + } + + /** + * @return the backToNormalPercentageOfMemoryUsed + */ + public int getBackToNormalMemoryThreshold() { + return backToNormalMemoryThreshold; + } + + /** + * @param backToNormalQueueSize the backToNormalQueueSize to set + */ + public void setBackToNormalSipMessageQueueSize(int backToNormalSipMessageQueueSize) { + this.backToNormalSipMessageQueueSize = backToNormalSipMessageQueueSize; + } + + /** + * @return the backToNormalQueueSize + */ + public int getBackToNormalSipMessageQueueSize() { + return backToNormalSipMessageQueueSize; + } + + + /** + * @param congestionControlPolicy the congestionControlPolicy to set + */ + public void setCongestionControlPolicy(String congestionControlPolicy) { + this.congestionControlPolicy = congestionControlPolicy; + } + + + /** + * @return the congestionControlPolicy + */ + public String getCongestionControlPolicy() { + return congestionControlPolicy; + } + + + /** + * @param congestionControlCheckingInterval the congestionControlCheckingInterval to set + */ + public void setCongestionControlCheckingInterval( + long congestionControlCheckingInterval) { + this.congestionControlCheckingInterval = congestionControlCheckingInterval; + } + + + /** + * @return the congestionControlCheckingInterval + */ + public long getCongestionControlCheckingInterval() { + return congestionControlCheckingInterval; + } + + + public String getAdditionalParameterableHeaders() { + return additionalParameterableHeaders; + } + + + public void setAdditionalParameterableHeaders( + String additionalParameterableHeaders) { + this.additionalParameterableHeaders = additionalParameterableHeaders; + String[] headers = additionalParameterableHeaders.split(","); + for(String header : headers) { + if(header != null && header.length()>0) { + JainSipUtils.PARAMETERABLE_HEADER_NAMES.add(header); + } + } + } + + + /** + * @return the bypassResponseExecutor + */ + public boolean isBypassResponseExecutor() { + return bypassResponseExecutor; + } + + + /** + * @param bypassResponseExecutor the bypassResponseExecutor to set + */ + public void setBypassResponseExecutor(boolean bypassResponseExecutor) { + this.bypassResponseExecutor = bypassResponseExecutor; + } + + + /** + * @return the bypassRequestExecutor + */ + public boolean isBypassRequestExecutor() { + return bypassRequestExecutor; + } + + + /** + * @param bypassRequestExecutor the bypassRequestExecutor to set + */ + public void setBypassRequestExecutor(boolean bypassRequestExecutor) { + this.bypassRequestExecutor = bypassRequestExecutor; + } + + public boolean isMd5ContactUserPart() { + return md5ContactUserPart; + } + + + public void setMd5ContactUserPart(boolean md5ContactUserPart) { + this.md5ContactUserPart = md5ContactUserPart; + } + + + /** + * @param usePrettyEncoding the usePrettyEncoding to set + */ + public void setUsePrettyEncoding(boolean usePrettyEncoding) { + this.usePrettyEncoding = usePrettyEncoding; + } + + /** + * @return the usePrettyEncoding + */ + public boolean isUsePrettyEncoding() { + return usePrettyEncoding; + } + + /** + * @param sipPathName the sipPathName to set + */ + public void setSipPathName(String sipPathName) { + this.sipPathName = sipPathName; + } + + /** + * @return the sipPathName + */ + public String getSipPathName() { + return sipPathName; + } + + + /** + * @param baseTimerInterval the baseTimerInterval to set + */ + public void setBaseTimerInterval(int baseTimerInterval) { + this.baseTimerInterval = baseTimerInterval; + } + + + /** + * @return the baseTimerInterval + */ + public int getBaseTimerInterval() { + return baseTimerInterval; + } + + + public OutboundProxy getOutboundProxy() { + return outboundProxy; + } + + + public void setOutboundProxy(String outboundProxy) { + if(outboundProxy != null) { + this.outboundProxy = new OutboundProxy(outboundProxy); + } else { + this.outboundProxy = null; + } + if(logger.isDebugEnabled()) { + logger.debug("Outbound Proxy : " + outboundProxy); + } + } + + public int getDispatcherThreadPoolSize() { + return dispatcherThreadPoolSize; + } + + + public void setDispatcherThreadPoolSize(int dispatcherThreadPoolSize) { + this.dispatcherThreadPoolSize = dispatcherThreadPoolSize; + } + + public int getCanceledTimerTasksPurgePeriod() { + return canceledTimerTasksPurgePeriod; + } + + public void setCanceledTimerTasksPurgePeriod(int purgePeriod) { + this.canceledTimerTasksPurgePeriod = purgePeriod; + } + + + /** + * @deprecated + * @param balancers the balancers to set + */ + public void setBalancers(String balancers) { + this.balancers = balancers; + } + + public boolean addSipConnector(SipConnector sipConnector) throws Exception { + if(sipConnector == null) { + throw new IllegalArgumentException("The sip connector passed is null"); + } + Connector connectorToAdd = findSipConnector(sipConnector.getIpAddress(), sipConnector.getPort(), + sipConnector.getTransport()); + if(connectorToAdd == null) { + Connector connector = new Connector( + SipProtocolHandler.class.getName()); + SipProtocolHandler sipProtocolHandler = (SipProtocolHandler) connector + .getProtocolHandler(); + sipProtocolHandler.setSipConnector(sipConnector); + sipProtocolHandler.setSipStack(sipStack); + connector.setService(this); +//TODO connector.setContainer(container); + connector.init(); + addConnector(connector); + MobicentsExtendedListeningPoint extendedListeningPoint = (MobicentsExtendedListeningPoint) + sipProtocolHandler.getAttribute(ExtendedListeningPoint.class.getSimpleName()); + if(extendedListeningPoint != null) { + try { + extendedListeningPoint.getSipProvider().addSipListener(sipApplicationDispatcher); + sipApplicationDispatcher.getSipNetworkInterfaceManager().addExtendedListeningPoint(extendedListeningPoint); + } catch (TooManyListenersException e) { + logger.error("Connector.initialize", e); + removeConnector(connector); + return false; + } + } + if(!sipProtocolHandler.isStarted()) { + if(logger.isDebugEnabled()) { + logger.debug("Sip Connector couldn't be started, removing it automatically"); + } + removeConnector(connector); + } + return sipProtocolHandler.isStarted(); + } + return false; + } + + public boolean removeSipConnector(String ipAddress, int port, String transport) throws Exception { + Connector connectorToRemove = findSipConnector(ipAddress, port, + transport); + if(connectorToRemove != null) { + removeConnector(connectorToRemove); + return true; + } + return false; + } + + + /** + * Find a sip Connector by it's ip address, port and transport + * @param ipAddress ip address of the connector to find + * @param port port of the connector to find + * @param transport transport of the connector to find + * @return the found sip connector or null if noting found + */ + private Connector findSipConnector(String ipAddress, int port, + String transport) { + Connector connectorToRemove = null; + for (Connector connector : connectors) { + final ProtocolHandler protocolHandler = connector.getProtocolHandler(); + if(protocolHandler instanceof SipProtocolHandler) { + final SipProtocolHandler sipProtocolHandler = (SipProtocolHandler) protocolHandler; + if(sipProtocolHandler.getIpAddress().equals(ipAddress) && sipProtocolHandler.getPort() == port && sipProtocolHandler.getSignalingTransport().equalsIgnoreCase(transport)) { +// connector.destroy(); + connectorToRemove = connector; + break; + } + } + } + return connectorToRemove; + } + + public SipConnector findSipConnector(String transport) { + List sipConnectors = new ArrayList(); + for (Connector connector : connectors) { + final ProtocolHandler protocolHandler = connector.getProtocolHandler(); + if(protocolHandler instanceof SipProtocolHandler) { + SipConnector sc = (((SipProtocolHandler)protocolHandler).getSipConnector()); + if(sc.getTransport().equalsIgnoreCase(transport)) return sc; + } + } + return null; + } + + public SipConnector[] findSipConnectors() { + List sipConnectors = new ArrayList(); + for (Connector connector : connectors) { + final ProtocolHandler protocolHandler = connector.getProtocolHandler(); + if(protocolHandler instanceof SipProtocolHandler) { + sipConnectors.add(((SipProtocolHandler)protocolHandler).getSipConnector()); + } + } + return sipConnectors.toArray(new SipConnector[sipConnectors.size()]); + } + + /** + * This method simply makes the HTTP and SSL ports avaialble everywhere in the JVM in order jsip ha to read them for + * balancer description purposes. There is no other good way to communicate the properies to jsip ha without adding + * more dependencies. + */ + public void initializeSystemPortProperties() { + for (Connector connector : connectors) { + if(connector.getProtocol().contains("HTTP")) { + if(connector.getSecure()) { + System.setProperty("org.mobicents.properties.sslPort", Integer.toString(connector.getPort())); + } else { + System.setProperty("org.mobicents.properties.httpPort", Integer.toString(connector.getPort())); + } + } + } + } + + protected ObjectName createSipConnectorObjectName(Connector connector, String domain, String type) + throws MalformedObjectNameException { + String encodedAddr = null; + if (connector.getProperty("address") != null) { + encodedAddr = URLEncoder.encode(connector.getProperty("address").toString()); + } + String addSuffix = (connector.getProperty("address") == null) ? "" : ",address=" + + encodedAddr; + ObjectName _oname = new ObjectName(domain + ":type=" + type + ",port=" + + connector.getPort() + ",transport=" + connector.getProperty("transport") + addSuffix); + return _oname; + } + + + /** + * @param t2Interval the t2Interval to set + */ + public void setT2Interval(int t2Interval) { + this.t2Interval = t2Interval; + } + + + /** + * @return the t2Interval + */ + public int getT2Interval() { + return t2Interval; + } + + + /** + * @param t4Interval the t4Interval to set + */ + public void setT4Interval(int t4Interval) { + this.t4Interval = t4Interval; + } + + + /** + * @return the t4Interval + */ + public int getT4Interval() { + return t4Interval; + } + + + /** + * @param timerDInterval the timerDInterval to set + */ + public void setTimerDInterval(int timerDInterval) { + this.timerDInterval = timerDInterval; + } + + + /** + * @return the timerDInterval + */ + public int getTimerDInterval() { + return timerDInterval; + } + + /** + * @param sipStackPropertiesFile the sipStackPropertiesFile to set + */ + public void setSipStackPropertiesFile(String sipStackPropertiesFile) { + sipStackPropertiesFileLocation = sipStackPropertiesFile; + } + + /** + * @return the sipStackProperties + */ + public Properties getSipStackProperties() { + return sipStackProperties; + } + + /** + * @param sipStackProperties the sipStackProperties to set + */ + public void setSipStackProperties(Properties sipStackProperties) { + this.sipStackProperties = sipStackProperties; + } + + /** + * @return the sipStackPropertiesFile + */ + public String getSipStackPropertiesFile() { + return sipStackPropertiesFileLocation; + } + + /** + * @param dnsAddressResolverClass the dnsAddressResolverClass to set + */ + @Deprecated + public void setAddressResolverClass(String dnsAddressResolverClass) { + this.addressResolverClass = dnsAddressResolverClass; + } + + /** + * @return the dnsAddressResolverClass + */ + @Deprecated + public String getAddressResolverClass() { + return addressResolverClass; + } + + /** + * Whether we check for pending requests and return 491 response if there are any + * + * @return the flag value + */ + public boolean isDialogPendingRequestChecking() { + return dialogPendingRequestChecking; + } + + /** + * + * Whether we check for pending requests and return 491 response if there are any + * + * @param dialogPendingRequestChecking + */ + public void setDialogPendingRequestChecking(boolean dialogPendingRequestChecking) { + this.dialogPendingRequestChecking = dialogPendingRequestChecking; + } + + + public boolean isHttpFollowsSip() { + return httpFollowsSip; + } + + + public void setHttpFollowsSip(boolean httpFollowsSip) { + this.httpFollowsSip = httpFollowsSip; + } + + /** + * @return the tagHashMaxLength + */ + public int getTagHashMaxLength() { + return tagHashMaxLength; + } + + /** + * @param tagHashMaxLength the tagHashMaxLength to set + */ + public void setTagHashMaxLength(int tagHashMaxLength) { + this.tagHashMaxLength = tagHashMaxLength; + } + + /** + * @return the callIdMaxLength + */ + public int getCallIdMaxLength() { + return callIdMaxLength; + } + + /** + * @param callIdMaxLength the callIdMaxLength to set + */ + public void setCallIdMaxLength(int callIdMaxLength) { + this.callIdMaxLength = callIdMaxLength; + } + + /** + * @return the sipStack + */ + public SipStack getSipStack() { + return sipStack; + } + + /** + * @param dnsServerLocatorClass the dnsServerLocatorClass to set + */ + public void setDnsServerLocatorClass(String dnsServerLocatorClass) { + this.dnsServerLocatorClass = dnsServerLocatorClass; + } + + /** + * @return the dnsServerLocatorClass + */ + public String getDnsServerLocatorClass() { + return dnsServerLocatorClass; + } + + /** + * @param dnsResolverClass the dnsResolverClass to set + */ + public void setDnsResolverClass(String dnsResolverClass) { + this.dnsResolverClass = dnsResolverClass; + } + + /** + * @return the dnsResolverClass + */ + public String getDnsResolverClass() { + return dnsResolverClass; + } + + /** + * Returns first the catalina.base if it is defined then the catalina.home if it is defined + * then the current dir if none is specified + */ + protected String getCatalinaBase() { + String catalinaBase = System.getProperty("catalina.base"); + if (catalinaBase == null) { + catalinaBase = System.getProperty("catalina.home"); + } + if(catalinaBase == null) { + catalinaBase = "."; + } + return catalinaBase; + } + + public ReplicationStrategy getReplicationStrategy() { + return replicationStrategy; + } + + @Override + public String getMobicentsSipServletMessageFactoryClassName() { + return mobicentsSipServletMessageFactoryClassName; + } + + @Override + public void setMobicentsSipServletMessageFactoryClassName( + String mobicentsSipServletMessageFactoryClassName) { + this.mobicentsSipServletMessageFactoryClassName = mobicentsSipServletMessageFactoryClassName; + } + + public void sendHeartBeat(String localAddress, int localPort, String transport, String remoteIpAddress, int remotePort) throws IOException { + MobicentsExtendedListeningPoint extendedListeningPoint = sipApplicationDispatcher.getSipNetworkInterfaceManager().findMatchingListeningPoint(localAddress, localPort, transport); + if(extendedListeningPoint != null) { + extendedListeningPoint.getListeningPoint().sendHeartbeat(remoteIpAddress, remotePort); + } + } + + public boolean setKeepAliveTimeout(SipConnector sipConnector, String clientAddress, int clientPort, long timeout) { + SIPTransactionStack sipStack = ((SIPTransactionStack) sipApplicationDispatcher.getSipStack()); + + return sipStack.setKeepAliveTimeout(sipConnector.getIpAddress(), sipConnector.getPort(), sipConnector.getTransport(), + clientAddress, clientPort, timeout); + } + + public void closeReliableConnection(SipConnector sipConnector, String clientAddress, int clientPort) { + SIPTransactionStack sipStack = ((SIPTransactionStack) sipApplicationDispatcher.getSipStack()); + + sipStack.closeReliableConnection(sipConnector.getIpAddress(),sipConnector.getPort(), sipConnector.getTransport(), + clientAddress, clientPort); + } + + /* + * (non-Javadoc) + * @see org.mobicents.servlet.sip.core.SipService#stopGracefully(long) + */ + public void stopGracefully(long timeToWait) { + if(logger.isInfoEnabled()) { + logger.info("Stopping the Server Gracefully in " + timeToWait + " ms"); + } + if(timeToWait == 0) { + if(gracefulStopFuture != null) { + gracefulStopFuture.cancel(false); + } + try { + getServer().stop(); + } catch (LifecycleException e) { + logger.error("The server couldn't be stopped", e); + } + } else { + sipApplicationDispatcher.setGracefulShutdown(true); + Iterator sipContexts = sipApplicationDispatcher.findSipApplications(); + while (sipContexts.hasNext()) { + SipContext sipContext = sipContexts.next(); + sipContext.setGracefulInterval(gracefulInterval); + sipContext.stopGracefully(timeToWait); + } + gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().scheduleWithFixedDelay(new ServiceGracefulStopTask(this), 30000, 30000, TimeUnit.MILLISECONDS); + if(timeToWait > 0) { + gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().schedule( + new Runnable() { + public void run() { + gracefulStopFuture.cancel(false); + try { + getServer().stop(); + } catch (LifecycleException e) { + logger.error("The server couldn't be stopped", e); + } + } + } + , timeToWait, TimeUnit.MILLISECONDS); + } + } + } + + /** + * @return the dnsTimeout + */ + public int getDnsTimeout() { + return dnsTimeout; + } + + /** + * @param dnsTimeout the dnsTimeout to set + */ + public void setDnsTimeout(int dnsTimeout) { + this.dnsTimeout = dnsTimeout; + } + + public String getProxyTimerServiceImplementationType() { + return proxyTimerServiceImplementationType; + } + + public void setProxyTimerServiceImplementationType(String proxyTimerServiceImplementationType) { + this.proxyTimerServiceImplementationType = proxyTimerServiceImplementationType; + } + + public String getSasTimerServiceImplementationType() { + return sasTimerServiceImplementationType; + } + + public void setSasTimerServiceImplementationType(String sasTimerServiceImplementationType) { + this.sasTimerServiceImplementationType = sasTimerServiceImplementationType; + } + + public void setGracefulInterval(long gracefulStopTaskInterval) { + this.gracefulInterval = gracefulStopTaskInterval; + } +} diff --git a/containers/sip-servlets-catalina-8/src/main/java/org/mobicents/servlet/sip/catalina/ContextGracefulStopTask.java b/containers/sip-servlets-catalina-8/src/main/java/org/mobicents/servlet/sip/catalina/ContextGracefulStopTask.java index 1d854e838e..8561bc961a 100644 --- a/containers/sip-servlets-catalina-8/src/main/java/org/mobicents/servlet/sip/catalina/ContextGracefulStopTask.java +++ b/containers/sip-servlets-catalina-8/src/main/java/org/mobicents/servlet/sip/catalina/ContextGracefulStopTask.java @@ -22,9 +22,10 @@ package org.mobicents.servlet.sip.catalina; import org.apache.catalina.Context; -import org.apache.catalina.LifecycleException; import org.apache.catalina.core.StandardContext; import org.apache.log4j.Logger; +import org.mobicents.javax.servlet.ContainerListener; +import org.mobicents.javax.servlet.GracefulShutdownCheckEvent; import org.mobicents.servlet.sip.core.SipContext; /** @@ -43,24 +44,55 @@ public ContextGracefulStopTask(Context context, long timeToWait) { startTime = System.currentTimeMillis(); } - public void run() { - int numberOfActiveSipApplicationSessions = ((SipContext)sipContext).getSipManager().getActiveSipApplicationSessions(); - int numberOfActiveHttpSessions = sipContext.getManager().getActiveSessions(); - if(logger.isTraceEnabled()) { - logger.trace("ContextGracefulStopTask running for context " + sipContext.getName() + ", number of Sip Application Sessions still active " + numberOfActiveSipApplicationSessions + " number of HTTP Sessions still active " + numberOfActiveHttpSessions); - } - boolean stopPrematuraly = false; - long currentTime = System.currentTimeMillis(); - // if timeToWait is positive, then we check the time since the task started, if the time is greater than timeToWait we can safely stop the context - if(timeToWait > 0 && ((currentTime - startTime) > timeToWait)) { - stopPrematuraly = true; - } - if((numberOfActiveSipApplicationSessions <= 0 && numberOfActiveHttpSessions <= 0) || stopPrematuraly) { - try { - ((StandardContext)sipContext).stop(); - } catch (LifecycleException e) { - logger.error("Couldn't gracefully stop context " + sipContext.getName(), e); - } - } - } -} + private static final String PREVENT_PREMATURE_SHUTDOWN = "org.mobicents.servlet.sip.PREVENT_PREMATURE_SHUTDOWN"; + + @Override + public void run() { + int numberOfActiveSipApplicationSessions = ((SipContext) sipContext).getSipManager().getActiveSipApplicationSessions(); + int numberOfActiveHttpSessions = sipContext.getManager().getActiveSessions(); + if (logger.isTraceEnabled()) { + logger.trace("ContextGracefulStopTask running for context " + sipContext.getName() + ", number of Sip Application Sessions still active " + numberOfActiveSipApplicationSessions + " number of HTTP Sessions still active " + numberOfActiveHttpSessions); + } + + boolean stopPrematuraly = false; + long currentTime = System.currentTimeMillis(); + // if timeToWait is positive, then we check the time since the task started, if the time is greater than timeToWait we can safely stop the context + long elapsedTime = currentTime - startTime; + if (timeToWait > 0 && (elapsedTime > timeToWait)) { + logger.info("Graceful TimeToWait Consumed."); + stopContext(); + } + if (logger.isDebugEnabled()) { + logger.debug("ContextGracefulStopTask running for context " + sipContext.getName() + + ", number of Sip Application Sessions still active " + numberOfActiveSipApplicationSessions + + " number of HTTP Sessions still active " + numberOfActiveHttpSessions + + ", stopPrematurely " + stopPrematuraly); + } + if (numberOfActiveSipApplicationSessions <= 0 + && numberOfActiveHttpSessions <= 0) { + logger.info("No more active sessions, lets check with service"); + boolean servicePremature = true; + ContainerListener containerListener = ((SipContext) sipContext).getListeners().getContainerListener(); + if (containerListener != null) { + GracefulShutdownCheckEvent event = new GracefulShutdownCheckEvent(elapsedTime, timeToWait); + ((SipContext) sipContext).getListeners().callbackContainerListener(event); + servicePremature = sipContext.getServletContext().getAttribute(PREVENT_PREMATURE_SHUTDOWN) == null; + logger.info("servicePremature=" + servicePremature); + } + if (servicePremature) { + stopContext(); + } + + } + } + + private void stopContext() { + try { + logger.info("About to stop the context."); + ((StandardContext) sipContext).stop(); + } catch (Exception e) { + logger.error("Couldn't gracefully stop context " + sipContext.getName(), e); + } + } + +} \ No newline at end of file diff --git a/containers/sip-servlets-catalina-8/src/main/java/org/mobicents/servlet/sip/catalina/SipStandardService.java b/containers/sip-servlets-catalina-8/src/main/java/org/mobicents/servlet/sip/catalina/SipStandardService.java index ca6e7aa243..a2736e9daa 100644 --- a/containers/sip-servlets-catalina-8/src/main/java/org/mobicents/servlet/sip/catalina/SipStandardService.java +++ b/containers/sip-servlets-catalina-8/src/main/java/org/mobicents/servlet/sip/catalina/SipStandardService.java @@ -1,1401 +1,1412 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.catalina; - - -import gov.nist.core.net.AddressResolver; -import gov.nist.javax.sip.SipStackExt; -import gov.nist.javax.sip.message.MessageFactoryExt; -import gov.nist.javax.sip.stack.SIPTransactionStack; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.lang.reflect.Constructor; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Properties; -import java.util.StringTokenizer; -import java.util.TooManyListenersException; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; - -import javax.management.MalformedObjectNameException; -import javax.management.ObjectName; -import javax.sip.SipStack; -import javax.sip.header.ServerHeader; -import javax.sip.header.UserAgentHeader; - -import org.apache.catalina.Engine; -import org.apache.catalina.LifecycleException; -import org.apache.catalina.connector.Connector; -import org.apache.catalina.core.StandardService; -import org.apache.coyote.ProtocolHandler; -import org.apache.log4j.Logger; -import org.apache.tomcat.util.modeler.Registry; -import org.mobicents.ext.javax.sip.dns.DNSAwareRouter; -import org.mobicents.ext.javax.sip.dns.DNSServerLocator; -import org.mobicents.ext.javax.sip.dns.DefaultDNSServerLocator; -import org.mobicents.ha.javax.sip.ClusteredSipStack; -import org.mobicents.ha.javax.sip.LoadBalancerHeartBeatingListener; -import org.mobicents.ha.javax.sip.LoadBalancerHeartBeatingService; -import org.mobicents.ha.javax.sip.LoadBalancerHeartBeatingServiceImpl; -import org.mobicents.ha.javax.sip.ReplicationStrategy; -import org.mobicents.javax.servlet.CongestionControlPolicy; -import org.mobicents.servlet.sip.JainSipUtils; -import org.mobicents.servlet.sip.SipConnector; -import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; -import org.mobicents.servlet.sip.core.ExtendedListeningPoint; -import org.mobicents.servlet.sip.core.MobicentsExtendedListeningPoint; -import org.mobicents.servlet.sip.core.SipApplicationDispatcher; -import org.mobicents.servlet.sip.core.SipContext; -import org.mobicents.servlet.sip.core.message.OutboundProxy; -import org.mobicents.servlet.sip.dns.MobicentsDNSResolver; -import org.mobicents.servlet.sip.message.Servlet3SipServletMessageFactory; -import org.mobicents.servlet.sip.startup.StaticServiceHolder; - -/** - * Sip Servlet implementation of the SipService interface. - * This class inherits from the Tomcat StandardService. It adds a SipApplicationDispatcher - * that will be listen for sip messages received by the sip stacks started by - * the sip connectors associated with this context. - * This has one attribute which is the sipApplicationDispatcherClassName allowing one - * to specify the class name of the sipApplicationDispacther to easily replace - * the default sipApplicationDispatcher with a custom one. - * - * @author Jean Deruelle - */ -public class SipStandardService extends StandardService implements CatalinaSipService { - //the logger - private static final Logger logger = Logger.getLogger(SipStandardService.class); - public static final String DEFAULT_SIP_PATH_NAME = "gov.nist"; - public static final String PASS_INVITE_NON_2XX_ACK_TO_LISTENER = "gov.nist.javax.sip.PASS_INVITE_NON_2XX_ACK_TO_LISTENER"; - public static final String TCP_POST_PARSING_THREAD_POOL_SIZE = "gov.nist.javax.sip.TCP_POST_PARSING_THREAD_POOL_SIZE"; - public static final String AUTOMATIC_DIALOG_SUPPORT_STACK_PROP = "javax.sip.AUTOMATIC_DIALOG_SUPPORT"; - public static final String LOOSE_DIALOG_VALIDATION = "gov.nist.javax.sip.LOOSE_DIALOG_VALIDATION"; - public static final String SERVER_LOG_STACK_PROP = "gov.nist.javax.sip.SERVER_LOG"; - public static final String DEBUG_LOG_STACK_PROP = "gov.nist.javax.sip.DEBUG_LOG"; - public static final String SERVER_HEADER = "org.mobicents.servlet.sip.SERVER_HEADER"; - public static final String USER_AGENT_HEADER = "org.mobicents.servlet.sip.USER_AGENT_HEADER"; - public static final String JVM_ROUTE = "jvmRoute"; - /** - * The descriptive information string for this implementation. - */ - private static final String INFO = - "org.mobicents.servlet.sip.startup.SipStandardService/1.0"; - //the sip application dispatcher class name defined in the server.xml - protected String sipApplicationDispatcherClassName; - //instatiated class from the sipApplicationDispatcherClassName of the sip application dispatcher - protected SipApplicationDispatcher sipApplicationDispatcher; - private boolean gatherStatistics = true; - protected int sipMessageQueueSize = 1500; - private int backToNormalSipMessageQueueSize = 1300; - protected int memoryThreshold = 95; - private int backToNormalMemoryThreshold = 90; - protected OutboundProxy outboundProxy; - protected String proxyTimerServiceImplementationType; - protected String sasTimerServiceImplementationType; - protected long congestionControlCheckingInterval = 30000; - private int canceledTimerTasksPurgePeriod = 0; - // base timer interval for jain sip tx - private int baseTimerInterval = 500; - private int t2Interval = 4000; - private int t4Interval = 5000; - private int timerDInterval = 32000; - protected int dispatcherThreadPoolSize = 15; - private boolean md5ContactUserPart = false; - - protected String concurrencyControlMode = ConcurrencyControlMode.SipApplicationSession.toString(); - protected String congestionControlPolicy = CongestionControlPolicy.ErrorResponse.toString(); - protected String additionalParameterableHeaders; - protected boolean bypassResponseExecutor = true; - protected boolean bypassRequestExecutor = true; - //this should be made available to the application router as a system prop - protected String darConfigurationFileLocation; - protected boolean connectorsStartedExternally = false; - protected boolean dialogPendingRequestChecking = false; - protected int callIdMaxLength; - protected int tagHashMaxLength; - - protected boolean httpFollowsSip = false; - protected String jvmRoute; - protected ReplicationStrategy replicationStrategy; - - /** - * the sip stack path name. Since the sip factory is per classloader it should be set here for all underlying stacks - */ - private String sipPathName; - /** - * use Pretty Encoding - */ - private boolean usePrettyEncoding = true; - - private SipStack sipStack; - // defining sip stack properties - private Properties sipStackProperties; - private String sipStackPropertiesFileLocation; - @Deprecated - private String addressResolverClass = null; - private String dnsServerLocatorClass = DefaultDNSServerLocator.class.getName(); - private int dnsTimeout = 1; - private String dnsResolverClass = MobicentsDNSResolver.class.getName(); - private String mobicentsSipServletMessageFactoryClassName = Servlet3SipServletMessageFactory.class.getName(); - - //the balancers to send heartbeat to and our health info - @Deprecated - private String balancers; - // - private ScheduledFuture gracefulStopFuture; - - @Override - public void addConnector(Connector connector) { - MobicentsExtendedListeningPoint extendedListeningPoint = null; - if (connector.getProtocolHandler() instanceof SipProtocolHandler) { - extendedListeningPoint = (MobicentsExtendedListeningPoint) - ((SipProtocolHandler)connector.getProtocolHandler()).getAttribute(ExtendedListeningPoint.class.getSimpleName());} - if(extendedListeningPoint != null) { - try { - extendedListeningPoint.getSipProvider().addSipListener(sipApplicationDispatcher); - sipApplicationDispatcher.getSipNetworkInterfaceManager().addExtendedListeningPoint(extendedListeningPoint); - } catch (TooManyListenersException e) { - logger.error("Connector.initialize", e); - } - } - ProtocolHandler protocolHandler = connector.getProtocolHandler(); - if(protocolHandler instanceof SipProtocolHandler) { - connector.setPort(((SipProtocolHandler)protocolHandler).getPort()); - ((SipProtocolHandler)protocolHandler).setSipStack(sipStack); - ((SipProtocolHandler)protocolHandler).setAttribute(SipApplicationDispatcher.class.getSimpleName(), sipApplicationDispatcher); - registerSipConnector(connector); - } - super.addConnector(connector); - } - - /** - * Register the sip connector under a different name than HTTP Connector and we add the transport to avoid clashing with 2 connectors having the same port and address - * @param connector connector to register - */ - protected void registerSipConnector(Connector connector) { - try { - - ObjectName objectName = createSipConnectorObjectName(connector, getName(), "SipConnector"); - Registry.getRegistry(null, null) - .registerComponent(connector, objectName, null); -//TODO connector.setController(objectName); - } catch (Exception e) { - logger.error( "Error registering connector ", e); - } - if(logger.isDebugEnabled()) - logger.debug("Creating name for connector " + getObjectName()); - } - - @Override - public void removeConnector(Connector connector) { - MobicentsExtendedListeningPoint extendedListeningPoint = null; - if (connector.getProtocolHandler() instanceof SipProtocolHandler){ - extendedListeningPoint = (MobicentsExtendedListeningPoint) - ((SipProtocolHandler)connector.getProtocolHandler()).getAttribute(ExtendedListeningPoint.class.getSimpleName());} - if(extendedListeningPoint != null) { - extendedListeningPoint.getSipProvider().removeSipListener(sipApplicationDispatcher); - sipApplicationDispatcher.getSipNetworkInterfaceManager().removeExtendedListeningPoint(extendedListeningPoint); - } - super.removeConnector(connector); - } - - @Override - public void initInternal() throws LifecycleException { - //load the sip application disptacher from the class name specified in the server.xml file - //and initializes it - StaticServiceHolder.sipStandardService = this; - try { - sipApplicationDispatcher = (SipApplicationDispatcher) - Class.forName(sipApplicationDispatcherClassName).newInstance(); - } catch (InstantiationException e) { - throw new LifecycleException("Impossible to load the Sip Application Dispatcher",e); - } catch (IllegalAccessException e) { - throw new LifecycleException("Impossible to load the Sip Application Dispatcher",e); - } catch (ClassNotFoundException e) { - throw new LifecycleException("Impossible to load the Sip Application Dispatcher",e); - } catch (ClassCastException e) { - throw new LifecycleException("Sip Application Dispatcher defined does not implement " + SipApplicationDispatcher.class.getName(),e); - } - if(logger.isInfoEnabled()) { - logger.info("Pretty encoding of headers enabled ? " + usePrettyEncoding); - } - if(sipPathName == null) { - sipPathName = DEFAULT_SIP_PATH_NAME; - } - if(logger.isInfoEnabled()) { - logger.info("Sip Stack path name : " + sipPathName); - } - sipApplicationDispatcher.setSipService(this); - sipApplicationDispatcher.getSipFactory().initialize(sipPathName, usePrettyEncoding); - - String catalinaBase = getCatalinaBase(); - if(darConfigurationFileLocation != null) { - if(!darConfigurationFileLocation.startsWith("file:///")) { - darConfigurationFileLocation = "file:///" + catalinaBase.replace(File.separatorChar, '/') + "/" + darConfigurationFileLocation; - } - System.setProperty("javax.servlet.sip.dar", darConfigurationFileLocation); - } - super.initInternal(); - sipApplicationDispatcher.setDomain(this.getName()); - if(baseTimerInterval < 1) { - throw new LifecycleException("It's forbidden to set the Base Timer Interval to a non positive value"); - } - initSipStack(); - // https://telestax.atlassian.net/browse/MSS-148 make sure we have a default to bin direction for better out of the box experience - if(System.getProperty("telscale.license.dir") == null) { - System.setProperty("telscale.license.dir", getCatalinaBase() + File.separatorChar + "bin"); - if(logger.isDebugEnabled()) { - logger.debug("Setting telscale.license.dir directory to : " + getCatalinaBase() + File.separatorChar + "bin"); - } - } - if(System.getProperty("telscale.license.key.location") == null) { - System.setProperty("telscale.license.key.location", getCatalinaBase() + File.separatorChar + "bin"); - if(logger.isDebugEnabled()) { - logger.debug("Setting telscale.license.key.location directory to : " + getCatalinaBase() + File.separatorChar + "bin"); - } - } - - sipApplicationDispatcher.setBaseTimerInterval(baseTimerInterval); - sipApplicationDispatcher.setT2Interval(t2Interval); - sipApplicationDispatcher.setT4Interval(t4Interval); - sipApplicationDispatcher.setTimerDInterval(timerDInterval); - sipApplicationDispatcher.setMemoryThreshold(getMemoryThreshold()); - sipApplicationDispatcher.setBackToNormalMemoryThreshold(backToNormalMemoryThreshold); - sipApplicationDispatcher.setCongestionControlCheckingInterval(getCongestionControlCheckingInterval()); - sipApplicationDispatcher.setCongestionControlPolicyByName(getCongestionControlPolicy()); - sipApplicationDispatcher.setQueueSize(getSipMessageQueueSize()); - sipApplicationDispatcher.setBackToNormalQueueSize(backToNormalSipMessageQueueSize); - sipApplicationDispatcher.setGatherStatistics(gatherStatistics); - sipApplicationDispatcher.setConcurrencyControlMode(ConcurrencyControlMode.valueOf(getConcurrencyControlMode())); - sipApplicationDispatcher.setBypassRequestExecutor(bypassRequestExecutor); - sipApplicationDispatcher.setBypassResponseExecutor(bypassResponseExecutor); - sipApplicationDispatcher.setSipStack(sipStack); - sipApplicationDispatcher.init(); - // Tomcat specific loading case where the connectors are added even before the service is initialized - // so we need to set the sip stack before it starts - synchronized (connectors) { - for (Connector connector : connectors) { - ProtocolHandler protocolHandler = connector.getProtocolHandler(); - if(protocolHandler instanceof SipProtocolHandler) { - connector.setPort(((SipProtocolHandler)protocolHandler).getPort()); - ((SipProtocolHandler)protocolHandler).setSipStack(sipStack); - ((SipProtocolHandler)protocolHandler).setAttribute(SipApplicationDispatcher.class.getSimpleName(), sipApplicationDispatcher); - registerSipConnector(connector); - } - } - } - } - - @Override - public void startInternal() throws LifecycleException { - super.startInternal(); - synchronized (connectors) { - for (Connector connector : connectors) { - final ProtocolHandler protocolHandler = connector.getProtocolHandler(); - //Jboss sepcific loading case - Boolean isSipConnector = false; - if (protocolHandler instanceof SipProtocolHandler) - isSipConnector = (Boolean) ((SipProtocolHandler)protocolHandler).getAttribute(SipProtocolHandler.IS_SIP_CONNECTOR); - if(isSipConnector != null && isSipConnector) { - if(logger.isDebugEnabled()) { - logger.debug("Attaching the sip application dispatcher " + - "as a sip listener to connector listening on port " + - connector.getPort()); - } - ((SipProtocolHandler)protocolHandler).setAttribute(SipApplicationDispatcher.class.getSimpleName(), sipApplicationDispatcher); - ((SipProtocolHandler)protocolHandler).setSipStack(sipStack); - connectorsStartedExternally = true; - } - //Tomcat specific loading case - MobicentsExtendedListeningPoint extendedListeningPoint = null; - if (protocolHandler instanceof SipProtocolHandler) { - extendedListeningPoint = (MobicentsExtendedListeningPoint) - ((SipProtocolHandler)protocolHandler).getAttribute(ExtendedListeningPoint.class.getSimpleName());} - if(extendedListeningPoint != null && sipStack != null) { - try { - extendedListeningPoint.getSipProvider().addSipListener(sipApplicationDispatcher); - sipApplicationDispatcher.getSipNetworkInterfaceManager().addExtendedListeningPoint(extendedListeningPoint); - connectorsStartedExternally = false; - } catch (TooManyListenersException e) { - throw new LifecycleException("Couldn't add the sip application dispatcher " - + sipApplicationDispatcher + " as a listener to the following listening point provider " + extendedListeningPoint, e); - } - } - } - } - if(!connectorsStartedExternally) { - sipApplicationDispatcher.start(); - } - - if(this.getSipMessageQueueSize() <= 0) - throw new LifecycleException("Message queue size can not be 0 or less"); - - if(logger.isDebugEnabled()) { - logger.debug("SIP Standard Service Started."); - } - } - - public String getJvmRoute() { - return this.jvmRoute; - } - - public void setJvmRoute(String jvmRoute) { - this.jvmRoute = jvmRoute; - } - - protected void initSipStack() throws LifecycleException { - try { - if(logger.isDebugEnabled()) { - logger.debug("Initializing SIP stack"); - } - - // This simply puts HTTP and SSL port numbers in JVM properties menat to be read by jsip ha when sending heart beats with Node description. - initializeSystemPortProperties(); - - String catalinaBase = getCatalinaBase(); - if(sipStackPropertiesFileLocation != null && !sipStackPropertiesFileLocation.startsWith("file:///")) { - sipStackPropertiesFileLocation = "file:///" + catalinaBase.replace(File.separatorChar, '/') + "/" + sipStackPropertiesFileLocation; - } - boolean isPropsLoaded = false; - if(sipStackProperties == null) { - sipStackProperties = new Properties(); - } else { - isPropsLoaded = true; - } - - if (logger.isDebugEnabled()) { - logger.debug("Loading SIP stack properties from following file : " + sipStackPropertiesFileLocation); - } - if(sipStackPropertiesFileLocation != null) { - //hack to get around space char in path see http://weblogs.java.net/blog/kohsuke/archive/2007/04/how_to_convert.html, - // we create a URL since it's permissive enough - File sipStackPropertiesFile = null; - URL url = null; - try { - url = new URL(sipStackPropertiesFileLocation); - } catch (MalformedURLException e) { - logger.fatal("Cannot find the sip stack properties file ! ",e); - throw new IllegalArgumentException("The Default Application Router file Location : "+sipStackPropertiesFileLocation+" is not valid ! ",e); - } - try { - sipStackPropertiesFile = new File(new URI(sipStackPropertiesFileLocation)); - } catch (URISyntaxException e) { - //if the uri contains space this will fail, so getting the path will work - sipStackPropertiesFile = new File(url.getPath()); - } - FileInputStream sipStackPropertiesInputStream = null; - try { - sipStackPropertiesInputStream = new FileInputStream(sipStackPropertiesFile); - sipStackProperties.load(sipStackPropertiesInputStream); - } catch (Exception e) { - logger.warn("Could not find or problem when loading the sip stack properties file : " + sipStackPropertiesFileLocation, e); - } finally { - if(sipStackPropertiesInputStream != null) { - try { - sipStackPropertiesInputStream.close(); - } catch (IOException e) { - logger.error("fail to close the following file " + sipStackPropertiesFile.getAbsolutePath(), e); - } - } - } - - String debugLog = sipStackProperties.getProperty(DEBUG_LOG_STACK_PROP); - if(debugLog != null && debugLog.length() > 0 && !debugLog.startsWith("file:///")) { - sipStackProperties.setProperty(DEBUG_LOG_STACK_PROP, - catalinaBase + "/" + debugLog); - } - String serverLog = sipStackProperties.getProperty(SERVER_LOG_STACK_PROP); - if(serverLog != null && serverLog.length() > 0 && !serverLog.startsWith("file:///")) { - sipStackProperties.setProperty(SERVER_LOG_STACK_PROP, - catalinaBase + "/" + serverLog); - } - // The whole MSS is built upon those assumptions, so those properties are not overrideable - if (sipStackProperties.getProperty(AUTOMATIC_DIALOG_SUPPORT_STACK_PROP) == null) { - //https://github.com/RestComm/sip-servlets/issues/143 - //set off if user didnt provided any value. - sipStackProperties.setProperty(AUTOMATIC_DIALOG_SUPPORT_STACK_PROP, "off"); - } - sipStackProperties.setProperty(LOOSE_DIALOG_VALIDATION, "true"); - sipStackProperties.setProperty(PASS_INVITE_NON_2XX_ACK_TO_LISTENER, "true"); - isPropsLoaded = true; - } else { - logger.warn("no sip stack properties file defined "); - } - if(!isPropsLoaded) { - logger.warn("loading default Mobicents Sip Servlets sip stack properties"); - // Silently set default values - sipStackProperties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", - "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", - "32"); - sipStackProperties.setProperty(DEBUG_LOG_STACK_PROP, - catalinaBase + "/" + "mss-jsip-" + getName() +"-debug.txt"); - sipStackProperties.setProperty(SERVER_LOG_STACK_PROP, - catalinaBase + "/" + "mss-jsip-" + getName() +"-messages.xml"); - sipStackProperties.setProperty("javax.sip.STACK_NAME", "mss-" + getName()); - sipStackProperties.setProperty(AUTOMATIC_DIALOG_SUPPORT_STACK_PROP, "off"); - sipStackProperties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.THREAD_POOL_SIZE", "64"); - sipStackProperties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.MAX_FORK_TIME_SECONDS", "0"); - sipStackProperties.setProperty(LOOSE_DIALOG_VALIDATION, "true"); - sipStackProperties.setProperty(PASS_INVITE_NON_2XX_ACK_TO_LISTENER, "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.AUTOMATIC_DIALOG_ERROR_HANDLING", "false"); - sipStackProperties.setProperty("gov.nist.javax.sip.AGGRESSIVE_CLEANUP", "true"); - } - - if(sipStackProperties.get(TCP_POST_PARSING_THREAD_POOL_SIZE) == null) { - sipStackProperties.setProperty(TCP_POST_PARSING_THREAD_POOL_SIZE, "30"); - } - - // set the DNSServerLocator allowing to support RFC 3263 and do DNS lookups to resolve uris - if(dnsServerLocatorClass != null && dnsServerLocatorClass.trim().length() > 0) { - if(logger.isDebugEnabled()) { - logger.debug("Sip Stack " + sipStackProperties.getProperty("javax.sip.STACK_NAME") +" will be using " + dnsServerLocatorClass + " as DNSServerLocator"); - } - try { - // create parameters argument to identify constructor - Class[] paramTypes = new Class[0]; - // get constructor of AddressResolver in order to instantiate - Constructor dnsServerLocatorConstructor = Class.forName(dnsServerLocatorClass).getConstructor( - paramTypes); - // Wrap properties object in order to pass to constructor of AddressResolver - Object[] conArgs = new Object[0]; - // Creates a new instance of AddressResolver Class with the supplied sipApplicationDispatcher. - DNSServerLocator dnsServerLocator = (DNSServerLocator) dnsServerLocatorConstructor.newInstance(conArgs); - sipApplicationDispatcher.setDNSServerLocator(dnsServerLocator); - sipApplicationDispatcher.setDNSTimeout(dnsTimeout); - if(sipStackProperties.getProperty("javax.sip.ROUTER_PATH") == null) { - sipStackProperties.setProperty("javax.sip.ROUTER_PATH", DNSAwareRouter.class.getCanonicalName()); - } - } catch (Exception e) { - logger.error("Couldn't set the AddressResolver " + addressResolverClass, e); - throw e; - } - } else { - if(logger.isInfoEnabled()) { - logger.info("no DNSServerLocator will be used since none has been specified."); - } - } - - String serverHeaderValue = sipStackProperties.getProperty(SERVER_HEADER); - if(serverHeaderValue != null) { - List serverHeaderList = new ArrayList(); - StringTokenizer stringTokenizer = new StringTokenizer(serverHeaderValue, ","); - while(stringTokenizer.hasMoreTokens()) { - serverHeaderList.add(stringTokenizer.nextToken()); - } - ServerHeader serverHeader = sipApplicationDispatcher.getSipFactory().getHeaderFactory().createServerHeader(serverHeaderList); - ((MessageFactoryExt)sipApplicationDispatcher.getSipFactory().getMessageFactory()).setDefaultServerHeader(serverHeader); - } - String userAgent = sipStackProperties.getProperty(USER_AGENT_HEADER); - if(userAgent != null) { - List userAgentList = new ArrayList(); - StringTokenizer stringTokenizer = new StringTokenizer(userAgent, ","); - while(stringTokenizer.hasMoreTokens()) { - userAgentList.add(stringTokenizer.nextToken()); - } - UserAgentHeader userAgentHeader = sipApplicationDispatcher.getSipFactory().getHeaderFactory().createUserAgentHeader(userAgentList); - ((MessageFactoryExt)sipApplicationDispatcher.getSipFactory().getMessageFactory()).setDefaultUserAgentHeader(userAgentHeader); - } - if(balancers != null) { - if(sipStackProperties.get(LoadBalancerHeartBeatingService.LB_HB_SERVICE_CLASS_NAME) == null) { - sipStackProperties.put(LoadBalancerHeartBeatingService.LB_HB_SERVICE_CLASS_NAME, LoadBalancerHeartBeatingServiceImpl.class.getCanonicalName()); - } - if(sipStackProperties.get(LoadBalancerHeartBeatingService.BALANCERS) == null) { - sipStackProperties.put(LoadBalancerHeartBeatingService.BALANCERS, balancers); - } - } - String replicationStrategyString = sipStackProperties.getProperty(ClusteredSipStack.REPLICATION_STRATEGY_PROPERTY); - if(replicationStrategyString == null) { - replicationStrategyString = ReplicationStrategy.ConfirmedDialog.toString(); - } - boolean replicateApplicationData = false; - if(replicationStrategyString.equals(ReplicationStrategy.EarlyDialog.toString())) { - replicateApplicationData = true; - } - if(replicationStrategyString != null) { - replicationStrategy = ReplicationStrategy.valueOf(replicationStrategyString); - } - sipStackProperties.put(ClusteredSipStack.REPLICATION_STRATEGY_PROPERTY, replicationStrategyString); - sipStackProperties.put(ClusteredSipStack.REPLICATE_APPLICATION_DATA, Boolean.valueOf(replicateApplicationData).toString()); - if(logger.isInfoEnabled()) { - logger.info("Mobicents Sip Servlets sip stack properties : " + sipStackProperties); - } - // Create SipStack object - sipStack = sipApplicationDispatcher.getSipFactory().getJainSipFactory().createSipStack(sipStackProperties); - LoadBalancerHeartBeatingService loadBalancerHeartBeatingService = null; - if(sipStack instanceof ClusteredSipStack) { - loadBalancerHeartBeatingService = ((ClusteredSipStack) sipStack).getLoadBalancerHeartBeatingService(); - if ((this.container != null) && (this.container instanceof Engine) && ((Engine)container).getJvmRoute() != null) { - final String jvmRoute = ((Engine)container).getJvmRoute(); - if(jvmRoute != null) { - loadBalancerHeartBeatingService.setJvmRoute(jvmRoute); - setJvmRoute(jvmRoute); - } - } - } - if(sipApplicationDispatcher != null && loadBalancerHeartBeatingService != null && sipApplicationDispatcher instanceof LoadBalancerHeartBeatingListener) { - loadBalancerHeartBeatingService.addLoadBalancerHeartBeatingListener((LoadBalancerHeartBeatingListener)sipApplicationDispatcher); - } - // for nist sip stack set the DNS Address resolver allowing to make DNS SRV lookups - if(sipStack instanceof SipStackExt && addressResolverClass != null && addressResolverClass.trim().length() > 0) { - if(logger.isDebugEnabled()) { - logger.debug("Sip Stack " + sipStack.getStackName() +" will be using " + addressResolverClass + " as AddressResolver"); - } - try { - // create parameters argument to identify constructor - Class[] paramTypes = new Class[1]; - paramTypes[0] = SipApplicationDispatcher.class; - // get constructor of AddressResolver in order to instantiate - Constructor addressResolverConstructor = Class.forName(addressResolverClass).getConstructor( - paramTypes); - // Wrap properties object in order to pass to constructor of AddressResolver - Object[] conArgs = new Object[1]; - conArgs[0] = sipApplicationDispatcher; - // Creates a new instance of AddressResolver Class with the supplied sipApplicationDispatcher. - AddressResolver addressResolver = (AddressResolver) addressResolverConstructor.newInstance(conArgs); - ((SipStackExt) sipStack).setAddressResolver(addressResolver); - } catch (Exception e) { - logger.error("Couldn't set the AddressResolver " + addressResolverClass, e); - throw e; - } - } else { - if(logger.isInfoEnabled()) { - logger.info("no AddressResolver will be used since none has been specified."); - } - } - if(logger.isInfoEnabled()) { - logger.info("SIP stack initialized"); - } - } catch (Exception ex) { - throw new LifecycleException("A problem occured while initializing the SIP Stack", ex); - } - } - - @Override - public void stopInternal() throws LifecycleException { - // on Tomcat 7 super.stop needs to be called before for Issue 1411 http://code.google.com/p/mobicents/issues/detail?id=1411 - super.stopInternal(); - // Tomcat specific unloading case - // Issue 1411 http://code.google.com/p/mobicents/issues/detail?id=1411 - // Sip Connectors should be removed after removing all Sip Servlets to allow them to send BYE to terminate cleanly - synchronized (connectors) { - for (Connector connector : connectors) { - MobicentsExtendedListeningPoint extendedListeningPoint = null; - if (connector.getProtocolHandler() instanceof SipProtocolHandler) { - extendedListeningPoint = (MobicentsExtendedListeningPoint) - ((SipProtocolHandler)connector.getProtocolHandler()).getAttribute(ExtendedListeningPoint.class.getSimpleName()); - } - if(extendedListeningPoint != null) { - extendedListeningPoint.getSipProvider().removeSipListener(sipApplicationDispatcher); - sipApplicationDispatcher.getSipNetworkInterfaceManager().removeExtendedListeningPoint(extendedListeningPoint); - } - } - } - if(!connectorsStartedExternally) { - sipApplicationDispatcher.stop(); - } - if(logger.isDebugEnabled()) { - logger.debug("SIP Standard Service Stopped."); - } -// setState(LifecycleState.STOPPING); - } - - /** - * Retrieve the sip application dispatcher class name - * @return the sip application dispatcher class name - */ - public String getSipApplicationDispatcherClassName() { - return sipApplicationDispatcherClassName; - } - - /** - * Set the sip application dispatcher class name - * @param sipApplicationDispatcherClassName the sip application dispatcher class name to be set - */ - public void setSipApplicationDispatcherClassName(String sipApplicationDispatcherName) { - this.sipApplicationDispatcherClassName = sipApplicationDispatcherName; - } - - /** - * @return the sipApplicationDispatcher - */ - public SipApplicationDispatcher getSipApplicationDispatcher() { - return sipApplicationDispatcher; - } - - /** - * @param sipApplicationDispatcher the sipApplicationDispatcher to set - */ - public void setSipApplicationDispatcher( - SipApplicationDispatcher sipApplicationDispatcher) { - this.sipApplicationDispatcher = sipApplicationDispatcher; - } - - /** - * @return the darConfigurationFileLocation - */ - public String getDarConfigurationFileLocation() { - return darConfigurationFileLocation; - } - - /** - * @param darConfigurationFileLocation the darConfigurationFileLocation to set - */ - public void setDarConfigurationFileLocation(String darConfigurationFileLocation) { - this.darConfigurationFileLocation = darConfigurationFileLocation; - } - - /** - * Message queue size. If the number of pending requests exceeds this number they are rejected. - * - * @return - */ - public int getSipMessageQueueSize() { - return sipMessageQueueSize; - } - - /** - * Message queue size. If the number of pending requests exceeds this number they are rejected. - * - * @return - */ - public void setSipMessageQueueSize(int sipMessageQueueSize) { - this.sipMessageQueueSize = sipMessageQueueSize; - } - - /** - * ConcurrencyControl control mode is SipSession, AppSession or None - * Specifies the isolation level of concurrently executing requests. - * - * @return - */ - public String getConcurrencyControlMode() { - return concurrencyControlMode; - } - - /** - * ConcurrencyControl control mode is SipSession, AppSession or None - * Specifies the isolation level of concurrently executing requests. - * - * @return - */ - public void setConcurrencyControlMode(String concurrencyControlMode) { - this.concurrencyControlMode = concurrencyControlMode; - } - - - /** - * @param memoryThreshold the memoryThreshold to set - */ - public void setMemoryThreshold(int memoryThreshold) { - this.memoryThreshold = memoryThreshold; - } - - - /** - * @return the memoryThreshold - */ - public int getMemoryThreshold() { - return memoryThreshold; - } - - /** - * @param skipStatistics the skipStatistics to set - */ - public void setGatherStatistics(boolean skipStatistics) { - this.gatherStatistics = skipStatistics; - if(logger.isInfoEnabled()) { - logger.info("Gathering Statistics set to " + skipStatistics); - } - } - - /** - * @return the skipStatistics - */ - public boolean isGatherStatistics() { - return gatherStatistics; - } - - /** - * PRESENT TO ACCOMODATE JOPR. NEED TO FILE A BUG ON THIS - * @return the skipStatistics - */ - public boolean getGatherStatistics() { - return gatherStatistics; - } - - /** - * @param backToNormalPercentageOfMemoryUsed the backToNormalPercentageOfMemoryUsed to set - */ - public void setBackToNormalMemoryThreshold( - int backToNormalMemoryThreshold) { - this.backToNormalMemoryThreshold = backToNormalMemoryThreshold; - } - - /** - * @return the backToNormalPercentageOfMemoryUsed - */ - public int getBackToNormalMemoryThreshold() { - return backToNormalMemoryThreshold; - } - - /** - * @param backToNormalQueueSize the backToNormalQueueSize to set - */ - public void setBackToNormalSipMessageQueueSize(int backToNormalSipMessageQueueSize) { - this.backToNormalSipMessageQueueSize = backToNormalSipMessageQueueSize; - } - - /** - * @return the backToNormalQueueSize - */ - public int getBackToNormalSipMessageQueueSize() { - return backToNormalSipMessageQueueSize; - } - - - /** - * @param congestionControlPolicy the congestionControlPolicy to set - */ - public void setCongestionControlPolicy(String congestionControlPolicy) { - this.congestionControlPolicy = congestionControlPolicy; - } - - - /** - * @return the congestionControlPolicy - */ - public String getCongestionControlPolicy() { - return congestionControlPolicy; - } - - - /** - * @param congestionControlCheckingInterval the congestionControlCheckingInterval to set - */ - public void setCongestionControlCheckingInterval( - long congestionControlCheckingInterval) { - this.congestionControlCheckingInterval = congestionControlCheckingInterval; - } - - - /** - * @return the congestionControlCheckingInterval - */ - public long getCongestionControlCheckingInterval() { - return congestionControlCheckingInterval; - } - - - public String getAdditionalParameterableHeaders() { - return additionalParameterableHeaders; - } - - - public void setAdditionalParameterableHeaders( - String additionalParameterableHeaders) { - this.additionalParameterableHeaders = additionalParameterableHeaders; - String[] headers = additionalParameterableHeaders.split(","); - for(String header : headers) { - if(header != null && header.length()>0) { - JainSipUtils.PARAMETERABLE_HEADER_NAMES.add(header); - } - } - } - - - /** - * @return the bypassResponseExecutor - */ - public boolean isBypassResponseExecutor() { - return bypassResponseExecutor; - } - - - /** - * @param bypassResponseExecutor the bypassResponseExecutor to set - */ - public void setBypassResponseExecutor(boolean bypassResponseExecutor) { - this.bypassResponseExecutor = bypassResponseExecutor; - } - - - /** - * @return the bypassRequestExecutor - */ - public boolean isBypassRequestExecutor() { - return bypassRequestExecutor; - } - - - /** - * @param bypassRequestExecutor the bypassRequestExecutor to set - */ - public void setBypassRequestExecutor(boolean bypassRequestExecutor) { - this.bypassRequestExecutor = bypassRequestExecutor; - } - - public boolean isMd5ContactUserPart() { - return md5ContactUserPart; - } - - - public void setMd5ContactUserPart(boolean md5ContactUserPart) { - this.md5ContactUserPart = md5ContactUserPart; - } - - - /** - * @param usePrettyEncoding the usePrettyEncoding to set - */ - public void setUsePrettyEncoding(boolean usePrettyEncoding) { - this.usePrettyEncoding = usePrettyEncoding; - } - - /** - * @return the usePrettyEncoding - */ - public boolean isUsePrettyEncoding() { - return usePrettyEncoding; - } - - /** - * @param sipPathName the sipPathName to set - */ - public void setSipPathName(String sipPathName) { - this.sipPathName = sipPathName; - } - - /** - * @return the sipPathName - */ - public String getSipPathName() { - return sipPathName; - } - - - /** - * @param baseTimerInterval the baseTimerInterval to set - */ - public void setBaseTimerInterval(int baseTimerInterval) { - this.baseTimerInterval = baseTimerInterval; - } - - - /** - * @return the baseTimerInterval - */ - public int getBaseTimerInterval() { - return baseTimerInterval; - } - - - public OutboundProxy getOutboundProxy() { - return outboundProxy; - } - - - public void setOutboundProxy(String outboundProxy) { - if(outboundProxy != null) { - this.outboundProxy = new OutboundProxy(outboundProxy); - } else { - this.outboundProxy = null; - } - if(logger.isDebugEnabled()) { - logger.debug("Outbound Proxy : " + outboundProxy); - } - } - - public int getDispatcherThreadPoolSize() { - return dispatcherThreadPoolSize; - } - - - public void setDispatcherThreadPoolSize(int dispatcherThreadPoolSize) { - this.dispatcherThreadPoolSize = dispatcherThreadPoolSize; - } - - public int getCanceledTimerTasksPurgePeriod() { - return canceledTimerTasksPurgePeriod; - } - - public void setCanceledTimerTasksPurgePeriod(int purgePeriod) { - this.canceledTimerTasksPurgePeriod = purgePeriod; - } - - - /** - * @deprecated - * @param balancers the balancers to set - */ - public void setBalancers(String balancers) { - this.balancers = balancers; - } - - public boolean addSipConnector(SipConnector sipConnector) throws Exception { - if(sipConnector == null) { - throw new IllegalArgumentException("The sip connector passed is null"); - } - Connector connectorToAdd = findSipConnector(sipConnector.getIpAddress(), sipConnector.getPort(), - sipConnector.getTransport()); - if(connectorToAdd == null) { - Connector connector = new Connector( - SipProtocolHandler.class.getName()); - SipProtocolHandler sipProtocolHandler = (SipProtocolHandler) connector - .getProtocolHandler(); - sipProtocolHandler.setSipConnector(sipConnector); - sipProtocolHandler.setSipStack(sipStack); - connector.setService(this); -//TODO connector.setContainer(container); - connector.init(); - addConnector(connector); - MobicentsExtendedListeningPoint extendedListeningPoint = (MobicentsExtendedListeningPoint) - sipProtocolHandler.getAttribute(ExtendedListeningPoint.class.getSimpleName()); - if(extendedListeningPoint != null) { - try { - extendedListeningPoint.getSipProvider().addSipListener(sipApplicationDispatcher); - sipApplicationDispatcher.getSipNetworkInterfaceManager().addExtendedListeningPoint(extendedListeningPoint); - } catch (TooManyListenersException e) { - logger.error("Connector.initialize", e); - removeConnector(connector); - return false; - } - } - if(!sipProtocolHandler.isStarted()) { - if(logger.isDebugEnabled()) { - logger.debug("Sip Connector couldn't be started, removing it automatically"); - } - removeConnector(connector); - } - return sipProtocolHandler.isStarted(); - } - return false; - } - - public boolean removeSipConnector(String ipAddress, int port, String transport) throws Exception { - Connector connectorToRemove = findSipConnector(ipAddress, port, - transport); - if(connectorToRemove != null) { - removeConnector(connectorToRemove); - return true; - } - return false; - } - - - /** - * Find a sip Connector by it's ip address, port and transport - * @param ipAddress ip address of the connector to find - * @param port port of the connector to find - * @param transport transport of the connector to find - * @return the found sip connector or null if noting found - */ - private Connector findSipConnector(String ipAddress, int port, - String transport) { - Connector connectorToRemove = null; - for (Connector connector : connectors) { - final ProtocolHandler protocolHandler = connector.getProtocolHandler(); - if(protocolHandler instanceof SipProtocolHandler) { - final SipProtocolHandler sipProtocolHandler = (SipProtocolHandler) protocolHandler; - if(sipProtocolHandler.getIpAddress().equals(ipAddress) && sipProtocolHandler.getPort() == port && sipProtocolHandler.getSignalingTransport().equals(transport)) { -// connector.destroy(); - connectorToRemove = connector; - break; - } - } - } - return connectorToRemove; - } - - public SipConnector findSipConnector(String transport) { - List sipConnectors = new ArrayList(); - for (Connector connector : connectors) { - final ProtocolHandler protocolHandler = connector.getProtocolHandler(); - if(protocolHandler instanceof SipProtocolHandler) { - SipConnector sc = (((SipProtocolHandler)protocolHandler).getSipConnector()); - if(sc.getTransport().equalsIgnoreCase(transport)) return sc; - } - } - return null; - } - - public SipConnector[] findSipConnectors() { - List sipConnectors = new ArrayList(); - for (Connector connector : connectors) { - final ProtocolHandler protocolHandler = connector.getProtocolHandler(); - if(protocolHandler instanceof SipProtocolHandler) { - sipConnectors.add(((SipProtocolHandler)protocolHandler).getSipConnector()); - } - } - return sipConnectors.toArray(new SipConnector[sipConnectors.size()]); - } - - /** - * This method simply makes the HTTP and SSL ports avaialble everywhere in the JVM in order jsip ha to read them for - * balancer description purposes. There is no other good way to communicate the properies to jsip ha without adding - * more dependencies. - */ - public void initializeSystemPortProperties() { - for (Connector connector : connectors) { - if(connector.getProtocol().contains("HTTP")) { - if(connector.getSecure()) { - System.setProperty("org.mobicents.properties.sslPort", Integer.toString(connector.getPort())); - } else { - System.setProperty("org.mobicents.properties.httpPort", Integer.toString(connector.getPort())); - } - } - } - } - - protected ObjectName createSipConnectorObjectName(Connector connector, String domain, String type) - throws MalformedObjectNameException { - String encodedAddr = null; - if (connector.getProperty("address") != null) { - encodedAddr = URLEncoder.encode(connector.getProperty("address").toString()); - } - String addSuffix = (connector.getProperty("address") == null) ? "" : ",address=" - + encodedAddr; - ObjectName _oname = new ObjectName(domain + ":type=" + type + ",port=" - + connector.getPort() + ",transport=" + connector.getProperty("transport") + addSuffix); - return _oname; - } - - - /** - * @param t2Interval the t2Interval to set - */ - public void setT2Interval(int t2Interval) { - this.t2Interval = t2Interval; - } - - - /** - * @return the t2Interval - */ - public int getT2Interval() { - return t2Interval; - } - - - /** - * @param t4Interval the t4Interval to set - */ - public void setT4Interval(int t4Interval) { - this.t4Interval = t4Interval; - } - - - /** - * @return the t4Interval - */ - public int getT4Interval() { - return t4Interval; - } - - - /** - * @param timerDInterval the timerDInterval to set - */ - public void setTimerDInterval(int timerDInterval) { - this.timerDInterval = timerDInterval; - } - - - /** - * @return the timerDInterval - */ - public int getTimerDInterval() { - return timerDInterval; - } - - /** - * @param sipStackPropertiesFile the sipStackPropertiesFile to set - */ - public void setSipStackPropertiesFile(String sipStackPropertiesFile) { - sipStackPropertiesFileLocation = sipStackPropertiesFile; - } - - /** - * @return the sipStackProperties - */ - public Properties getSipStackProperties() { - return sipStackProperties; - } - - /** - * @param sipStackProperties the sipStackProperties to set - */ - public void setSipStackProperties(Properties sipStackProperties) { - this.sipStackProperties = sipStackProperties; - } - - /** - * @return the sipStackPropertiesFile - */ - public String getSipStackPropertiesFile() { - return sipStackPropertiesFileLocation; - } - - /** - * @param dnsAddressResolverClass the dnsAddressResolverClass to set - */ - @Deprecated - public void setAddressResolverClass(String dnsAddressResolverClass) { - this.addressResolverClass = dnsAddressResolverClass; - } - - /** - * @return the dnsAddressResolverClass - */ - @Deprecated - public String getAddressResolverClass() { - return addressResolverClass; - } - - /** - * Whether we check for pending requests and return 491 response if there are any - * - * @return the flag value - */ - public boolean isDialogPendingRequestChecking() { - return dialogPendingRequestChecking; - } - - /** - * - * Whether we check for pending requests and return 491 response if there are any - * - * @param dialogPendingRequestChecking - */ - public void setDialogPendingRequestChecking(boolean dialogPendingRequestChecking) { - this.dialogPendingRequestChecking = dialogPendingRequestChecking; - } - - - public boolean isHttpFollowsSip() { - return httpFollowsSip; - } - - - public void setHttpFollowsSip(boolean httpFollowsSip) { - this.httpFollowsSip = httpFollowsSip; - } - - /** - * @return the tagHashMaxLength - */ - public int getTagHashMaxLength() { - return tagHashMaxLength; - } - - /** - * @param tagHashMaxLength the tagHashMaxLength to set - */ - public void setTagHashMaxLength(int tagHashMaxLength) { - this.tagHashMaxLength = tagHashMaxLength; - } - - /** - * @return the callIdMaxLength - */ - public int getCallIdMaxLength() { - return callIdMaxLength; - } - - /** - * @param callIdMaxLength the callIdMaxLength to set - */ - public void setCallIdMaxLength(int callIdMaxLength) { - this.callIdMaxLength = callIdMaxLength; - } - - /** - * @return the sipStack - */ - public SipStack getSipStack() { - return sipStack; - } - - /** - * @param dnsServerLocatorClass the dnsServerLocatorClass to set - */ - public void setDnsServerLocatorClass(String dnsServerLocatorClass) { - this.dnsServerLocatorClass = dnsServerLocatorClass; - } - - /** - * @return the dnsServerLocatorClass - */ - public String getDnsServerLocatorClass() { - return dnsServerLocatorClass; - } - - /** - * @param dnsResolverClass the dnsResolverClass to set - */ - public void setDnsResolverClass(String dnsResolverClass) { - this.dnsResolverClass = dnsResolverClass; - } - - /** - * @return the dnsResolverClass - */ - public String getDnsResolverClass() { - return dnsResolverClass; - } - - - /** - * Returns first the catalina.base if it is defined then the catalina.home if it is defined - * then the current dir if none is specified - */ - protected String getCatalinaBase() { - String catalinaBase = System.getProperty("catalina.base"); - if (catalinaBase == null) { - catalinaBase = System.getProperty("catalina.home"); - } - if(catalinaBase == null) { - catalinaBase = "."; - } - return catalinaBase; - } - - public ReplicationStrategy getReplicationStrategy() { - return replicationStrategy; - } - - @Override - public String getMobicentsSipServletMessageFactoryClassName() { - return mobicentsSipServletMessageFactoryClassName; - } - - @Override - public void setMobicentsSipServletMessageFactoryClassName( - String mobicentsSipServletMessageFactoryClassName) { - this.mobicentsSipServletMessageFactoryClassName = mobicentsSipServletMessageFactoryClassName; - } - - public void sendHeartBeat(String localAddress, int localPort, String transport, String remoteIpAddress, int remotePort) throws IOException { - MobicentsExtendedListeningPoint extendedListeningPoint = sipApplicationDispatcher.getSipNetworkInterfaceManager().findMatchingListeningPoint(localAddress, localPort, transport); - if(extendedListeningPoint != null) { - extendedListeningPoint.getListeningPoint().sendHeartbeat(remoteIpAddress, remotePort); - } - } - - public boolean setKeepAliveTimeout(SipConnector sipConnector, String clientAddress, int clientPort, long timeout) { - SIPTransactionStack sipStack = ((SIPTransactionStack) sipApplicationDispatcher.getSipStack()); - - return sipStack.setKeepAliveTimeout(sipConnector.getIpAddress(), sipConnector.getPort(), sipConnector.getTransport(), - clientAddress, clientPort, timeout); - } - - public void closeReliableConnection(SipConnector sipConnector, String clientAddress, int clientPort) { - SIPTransactionStack sipStack = ((SIPTransactionStack) sipApplicationDispatcher.getSipStack()); - - sipStack.closeReliableConnection(sipConnector.getIpAddress(),sipConnector.getPort(), sipConnector.getTransport(), - clientAddress, clientPort); - } - - /* - * (non-Javadoc) - * @see org.mobicents.servlet.sip.core.SipService#stopGracefully(long) - */ - public void stopGracefully(long timeToWait) { - if(logger.isInfoEnabled()) { - logger.info("Stopping the Server Gracefully in " + timeToWait + " ms"); - } - if(timeToWait == 0) { - if(gracefulStopFuture != null) { - gracefulStopFuture.cancel(false); - } - try { - getServer().stop(); - } catch (LifecycleException e) { - logger.error("The server couldn't be stopped", e); - } - } else { - sipApplicationDispatcher.setGracefulShutdown(true); - Iterator sipContexts = sipApplicationDispatcher.findSipApplications(); - while (sipContexts.hasNext()) { - SipContext sipContext = sipContexts.next(); - sipContext.stopGracefully(timeToWait); - } - gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().scheduleWithFixedDelay(new ServiceGracefulStopTask(this), 30000, 30000, TimeUnit.MILLISECONDS); - if(timeToWait > 0) { - gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().schedule( - new Runnable() { - public void run() { - gracefulStopFuture.cancel(false); - try { - getServer().stop(); - } catch (LifecycleException e) { - logger.error("The server couldn't be stopped", e); - } - } - } - , timeToWait, TimeUnit.MILLISECONDS); - } - } - } - - /** - * @return the dnsTimeout - */ - public int getDnsTimeout() { - return dnsTimeout; - } - - /** - * @param dnsTimeout the dnsTimeout to set - */ - public void setDnsTimeout(int dnsTimeout) { - this.dnsTimeout = dnsTimeout; - } - - public String getProxyTimerServiceImplementationType() { - return proxyTimerServiceImplementationType; - } - - public void setProxyTimerServiceImplementationType(String proxyTimerServiceImplementationType) { - this.proxyTimerServiceImplementationType = proxyTimerServiceImplementationType; - } - - public String getSasTimerServiceImplementationType() { - return sasTimerServiceImplementationType; - } - - public void setSasTimerServiceImplementationType(String sasTimerServiceImplementationType) { - this.sasTimerServiceImplementationType = sasTimerServiceImplementationType; - } -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.catalina; + + +import gov.nist.core.net.AddressResolver; +import gov.nist.javax.sip.SipStackExt; +import gov.nist.javax.sip.message.MessageFactoryExt; +import gov.nist.javax.sip.stack.SIPTransactionStack; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; +import java.util.StringTokenizer; +import java.util.TooManyListenersException; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; +import javax.sip.SipStack; +import javax.sip.header.ServerHeader; +import javax.sip.header.UserAgentHeader; + +import org.apache.catalina.Engine; +import org.apache.catalina.LifecycleException; +import org.apache.catalina.connector.Connector; +import org.apache.catalina.core.StandardService; +import org.apache.coyote.ProtocolHandler; +import org.apache.log4j.Logger; +import org.apache.tomcat.util.modeler.Registry; +import org.mobicents.ext.javax.sip.dns.DNSAwareRouter; +import org.mobicents.ext.javax.sip.dns.DNSServerLocator; +import org.mobicents.ext.javax.sip.dns.DefaultDNSServerLocator; +import org.mobicents.ha.javax.sip.ClusteredSipStack; +import org.mobicents.ha.javax.sip.LoadBalancerHeartBeatingListener; +import org.mobicents.ha.javax.sip.LoadBalancerHeartBeatingService; +import org.mobicents.ha.javax.sip.LoadBalancerHeartBeatingServiceImpl; +import org.mobicents.ha.javax.sip.ReplicationStrategy; +import org.mobicents.javax.servlet.CongestionControlPolicy; +import org.mobicents.servlet.sip.JainSipUtils; +import org.mobicents.servlet.sip.SipConnector; +import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; +import org.mobicents.servlet.sip.core.ExtendedListeningPoint; +import org.mobicents.servlet.sip.core.MobicentsExtendedListeningPoint; +import org.mobicents.servlet.sip.core.SipApplicationDispatcher; +import org.mobicents.servlet.sip.core.SipContext; +import org.mobicents.servlet.sip.core.message.OutboundProxy; +import org.mobicents.servlet.sip.dns.MobicentsDNSResolver; +import org.mobicents.servlet.sip.message.Servlet3SipServletMessageFactory; +import org.mobicents.servlet.sip.startup.StaticServiceHolder; + +/** + * Sip Servlet implementation of the SipService interface. + * This class inherits from the Tomcat StandardService. It adds a SipApplicationDispatcher + * that will be listen for sip messages received by the sip stacks started by + * the sip connectors associated with this context. + * This has one attribute which is the sipApplicationDispatcherClassName allowing one + * to specify the class name of the sipApplicationDispacther to easily replace + * the default sipApplicationDispatcher with a custom one. + * + * @author Jean Deruelle + */ +public class SipStandardService extends StandardService implements CatalinaSipService { + //the logger + private static final Logger logger = Logger.getLogger(SipStandardService.class); + public static final String DEFAULT_SIP_PATH_NAME = "gov.nist"; + public static final String PASS_INVITE_NON_2XX_ACK_TO_LISTENER = "gov.nist.javax.sip.PASS_INVITE_NON_2XX_ACK_TO_LISTENER"; + public static final String TCP_POST_PARSING_THREAD_POOL_SIZE = "gov.nist.javax.sip.TCP_POST_PARSING_THREAD_POOL_SIZE"; + public static final String AUTOMATIC_DIALOG_SUPPORT_STACK_PROP = "javax.sip.AUTOMATIC_DIALOG_SUPPORT"; + public static final String LOOSE_DIALOG_VALIDATION = "gov.nist.javax.sip.LOOSE_DIALOG_VALIDATION"; + public static final String SERVER_LOG_STACK_PROP = "gov.nist.javax.sip.SERVER_LOG"; + public static final String DEBUG_LOG_STACK_PROP = "gov.nist.javax.sip.DEBUG_LOG"; + public static final String SERVER_HEADER = "org.mobicents.servlet.sip.SERVER_HEADER"; + public static final String USER_AGENT_HEADER = "org.mobicents.servlet.sip.USER_AGENT_HEADER"; + public static final String JVM_ROUTE = "jvmRoute"; + /** + * The descriptive information string for this implementation. + */ + private static final String INFO = + "org.mobicents.servlet.sip.startup.SipStandardService/1.0"; + //the sip application dispatcher class name defined in the server.xml + protected String sipApplicationDispatcherClassName; + //instatiated class from the sipApplicationDispatcherClassName of the sip application dispatcher + protected SipApplicationDispatcher sipApplicationDispatcher; + private boolean gatherStatistics = true; + protected int sipMessageQueueSize = 1500; + private int backToNormalSipMessageQueueSize = 1300; + protected int memoryThreshold = 95; + private int backToNormalMemoryThreshold = 90; + protected OutboundProxy outboundProxy; + protected String proxyTimerServiceImplementationType; + protected String sasTimerServiceImplementationType; + protected long congestionControlCheckingInterval = 30000; + private int canceledTimerTasksPurgePeriod = 0; + // base timer interval for jain sip tx + private int baseTimerInterval = 500; + private int t2Interval = 4000; + private int t4Interval = 5000; + private int timerDInterval = 32000; + protected int dispatcherThreadPoolSize = 15; + private boolean md5ContactUserPart = false; + + protected String concurrencyControlMode = ConcurrencyControlMode.SipApplicationSession.toString(); + protected String congestionControlPolicy = CongestionControlPolicy.ErrorResponse.toString(); + protected String additionalParameterableHeaders; + protected boolean bypassResponseExecutor = true; + protected boolean bypassRequestExecutor = true; + //this should be made available to the application router as a system prop + protected String darConfigurationFileLocation; + protected boolean connectorsStartedExternally = false; + protected boolean dialogPendingRequestChecking = false; + protected int callIdMaxLength; + protected int tagHashMaxLength; + + protected boolean httpFollowsSip = false; + protected String jvmRoute; + protected ReplicationStrategy replicationStrategy; + + /** + * the sip stack path name. Since the sip factory is per classloader it should be set here for all underlying stacks + */ + private String sipPathName; + /** + * use Pretty Encoding + */ + private boolean usePrettyEncoding = true; + + private SipStack sipStack; + // defining sip stack properties + private Properties sipStackProperties; + private String sipStackPropertiesFileLocation; + @Deprecated + private String addressResolverClass = null; + private String dnsServerLocatorClass = DefaultDNSServerLocator.class.getName(); + private int dnsTimeout = 1; + private String dnsResolverClass = MobicentsDNSResolver.class.getName(); + private String mobicentsSipServletMessageFactoryClassName = Servlet3SipServletMessageFactory.class.getName(); + + //the balancers to send heartbeat to and our health info + @Deprecated + private String balancers; + // + private ScheduledFuture gracefulStopFuture; + + @Override + public void addConnector(Connector connector) { + MobicentsExtendedListeningPoint extendedListeningPoint = null; + if (connector.getProtocolHandler() instanceof SipProtocolHandler) { + extendedListeningPoint = (MobicentsExtendedListeningPoint) + ((SipProtocolHandler)connector.getProtocolHandler()).getAttribute(ExtendedListeningPoint.class.getSimpleName());} + if(extendedListeningPoint != null) { + try { + extendedListeningPoint.getSipProvider().addSipListener(sipApplicationDispatcher); + sipApplicationDispatcher.getSipNetworkInterfaceManager().addExtendedListeningPoint(extendedListeningPoint); + } catch (TooManyListenersException e) { + logger.error("Connector.initialize", e); + } + } + ProtocolHandler protocolHandler = connector.getProtocolHandler(); + if(protocolHandler instanceof SipProtocolHandler) { + connector.setPort(((SipProtocolHandler)protocolHandler).getPort()); + ((SipProtocolHandler)protocolHandler).setSipStack(sipStack); + ((SipProtocolHandler)protocolHandler).setAttribute(SipApplicationDispatcher.class.getSimpleName(), sipApplicationDispatcher); + registerSipConnector(connector); + } + super.addConnector(connector); + } + + /** + * Register the sip connector under a different name than HTTP Connector and we add the transport to avoid clashing with 2 connectors having the same port and address + * @param connector connector to register + */ + protected void registerSipConnector(Connector connector) { + try { + + ObjectName objectName = createSipConnectorObjectName(connector, getName(), "SipConnector"); + Registry.getRegistry(null, null) + .registerComponent(connector, objectName, null); +//TODO connector.setController(objectName); + } catch (Exception e) { + logger.error( "Error registering connector ", e); + } + if(logger.isDebugEnabled()) + logger.debug("Creating name for connector " + getObjectName()); + } + + @Override + public void removeConnector(Connector connector) { + MobicentsExtendedListeningPoint extendedListeningPoint = null; + if (connector.getProtocolHandler() instanceof SipProtocolHandler){ + extendedListeningPoint = (MobicentsExtendedListeningPoint) + ((SipProtocolHandler)connector.getProtocolHandler()).getAttribute(ExtendedListeningPoint.class.getSimpleName());} + if(extendedListeningPoint != null) { + extendedListeningPoint.getSipProvider().removeSipListener(sipApplicationDispatcher); + sipApplicationDispatcher.getSipNetworkInterfaceManager().removeExtendedListeningPoint(extendedListeningPoint); + } + super.removeConnector(connector); + } + + @Override + public void initInternal() throws LifecycleException { + //load the sip application disptacher from the class name specified in the server.xml file + //and initializes it + StaticServiceHolder.sipStandardService = this; + try { + sipApplicationDispatcher = (SipApplicationDispatcher) + Class.forName(sipApplicationDispatcherClassName).newInstance(); + } catch (InstantiationException e) { + throw new LifecycleException("Impossible to load the Sip Application Dispatcher",e); + } catch (IllegalAccessException e) { + throw new LifecycleException("Impossible to load the Sip Application Dispatcher",e); + } catch (ClassNotFoundException e) { + throw new LifecycleException("Impossible to load the Sip Application Dispatcher",e); + } catch (ClassCastException e) { + throw new LifecycleException("Sip Application Dispatcher defined does not implement " + SipApplicationDispatcher.class.getName(),e); + } + if(logger.isInfoEnabled()) { + logger.info("Pretty encoding of headers enabled ? " + usePrettyEncoding); + } + if(sipPathName == null) { + sipPathName = DEFAULT_SIP_PATH_NAME; + } + if(logger.isInfoEnabled()) { + logger.info("Sip Stack path name : " + sipPathName); + } + sipApplicationDispatcher.setSipService(this); + sipApplicationDispatcher.getSipFactory().initialize(sipPathName, usePrettyEncoding); + + String catalinaBase = getCatalinaBase(); + if(darConfigurationFileLocation != null) { + if(!darConfigurationFileLocation.startsWith("file:///")) { + darConfigurationFileLocation = "file:///" + catalinaBase.replace(File.separatorChar, '/') + "/" + darConfigurationFileLocation; + } + System.setProperty("javax.servlet.sip.dar", darConfigurationFileLocation); + } + super.initInternal(); + sipApplicationDispatcher.setDomain(this.getName()); + if(baseTimerInterval < 1) { + throw new LifecycleException("It's forbidden to set the Base Timer Interval to a non positive value"); + } + initSipStack(); + // https://telestax.atlassian.net/browse/MSS-148 make sure we have a default to bin direction for better out of the box experience + if(System.getProperty("telscale.license.dir") == null) { + System.setProperty("telscale.license.dir", getCatalinaBase() + File.separatorChar + "bin"); + if(logger.isDebugEnabled()) { + logger.debug("Setting telscale.license.dir directory to : " + getCatalinaBase() + File.separatorChar + "bin"); + } + } + if(System.getProperty("telscale.license.key.location") == null) { + System.setProperty("telscale.license.key.location", getCatalinaBase() + File.separatorChar + "bin"); + if(logger.isDebugEnabled()) { + logger.debug("Setting telscale.license.key.location directory to : " + getCatalinaBase() + File.separatorChar + "bin"); + } + } + + sipApplicationDispatcher.setBaseTimerInterval(baseTimerInterval); + sipApplicationDispatcher.setT2Interval(t2Interval); + sipApplicationDispatcher.setT4Interval(t4Interval); + sipApplicationDispatcher.setTimerDInterval(timerDInterval); + sipApplicationDispatcher.setMemoryThreshold(getMemoryThreshold()); + sipApplicationDispatcher.setBackToNormalMemoryThreshold(backToNormalMemoryThreshold); + sipApplicationDispatcher.setCongestionControlCheckingInterval(getCongestionControlCheckingInterval()); + sipApplicationDispatcher.setCongestionControlPolicyByName(getCongestionControlPolicy()); + sipApplicationDispatcher.setQueueSize(getSipMessageQueueSize()); + sipApplicationDispatcher.setBackToNormalQueueSize(backToNormalSipMessageQueueSize); + sipApplicationDispatcher.setGatherStatistics(gatherStatistics); + sipApplicationDispatcher.setConcurrencyControlMode(ConcurrencyControlMode.valueOf(getConcurrencyControlMode())); + sipApplicationDispatcher.setBypassRequestExecutor(bypassRequestExecutor); + sipApplicationDispatcher.setBypassResponseExecutor(bypassResponseExecutor); + sipApplicationDispatcher.setSipStack(sipStack); + sipApplicationDispatcher.init(); + // Tomcat specific loading case where the connectors are added even before the service is initialized + // so we need to set the sip stack before it starts + synchronized (connectors) { + for (Connector connector : connectors) { + ProtocolHandler protocolHandler = connector.getProtocolHandler(); + if(protocolHandler instanceof SipProtocolHandler) { + connector.setPort(((SipProtocolHandler)protocolHandler).getPort()); + ((SipProtocolHandler)protocolHandler).setSipStack(sipStack); + ((SipProtocolHandler)protocolHandler).setAttribute(SipApplicationDispatcher.class.getSimpleName(), sipApplicationDispatcher); + registerSipConnector(connector); + } + } + } + } + + @Override + public void startInternal() throws LifecycleException { + super.startInternal(); + synchronized (connectors) { + for (Connector connector : connectors) { + final ProtocolHandler protocolHandler = connector.getProtocolHandler(); + //Jboss sepcific loading case + Boolean isSipConnector = false; + if (protocolHandler instanceof SipProtocolHandler) + isSipConnector = (Boolean) ((SipProtocolHandler)protocolHandler).getAttribute(SipProtocolHandler.IS_SIP_CONNECTOR); + if(isSipConnector != null && isSipConnector) { + if(logger.isDebugEnabled()) { + logger.debug("Attaching the sip application dispatcher " + + "as a sip listener to connector listening on port " + + connector.getPort()); + } + ((SipProtocolHandler)protocolHandler).setAttribute(SipApplicationDispatcher.class.getSimpleName(), sipApplicationDispatcher); + ((SipProtocolHandler)protocolHandler).setSipStack(sipStack); + connectorsStartedExternally = true; + } + //Tomcat specific loading case + MobicentsExtendedListeningPoint extendedListeningPoint = null; + if (protocolHandler instanceof SipProtocolHandler) { + extendedListeningPoint = (MobicentsExtendedListeningPoint) + ((SipProtocolHandler)protocolHandler).getAttribute(ExtendedListeningPoint.class.getSimpleName());} + if(extendedListeningPoint != null && sipStack != null) { + try { + extendedListeningPoint.getSipProvider().addSipListener(sipApplicationDispatcher); + sipApplicationDispatcher.getSipNetworkInterfaceManager().addExtendedListeningPoint(extendedListeningPoint); + connectorsStartedExternally = false; + } catch (TooManyListenersException e) { + throw new LifecycleException("Couldn't add the sip application dispatcher " + + sipApplicationDispatcher + " as a listener to the following listening point provider " + extendedListeningPoint, e); + } + } + } + } + if(!connectorsStartedExternally) { + sipApplicationDispatcher.start(); + sipApplicationDispatcher.putInService(); + } + + if(this.getSipMessageQueueSize() <= 0) + throw new LifecycleException("Message queue size can not be 0 or less"); + + if(logger.isDebugEnabled()) { + logger.debug("SIP Standard Service Started."); + } + } + + public String getJvmRoute() { + return this.jvmRoute; + } + + public void setJvmRoute(String jvmRoute) { + this.jvmRoute = jvmRoute; + } + + protected void initSipStack() throws LifecycleException { + try { + if(logger.isDebugEnabled()) { + logger.debug("Initializing SIP stack"); + } + + // This simply puts HTTP and SSL port numbers in JVM properties menat to be read by jsip ha when sending heart beats with Node description. + initializeSystemPortProperties(); + + String catalinaBase = getCatalinaBase(); + if(sipStackPropertiesFileLocation != null && !sipStackPropertiesFileLocation.startsWith("file:///")) { + sipStackPropertiesFileLocation = "file:///" + catalinaBase.replace(File.separatorChar, '/') + "/" + sipStackPropertiesFileLocation; + } + boolean isPropsLoaded = false; + if(sipStackProperties == null) { + sipStackProperties = new Properties(); + } else { + isPropsLoaded = true; + } + + if (logger.isDebugEnabled()) { + logger.debug("Loading SIP stack properties from following file : " + sipStackPropertiesFileLocation); + } + if(sipStackPropertiesFileLocation != null) { + //hack to get around space char in path see http://weblogs.java.net/blog/kohsuke/archive/2007/04/how_to_convert.html, + // we create a URL since it's permissive enough + File sipStackPropertiesFile = null; + URL url = null; + try { + url = new URL(sipStackPropertiesFileLocation); + } catch (MalformedURLException e) { + logger.fatal("Cannot find the sip stack properties file ! ",e); + throw new IllegalArgumentException("The Default Application Router file Location : "+sipStackPropertiesFileLocation+" is not valid ! ",e); + } + try { + sipStackPropertiesFile = new File(new URI(sipStackPropertiesFileLocation)); + } catch (URISyntaxException e) { + //if the uri contains space this will fail, so getting the path will work + sipStackPropertiesFile = new File(url.getPath()); + } + FileInputStream sipStackPropertiesInputStream = null; + try { + sipStackPropertiesInputStream = new FileInputStream(sipStackPropertiesFile); + sipStackProperties.load(sipStackPropertiesInputStream); + } catch (Exception e) { + logger.warn("Could not find or problem when loading the sip stack properties file : " + sipStackPropertiesFileLocation, e); + } finally { + if(sipStackPropertiesInputStream != null) { + try { + sipStackPropertiesInputStream.close(); + } catch (IOException e) { + logger.error("fail to close the following file " + sipStackPropertiesFile.getAbsolutePath(), e); + } + } + } + + String debugLog = sipStackProperties.getProperty(DEBUG_LOG_STACK_PROP); + if(debugLog != null && debugLog.length() > 0 && !debugLog.startsWith("file:///")) { + sipStackProperties.setProperty(DEBUG_LOG_STACK_PROP, + catalinaBase + "/" + debugLog); + } + String serverLog = sipStackProperties.getProperty(SERVER_LOG_STACK_PROP); + if(serverLog != null && serverLog.length() > 0 && !serverLog.startsWith("file:///")) { + sipStackProperties.setProperty(SERVER_LOG_STACK_PROP, + catalinaBase + "/" + serverLog); + } + // The whole MSS is built upon those assumptions, so those properties are not overrideable + if (sipStackProperties.getProperty(AUTOMATIC_DIALOG_SUPPORT_STACK_PROP) == null) { + //https://github.com/RestComm/sip-servlets/issues/143 + //set off if user didnt provided any value. + sipStackProperties.setProperty(AUTOMATIC_DIALOG_SUPPORT_STACK_PROP, "off"); + } + sipStackProperties.setProperty(LOOSE_DIALOG_VALIDATION, "true"); + sipStackProperties.setProperty(PASS_INVITE_NON_2XX_ACK_TO_LISTENER, "true"); + isPropsLoaded = true; + } else { + logger.warn("no sip stack properties file defined "); + } + if(!isPropsLoaded) { + logger.warn("loading default Mobicents Sip Servlets sip stack properties"); + // Silently set default values + sipStackProperties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", + "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", + "32"); + sipStackProperties.setProperty(DEBUG_LOG_STACK_PROP, + catalinaBase + "/" + "mss-jsip-" + getName() +"-debug.txt"); + sipStackProperties.setProperty(SERVER_LOG_STACK_PROP, + catalinaBase + "/" + "mss-jsip-" + getName() +"-messages.xml"); + sipStackProperties.setProperty("javax.sip.STACK_NAME", "mss-" + getName()); + sipStackProperties.setProperty(AUTOMATIC_DIALOG_SUPPORT_STACK_PROP, "off"); + sipStackProperties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.THREAD_POOL_SIZE", "64"); + sipStackProperties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.MAX_FORK_TIME_SECONDS", "0"); + sipStackProperties.setProperty(LOOSE_DIALOG_VALIDATION, "true"); + sipStackProperties.setProperty(PASS_INVITE_NON_2XX_ACK_TO_LISTENER, "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.AUTOMATIC_DIALOG_ERROR_HANDLING", "false"); + sipStackProperties.setProperty("gov.nist.javax.sip.AGGRESSIVE_CLEANUP", "true"); + } + + if(sipStackProperties.get(TCP_POST_PARSING_THREAD_POOL_SIZE) == null) { + sipStackProperties.setProperty(TCP_POST_PARSING_THREAD_POOL_SIZE, "30"); + } + + // set the DNSServerLocator allowing to support RFC 3263 and do DNS lookups to resolve uris + if(dnsServerLocatorClass != null && dnsServerLocatorClass.trim().length() > 0) { + if(logger.isDebugEnabled()) { + logger.debug("Sip Stack " + sipStackProperties.getProperty("javax.sip.STACK_NAME") +" will be using " + dnsServerLocatorClass + " as DNSServerLocator"); + } + try { + // create parameters argument to identify constructor + Class[] paramTypes = new Class[0]; + // get constructor of AddressResolver in order to instantiate + Constructor dnsServerLocatorConstructor = Class.forName(dnsServerLocatorClass).getConstructor( + paramTypes); + // Wrap properties object in order to pass to constructor of AddressResolver + Object[] conArgs = new Object[0]; + // Creates a new instance of AddressResolver Class with the supplied sipApplicationDispatcher. + DNSServerLocator dnsServerLocator = (DNSServerLocator) dnsServerLocatorConstructor.newInstance(conArgs); + sipApplicationDispatcher.setDNSServerLocator(dnsServerLocator); + sipApplicationDispatcher.setDNSTimeout(dnsTimeout); + if(sipStackProperties.getProperty("javax.sip.ROUTER_PATH") == null) { + sipStackProperties.setProperty("javax.sip.ROUTER_PATH", DNSAwareRouter.class.getCanonicalName()); + } + } catch (Exception e) { + logger.error("Couldn't set the AddressResolver " + addressResolverClass, e); + throw e; + } + } else { + if(logger.isInfoEnabled()) { + logger.info("no DNSServerLocator will be used since none has been specified."); + } + } + + String serverHeaderValue = sipStackProperties.getProperty(SERVER_HEADER); + if(serverHeaderValue != null) { + List serverHeaderList = new ArrayList(); + StringTokenizer stringTokenizer = new StringTokenizer(serverHeaderValue, ","); + while(stringTokenizer.hasMoreTokens()) { + serverHeaderList.add(stringTokenizer.nextToken()); + } + ServerHeader serverHeader = sipApplicationDispatcher.getSipFactory().getHeaderFactory().createServerHeader(serverHeaderList); + ((MessageFactoryExt)sipApplicationDispatcher.getSipFactory().getMessageFactory()).setDefaultServerHeader(serverHeader); + } + String userAgent = sipStackProperties.getProperty(USER_AGENT_HEADER); + if(userAgent != null) { + List userAgentList = new ArrayList(); + StringTokenizer stringTokenizer = new StringTokenizer(userAgent, ","); + while(stringTokenizer.hasMoreTokens()) { + userAgentList.add(stringTokenizer.nextToken()); + } + UserAgentHeader userAgentHeader = sipApplicationDispatcher.getSipFactory().getHeaderFactory().createUserAgentHeader(userAgentList); + ((MessageFactoryExt)sipApplicationDispatcher.getSipFactory().getMessageFactory()).setDefaultUserAgentHeader(userAgentHeader); + } + if(balancers != null) { + if(sipStackProperties.get(LoadBalancerHeartBeatingService.LB_HB_SERVICE_CLASS_NAME) == null) { + sipStackProperties.put(LoadBalancerHeartBeatingService.LB_HB_SERVICE_CLASS_NAME, LoadBalancerHeartBeatingServiceImpl.class.getCanonicalName()); + } + if(sipStackProperties.get(LoadBalancerHeartBeatingService.BALANCERS) == null) { + sipStackProperties.put(LoadBalancerHeartBeatingService.BALANCERS, balancers); + } + } + String replicationStrategyString = sipStackProperties.getProperty(ClusteredSipStack.REPLICATION_STRATEGY_PROPERTY); + if(replicationStrategyString == null) { + replicationStrategyString = ReplicationStrategy.ConfirmedDialog.toString(); + } + boolean replicateApplicationData = false; + if(replicationStrategyString.equals(ReplicationStrategy.EarlyDialog.toString())) { + replicateApplicationData = true; + } + if(replicationStrategyString != null) { + replicationStrategy = ReplicationStrategy.valueOf(replicationStrategyString); + } + sipStackProperties.put(ClusteredSipStack.REPLICATION_STRATEGY_PROPERTY, replicationStrategyString); + sipStackProperties.put(ClusteredSipStack.REPLICATE_APPLICATION_DATA, Boolean.valueOf(replicateApplicationData).toString()); + if(logger.isInfoEnabled()) { + logger.info("Mobicents Sip Servlets sip stack properties : " + sipStackProperties); + } + // Create SipStack object + sipStack = sipApplicationDispatcher.getSipFactory().getJainSipFactory().createSipStack(sipStackProperties); + LoadBalancerHeartBeatingService loadBalancerHeartBeatingService = null; + if(sipStack instanceof ClusteredSipStack) { + loadBalancerHeartBeatingService = ((ClusteredSipStack) sipStack).getLoadBalancerHeartBeatingService(); + if ((this.container != null) && (this.container instanceof Engine) && ((Engine)container).getJvmRoute() != null) { + final String jvmRoute = ((Engine)container).getJvmRoute(); + if(jvmRoute != null) { + loadBalancerHeartBeatingService.setJvmRoute(jvmRoute); + setJvmRoute(jvmRoute); + } + } + } + if(sipApplicationDispatcher != null && loadBalancerHeartBeatingService != null && sipApplicationDispatcher instanceof LoadBalancerHeartBeatingListener) { + loadBalancerHeartBeatingService.addLoadBalancerHeartBeatingListener((LoadBalancerHeartBeatingListener)sipApplicationDispatcher); + } + // for nist sip stack set the DNS Address resolver allowing to make DNS SRV lookups + if(sipStack instanceof SipStackExt && addressResolverClass != null && addressResolverClass.trim().length() > 0) { + if(logger.isDebugEnabled()) { + logger.debug("Sip Stack " + sipStack.getStackName() +" will be using " + addressResolverClass + " as AddressResolver"); + } + try { + // create parameters argument to identify constructor + Class[] paramTypes = new Class[1]; + paramTypes[0] = SipApplicationDispatcher.class; + // get constructor of AddressResolver in order to instantiate + Constructor addressResolverConstructor = Class.forName(addressResolverClass).getConstructor( + paramTypes); + // Wrap properties object in order to pass to constructor of AddressResolver + Object[] conArgs = new Object[1]; + conArgs[0] = sipApplicationDispatcher; + // Creates a new instance of AddressResolver Class with the supplied sipApplicationDispatcher. + AddressResolver addressResolver = (AddressResolver) addressResolverConstructor.newInstance(conArgs); + ((SipStackExt) sipStack).setAddressResolver(addressResolver); + } catch (Exception e) { + logger.error("Couldn't set the AddressResolver " + addressResolverClass, e); + throw e; + } + } else { + if(logger.isInfoEnabled()) { + logger.info("no AddressResolver will be used since none has been specified."); + } + } + if(logger.isInfoEnabled()) { + logger.info("SIP stack initialized"); + } + } catch (Exception ex) { + throw new LifecycleException("A problem occured while initializing the SIP Stack", ex); + } + } + + @Override + public void stopInternal() throws LifecycleException { + // on Tomcat 7 super.stop needs to be called before for Issue 1411 http://code.google.com/p/mobicents/issues/detail?id=1411 + super.stopInternal(); + // Tomcat specific unloading case + // Issue 1411 http://code.google.com/p/mobicents/issues/detail?id=1411 + // Sip Connectors should be removed after removing all Sip Servlets to allow them to send BYE to terminate cleanly + synchronized (connectors) { + for (Connector connector : connectors) { + MobicentsExtendedListeningPoint extendedListeningPoint = null; + if (connector.getProtocolHandler() instanceof SipProtocolHandler) { + extendedListeningPoint = (MobicentsExtendedListeningPoint) + ((SipProtocolHandler)connector.getProtocolHandler()).getAttribute(ExtendedListeningPoint.class.getSimpleName()); + } + if(extendedListeningPoint != null) { + extendedListeningPoint.getSipProvider().removeSipListener(sipApplicationDispatcher); + sipApplicationDispatcher.getSipNetworkInterfaceManager().removeExtendedListeningPoint(extendedListeningPoint); + } + } + } + if(!connectorsStartedExternally) { + sipApplicationDispatcher.stop(); + } + if(logger.isDebugEnabled()) { + logger.debug("SIP Standard Service Stopped."); + } +// setState(LifecycleState.STOPPING); + } + + /** + * Retrieve the sip application dispatcher class name + * @return the sip application dispatcher class name + */ + public String getSipApplicationDispatcherClassName() { + return sipApplicationDispatcherClassName; + } + + /** + * Set the sip application dispatcher class name + * @param sipApplicationDispatcherClassName the sip application dispatcher class name to be set + */ + public void setSipApplicationDispatcherClassName(String sipApplicationDispatcherName) { + this.sipApplicationDispatcherClassName = sipApplicationDispatcherName; + } + + /** + * @return the sipApplicationDispatcher + */ + public SipApplicationDispatcher getSipApplicationDispatcher() { + return sipApplicationDispatcher; + } + + /** + * @param sipApplicationDispatcher the sipApplicationDispatcher to set + */ + public void setSipApplicationDispatcher( + SipApplicationDispatcher sipApplicationDispatcher) { + this.sipApplicationDispatcher = sipApplicationDispatcher; + } + + /** + * @return the darConfigurationFileLocation + */ + public String getDarConfigurationFileLocation() { + return darConfigurationFileLocation; + } + + /** + * @param darConfigurationFileLocation the darConfigurationFileLocation to set + */ + public void setDarConfigurationFileLocation(String darConfigurationFileLocation) { + this.darConfigurationFileLocation = darConfigurationFileLocation; + } + + /** + * Message queue size. If the number of pending requests exceeds this number they are rejected. + * + * @return + */ + public int getSipMessageQueueSize() { + return sipMessageQueueSize; + } + + /** + * Message queue size. If the number of pending requests exceeds this number they are rejected. + * + * @return + */ + public void setSipMessageQueueSize(int sipMessageQueueSize) { + this.sipMessageQueueSize = sipMessageQueueSize; + } + + /** + * ConcurrencyControl control mode is SipSession, AppSession or None + * Specifies the isolation level of concurrently executing requests. + * + * @return + */ + public String getConcurrencyControlMode() { + return concurrencyControlMode; + } + + /** + * ConcurrencyControl control mode is SipSession, AppSession or None + * Specifies the isolation level of concurrently executing requests. + * + * @return + */ + public void setConcurrencyControlMode(String concurrencyControlMode) { + this.concurrencyControlMode = concurrencyControlMode; + } + + + /** + * @param memoryThreshold the memoryThreshold to set + */ + public void setMemoryThreshold(int memoryThreshold) { + this.memoryThreshold = memoryThreshold; + } + + + /** + * @return the memoryThreshold + */ + public int getMemoryThreshold() { + return memoryThreshold; + } + + /** + * @param skipStatistics the skipStatistics to set + */ + public void setGatherStatistics(boolean skipStatistics) { + this.gatherStatistics = skipStatistics; + if(logger.isInfoEnabled()) { + logger.info("Gathering Statistics set to " + skipStatistics); + } + } + + /** + * @return the skipStatistics + */ + public boolean isGatherStatistics() { + return gatherStatistics; + } + + /** + * PRESENT TO ACCOMODATE JOPR. NEED TO FILE A BUG ON THIS + * @return the skipStatistics + */ + public boolean getGatherStatistics() { + return gatherStatistics; + } + + /** + * @param backToNormalPercentageOfMemoryUsed the backToNormalPercentageOfMemoryUsed to set + */ + public void setBackToNormalMemoryThreshold( + int backToNormalMemoryThreshold) { + this.backToNormalMemoryThreshold = backToNormalMemoryThreshold; + } + + /** + * @return the backToNormalPercentageOfMemoryUsed + */ + public int getBackToNormalMemoryThreshold() { + return backToNormalMemoryThreshold; + } + + /** + * @param backToNormalQueueSize the backToNormalQueueSize to set + */ + public void setBackToNormalSipMessageQueueSize(int backToNormalSipMessageQueueSize) { + this.backToNormalSipMessageQueueSize = backToNormalSipMessageQueueSize; + } + + /** + * @return the backToNormalQueueSize + */ + public int getBackToNormalSipMessageQueueSize() { + return backToNormalSipMessageQueueSize; + } + + + /** + * @param congestionControlPolicy the congestionControlPolicy to set + */ + public void setCongestionControlPolicy(String congestionControlPolicy) { + this.congestionControlPolicy = congestionControlPolicy; + } + + + /** + * @return the congestionControlPolicy + */ + public String getCongestionControlPolicy() { + return congestionControlPolicy; + } + + + /** + * @param congestionControlCheckingInterval the congestionControlCheckingInterval to set + */ + public void setCongestionControlCheckingInterval( + long congestionControlCheckingInterval) { + this.congestionControlCheckingInterval = congestionControlCheckingInterval; + } + + + /** + * @return the congestionControlCheckingInterval + */ + public long getCongestionControlCheckingInterval() { + return congestionControlCheckingInterval; + } + + + public String getAdditionalParameterableHeaders() { + return additionalParameterableHeaders; + } + + + public void setAdditionalParameterableHeaders( + String additionalParameterableHeaders) { + this.additionalParameterableHeaders = additionalParameterableHeaders; + String[] headers = additionalParameterableHeaders.split(","); + for(String header : headers) { + if(header != null && header.length()>0) { + JainSipUtils.PARAMETERABLE_HEADER_NAMES.add(header); + } + } + } + + + /** + * @return the bypassResponseExecutor + */ + public boolean isBypassResponseExecutor() { + return bypassResponseExecutor; + } + + + /** + * @param bypassResponseExecutor the bypassResponseExecutor to set + */ + public void setBypassResponseExecutor(boolean bypassResponseExecutor) { + this.bypassResponseExecutor = bypassResponseExecutor; + } + + + /** + * @return the bypassRequestExecutor + */ + public boolean isBypassRequestExecutor() { + return bypassRequestExecutor; + } + + + /** + * @param bypassRequestExecutor the bypassRequestExecutor to set + */ + public void setBypassRequestExecutor(boolean bypassRequestExecutor) { + this.bypassRequestExecutor = bypassRequestExecutor; + } + + public boolean isMd5ContactUserPart() { + return md5ContactUserPart; + } + + + public void setMd5ContactUserPart(boolean md5ContactUserPart) { + this.md5ContactUserPart = md5ContactUserPart; + } + + + /** + * @param usePrettyEncoding the usePrettyEncoding to set + */ + public void setUsePrettyEncoding(boolean usePrettyEncoding) { + this.usePrettyEncoding = usePrettyEncoding; + } + + /** + * @return the usePrettyEncoding + */ + public boolean isUsePrettyEncoding() { + return usePrettyEncoding; + } + + /** + * @param sipPathName the sipPathName to set + */ + public void setSipPathName(String sipPathName) { + this.sipPathName = sipPathName; + } + + /** + * @return the sipPathName + */ + public String getSipPathName() { + return sipPathName; + } + + + /** + * @param baseTimerInterval the baseTimerInterval to set + */ + public void setBaseTimerInterval(int baseTimerInterval) { + this.baseTimerInterval = baseTimerInterval; + } + + + /** + * @return the baseTimerInterval + */ + public int getBaseTimerInterval() { + return baseTimerInterval; + } + + + public OutboundProxy getOutboundProxy() { + return outboundProxy; + } + + + public void setOutboundProxy(String outboundProxy) { + if(outboundProxy != null) { + this.outboundProxy = new OutboundProxy(outboundProxy); + } else { + this.outboundProxy = null; + } + if(logger.isDebugEnabled()) { + logger.debug("Outbound Proxy : " + outboundProxy); + } + } + + public int getDispatcherThreadPoolSize() { + return dispatcherThreadPoolSize; + } + + + public void setDispatcherThreadPoolSize(int dispatcherThreadPoolSize) { + this.dispatcherThreadPoolSize = dispatcherThreadPoolSize; + } + + public int getCanceledTimerTasksPurgePeriod() { + return canceledTimerTasksPurgePeriod; + } + + public void setCanceledTimerTasksPurgePeriod(int purgePeriod) { + this.canceledTimerTasksPurgePeriod = purgePeriod; + } + + + /** + * @deprecated + * @param balancers the balancers to set + */ + public void setBalancers(String balancers) { + this.balancers = balancers; + } + + public boolean addSipConnector(SipConnector sipConnector) throws Exception { + if(sipConnector == null) { + throw new IllegalArgumentException("The sip connector passed is null"); + } + Connector connectorToAdd = findSipConnector(sipConnector.getIpAddress(), sipConnector.getPort(), + sipConnector.getTransport()); + if(connectorToAdd == null) { + Connector connector = new Connector( + SipProtocolHandler.class.getName()); + SipProtocolHandler sipProtocolHandler = (SipProtocolHandler) connector + .getProtocolHandler(); + sipProtocolHandler.setSipConnector(sipConnector); + sipProtocolHandler.setSipStack(sipStack); + connector.setService(this); +//TODO connector.setContainer(container); + connector.init(); + addConnector(connector); + MobicentsExtendedListeningPoint extendedListeningPoint = (MobicentsExtendedListeningPoint) + sipProtocolHandler.getAttribute(ExtendedListeningPoint.class.getSimpleName()); + if(extendedListeningPoint != null) { + try { + extendedListeningPoint.getSipProvider().addSipListener(sipApplicationDispatcher); + sipApplicationDispatcher.getSipNetworkInterfaceManager().addExtendedListeningPoint(extendedListeningPoint); + } catch (TooManyListenersException e) { + logger.error("Connector.initialize", e); + removeConnector(connector); + return false; + } + } + if(!sipProtocolHandler.isStarted()) { + if(logger.isDebugEnabled()) { + logger.debug("Sip Connector couldn't be started, removing it automatically"); + } + removeConnector(connector); + } + return sipProtocolHandler.isStarted(); + } + return false; + } + + public boolean removeSipConnector(String ipAddress, int port, String transport) throws Exception { + Connector connectorToRemove = findSipConnector(ipAddress, port, + transport); + if(connectorToRemove != null) { + removeConnector(connectorToRemove); + return true; + } + return false; + } + + + /** + * Find a sip Connector by it's ip address, port and transport + * @param ipAddress ip address of the connector to find + * @param port port of the connector to find + * @param transport transport of the connector to find + * @return the found sip connector or null if noting found + */ + private Connector findSipConnector(String ipAddress, int port, + String transport) { + Connector connectorToRemove = null; + for (Connector connector : connectors) { + final ProtocolHandler protocolHandler = connector.getProtocolHandler(); + if(protocolHandler instanceof SipProtocolHandler) { + final SipProtocolHandler sipProtocolHandler = (SipProtocolHandler) protocolHandler; + if(sipProtocolHandler.getIpAddress().equals(ipAddress) && sipProtocolHandler.getPort() == port && sipProtocolHandler.getSignalingTransport().equalsIgnoreCase(transport)) { +// connector.destroy(); + connectorToRemove = connector; + break; + } + } + } + return connectorToRemove; + } + + public SipConnector findSipConnector(String transport) { + List sipConnectors = new ArrayList(); + for (Connector connector : connectors) { + final ProtocolHandler protocolHandler = connector.getProtocolHandler(); + if(protocolHandler instanceof SipProtocolHandler) { + SipConnector sc = (((SipProtocolHandler)protocolHandler).getSipConnector()); + if(sc.getTransport().equalsIgnoreCase(transport)) return sc; + } + } + return null; + } + + public SipConnector[] findSipConnectors() { + List sipConnectors = new ArrayList(); + for (Connector connector : connectors) { + final ProtocolHandler protocolHandler = connector.getProtocolHandler(); + if(protocolHandler instanceof SipProtocolHandler) { + sipConnectors.add(((SipProtocolHandler)protocolHandler).getSipConnector()); + } + } + return sipConnectors.toArray(new SipConnector[sipConnectors.size()]); + } + + /** + * This method simply makes the HTTP and SSL ports avaialble everywhere in the JVM in order jsip ha to read them for + * balancer description purposes. There is no other good way to communicate the properies to jsip ha without adding + * more dependencies. + */ + public void initializeSystemPortProperties() { + for (Connector connector : connectors) { + if(connector.getProtocol().contains("HTTP")) { + if(connector.getSecure()) { + System.setProperty("org.mobicents.properties.sslPort", Integer.toString(connector.getPort())); + } else { + System.setProperty("org.mobicents.properties.httpPort", Integer.toString(connector.getPort())); + } + } + } + } + + protected ObjectName createSipConnectorObjectName(Connector connector, String domain, String type) + throws MalformedObjectNameException { + String encodedAddr = null; + if (connector.getProperty("address") != null) { + encodedAddr = URLEncoder.encode(connector.getProperty("address").toString()); + } + String addSuffix = (connector.getProperty("address") == null) ? "" : ",address=" + + encodedAddr; + ObjectName _oname = new ObjectName(domain + ":type=" + type + ",port=" + + connector.getPort() + ",transport=" + connector.getProperty("transport") + addSuffix); + return _oname; + } + + + /** + * @param t2Interval the t2Interval to set + */ + public void setT2Interval(int t2Interval) { + this.t2Interval = t2Interval; + } + + + /** + * @return the t2Interval + */ + public int getT2Interval() { + return t2Interval; + } + + + /** + * @param t4Interval the t4Interval to set + */ + public void setT4Interval(int t4Interval) { + this.t4Interval = t4Interval; + } + + + /** + * @return the t4Interval + */ + public int getT4Interval() { + return t4Interval; + } + + + /** + * @param timerDInterval the timerDInterval to set + */ + public void setTimerDInterval(int timerDInterval) { + this.timerDInterval = timerDInterval; + } + + + /** + * @return the timerDInterval + */ + public int getTimerDInterval() { + return timerDInterval; + } + + /** + * @param sipStackPropertiesFile the sipStackPropertiesFile to set + */ + public void setSipStackPropertiesFile(String sipStackPropertiesFile) { + sipStackPropertiesFileLocation = sipStackPropertiesFile; + } + + /** + * @return the sipStackProperties + */ + public Properties getSipStackProperties() { + return sipStackProperties; + } + + /** + * @param sipStackProperties the sipStackProperties to set + */ + public void setSipStackProperties(Properties sipStackProperties) { + this.sipStackProperties = sipStackProperties; + } + + /** + * @return the sipStackPropertiesFile + */ + public String getSipStackPropertiesFile() { + return sipStackPropertiesFileLocation; + } + + /** + * @param dnsAddressResolverClass the dnsAddressResolverClass to set + */ + @Deprecated + public void setAddressResolverClass(String dnsAddressResolverClass) { + this.addressResolverClass = dnsAddressResolverClass; + } + + /** + * @return the dnsAddressResolverClass + */ + @Deprecated + public String getAddressResolverClass() { + return addressResolverClass; + } + + /** + * Whether we check for pending requests and return 491 response if there are any + * + * @return the flag value + */ + public boolean isDialogPendingRequestChecking() { + return dialogPendingRequestChecking; + } + + /** + * + * Whether we check for pending requests and return 491 response if there are any + * + * @param dialogPendingRequestChecking + */ + public void setDialogPendingRequestChecking(boolean dialogPendingRequestChecking) { + this.dialogPendingRequestChecking = dialogPendingRequestChecking; + } + + + public boolean isHttpFollowsSip() { + return httpFollowsSip; + } + + + public void setHttpFollowsSip(boolean httpFollowsSip) { + this.httpFollowsSip = httpFollowsSip; + } + + /** + * @return the tagHashMaxLength + */ + public int getTagHashMaxLength() { + return tagHashMaxLength; + } + + /** + * @param tagHashMaxLength the tagHashMaxLength to set + */ + public void setTagHashMaxLength(int tagHashMaxLength) { + this.tagHashMaxLength = tagHashMaxLength; + } + + /** + * @return the callIdMaxLength + */ + public int getCallIdMaxLength() { + return callIdMaxLength; + } + + /** + * @param callIdMaxLength the callIdMaxLength to set + */ + public void setCallIdMaxLength(int callIdMaxLength) { + this.callIdMaxLength = callIdMaxLength; + } + + /** + * @return the sipStack + */ + public SipStack getSipStack() { + return sipStack; + } + + /** + * @param dnsServerLocatorClass the dnsServerLocatorClass to set + */ + public void setDnsServerLocatorClass(String dnsServerLocatorClass) { + this.dnsServerLocatorClass = dnsServerLocatorClass; + } + + /** + * @return the dnsServerLocatorClass + */ + public String getDnsServerLocatorClass() { + return dnsServerLocatorClass; + } + + /** + * @param dnsResolverClass the dnsResolverClass to set + */ + public void setDnsResolverClass(String dnsResolverClass) { + this.dnsResolverClass = dnsResolverClass; + } + + /** + * @return the dnsResolverClass + */ + public String getDnsResolverClass() { + return dnsResolverClass; + } + + + /** + * Returns first the catalina.base if it is defined then the catalina.home if it is defined + * then the current dir if none is specified + */ + protected String getCatalinaBase() { + String catalinaBase = System.getProperty("catalina.base"); + if (catalinaBase == null) { + catalinaBase = System.getProperty("catalina.home"); + } + if(catalinaBase == null) { + catalinaBase = "."; + } + return catalinaBase; + } + + public ReplicationStrategy getReplicationStrategy() { + return replicationStrategy; + } + + @Override + public String getMobicentsSipServletMessageFactoryClassName() { + return mobicentsSipServletMessageFactoryClassName; + } + + @Override + public void setMobicentsSipServletMessageFactoryClassName( + String mobicentsSipServletMessageFactoryClassName) { + this.mobicentsSipServletMessageFactoryClassName = mobicentsSipServletMessageFactoryClassName; + } + + public void sendHeartBeat(String localAddress, int localPort, String transport, String remoteIpAddress, int remotePort) throws IOException { + MobicentsExtendedListeningPoint extendedListeningPoint = sipApplicationDispatcher.getSipNetworkInterfaceManager().findMatchingListeningPoint(localAddress, localPort, transport); + if(extendedListeningPoint != null) { + extendedListeningPoint.getListeningPoint().sendHeartbeat(remoteIpAddress, remotePort); + } + } + + public boolean setKeepAliveTimeout(SipConnector sipConnector, String clientAddress, int clientPort, long timeout) { + SIPTransactionStack sipStack = ((SIPTransactionStack) sipApplicationDispatcher.getSipStack()); + + return sipStack.setKeepAliveTimeout(sipConnector.getIpAddress(), sipConnector.getPort(), sipConnector.getTransport(), + clientAddress, clientPort, timeout); + } + + public void closeReliableConnection(SipConnector sipConnector, String clientAddress, int clientPort) { + SIPTransactionStack sipStack = ((SIPTransactionStack) sipApplicationDispatcher.getSipStack()); + + sipStack.closeReliableConnection(sipConnector.getIpAddress(),sipConnector.getPort(), sipConnector.getTransport(), + clientAddress, clientPort); + } + + private long gracefulInterval = 30000; + + /* + * (non-Javadoc) + * @see org.mobicents.servlet.sip.core.SipService#stopGracefully(long) + */ + @Override + public void stopGracefully(long timeToWait) { + if(logger.isInfoEnabled()) { + logger.info("Stopping the Server Gracefully in " + timeToWait + " ms"); + } + if(timeToWait == 0) { + if(gracefulStopFuture != null) { + gracefulStopFuture.cancel(false); + } + try { + getServer().stop(); + } catch (LifecycleException e) { + logger.error("The server couldn't be stopped", e); + } + } else { + sipApplicationDispatcher.setGracefulShutdown(true); + Iterator sipContexts = sipApplicationDispatcher.findSipApplications(); + while (sipContexts.hasNext()) { + SipContext sipContext = sipContexts.next(); + sipContext.setGracefulInterval(gracefulInterval); + sipContext.stopGracefully(timeToWait); + } + gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().scheduleWithFixedDelay(new ServiceGracefulStopTask(this), gracefulInterval, gracefulInterval, TimeUnit.MILLISECONDS); + if(timeToWait > 0) { + gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().schedule( + new Runnable() { + public void run() { + gracefulStopFuture.cancel(false); + try { + getServer().stop(); + } catch (LifecycleException e) { + logger.error("The server couldn't be stopped", e); + } + } + } + , timeToWait, TimeUnit.MILLISECONDS); + } + } + } + + /** + * @return the dnsTimeout + */ + public int getDnsTimeout() { + return dnsTimeout; + } + + /** + * @param dnsTimeout the dnsTimeout to set + */ + public void setDnsTimeout(int dnsTimeout) { + this.dnsTimeout = dnsTimeout; + } + + public String getProxyTimerServiceImplementationType() { + return proxyTimerServiceImplementationType; + } + + public void setProxyTimerServiceImplementationType(String proxyTimerServiceImplementationType) { + this.proxyTimerServiceImplementationType = proxyTimerServiceImplementationType; + } + + public String getSasTimerServiceImplementationType() { + return sasTimerServiceImplementationType; + } + + public void setSasTimerServiceImplementationType(String sasTimerServiceImplementationType) { + this.sasTimerServiceImplementationType = sasTimerServiceImplementationType; + } + + public void setGracefulInterval(long gracefulInterval) { + this.gracefulInterval = gracefulInterval; + } + + +} diff --git a/containers/tomcat-7/.classpath b/containers/tomcat-7/.classpath index fdfa68015c..af1ace8115 100644 --- a/containers/tomcat-7/.classpath +++ b/containers/tomcat-7/.classpath @@ -3,35 +3,63 @@ - + + - + + + + + + + + + + + + + + + + + + + + - - - - + + + + + - - + - - - - - - - + + + + + + + + + + + + + + + diff --git a/containers/tomcat-7/src/main/java/org/mobicents/servlet/sip/startup/SipStandardContext.java b/containers/tomcat-7/src/main/java/org/mobicents/servlet/sip/startup/SipStandardContext.java index 1b6cd4d9e9..e7d2f3e1fd 100644 --- a/containers/tomcat-7/src/main/java/org/mobicents/servlet/sip/startup/SipStandardContext.java +++ b/containers/tomcat-7/src/main/java/org/mobicents/servlet/sip/startup/SipStandardContext.java @@ -66,6 +66,7 @@ import org.apache.naming.resources.FileDirContext; import org.apache.naming.resources.WARDirContext; import org.apache.tomcat.InstanceManager; +import org.mobicents.javax.servlet.GracefulShutdownStartedEvent; import org.mobicents.servlet.sip.SipConnector; import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; import org.mobicents.servlet.sip.annotations.DefaultSipInstanceManager; @@ -134,6 +135,9 @@ public class SipStandardContext extends StandardContext implements CatalinaSipCo // application session is 3 minutes private static int DEFAULT_LIFETIME = 3; + // The key to get configurable timer serive pool size + private static final String TIMER_SERVICE_POOL_SIZE = "org.restcomm.servlets.sip.TIMER_SERVICE_THREADS"; + protected String applicationName; protected String smallIcon; protected String largeIcon; @@ -183,8 +187,6 @@ public class SipStandardContext extends StandardContext implements CatalinaSipCo protected transient SipServletTimerService timerService = null; // timer service used to schedule proxy timer tasks protected transient ProxyTimerService proxyTimerService = null; - // http://code.google.com/p/mobicents/issues/detail?id=2450 - private transient ThreadLocal sipApplicationSessionsAccessedThreadLocal = new ThreadLocal(); // http://code.google.com/p/mobicents/issues/detail?id=2534 && http://code.google.com/p/mobicents/issues/detail?id=2526 private transient ThreadLocal isManagedThread = new ThreadLocal(); // http://code.google.com/p/sipservlets/issues/detail?id=195 @@ -225,67 +227,85 @@ public void initInternal() throws LifecycleException { // is correctly initialized too super.initInternal(); - prepareServletContext(); + initInternalApplicationComponents(); if(logger.isInfoEnabled()) { logger.info("sip context Initialized " + getName()); } } - - protected void prepareServletContext() throws LifecycleException { - if(sipApplicationDispatcher == null) { - setApplicationDispatcher(); - } - if(sipFactoryFacade == null) { - sipFactoryFacade = new SipFactoryFacade((SipFactoryImpl)sipApplicationDispatcher.getSipFactory(), this); - } - if(sipSessionsUtil == null) { - sipSessionsUtil = new SipSessionsUtilImpl(this); - } - if(timerService == null) { - timerService = new TimerServiceImpl(sipApplicationDispatcher.getSipService(), applicationName); - } - if(proxyTimerService == null) { - String proxyTimerServiceType = sipApplicationDispatcher.getSipService().getProxyTimerServiceImplementationType(); - if(proxyTimerServiceType != null && proxyTimerServiceType.equalsIgnoreCase("Standard")) { - proxyTimerService = new ProxyTimerServiceImpl(applicationName); - } else if(proxyTimerServiceType != null && proxyTimerServiceType.equalsIgnoreCase("Default")) { - proxyTimerService = new DefaultProxyTimerService(applicationName); - } else { - proxyTimerService = new ProxyTimerServiceImpl(applicationName); - } - } - - if(sasTimerService == null || !sasTimerService.isStarted()) { - String sasTimerServiceType = sipApplicationDispatcher.getSipService().getSasTimerServiceImplementationType(); - if(sasTimerServiceType != null && sasTimerServiceType.equalsIgnoreCase("Standard")) { + + /** + * This function is to prepare basic servlet context attributes before the underlying + * context is really ready. + * + * The method is designed to be idempotent, so we may call it as many times as + * required to actually initiate all possible structures/atts. + * + * @throws LifecycleException + */ + protected void initInternalApplicationComponents() throws LifecycleException { + if (sipApplicationDispatcher == null) { + setApplicationDispatcher(); + } + if (sipFactoryFacade == null) { + sipFactoryFacade = new SipFactoryFacade((SipFactoryImpl) sipApplicationDispatcher.getSipFactory(), this); + } + if (sipSessionsUtil == null) { + sipSessionsUtil = new SipSessionsUtilImpl(this); + } + if (timerService == null) { + timerService = new TimerServiceImpl(sipApplicationDispatcher.getSipService(), applicationName); + } + if (sasTimerService == null || !sasTimerService.isStarted()) { + String sasTimerServiceType = sipApplicationDispatcher.getSipService().getSasTimerServiceImplementationType(); + if (sasTimerServiceType != null && sasTimerServiceType.equalsIgnoreCase("Standard")) { sasTimerService = new StandardSipApplicationSessionTimerService(applicationName); } else if (sasTimerServiceType != null && sasTimerServiceType.equalsIgnoreCase("Default")) { sasTimerService = new DefaultSipApplicationSessionTimerService(applicationName); } else { sasTimerService = new StandardSipApplicationSessionTimerService(applicationName); } - } - //needed when restarting applications through the tomcat manager - this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.SIP_FACTORY, - sipFactoryFacade); - this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.TIMER_SERVICE, - timerService); - this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.SUPPORTED, - Arrays.asList(sipApplicationDispatcher.getExtensionsSupported())); - this.getServletContext().setAttribute("javax.servlet.sip.100rel", Boolean.TRUE); - this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.SUPPORTED_RFCs, - Arrays.asList(sipApplicationDispatcher.getRfcSupported())); - this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.SIP_SESSIONS_UTIL, - sipSessionsUtil); - this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.OUTBOUND_INTERFACES, - sipApplicationDispatcher.getOutboundInterfaces()); - this.getServletContext().setAttribute("org.mobicents.servlet.sip.SIP_CONNECTORS", - sipApplicationDispatcher.getSipService().findSipConnectors()); - this.getServletContext().setAttribute("org.mobicents.servlet.sip.DNS_RESOLVER", - sipApplicationDispatcher.getDNSResolver()); - } + } + // needed when restarting applications through the tomcat manager + this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.SIP_FACTORY, sipFactoryFacade); + this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.TIMER_SERVICE, timerService); + this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.SUPPORTED, + Arrays.asList(sipApplicationDispatcher.getExtensionsSupported())); + this.getServletContext().setAttribute("javax.servlet.sip.100rel", Boolean.TRUE); + this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.SUPPORTED_RFCs, + Arrays.asList(sipApplicationDispatcher.getRfcSupported())); + this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.SIP_SESSIONS_UTIL, sipSessionsUtil); + this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.OUTBOUND_INTERFACES, + sipApplicationDispatcher.getOutboundInterfaces()); + this.getServletContext().setAttribute("org.mobicents.servlet.sip.SIP_CONNECTORS", + sipApplicationDispatcher.getSipService().findSipConnectors()); + this.getServletContext().setAttribute("org.mobicents.servlet.sip.DNS_RESOLVER", + sipApplicationDispatcher.getDNSResolver()); + + if (proxyTimerService == null) { + String proxyTimerServiceType = sipApplicationDispatcher.getSipService().getProxyTimerServiceImplementationType(); + if (proxyTimerServiceType != null && proxyTimerServiceType.equalsIgnoreCase("Standard")) { + proxyTimerService = new ProxyTimerServiceImpl(applicationName); + } else if (proxyTimerServiceType != null && proxyTimerServiceType.equalsIgnoreCase("Default")) { + String strCorePoolSize = this.getServletContext().getInitParameter(TIMER_SERVICE_POOL_SIZE); + if (strCorePoolSize != null && !strCorePoolSize.isEmpty()) { + try { + int CorePoolSize = Integer.parseInt(strCorePoolSize); + proxyTimerService = new DefaultProxyTimerService(applicationName, CorePoolSize); + } catch (NumberFormatException ex) { + logger.warn("Failed to parse timer service pool size with string value [" + strCorePoolSize + "], use default value."); + proxyTimerService = new DefaultProxyTimerService(applicationName); + } + } else { + proxyTimerService = new DefaultProxyTimerService(applicationName); + } + } else { + proxyTimerService = new ProxyTimerServiceImpl(applicationName); + } + } + } + /** * @throws Exception */ @@ -309,7 +329,7 @@ public synchronized void startInternal() throws LifecycleException { logger.info("Starting the sip context " + getName()); } // if( this.getState().equals(LifecycleState.INITIALIZED)) { - prepareServletContext(); + initInternalApplicationComponents(); // } // Add missing components as necessary boolean ok = true; @@ -1146,7 +1166,7 @@ public boolean notifySipContextListeners(SipContextEvent event) { //the context again just in case some att was not properly //initiated try { - prepareServletContext(); + initInternalApplicationComponents(); } catch (Exception e) { logger.warn("Couldnt prepare context", e); } @@ -1296,10 +1316,10 @@ public void enterSipApp(MobicentsSipApplicationSession sipApplicationSession, Mo isManagedThread.set(Boolean.TRUE); } if(sipApplicationSession != null) { - SipApplicationSessionCreationThreadLocal sipApplicationSessionCreationThreadLocal = sipApplicationSessionsAccessedThreadLocal.get(); + SipApplicationSessionCreationThreadLocal sipApplicationSessionCreationThreadLocal = SipApplicationSessionCreationThreadLocal.getTHRef().get(); if(sipApplicationSessionCreationThreadLocal == null) { sipApplicationSessionCreationThreadLocal = new SipApplicationSessionCreationThreadLocal(); - sipApplicationSessionsAccessedThreadLocal.set(sipApplicationSessionCreationThreadLocal); + SipApplicationSessionCreationThreadLocal.getTHRef().set(sipApplicationSessionCreationThreadLocal); } boolean notPresent = sipApplicationSessionCreationThreadLocal.getSipApplicationSessions().add(sipApplicationSession); if(notPresent && isContainerManaged) { @@ -1348,17 +1368,17 @@ public void exitSipApp(MobicentsSipApplicationSession sipApplicationSession, Mob break; case SipApplicationSession: boolean wasSessionReleased = false; - SipApplicationSessionCreationThreadLocal sipApplicationSessionCreationThreadLocal = sipApplicationSessionsAccessedThreadLocal.get(); + SipApplicationSessionCreationThreadLocal sipApplicationSessionCreationThreadLocal = SipApplicationSessionCreationThreadLocal.getTHRef().get(); if(sipApplicationSessionCreationThreadLocal != null) { - for(MobicentsSipApplicationSession sipApplicationSessionAccessed : sipApplicationSessionsAccessedThreadLocal.get().getSipApplicationSessions()) { + for(MobicentsSipApplicationSession sipApplicationSessionAccessed : SipApplicationSessionCreationThreadLocal.getTHRef().get().getSipApplicationSessions()) { sipApplicationSessionAccessed.release(); if(sipApplicationSessionAccessed.equals(sipApplicationSession)) { wasSessionReleased = true; } } - sipApplicationSessionsAccessedThreadLocal.get().getSipApplicationSessions().clear(); - sipApplicationSessionsAccessedThreadLocal.set(null); - sipApplicationSessionsAccessedThreadLocal.remove(); + SipApplicationSessionCreationThreadLocal.getTHRef().get().getSipApplicationSessions().clear(); + SipApplicationSessionCreationThreadLocal.getTHRef().set(null); + SipApplicationSessionCreationThreadLocal.getTHRef().remove(); } isManagedThread.set(null); isManagedThread.remove(); @@ -1531,6 +1551,8 @@ public void exitSipContext(ClassLoader oldClassLoader) { Thread.currentThread().setContextClassLoader(oldClassLoader); } + private long gracefulInterval = 30000; + @Override /* * (non-Javadoc) @@ -1542,6 +1564,8 @@ public void stopGracefully(long timeToWait) { if(logger.isInfoEnabled()) { logger.info("Stopping the Context " + getName() + " Gracefully in " + timeToWait + " ms"); } + GracefulShutdownStartedEvent event = new GracefulShutdownStartedEvent(timeToWait); + getListeners().callbackContainerListener(event); // Guarantees that the application won't be routed any initial requests anymore but will still handle subsequent requests List applicationsUndeployed = new ArrayList(); applicationsUndeployed.add(applicationName); @@ -1556,14 +1580,14 @@ public void stopGracefully(long timeToWait) { } catch (LifecycleException e) { logger.error("The server couldn't be stopped", e); } - } else { - long gracefulStopTaskInterval = 30000; - if(timeToWait > 0 && timeToWait < gracefulStopTaskInterval) { + } else { + + if(timeToWait > 0 && timeToWait < gracefulInterval) { // if the time to Wait is < to the gracefulStopTaskInterval then we schedule the task directly once to the time to wait gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().schedule(new ContextGracefulStopTask(this, timeToWait), timeToWait, TimeUnit.MILLISECONDS); } else { // if the time to Wait is > to the gracefulStopTaskInterval or infinite (negative value) then we schedule the task to run every gracefulStopTaskInterval, not needed to be exactly precise on the timeToWait in this case - gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().scheduleWithFixedDelay(new ContextGracefulStopTask(this, timeToWait), gracefulStopTaskInterval, gracefulStopTaskInterval, TimeUnit.MILLISECONDS); + gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().scheduleWithFixedDelay(new ContextGracefulStopTask(this, timeToWait), 0, gracefulInterval, TimeUnit.MILLISECONDS); } } } @@ -1592,4 +1616,14 @@ public int compare(MobicentsSipServlet o1, MobicentsSipServlet o2) { return 0; } } + + public long getGracefulInterval() { + return gracefulInterval; + } + + public void setGracefulInterval(long gracefulInterval) { + this.gracefulInterval = gracefulInterval; + } + + } diff --git a/containers/tomcat-7/src/main/java/org/mobicents/servlet/sip/startup/SipStandardContextValve.java b/containers/tomcat-7/src/main/java/org/mobicents/servlet/sip/startup/SipStandardContextValve.java index d0ab886656..70b026f58c 100644 --- a/containers/tomcat-7/src/main/java/org/mobicents/servlet/sip/startup/SipStandardContextValve.java +++ b/containers/tomcat-7/src/main/java/org/mobicents/servlet/sip/startup/SipStandardContextValve.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.text.ParseException; +import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletRequestEvent; @@ -182,6 +183,17 @@ public final void invoke(Request request, Response response) return; } } + + // Acknowledge the request + try { + response.sendAcknowledgement(); + } catch (IOException ioe) { + container.getLogger().error(sm.getString( + "standardContextValve.acknowledgeException"), ioe); + request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, ioe); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + return; + } // Normal request processing Object instances[] = context.getApplicationEventListeners(); diff --git a/containers/tomcat-8/src/main/java/org/mobicents/servlet/sip/startup/SipStandardContext.java b/containers/tomcat-8/src/main/java/org/mobicents/servlet/sip/startup/SipStandardContext.java index 89d8e17548..b9ba87b210 100644 --- a/containers/tomcat-8/src/main/java/org/mobicents/servlet/sip/startup/SipStandardContext.java +++ b/containers/tomcat-8/src/main/java/org/mobicents/servlet/sip/startup/SipStandardContext.java @@ -73,6 +73,7 @@ import org.apache.tomcat.util.descriptor.web.Injectable; import org.apache.tomcat.util.descriptor.web.InjectionTarget; import org.apache.tomcat.util.descriptor.web.LoginConfig; +import org.mobicents.javax.servlet.GracefulShutdownStartedEvent; import org.mobicents.servlet.sip.SipConnector; import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; import org.mobicents.servlet.sip.annotations.DefaultSipInstanceManager; @@ -140,6 +141,9 @@ public class SipStandardContext extends StandardContext implements CatalinaSipCo // application session is 3 minutes private static int DEFAULT_LIFETIME = 3; + // The key to get configurable timer serive pool size + private static final String TIMER_SERVICE_POOL_SIZE = "org.restcomm.servlets.sip.TIMER_SERVICE_THREADS"; + protected String applicationName; protected String smallIcon; protected String largeIcon; @@ -189,8 +193,6 @@ public class SipStandardContext extends StandardContext implements CatalinaSipCo protected transient SipServletTimerService timerService = null; // timer service used to schedule proxy timer tasks protected transient ProxyTimerService proxyTimerService = null; - // http://code.google.com/p/mobicents/issues/detail?id=2450 - private transient ThreadLocal sipApplicationSessionsAccessedThreadLocal = new ThreadLocal(); // http://code.google.com/p/mobicents/issues/detail?id=2534 && http://code.google.com/p/mobicents/issues/detail?id=2526 private transient ThreadLocal isManagedThread = new ThreadLocal(); // http://code.google.com/p/sipservlets/issues/detail?id=195 @@ -230,66 +232,84 @@ public void initInternal() throws LifecycleException { // is correctly initialized too super.initInternal(); - prepareServletContext(); + initInternalApplicationComponents(); if(logger.isInfoEnabled()) { logger.info("sip context Initialized " + getName()); } } - - protected void prepareServletContext() throws LifecycleException { - if(sipApplicationDispatcher == null) { - setApplicationDispatcher(); - } - if(sipFactoryFacade == null) { - sipFactoryFacade = new SipFactoryFacade((SipFactoryImpl)sipApplicationDispatcher.getSipFactory(), this); - } - if(sipSessionsUtil == null) { - sipSessionsUtil = new SipSessionsUtilImpl(this); - } - if(timerService == null) { - timerService = new TimerServiceImpl(sipApplicationDispatcher.getSipService(), applicationName); - } - if(proxyTimerService == null) { - String proxyTimerServiceType = sipApplicationDispatcher.getSipService().getProxyTimerServiceImplementationType(); - if(proxyTimerServiceType != null && proxyTimerServiceType.equalsIgnoreCase("Standard")) { - proxyTimerService = new ProxyTimerServiceImpl(applicationName); - } else if(proxyTimerServiceType != null && proxyTimerServiceType.equalsIgnoreCase("Default")) { - proxyTimerService = new DefaultProxyTimerService(applicationName); - } else { - proxyTimerService = new ProxyTimerServiceImpl(applicationName); - } - } - - if(sasTimerService == null || !sasTimerService.isStarted()) { - String sasTimerServiceType = sipApplicationDispatcher.getSipService().getSasTimerServiceImplementationType(); - if(sasTimerServiceType != null && sasTimerServiceType.equalsIgnoreCase("Standard")) { + + /** + * This function is to prepare basic servlet context attributes before the underlying + * context is really ready. + * + * The method is designed to be idempotent, so we may call it as many times as + * required to actually initiate all possible structures/atts. + * + * @throws LifecycleException + */ + protected void initInternalApplicationComponents() throws LifecycleException { + if (sipApplicationDispatcher == null) { + setApplicationDispatcher(); + } + if (sipFactoryFacade == null) { + sipFactoryFacade = new SipFactoryFacade((SipFactoryImpl) sipApplicationDispatcher.getSipFactory(), this); + } + if (sipSessionsUtil == null) { + sipSessionsUtil = new SipSessionsUtilImpl(this); + } + if (timerService == null) { + timerService = new TimerServiceImpl(sipApplicationDispatcher.getSipService(), applicationName); + } + if (sasTimerService == null || !sasTimerService.isStarted()) { + String sasTimerServiceType = sipApplicationDispatcher.getSipService().getSasTimerServiceImplementationType(); + if (sasTimerServiceType != null && sasTimerServiceType.equalsIgnoreCase("Standard")) { sasTimerService = new StandardSipApplicationSessionTimerService(applicationName); } else if (sasTimerServiceType != null && sasTimerServiceType.equalsIgnoreCase("Default")) { sasTimerService = new DefaultSipApplicationSessionTimerService(applicationName); } else { sasTimerService = new StandardSipApplicationSessionTimerService(applicationName); } - } - //needed when restarting applications through the tomcat manager - this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.SIP_FACTORY, - sipFactoryFacade); - this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.TIMER_SERVICE, - timerService); - this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.SUPPORTED, - Arrays.asList(sipApplicationDispatcher.getExtensionsSupported())); - this.getServletContext().setAttribute("javax.servlet.sip.100rel", Boolean.TRUE); - this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.SUPPORTED_RFCs, - Arrays.asList(sipApplicationDispatcher.getRfcSupported())); - this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.SIP_SESSIONS_UTIL, - sipSessionsUtil); - this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.OUTBOUND_INTERFACES, - sipApplicationDispatcher.getOutboundInterfaces()); - this.getServletContext().setAttribute("org.mobicents.servlet.sip.SIP_CONNECTORS", - sipApplicationDispatcher.getSipService().findSipConnectors()); - this.getServletContext().setAttribute("org.mobicents.servlet.sip.DNS_RESOLVER", - sipApplicationDispatcher.getDNSResolver()); - } + } + + // needed when restarting applications through the tomcat manager + this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.SIP_FACTORY, sipFactoryFacade); + this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.TIMER_SERVICE, timerService); + this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.SUPPORTED, + Arrays.asList(sipApplicationDispatcher.getExtensionsSupported())); + this.getServletContext().setAttribute("javax.servlet.sip.100rel", Boolean.TRUE); + this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.SUPPORTED_RFCs, + Arrays.asList(sipApplicationDispatcher.getRfcSupported())); + this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.SIP_SESSIONS_UTIL, sipSessionsUtil); + this.getServletContext().setAttribute(javax.servlet.sip.SipServlet.OUTBOUND_INTERFACES, + sipApplicationDispatcher.getOutboundInterfaces()); + this.getServletContext().setAttribute("org.mobicents.servlet.sip.SIP_CONNECTORS", + sipApplicationDispatcher.getSipService().findSipConnectors()); + this.getServletContext().setAttribute("org.mobicents.servlet.sip.DNS_RESOLVER", + sipApplicationDispatcher.getDNSResolver()); + + if (proxyTimerService == null) { + String proxyTimerServiceType = sipApplicationDispatcher.getSipService().getProxyTimerServiceImplementationType(); + if (proxyTimerServiceType != null && proxyTimerServiceType.equalsIgnoreCase("Standard")) { + proxyTimerService = new ProxyTimerServiceImpl(applicationName); + } else if (proxyTimerServiceType != null && proxyTimerServiceType.equalsIgnoreCase("Default")) { + String strCorePoolSize = this.getServletContext().getInitParameter(TIMER_SERVICE_POOL_SIZE); + if (strCorePoolSize != null && !strCorePoolSize.isEmpty()) { + try { + int CorePoolSize = Integer.parseInt(strCorePoolSize); + proxyTimerService = new DefaultProxyTimerService(applicationName, CorePoolSize); + } catch (NumberFormatException ex) { + logger.warn("Failed to parse timer service pool size with string value [" + strCorePoolSize + "], use default value."); + proxyTimerService = new DefaultProxyTimerService(applicationName); + } + } else { + proxyTimerService = new DefaultProxyTimerService(applicationName); + } + } else { + proxyTimerService = new ProxyTimerServiceImpl(applicationName); + } + } + } /** * @throws Exception @@ -314,7 +334,7 @@ public synchronized void startInternal() throws LifecycleException { logger.info("Starting the sip context " + getName()); } // if( this.getState().equals(LifecycleState.INITIALIZED)) { - prepareServletContext(); + initInternalApplicationComponents(); // } // Add missing components as necessary boolean ok = true; @@ -1263,7 +1283,7 @@ public boolean notifySipContextListeners(SipContextEvent event) { //the context again just in case some att was not properly //initiated try { - prepareServletContext(); + initInternalApplicationComponents(); } catch (Exception e) { logger.warn("Couldnt prepare context", e); } @@ -1412,10 +1432,10 @@ public void enterSipApp(MobicentsSipApplicationSession sipApplicationSession, Mo isManagedThread.set(Boolean.TRUE); } if(sipApplicationSession != null) { - SipApplicationSessionCreationThreadLocal sipApplicationSessionCreationThreadLocal = sipApplicationSessionsAccessedThreadLocal.get(); + SipApplicationSessionCreationThreadLocal sipApplicationSessionCreationThreadLocal = SipApplicationSessionCreationThreadLocal.getTHRef().get(); if(sipApplicationSessionCreationThreadLocal == null) { sipApplicationSessionCreationThreadLocal = new SipApplicationSessionCreationThreadLocal(); - sipApplicationSessionsAccessedThreadLocal.set(sipApplicationSessionCreationThreadLocal); + SipApplicationSessionCreationThreadLocal.getTHRef().set(sipApplicationSessionCreationThreadLocal); } boolean notPresent = sipApplicationSessionCreationThreadLocal.getSipApplicationSessions().add(sipApplicationSession); if(notPresent && isContainerManaged) { @@ -1464,17 +1484,17 @@ public void exitSipApp(MobicentsSipApplicationSession sipApplicationSession, Mob break; case SipApplicationSession: boolean wasSessionReleased = false; - SipApplicationSessionCreationThreadLocal sipApplicationSessionCreationThreadLocal = sipApplicationSessionsAccessedThreadLocal.get(); + SipApplicationSessionCreationThreadLocal sipApplicationSessionCreationThreadLocal = SipApplicationSessionCreationThreadLocal.getTHRef().get(); if(sipApplicationSessionCreationThreadLocal != null) { - for(MobicentsSipApplicationSession sipApplicationSessionAccessed : sipApplicationSessionsAccessedThreadLocal.get().getSipApplicationSessions()) { + for(MobicentsSipApplicationSession sipApplicationSessionAccessed : SipApplicationSessionCreationThreadLocal.getTHRef().get().getSipApplicationSessions()) { sipApplicationSessionAccessed.release(); if(sipApplicationSessionAccessed.equals(sipApplicationSession)) { wasSessionReleased = true; } } - sipApplicationSessionsAccessedThreadLocal.get().getSipApplicationSessions().clear(); - sipApplicationSessionsAccessedThreadLocal.set(null); - sipApplicationSessionsAccessedThreadLocal.remove(); + SipApplicationSessionCreationThreadLocal.getTHRef().get().getSipApplicationSessions().clear(); + SipApplicationSessionCreationThreadLocal.getTHRef().set(null); + SipApplicationSessionCreationThreadLocal.getTHRef().remove(); } isManagedThread.set(null); isManagedThread.remove(); @@ -1615,6 +1635,8 @@ public void exitSipContext(ClassLoader oldClassLoader) { Thread.currentThread().setContextClassLoader(oldClassLoader); } + private long gracefulInterval = 30000; + @Override /* * (non-Javadoc) @@ -1626,6 +1648,8 @@ public void stopGracefully(long timeToWait) { if(logger.isInfoEnabled()) { logger.info("Stopping the Context " + getName() + " Gracefully in " + timeToWait + " ms"); } + GracefulShutdownStartedEvent event = new GracefulShutdownStartedEvent(timeToWait); + getListeners().callbackContainerListener(event); // Guarantees that the application won't be routed any initial requests anymore but will still handle subsequent requests List applicationsUndeployed = new ArrayList(); applicationsUndeployed.add(applicationName); @@ -1641,13 +1665,12 @@ public void stopGracefully(long timeToWait) { logger.error("The server couldn't be stopped", e); } } else { - long gracefulStopTaskInterval = 30000; - if(timeToWait > 0 && timeToWait < gracefulStopTaskInterval) { + if(timeToWait > 0 && timeToWait < gracefulInterval) { // if the time to Wait is < to the gracefulStopTaskInterval then we schedule the task directly once to the time to wait gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().schedule(new ContextGracefulStopTask(this, timeToWait), timeToWait, TimeUnit.MILLISECONDS); } else { // if the time to Wait is > to the gracefulStopTaskInterval or infinite (negative value) then we schedule the task to run every gracefulStopTaskInterval, not needed to be exactly precise on the timeToWait in this case - gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().scheduleWithFixedDelay(new ContextGracefulStopTask(this, timeToWait), gracefulStopTaskInterval, gracefulStopTaskInterval, TimeUnit.MILLISECONDS); + gracefulStopFuture = sipApplicationDispatcher.getAsynchronousScheduledExecutor().scheduleWithFixedDelay(new ContextGracefulStopTask(this, timeToWait), 0, gracefulInterval, TimeUnit.MILLISECONDS); } } } @@ -1676,4 +1699,14 @@ public int compare(MobicentsSipServlet o1, MobicentsSipServlet o2) { return 0; } } + + public long getGracefulInterval() { + return gracefulInterval; + } + + public void setGracefulInterval(long gracefulInterval) { + this.gracefulInterval = gracefulInterval; + } + + } diff --git a/containers/tomcat-8/src/main/java/org/mobicents/servlet/sip/startup/SipStandardContextValve.java b/containers/tomcat-8/src/main/java/org/mobicents/servlet/sip/startup/SipStandardContextValve.java index d0ab886656..1ab04e2f49 100644 --- a/containers/tomcat-8/src/main/java/org/mobicents/servlet/sip/startup/SipStandardContextValve.java +++ b/containers/tomcat-8/src/main/java/org/mobicents/servlet/sip/startup/SipStandardContextValve.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.text.ParseException; +import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletRequestEvent; @@ -183,6 +184,17 @@ public final void invoke(Request request, Response response) } } + // Acknowledge the request + try { + response.sendAcknowledgement(); + } catch (IOException ioe) { + container.getLogger().error(sm.getString( + "standardContextValve.acknowledgeException"), ioe); + request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, ioe); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + return; + } + // Normal request processing Object instances[] = context.getApplicationEventListeners(); diff --git a/docs/jdocbook-restcomm/pom.xml b/docs/jdocbook-restcomm/pom.xml deleted file mode 100644 index d10b9f6403..0000000000 --- a/docs/jdocbook-restcomm/pom.xml +++ /dev/null @@ -1,98 +0,0 @@ - - - - - org.mobicents.servlet.sip.docs - sip-servlets-docs - 3.0.0-SNAPSHOT - - - sip-servlets-docs-jdocbook-restcomm - - 4.0.0 - - jdocbook - - - - - org.apache.maven.plugins - maven-dependency-plugin - - - unpack - generate-resources - - unpack - - - - - ${project.groupId} - sip-servlets-docs-sources-restcomm - ${project.version} - jar - true - ${project.build.directory}/docbook/resources - - - - - - - - org.jboss.maven.plugins - maven-jdocbook-plugin - 2.3.5 - true - - - org.mobicents.jdocbook - telestax-xslt-ns - 1.2.0 - - - org.mobicents.jdocbook - telestax-community-style - jdocbook-style - 1.3.0-SNAPSHOT - - - - SIP_Servlets_Server_User_Guide.xml - ${project.build.directory}/docbook/resources - - ${project.build.directory}/docbook/resources/en-US - - images/* - - - - - pdf - classpath:/xslt/org/jboss/pdf.xsl - SIP_Servlets_Server_User_Guide.pdf - - - html - classpath:/xslt/org/jboss/xhtml.xsl - index.html - - - html_single - classpath:/xslt/org/jboss/xhtml-single.xsl - index.html - - - - true - - - 1.72.0 - - - - - - - diff --git a/docs/jdocbook-telscale/pom.xml b/docs/jdocbook-telscale/pom.xml deleted file mode 100644 index bef6707764..0000000000 --- a/docs/jdocbook-telscale/pom.xml +++ /dev/null @@ -1,98 +0,0 @@ - - - - - org.mobicents.servlet.sip.docs - sip-servlets-docs - 3.0.0-SNAPSHOT - - - sip-servlets-docs-jdocbook-telscale - - 4.0.0 - - jdocbook - - - - - org.apache.maven.plugins - maven-dependency-plugin - - - unpack - generate-resources - - unpack - - - - - ${project.groupId} - sip-servlets-docs-sources-telscale - ${project.version} - jar - true - ${project.build.directory}/docbook/resources - - - - - - - - org.jboss.maven.plugins - maven-jdocbook-plugin - 2.3.5 - true - - - org.mobicents.jdocbook - telestax-xslt-ns - 1.2.0 - - - org.mobicents.jdocbook - telestax-telscale-style - jdocbook-style - 1.3.0-SNAPSHOT - - - - SIP_Servlets_Server_User_Guide.xml - ${project.build.directory}/docbook/resources - - ${project.build.directory}/docbook/resources/en-US - - images/* - - - - - pdf - classpath:/xslt/org/jboss/pdf.xsl - SIP_Servlets_Server_User_Guide.pdf - - - html - classpath:/xslt/org/jboss/xhtml.xsl - index.html - - - html_single - classpath:/xslt/org/jboss/xhtml-single.xsl - index.html - - - - true - - - 1.72.0 - - - - - - - diff --git a/docs/pom.xml b/docs/pom.xml index 4a7df26522..7eaf53ce8a 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -22,9 +22,6 @@ all sources-asciidoc - @@ -34,14 +31,12 @@ sources-asciidoc - telscale sources-asciidoc - diff --git a/docs/sources-asciidoc/pom.xml b/docs/sources-asciidoc/pom.xml index b8c3c00101..4ea9e8b0c2 100644 --- a/docs/sources-asciidoc/pom.xml +++ b/docs/sources-asciidoc/pom.xml @@ -21,6 +21,7 @@ UTF-8 1.5.3 1.5.0-alpha.11 + 1.5.0 1.5.4 1.7.21 @@ -55,7 +56,18 @@ asciidoctorj ${asciidoctorj.version} + + + org.asciidoctor + asciidoctorj-diagram + ${asciidoctorj.diagram.version} + + + + asciidoctor-diagram + + output-html-website diff --git a/docs/sources-asciidoc/src/main/asciidoc/SIP_Servlets_Server_User_Guide.adoc b/docs/sources-asciidoc/src/main/asciidoc/SIP_Servlets_Server_User_Guide.adoc index ff413e0bd8..36227f033e 100644 --- a/docs/sources-asciidoc/src/main/asciidoc/SIP_Servlets_Server_User_Guide.adoc +++ b/docs/sources-asciidoc/src/main/asciidoc/SIP_Servlets_Server_User_Guide.adoc @@ -64,11 +64,11 @@ include::concept-chapter-Best_Practices.adoc[] :leveloffset: 0 -:leveloffset: 1 +#:leveloffset: 1 -include::concept-chapter-Appendix.adoc[] +#include::concept-chapter-Appendix.adoc[] -:leveloffset: 0 +#:leveloffset: 0 :leveloffset: 1 diff --git a/docs/sources-asciidoc/src/main/asciidoc/concept-chapter-AS7-mss.adoc b/docs/sources-asciidoc/src/main/asciidoc/concept-chapter-AS7-mss.adoc index fa895e2239..70c43e1aaf 100644 --- a/docs/sources-asciidoc/src/main/asciidoc/concept-chapter-AS7-mss.adoc +++ b/docs/sources-asciidoc/src/main/asciidoc/concept-chapter-AS7-mss.adoc @@ -32,12 +32,6 @@ The root directory of the Restcomm SIP Servlets for JBoss AS7 that you downloade If this is your first time working with Restcomm SIP Servlets for JBoss, you will need to make sure you have Java Run Time or JDK installed on your computer. You will also need to have the environment variables set. -See the links below to learn how to get JRE or JDK setup on your system. - - -link:Common_Content/Java_Development_Kit-Installing_Configuring_and_Running.adoc[Installing and Configuring JDK] - -link:Common_Content/Setting_the_JBOSS_HOME_Environment_Variable.adoc[Setting Environment Variables] . Starting Restcomm SIP Servlets for JBoss AS7 To start the server do the following: @@ -48,7 +42,7 @@ $JBOSS_HOME/bin/standalone.sh ---- During the startup process, you will notice that the final part of the log output will be similar to the truncated output below. -Notice that the Admin Console interface can be accessed at http://172.0.0.1:9990. +Notice that the Admin Console interface can be accessed at `http\://172.0.0.1:9990`. This will be explained later. @@ -62,7 +56,7 @@ started in 22148ms - Started 222 of 306 services (83 services are passive or on- You will notice that the startup is very fast. The reason for this is that JBoss was rewritten from the ground up for speed with services being started concurrently and non critical services remain passive until first use. This provides better system resource management. -With the simple startup above, you will be able to enter the default web interface of the application server by going to this url http://127.0.0.1:8080. +With the simple startup above, you will be able to enter the default web interface of the application server by going to this url 'http\://127.0.0.1:8080'. The result will show a screenshot similar to the one below. @@ -105,7 +99,7 @@ Type the following command: 20:43:21,648 INFO [org.jboss.as] (Controller Boot Thread) JBAS015874: JBoss AS 7.1.2.Final "Steropes" started in 26560ms - Started 232 of 321 services (88 services are passive or on-demand) ---- -The click2call SIP sample application bundled with Restcomm SIP Servlets will become available at this url http://127.0.0.1:8080/click2call. +The click2call SIP sample application bundled with Restcomm SIP Servlets will become available at this url `http\://127.0.0.1:8080/click2call`. You can configure multiple SIP softphones to use the sample application. See the section below for how to configure and test the SIP sample application. @@ -153,7 +147,7 @@ A correctly configured Linphone will look like the screenshot below. image::images/linphone-registration-port-5080.png[] -Once the phones are successfully registered with the Restcomm SIP Servlets for JBoss AS7 server, you can check the result in the sample SIP application at this url, http://127.0.0.1:8080/click2call +Once the phones are successfully registered with the Restcomm SIP Servlets for JBoss AS7 server, you can check the result in the sample SIP application at this url, `http\://127.0.0.1:8080/click2call` @@ -280,7 +274,7 @@ The data from the SIP subsystem are only available if you have the click2call s ==== . SIP Servlets Management Console -There is also a SIP servlets management console that is available at this url http://127.0.0.1:8080/sip-servlets-management. +There is also a SIP servlets management console that is available at this url `http\://127.0.0.1:8080/sip-servlets-management`. The resulting page will be similar to the screenshot below. More information will be provided about the SIP servlets management console in later chapters of this guide. @@ -294,7 +288,7 @@ image::images/sip-servlets-management-console-AS7.png[] == Accessing Management Console Restcomm SIP Servlets for JBoss AS7 provides a management console that can be useful for accessing vital information about your server. -In the welcome page that appears when you access http://127.0.0.1:8080, there is a link that points to the Administration Console. +In the welcome page that appears when you access `http\://127.0.0.1:8080`, there is a link that points to the Administration Console. If you don't have a user account for the management console, you will see a screenshot like the one below. diff --git a/docs/sources-asciidoc/src/main/asciidoc/concept-chapter-Best_Practices.adoc b/docs/sources-asciidoc/src/main/asciidoc/concept-chapter-Best_Practices.adoc index a854719c40..cb402a1f24 100644 --- a/docs/sources-asciidoc/src/main/asciidoc/concept-chapter-Best_Practices.adoc +++ b/docs/sources-asciidoc/src/main/asciidoc/concept-chapter-Best_Practices.adoc @@ -115,7 +115,7 @@ The full list of JAIN SIP stack properties is available from https://mobicents.c === Tuning The JVM -The following tuning information applies to Sun JDK 1.6, however the information should also apply to Sun JDK 1.5. +The following tuning information applies to Sun JDK 1.7 [NOTE] ==== diff --git a/docs/sources-asciidoc/src/main/asciidoc/concept-section-SS_Load_Balancer.adoc b/docs/sources-asciidoc/src/main/asciidoc/concept-section-SS_Load_Balancer.adoc index 0315e7ff04..4db4e05416 100644 --- a/docs/sources-asciidoc/src/main/asciidoc/concept-section-SS_Load_Balancer.adoc +++ b/docs/sources-asciidoc/src/main/asciidoc/concept-section-SS_Load_Balancer.adoc @@ -285,7 +285,7 @@ On Restcomm for JBoss server installations, the default [path]_standalone-sip.xm .Easy Node Configuration with JMX Both SIP Servlet-enabled JBoss and Tomcat have (Java Management Extensions) interfaces that allow for easy server configuration. -The JMX Console is available once the server has been started by navigating to http://localhost:8080/jmx-console/. +The JMX Console is available once the server has been started by navigating to `http\://localhost:8080/jmx-console/`. Both the `balancers` and `heartBeatInterval` attribute values are available under `name=-SIP-Servlets,type=load-balancer-heartbeat-service` in the JMX Console. @@ -405,7 +405,7 @@ Deploy the Location service manually on both nodes. . Start the "Sender" SIP softphone + Start a SIP softphone client with the SIP address of `sip:sender@sip-servlets-com`, listening on port 5055. -The outbound proxy must be specified as the sip-balancer (http://127.0.0.1:5060) +The outbound proxy must be specified as the sip-balancer (`http\://127.0.0.1:5060`) . Start the "Receiver" SIP softphone + diff --git a/docs/sources-asciidoc/src/main/asciidoc/concept-section-SS_TLS.adoc b/docs/sources-asciidoc/src/main/asciidoc/concept-section-SS_TLS.adoc index b4844c5ab3..b3cc229e08 100644 --- a/docs/sources-asciidoc/src/main/asciidoc/concept-section-SS_TLS.adoc +++ b/docs/sources-asciidoc/src/main/asciidoc/concept-section-SS_TLS.adoc @@ -41,9 +41,6 @@ If you leave these two options out, the keytool command will ask you for it. + -keyalg specifies which algorithm to use when generating the keys and the keysize how long those keys should be. + -Note: the command -genkeypair is new in JDK 6 and was previously named -genkey. -The keytool in JDK 6 has some improvements over the previous versions so it is recommended to use it instead. -+ See more about the Java keytool here: http://docs.oracle.com/javase/6/docs/technotes/tools/solaris/keytool.html . Configure the SIP Servlet Container diff --git a/docs/sources-asciidoc/src/main/asciidoc/images/RestComm_Platform.png b/docs/sources-asciidoc/src/main/asciidoc/images/RestComm_Platform.png index e9c364dd86..1ee09c5b6f 100644 Binary files a/docs/sources-asciidoc/src/main/asciidoc/images/RestComm_Platform.png and b/docs/sources-asciidoc/src/main/asciidoc/images/RestComm_Platform.png differ diff --git a/docs/sources-asciidoc/src/main/asciidoc/task-section-SIP_Servlets_Server-Configuring.adoc b/docs/sources-asciidoc/src/main/asciidoc/task-section-SIP_Servlets_Server-Configuring.adoc index 36ae0507cd..5856412be9 100644 --- a/docs/sources-asciidoc/src/main/asciidoc/task-section-SIP_Servlets_Server-Configuring.adoc +++ b/docs/sources-asciidoc/src/main/asciidoc/task-section-SIP_Servlets_Server-Configuring.adoc @@ -1,22 +1,22 @@ [[_bsssc_binary_sip_servlets_server_configuring]] -= Sip Connectors += Sip Connectors Restcomm SIP Servlets comes with default settings that are designed to get your system up and running without the need to know about all the detailed configurations. That said, there are situations in which you might like to fine-tune your setttings to adapt it to your needs. That is what the following section will help you achieve. -You will get a better understand of SIP connectors and how to make them work for you. +You will get a better understand of SIP connectors and how to make them work for you. [[_bsssc_binary_sip_servlets_server_adding_sip_connectors]] == Configuring SIP Connectors and Bindings There are two important configuration files that you might need to modifying depending on your system needs. The standalone-sip.xml file in Restcomm SIP Servlets for JBoss AS7 and the server.xml file in Restcomm SIP Servlets for Tomcat. -The extracts below will give you a snapshot of default configurations. +The extracts below will give you a snapshot of default configurations. .For JBoss Changing the ports and other configuration for the SIP connector can be done in the standalone-sip.xml file. -Below is an extract : +Below is an extract : .Adding a SIP Connector to $JBOSS_HOME/standalone/configuration/standalone-sip.xml ==== @@ -48,12 +48,15 @@ Below is an extract : If you need to add a connector for the same protocol, a new socket-binding should be created. A naming convention should be followed for the name attribute of the new socket-binding. -The convention is -sip-. By example, +The convention is -sip-. By example, + +==== [source,xml] ---- ---- +==== .SIP Attributes @@ -106,25 +109,25 @@ static-server-port:: This parameter is useful in cluster configurations where requests should be bound to a load-balancer address rather than a specific node address. http-follow-sip:: - Makes the application server aware of how the SIP Load Balancers assign request affinity, and stores this information in the application session. + Makes the application server aware of how the SIP Load Balancers assign request affinity, and stores this information in the application session. .For Tomcat Changing the ports and other configuration for the SIP connector can be done in the server.xml file. -Below is an extract. +Below is an extract. .Adding a SIP Connector to $CATALINA_HOME/conf/server.xml ==== [source,xml] ---- - @@ -185,7 +188,7 @@ staticServerPort:: This parameter is useful in cluster configurations where requests should be bound to a load-balancer address rather than a specific node address. httpFollowsSip:: - Makes the application server aware of how the SIP Load Balancers assign request affinity, and stores this information in the application session. + Makes the application server aware of how the SIP Load Balancers assign request affinity, and stores this information in the application session. NOTE: A comprehensive list of implementing classes for the SIP Stack is available from the http://ci.jboss.org/jenkins/job/jain-sip/lastSuccessfulBuild/artifact/javadoc/javax/sip/SipStack.html[Class SipStackImpl page on nist.gov]. @@ -199,14 +202,14 @@ An application router is required for a container to function, but it is a separ The application router is responsible for application selection and must not implement application logic. For example, the application router cannot modify a request or send a response. -For more information about the application router, refer to the following sections of the http://jcp.org/en/jsr/detail?id=289[JSR 289 specification]: Application Router Packaging and Deployment, Application Selection Process, and Appendix C. +For more information about the application router, refer to the following sections of the http://jcp.org/en/jsr/detail?id=289[JSR 289 specification]: Application Router Packaging and Deployment, Application Selection Process, and Appendix C. . [NOTE] ==== -See the example chapters for more information about the Application Router Configuration for SIP Restcomm SIP Servlets for JBoss AS7 +See the example chapters for more information about the Application Router Configuration for SIP Restcomm SIP Servlets for JBoss AS7 -<<_sfss_services_for_sip_servlets>> +<<_sfss_services_for_sip_servlets>> ==== In order to configure the application router for Tomcat, you should edit the `Service` element in the container's [path]_server.xml_ configuration file @@ -219,10 +222,10 @@ In order to configure the application router for Tomcat, you should edit the `Se - - - ----- -==== + + + + + ---- + ==== -The configuration above produces SIP logs that can be found in the $JBOSS_HOME/standalone/log directory. -Below is an extract of the log files. - + The configuration above produces SIP logs that can be found in the $JBOSS_HOME/standalone/log directory. + Below is an extract of the log files. ----- - server.log.2012-08-14 server.log.2012-08-24 -server.log server.log.2012-08-16 server.log.2012-08-25 -server.log.2012-08-07 server.log.2012-08-21 server.log.2012-08-26 -server.log.2012-08-13 server.log.2012-08-22 ----- + ---- -.Logging Files for Restcomm SIP Servlets for Tomcat -If you are working with Tomcat, the log configuration files are located in the $CATALINA_HOME/conf/ directory. -The log4j configuration file is located in $CATALINA_HOME/lib/ directory + server.log.2012-08-14 server.log.2012-08-24 + server.log server.log.2012-08-16 server.log.2012-08-25 + server.log.2012-08-07 server.log.2012-08-21 server.log.2012-08-26 + server.log.2012-08-13 server.log.2012-08-22 + ---- -$CATALINA_HOME/conf/logging.properties + .Logging Files for Restcomm SIP Servlets for Tomcat + If you are working with Tomcat, the log configuration files are located in the $CATALINA_HOME/conf/ directory. + The log4j configuration file is located in $CATALINA_HOME/lib/ directory -$CATALINA_HOME/conf/mss-sip-stack.properties + $CATALINA_HOME/conf/logging.properties -$CATALINA_HOME/conf/server.xml + $CATALINA_HOME/conf/mss-sip-stack.properties -$CATALINA_HOME/lib/log4j.xml + $CATALINA_HOME/conf/server.xml -.Truncated Sample Configuration from Server.xml -.Setting the log file name $CATALINA_HOME/conf/server.xml -==== -[source,xml] ----- + $CATALINA_HOME/lib/log4j.xml + .Truncated Sample Configuration from Server.xml + .Setting the log file name $CATALINA_HOME/conf/server.xml + ==== + [source,xml] + ---- - ----- -==== -.Truncated Sample Configuration from log4j.xml -.Configuring the log file name $CATALINA_HOME/lib/log4j.xml -==== -[source,xml] ----- + + ---- + ==== + .Truncated Sample Configuration from log4j.xml + .Configuring the log file name $CATALINA_HOME/lib/log4j.xml + ==== + [source,xml] + ---- - - - - ----- -==== -The result of the extracted configuration above that is taken from the log4j.xml file and can be found in the $CATALINA_HOME/logs directory. - -JAIN-SIP Stack Logging + + + + + ---- + ==== -There are two separate levels of logging: + The result of the extracted configuration above that is taken from the log4j.xml file and can be found in the $CATALINA_HOME/logs directory. -* Logging at the container level, which can be configured using the [path]_log4j.xml_ or [path]_standalone-sip.xml_ configuration file seen above -* Logging of the JAIN SIP stack, which is configured through the container logging and the SIP stack properties themselves + JAIN-SIP Stack Logging -You can setup the logging so that the JAIN SIP Stack will log into the container logs. + There are two separate levels of logging: -To use LOG4J in JAIN SIP Stack in Tomcat, you need to define a category in [path]_CATALINE_HOME/lib/jboss-log4j.xml_ and set it to `DEBUG`. + * Logging at the container level, which can be configured using the [path]_log4j.xml_ or [path]_standalone-sip.xml_ configuration file seen above + * Logging of the JAIN SIP stack, which is configured through the container logging and the SIP stack properties themselves -.Configuring the JAIN SIP Stack to log into the Tomcat Container's logs -==== -[source,xml] ----- + You can setup the logging so that the JAIN SIP Stack will log into the container logs. - - - ----- -==== + To use LOG4J in JAIN SIP Stack in Tomcat, you need to define a category in [path]_CATALINE_HOME/lib/jboss-log4j.xml_ and set it to `DEBUG`. -To use LOG4J in JAIN SIP Stack in JBoss, you need to define a logger in [path]_JBOSS_HOME/standalone/configuration/standalone-sip.xml_ and set it to `DEBUG`. + .Configuring the JAIN SIP Stack to log into the Tomcat Container's logs + ==== + [source,xml] + ---- -.Configuring the JAIN SIP Stack to log into the JBoss Container's logs -==== -[source,xml] ----- + + + + ---- + ==== - - - ----- -==== + To use LOG4J in JAIN SIP Stack in JBoss, you need to define a logger in [path]_JBOSS_HOME/standalone/configuration/standalone-sip.xml_ and set it to `DEBUG`. -For this category to be used in Restcomm SIP Servlets, you need to specify it in [path]_JBOSS_HOME/standalone/configuration/mss-sip-stack.properties_ or [path]_CATALINE_HOME/conf/mss-sip-stack.properties_, add the `gov.nist.javax.sip.LOG4J_LOGGER_NAME=gov.nist` property, and set the `gov.nist.javax.sip.TRACE_LEVEL=LOG4J` property. + .Configuring the JAIN SIP Stack to log into the JBoss Container's logs + ==== + [source,xml] + ---- -==== -**NOTE** -When using ``loadbalanceraddress`` algorithm for LB it is necessary to add the following at ``mss-sip-stack.properties`` file for the keepalive mechanism: + + + + ---- + ==== ----- -org.mobicents.ha.javax.sip.LoadBalancerHeartBeatingServiceClassName=org.mobicents.ha.javax.sip.MultiNetworkLoadBalancerHeartBeatingServiceImpl ----- + For this category to be used in Restcomm SIP Servlets, you need to specify it in [path]_JBOSS_HOME/standalone/configuration/mss-sip-stack.properties_ or [path]_CATALINE_HOME/conf/mss-sip-stack.properties_, add the `gov.nist.javax.sip.LOG4J_LOGGER_NAME=gov.nist` property, and set the `gov.nist.javax.sip.TRACE_LEVEL=LOG4J` property. + + ==== + **NOTE** + When using ``loadbalanceraddress`` algorithm for LB it is necessary to add the following at ``mss-sip-stack.properties`` file for the keepalive mechanism: + + ---- + org.mobicents.ha.javax.sip.LoadBalancerHeartBeatingServiceClassName=org.mobicents.ha.javax.sip.MultiNetworkLoadBalancerHeartBeatingServiceImpl + ---- diff --git a/docs/sources-asciidoc/src/main/asciidoc/task-section-binary-SIP_Servlets_Server_with_Tomcat-Installing_Configuring_and_Running.adoc b/docs/sources-asciidoc/src/main/asciidoc/task-section-binary-SIP_Servlets_Server_with_Tomcat-Installing_Configuring_and_Running.adoc index 31d2fbaa33..b63f6b19a8 100644 --- a/docs/sources-asciidoc/src/main/asciidoc/task-section-binary-SIP_Servlets_Server_with_Tomcat-Installing_Configuring_and_Running.adoc +++ b/docs/sources-asciidoc/src/main/asciidoc/task-section-binary-SIP_Servlets_Server_with_Tomcat-Installing_Configuring_and_Running.adoc @@ -50,7 +50,7 @@ link:Common_Content/Setting_the_JBOSS_HOME_Environment_Variable.adoc[Setting Env == Testing Click2CallAsync with Restcomm for Tomcat 7 -If Restcomm SIP Servlets for Tomcat 7 is started and running, you should be able to use your web browser to access the welcome page at this url http://127.0.0.1:8080/ This will show you a screenshot similar to the one below. +If Restcomm SIP Servlets for Tomcat 7 is started and running, you should be able to use your web browser to access the welcome page at this url `http\://127.0.0.1:8080/` This will show you a screenshot similar to the one below. @@ -64,13 +64,13 @@ You need to copy your .War files to the $CATALINA_HOME/webapps directory. There is a pre-installed sample SIP application that you can use to test your Restcomm SIP Servlets Tomcat 7 configuration. The application is also located in the $CATALINA_HOME/webapps directory -Start your web browser and go to the link, http://127.0.0.1:8080/Click2CallAsync/ +Start your web browser and go to the link, `http\://127.0.0.1:8080/Click2CallAsync/` .Sample Application Name [NOTE] ==== -Note that the application name is case-sensitive and will not work if you try to access it as http://127.0.0.1:8080/click2callasync/ +Note that the application name is case-sensitive and will not work if you try to access it as `http\://127.0.0.1:8080/click2callasync/` ==== @@ -126,7 +126,7 @@ On the Manage SIP Accounts tab, Leave the rest of the settings as default. ---- -Once the softphones are configured and are successfully registered with the Restcomm SIP Servlets for Tomcat 7 server, you will see a screenshot like the one below in the web browser at this url http://127.0.0.1:8080/Click2CallAsync/ +Once the softphones are configured and are successfully registered with the Restcomm SIP Servlets for Tomcat 7 server, you will see a screenshot like the one below in the web browser at this url `http\://127.0.0.1:8080/Click2CallAsync/` diff --git a/docs/sources-asciidoc/src/main/asciidoc/uml/router-seq-diagram.plantuml b/docs/sources-asciidoc/src/main/asciidoc/uml/router-seq-diagram.plantuml new file mode 100644 index 0000000000..2144b26f3f --- /dev/null +++ b/docs/sources-asciidoc/src/main/asciidoc/uml/router-seq-diagram.plantuml @@ -0,0 +1,72 @@ +@startuml +autonumber +actor UAC +control SIPApplicationDispatcher +control DefaultApplicationRouter +control SipServlet +actor UAS + +legend left + We have to record somewhere the application path + for dialog creating requests for + subsequent requests JSR 289 Spec 15.6 +endlegend + + +UAC -> SIPApplicationDispatcher: request +activate SIPApplicationDispatcher +SIPApplicationDispatcher -> SIPApplicationDispatcher : onRequest +SIPApplicationDispatcher -> SIPApplicationDispatcher : translating jsip req to servlet req +SIPApplicationDispatcher -> SIPApplicationDispatcher : isInitialRequest +note right + use algorithm in Appendix B +end note +SIPApplicationDispatcher -> SIPApplicationDispatcher : checkDirective +note right + Routing directive : + If request is received from an external SIP entity, directive is set to NEW. + If request is received from an application, directive is set either implicitly or explicitly by the application. + end note +SIPApplicationDispatcher -> SIPApplicationDispatcher : setStateInfo + +activate DefaultApplicationRouter +SIPApplicationDispatcher -> DefaultApplicationRouter: getNextApplication +note right + check 15.4 +end note +DefaultApplicationRouter --> SIPApplicationDispatcher : SipApplicationRouterInfo +deactivate DefaultApplicationRouter + +SIPApplicationDispatcher -> SIPApplicationDispatcher : routeRequest +note left + use Algorithm in JSR 289 Spec 15.4.1 +end note +SIPApplicationDispatcher -> SIPApplicationDispatcher : maintainApplicationChain +note left + the Application Chain can be encoded + directly in route headers/ Via Headers or + the container can maintain the application + path by itself as stated in 15.6 +end note + + +activate SipServlet +SIPApplicationDispatcher -> SipServlet: invoke +SipServlet -> SipServlet : appLogic +note left + some Routing directive (NEW, CONTINUE or REVERSE) can be set + by the application to clearly define its intentions. see JSR 289 Section 15.2 +end note +SipServlet --> SIPApplicationDispatcher : sendRequest +deactivate SipServlet + +SIPApplicationDispatcher -> SIPApplicationDispatcher : checkDirective +SIPApplicationDispatcher -> UAS : sendRequest +deactivate SIPApplicationDispatcher + +note over SIPApplicationDispatcher + step 2 to 14 can be done n times until + chain ends when either an application acts as a UAS or + if no more applications are selected and the request is sent to an external SIP entity. +end note +@enduml \ No newline at end of file diff --git a/docs/sources-restcomm/pom.xml b/docs/sources-restcomm/pom.xml deleted file mode 100644 index 0acabfa760..0000000000 --- a/docs/sources-restcomm/pom.xml +++ /dev/null @@ -1,83 +0,0 @@ - - - - 4.0.0 - - - org.mobicents.servlet.sip.docs - sip-servlets-docs - 3.0.0-SNAPSHOT - - - sip-servlets-docs-sources-restcomm - - - RestComm - MSS - mss - mobicents-all-1.2.1.GA-jboss-4.2.3.GA/jboss/ - mss-3.1.633-jboss-as-7.2.0.Final.zip - mss-3.1.633-apache-tomcat-8.0.26.zip - ivelin.atanasoff.ivanov (at) gmail.com - jean.deruelle (at) gmail.com - vladimir.ralev (at) gmail.com - charles.roufay (at) gmail.com - https://github.com/RestComm/sip-servlets/releases/latest - - - - - - ${basedir}/src/main/resources - true - - - - - org.apache.maven.plugins - maven-dependency-plugin - - - unpack - generate-resources - - unpack - - - - - ${project.groupId} - sip-servlets-docs-sources - ${project.version} - jar - true - ${basedir}/src/main/resources - - - - - - - - maven-antrun-plugin - - - clean-resources - clean - - run - - - - - - - - - - - - - - - diff --git a/docs/sources-telscale/Makefile b/docs/sources-telscale/Makefile deleted file mode 100644 index 3f791eb6d7..0000000000 --- a/docs/sources-telscale/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -#Makefile for Platform_User_Guide - -XML_LANG = en-US -# DOCNAME = Platform_User_Guide -# PRODUCT = FIX_ME! -BRAND = JBoss -# DOC_TYPE = Set - -# Uncomment below 3 lines for a Distributed Set -#BOOKS = Platform_Installation_Guide JAIN_SLEE_Server_User_Guide -#BOOKS = Platform_Installation_Guide JAIN_SLEE_Server_User_Guide SIP_Servlets_Server_User_Guide Media_Server_User_Guide SIP_Presence_Service_User_Guide -#SET_REPO = https://svn.devel.redhat.com/repos/ecs/JBoss_Communications_Platform/1.2.0/ -#SET_REPO_TYPE = SVN - -#OTHER_LANGS = as-IN bn-IN de-DE es-ES fr-FR gu-IN hi-IN it-IT ja-JP kn-IN ko-KR ml-IN mr-IN or-IN pa-IN pt-BR ru-RU si-LK ta-IN te-IN zh-CN zh-TW - -# Extra Parameters start here - -# Extra Parameters stop here -COMMON_CONFIG = /usr/share/publican -include $(COMMON_CONFIG)/make/Makefile.common - -# Uncomment below 2 lines for a Distributed Set -#pre:: get_books set_books -#clean:: clean_set_books - diff --git a/docs/sources-telscale/README.txt b/docs/sources-telscale/README.txt deleted file mode 100644 index d0424ade74..0000000000 --- a/docs/sources-telscale/README.txt +++ /dev/null @@ -1,7 +0,0 @@ -when mvn clean install has been performed in the parent directory, to validate against publican do : - -cd ./src/main/resources -chmod 777 mkbk Makefile -./mkbk sss jbcp html-single-en-US - -that's it diff --git a/docs/sources-telscale/mkbk b/docs/sources-telscale/mkbk deleted file mode 100644 index e8f07671d0..0000000000 --- a/docs/sources-telscale/mkbk +++ /dev/null @@ -1,144 +0,0 @@ -#! /usr/bin/env bash -# :mode=shellscript: - -# short script for building Mobicents docs and ensuring -# necessary files for JDocBook (all-*) are updated -# for usage, call ./build_docs.bash without any arguments - -# EXAMPLES: - -# mkbk test -# ...means: run xmllint on all books, looking for the first that does not build - -# make CONDITION="mob" html-single-en-US -# BECOMES -# mkbk jss mob html-single-en-US - -# make CONDITION="jbcp" html-single-en-US -# BECOMES -# mkbk jss jbcp html-single-en-US - -# JDocBook Reference (ignore this): -# mvn compile -Denv.DOCNAME="SIP_Servlets_Server_User_Guide" -Phtml_single - -echo "Arg 1 [\$BK] (codename of book OR simply 'test'): $1"; BK=$(echo $1 | tr '[:upper:]' '[:lower:]') -echo "Arg 2 [\$COND] (CONDITION): $2"; COND=$(echo $2 | tr '[:upper:]' '[:lower:]') -echo -n "Arg 3 (pass-through arg; 3rd arg to 'make', if exists): "; THIRD="$3"; echo $THIRD -echo -n "Arg 4 (pass-through arg; 4th arg to 'make', if exists): "; FOURTH="$4"; echo $FOURTH -echo -n "Arg 5 (pass-through arg; 5th arg to 'make', if exists): "; FIFTH="$5"; echo $FIFTH -echo "-------------------------------------------------" - -pre="[MKBK] " - -ALL_BKS="jss ms sss sps pig plat" -ALL_CONDS="mob jbcp" - -PLAT="Platform_User_Guide" -PIG="Platform_Installation_Guide" -JSS="JAIN_SLEE_Server_User_Guide" -MS="Media_Server_User_Guide" -SSS="SIP_Servlets_Server_User_Guide" -SPS="SIP_Presence_Service_User_Guide" - -set_docname() { - case $BK in - "plat") DOCNAME="$PLAT";; - "pig" ) DOCNAME="$PIG";; - "jss" ) DOCNAME="$JSS";; - "ms" ) DOCNAME="$MS";; - "sss") DOCNAME="$SSS";; - "sps") DOCNAME="$SPS";; - esac -} - -test() { - for bk in "jss" "ms" "sss" "sps" "pig" "plat" # $PLAT $PIG $JSS $MS $SPS - do - BK=$bk - set_docname - cmd = "mkbk $bk jbcp xml-en-US &>/dev/null" - - echo -n "$pre"; echo "DOCNAME is $DOCNAME" - echo -n "$pre"; echo "Calling:"; echo "" - echo -n "$pre"; echo " $cmd" - - eval $cmd - - if [ $? -ne 0 ]; then - echo -n "$pre"; echo "$bk is failing to build! Run!" - exit 1 - else - echo -n "$pre"; echo "$DOCNAME builds correctly." - echo -n "$pre"; echo "*****************************" - fi - done - echo -n "$pre"; echo "All books build correctly. Throw a party!" - exit 0 -} - -rm_tmp() { - if [[ -e Makefile ]]; then - if [[ -e pom.xml ]]; then - if [[ -e tmp ]]; then - echo -n "$pre"; echo "Removing 'tmp'..." - rm tmp -fr - fi - fi - fi -} - -build_bk() { - rm_tmp - set_docname - cmd="make DOCNAME=$DOCNAME CONDITION=$COND $THIRD $FOURTH $FIFTH" - echo -n "$pre"; echo "DOCNAME is '$DOCNAME'" - echo -n "$pre"; echo "Calling:"; echo "" - echo -n "$pre"; echo " $cmd" - eval $cmd - - if [ $? -ne 0 ]; then - echo -n "$pre"; echo "$DOCNAME did not build!" - exit 1 - else - if [ "$COND" = "mob" ]; then - echo -n "$pre"; echo "Removing 'en-US/all-$DOCNAME.xml'..." - rm "en-US/all-$DOCNAME.xml" - echo -n "$pre"; echo "Copying 'tmp/en-US/xml/$DOCNAME.xml' to 'en-US/all-$DOCNAME.xml'..." - xmllint --postvalid --noent --xinclude "tmp/en-US/xml/$DOCNAME.xml" > "en-US/all-$DOCNAME.xml" - fi - echo -n "$pre"; echo "$DOCNAME built. Exiting successfully." - exit 0 - fi -} - -# TEST ARGUMENTS -chk_BK_arg() { - if [ "$BK" = "" ]; then - echo -n "$pre"; echo "***************************************" - echo -n "$pre"; echo "Error: the BK argument must either represent a book or be 'test'" - echo -n "$pre"; echo " A possible argument for the BK OPTION is one of : $ALL_BKS" - echo -n "$pre"; echo "***************************************" - exit 1 - fi -} - -chk_COND_arg() { - if [ "$COND" != "mob" -a "$COND" != "jbcp" ]; then - echo -n "$pre"; echo "***************************************" - echo -n "$pre"; echo "Error: the second argument must be one of these conditions: $ALL_CONDS" - echo -n "$pre"; echo "***************************************" - exit 1 - fi -} - -dispatch() { - chk_BK_arg - if [ "$BK" = "test" ]; then - test - fi - chk_COND_arg - - build_bk -} - -dispatch diff --git a/docs/sources-telscale/pom.xml b/docs/sources-telscale/pom.xml deleted file mode 100644 index 909d0068d4..0000000000 --- a/docs/sources-telscale/pom.xml +++ /dev/null @@ -1,97 +0,0 @@ - - - - 4.0.0 - - - org.mobicents.servlet.sip.docs - sip-servlets-docs - 3.0.0-SNAPSHOT - - - sip-servlets-docs-sources-telscale - - - TelScale - TelScale SIP Servlets - telscale-ss - telscale-6.1/jboss-eap-5.1/jboss-as/ - telscale-ss-6.1-eap-5.1.GA.zip - telscale-ss-1.0.GA-apache-tomcat-6.0.35.zip - ivelin@telestax.com - jean.deruelle@telestax.com - vralev@telestax.com - charles.roufay@telestax.com - http://support.telestax.com/ - - - - - - ${basedir}/src/main/resources - true - - - - - org.apache.maven.plugins - maven-dependency-plugin - - - unpack - generate-resources - - unpack - - - - - ${project.groupId} - sip-servlets-docs-sources - ${project.version} - jar - true - ${basedir}/src/main/resources - - - - - - - - maven-antrun-plugin - - - install - - run - - - - - - - - - - - - clean-resources - clean - - run - - - - - - - - - - - - - - - diff --git a/docs/sources-telscale/publican.cfg b/docs/sources-telscale/publican.cfg deleted file mode 100644 index 48c3d7b9b1..0000000000 --- a/docs/sources-telscale/publican.cfg +++ /dev/null @@ -1,7 +0,0 @@ -# Config::Simple 4.59 -# Thu Jan 27 14:23:54 2011 - -debug: 1 -xml_lang: en-US -brand: JBoss - diff --git a/docs/sources/pom.xml b/docs/sources/pom.xml deleted file mode 100644 index c3bfb68a76..0000000000 --- a/docs/sources/pom.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - 4.0.0 - - - org.mobicents.servlet.sip.docs - sip-servlets-docs - 3.0.0-SNAPSHOT - - - sip-servlets-docs-sources - - - SIP Servlets - 2009 - SIP_Servlets_Server_User_Guide - 135MB - 20MB - TeleStax, Inc. - - - - - - ${basedir}/src/main/resources - true - - - - - diff --git a/docs/sources/src/main/resources/en-US/Author_Group.xml b/docs/sources/src/main/resources/en-US/Author_Group.xml deleted file mode 100644 index 439fac7047..0000000000 --- a/docs/sources/src/main/resources/en-US/Author_Group.xml +++ /dev/null @@ -1,74 +0,0 @@ - - -%BOOK_ENTITIES; -]> - - - Douglas - Silas - - dhensley@redhat.com - - - Jean - Deruelle - - &AUTHOR_EMAIL_JEAN; - - - Vladimir - Ralev - - &AUTHOR_EMAIL_VLAD; - - - Ivelin - Ivanov - - &AUTHOR_EMAIL_IVELIN; - - - Charles - Roufay - - &AUTHOR_EMAIL_CHARLES; - - - Jared - Morgan - - jmorgan@redhat.com - - diff --git a/docs/sources/src/main/resources/en-US/Book_Info.xml b/docs/sources/src/main/resources/en-US/Book_Info.xml deleted file mode 100644 index 096ba4490e..0000000000 --- a/docs/sources/src/main/resources/en-US/Book_Info.xml +++ /dev/null @@ -1,24 +0,0 @@ - - -%BOOK_ENTITIES; -]> - - SIP Servlets Server User Guide - The Guide to the SIP Servlets v1.1-Certified Server - Mobicents Platform - 1.2.1 - 2.0 - 1 - - - - -This user guide will help you get a better understanding of &PLATFORM_NAME; SIP servlets and how the container can be used in an enterprise context. The guide will cover how to how to quickly get started with &PLATFORM_NAME; SIP servlets either on top of JBoss or Apache Tomcat containers. There are sample applications included for those who want to grasp how to build SIP applications. You will also learn how to use advanced features like High Availability through Clustering and Failover. Finally, monitoring and security will be explained. - - - - - - - diff --git a/docs/sources/src/main/resources/en-US/Common_Content/Conventions.xml b/docs/sources/src/main/resources/en-US/Common_Content/Conventions.xml deleted file mode 100644 index 9f65aa100f..0000000000 --- a/docs/sources/src/main/resources/en-US/Common_Content/Conventions.xml +++ /dev/null @@ -1,174 +0,0 @@ - - -%BOOK_ENTITIES; -]> - -

- Document Conventions - - This manual uses several conventions to highlight certain words and phrases and draw attention to specific pieces of information. - - - In PDF and paper editions, this manual uses typefaces drawn from the Liberation Fonts set. The Liberation Fonts set is also used in HTML editions if the set is installed on your system. If not, alternative but equivalent typefaces are displayed. Note: Red Hat Enterprise Linux 5 and later includes the Liberation Fonts set by default. - -
- Typographic Conventions - - Four typographic conventions are used to call attention to specific words and phrases. These conventions, and the circumstances they apply to, are as follows. - - - Mono-spaced Bold - - - Used to highlight system input, including shell commands, file names and paths. Also used to highlight key caps and key-combinations. For example: - -
- - To see the contents of the file my_next_bestselling_novel in your current working directory, enter the cat my_next_bestselling_novel command at the shell prompt and press Enter to execute the command. - -
- - The above includes a file name, a shell command and a key cap, all presented in Mono-spaced Bold and all distinguishable thanks to context. - - - Key-combinations can be distinguished from key caps by the hyphen connecting each part of a key-combination. For example: - -
- - Press Enter to execute the command. - - - Press CtrlAltF1 to switch to the first virtual terminal. Press CtrlAltF7 to return to your X-Windows session. - -
- - The first sentence highlights the particular key cap to press. The second highlights two sets of three key caps, each set pressed simultaneously. - - - If source code is discussed, class names, methods, functions, variable names and returned values mentioned within a paragraph will be presented as above, in Mono-spaced Bold. For example: - -
- - File-related classes include filesystem for file systems, file for files, and dir for directories. Each class has its own associated set of permissions. - -
- - Proportional Bold - - - This denotes words or phrases encountered on a system, including application names; dialogue box text; labelled buttons; check-box and radio button labels; menu titles and sub-menu titles. For example: - -
- - Choose System > Preferences > Mouse from the main menu bar to launch Mouse Preferences. In the Buttons tab, click the Left-handed mouse check box and click Close to switch the primary mouse button from the left to the right (making the mouse suitable for use in the left hand). - - - To insert a special character into a gedit file, choose Applications > Accessories > Character Map from the main menu bar. Next, choose Search > Find… from the Character Map menu bar, type the name of the character in the Search field and click Next. The character you sought will be highlighted in the Character Table. Double-click this highlighted character to place it in the Text to copy field and then click the Copy button. Now switch back to your document and choose Edit > Paste from the gedit menu bar. - -
- - The above text includes application names; system-wide menu names and items; application-specific menu names; and buttons and text found within a GUI interface, all presented in Proportional Bold and all distinguishable by context. - - - Note the > shorthand used to indicate traversal through a menu and its sub-menus. This is to avoid the difficult-to-follow 'Select Mouse from the Preferences sub-menu in the System menu of the main menu bar' approach. - - - Mono-spaced Bold Italic or Proportional Bold Italic - - - Whether Mono-spaced Bold or Proportional Bold, the addition of Italics indicates replaceable or variable text. Italics denotes text you do not input literally or displayed text that changes depending on circumstance. For example: - -
- - To connect to a remote machine using ssh, type ssh username@domain.name at a shell prompt. If the remote machine is example.com and your username on that machine is john, type ssh john@example.com. - - - The mount -o remount file-system command remounts the named file system. For example, to remount the /home file system, the command is mount -o remount /home. - - - To see the version of a currently installed package, use the rpm -q package command. It will return a result as follows: package-version-release. - -
- - Note the words in bold italics above — username, domain.name, file-system, package, version and release. Each word is a placeholder, either for text you enter when issuing a command or for text displayed by the system. - - - Aside from standard usage for presenting the title of a work, italics denotes the first use of a new and important term. For example: - -
- - When the Apache HTTP Server accepts requests, it dispatches child processes or threads to handle them. This group of child processes or threads is known as a server-pool. Under Apache HTTP Server 2.0, the responsibility for creating and maintaining these server-pools has been abstracted to a group of modules called Multi-Processing Modules (MPMs). Unlike other modules, only one module from the MPM group can be loaded by the Apache HTTP Server. - -
-
- -
- Pull-quote Conventions - - Two, commonly multi-line, data types are set off visually from the surrounding text. - - - Output sent to a terminal is set in Mono-spaced Roman and presented thus: - - - -books Desktop documentation drafts mss photos stuff svn -books_tests Desktop1 downloads images notes scripts svgs - - - Source-code listings are also set in Mono-spaced Roman but are presented and highlighted as follows: - - - -package org.jboss.book.jca.ex1; - -import javax.naming.InitialContext; - -public class ExClient -{ - public static void main(String args[]) - throws Exception - { - InitialContext iniCtx = new InitialContext(); - Object ref = iniCtx.lookup("EchoBean"); - EchoHome home = (EchoHome) ref; - Echo echo = home.create(); - - System.out.println("Created Echo"); - - System.out.println("Echo.echo('Hello') = " + echo.echo("Hello")); - } - -} - -
- -
- Notes and Warnings - - Finally, we use three visual styles to draw attention to information that might otherwise be overlooked. - - - Note - - A note is a tip or shortcut or alternative approach to the task at hand. Ignoring a note should have no negative consequences, but you might miss out on a trick that makes your life easier. - - - - Important - - Important boxes detail things that are easily missed: configuration changes that only apply to the current session, or services that need restarting before an update will apply. Ignoring Important boxes won't cause data loss but may cause irritation and frustration. - - - - Warning - - A Warning should not be ignored. Ignoring warnings will most likely cause data loss. - - -
- -
- - diff --git a/docs/sources/src/main/resources/en-US/Common_Content/Feedback.xml b/docs/sources/src/main/resources/en-US/Common_Content/Feedback.xml deleted file mode 100644 index 23e968b077..0000000000 --- a/docs/sources/src/main/resources/en-US/Common_Content/Feedback.xml +++ /dev/null @@ -1,21 +0,0 @@ - - -%BOOK_ENTITIES; -]> - -
- - Provide feedback to the authors! - - - feedback - - - If you find a typographical error in this manual, or if you have thought of a way to make this manual better, we would love to hear from you! Please submit a report in Bugzilla: http://bugzilla.redhat.com/bugzilla/ against the product ${product.name}, or contact the authors. - When submitting a bug report, be sure to mention the manual's identifier: &BOOKID; - If you have a suggestion for improving the documentation, try to be as specific as possible when describing it. If you have found an error, please include the section number and some of the surrounding text so we can find it easily. - -
- - diff --git a/docs/sources/src/main/resources/en-US/Common_Content/Java_Development_Kit-Installing_Configuring_and_Running.xml b/docs/sources/src/main/resources/en-US/Common_Content/Java_Development_Kit-Installing_Configuring_and_Running.xml deleted file mode 100644 index e640fa1290..0000000000 --- a/docs/sources/src/main/resources/en-US/Common_Content/Java_Development_Kit-Installing_Configuring_and_Running.xml +++ /dev/null @@ -1,254 +0,0 @@ - - -%BOOK_ENTITIES; - -]> -
- Java Development Kit (<acronym>JDK</acronym>): Installing, Configuring and Running - - The &PLATFORM_NAME; Platform is written in Java; therefore, before running any &PLATFORM_NAME; server, you must have a working Java Runtime Environment (JRE) or Java Development Kit (JDK) installed on your system. In addition, the JRE or JDK you are using to run &PLATFORM_NAME; must be version 5 or higher - - At this point in time, it is possible to run most &PLATFORM_NAME; servers, such as the JAIN SLEE Server, using a Java 6 JRE or JDK. Be aware, however, that presently the XML Document Management Server does not run on Java 6. We suggest checking the &PLATFORM_NAME; web site, forums or discussion pages if you need to inquire about the status of running the XML Document Management Server with Java 6. - - . - - - Should I Install the JRE or JDK? - - Although you can run &PLATFORM_NAME; servers using the Java Runtime Environment, we assume that most users are developers interested in developing Java-based, &PLATFORM_NAME;-driven solutions. Therefore, in this guide we take the tact of showing how to install the full Java Development Kit. - - - - Should I Install the 32-Bit or the 64-Bit JDK, and Does It Matter? - - Briefly stated: if you are running on a 64-Bit Linux or Windows platform, you should consider installing and running the 64-bit JDK over the 32-bit one. Here are some heuristics for determining whether you would rather run the 64-bit Java Virtual Machine (JVM) over its 32-bit cousin for your application: - - - - - - Wider datapath: the pipe between RAM and CPU is doubled, which improves the performance of memory-bound applications when using a 64-bit JVM. - - - - - 64-bit memory addressing gives virtually unlimited (1 exabyte) heap allocation. However large heaps affect garbage collection. - - - - - Applications that run with more than 1.5 GB of RAM (including free space for garbage collection optimization) should utilize the 64-bit JVM. - - - - - Applications that run on a 32-bit JVM and do not require more than minimal heap sizes will gain nothing from a 64-bit JVM. Barring memory issues, 64-bit hardware with the same relative clock speed and architecture is not likely to run Java applications faster than their 32-bit cousin. - - - - - Note that the following instructions detail how to download and install the 32-bit JDK, although the steps are nearly identical for installing the 64-bit version. - - - - - Downloading - - You can download the Sun JDK 5.0 (Java 2 Development Kit) from Sun's website: . Click on the Download link next to "JDK 5.0 Update <x>" (where <x> is the latest minor version release number). On the next page, select your language and platform (both architecture—whether 32- or 64-bit—and operating system), read and agree to the Java Development Kit 5.0 License Agreement, and proceed to the download page. - - - - The Sun website will present two download alternatives to you: one is an RPM inside a self-extracting file (for example, jdk-1_5_0_16-linux-i586-rpm.bin), and the other is merely a self-extracting file (e.g. jdk-1_5_0_16-linux-i586.bin). If you are installing the JDK on Red Hat Enterprise Linux, Fedora, or another RPM-based Linux system, we suggest that you download the self-extracting file containing the RPM package, which will set up and use the SysV service scripts in addition to installing the JDK. We also suggest installing the self-extracting RPM file if you will be running &PLATFORM_NAME; in a production environment. - - - - Installing - - The following procedures detail how to install the Java Development Kit on both Linux and Windows. - - - - Installing the JDK on Linux - - - Regardless of which file you downloaded, you can install it on Linux by simply making sure the file is executable and then running it: - - - ~]$ chmod +x "jdk-1_5_0_<minor_version>-linux-<architecture>-rpm.bin" -~]$ ./"jdk-1_5_0_<minor_version>-linux-<architecture>-rpm.bin" - - - - - You Installed Using the Non-RPM Installer, but Want the SysV Service Scripts - - If you download the non-RPM self-extracting file (and installed it), and you are running on an RPM-based system, you can still set up the SysV service scripts by downloading and installing one of the -compat packages from the JPackage project. Remember to download the -compat package which corresponds correctly to the minor release number of the JDK you installed. The compat packages are available from . - - - - - You do not need to install a -compat package in addition to the JDK if you installed the self-extracting RPM file! The -compat package merely performs the same SysV service script set up that the RPM version of the JDK installer does. - - - - Installing the JDK on Windows - - - Using Explorer, simply double-click the downloaded self-extracting installer and follow the instructions to install the JDK. - - - - - - - Configuring - - Configuring your system for the JDK consists in two tasks: setting the JAVA_HOME environment variable, and ensuring that the system is using the proper JDK (or JRE) using the alternatives command. Setting JAVA_HOME usually overrides the values for java, javac and java_sdk_1.5.0 in alternatives, but we will set them all just to be safe and consistent. - - - - - Setting the JAVA_HOME Environment Variable on Generic Linux - - - After installing the JDK, you must ensure that the JAVA_HOME environment variable exists and points to the location of your JDK installation. - - - Setting the <envar>JAVA_HOME</envar> Environment Variable on Linux - - You can determine whether JAVA_HOME is set on your system by echoing it on the command line: - - - - ~]$ echo $JAVA_HOME - - If JAVA_HOME is not set already, then you must set its value to the location of the JDK installation on your system. You can do this by adding two lines to your personal ~/.bashrc configuration file. Open ~/.bashrc (or create it if it doesn't exist) and add a line similar to the following one anywhere inside the file: - - - export JAVA_HOME="/usr/lib/jvm/jdk1.5.0_<version>" - - - You should also set this environment variable for any other users who will be running &PLATFORM_NAME; (any environment variables exported from ~/.bashrc files are local to that user). - - - - - Setting java, javac and java_sdk_1.5.0 Using the alternatives command - - - Selecting the Correct System JVM on Linux using <command>alternatives</command> - - - On systems with the alternatives command, including Red Hat Enterprise Linux and Fedora, you can easily choose which JDK (or JRE) installation you wish to use, as well as which java and javac executables should be run when called. - - - - As the root user, call /usr/sbin/alternatives with the option to select between JDKs and JREs installed on your system: - - - root@localhost ~]$ /usr/sbin/alternatives --config java - -There are 3 programs which provide 'java'. - - Selection Command ------------------------------------------------ - 1 /usr/lib/jvm/jre-1.5.0-gcj/bin/java - 2 /usr/lib/jvm/jre-1.6.0-sun/bin/java -*+ 3 /usr/lib/jvm/jre-1.5.0-sun/bin/java - - -Enter to keep the current selection[+], or type selection number: - - - In our case, we want to use the Sun JDK, version 5, that we downloaded and installed, to run the java executable. In the alternatives information printout above, a plus (+) next to a number indicates the one currently being used. As per alternatives' instructions, pressing Enter will simply keep the current JVM, or you can enter the number corresponding to the JVM you would prefer to use. - - - Repeat the procedure above for the javac command and the java_sdk_1.5.0 environment variable, as the root user: - - - ~]$ /usr/sbin/alternatives --config javac - - ~]$ /usr/sbin/alternatives --config java_sdk_1.5.0 - - - - Setting the JAVA_HOME Environment Variable on Windows - - - For information on how to set environment variables in Windows, refer to . - - - - - - - Testing - - Finally, to make sure that you are using the correct JDK or Java version (5 or higher), and that the java executable is in your PATH, run the java - command in the terminal from your home directory: - - - - ~]$ java -version -java version "1.5.0_16" -Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_16-b03) -Java HotSpot(TM) Client VM (build 1.5.0_16-b03, mixed mode, sharing) - - - - Uninstalling - - There is usually no reason (other than space concerns) to remove a particular JDK from your system, given that you can switch between JDKs and JREs easily using alternatives, and/or by setting JAVA_HOME. - - - - Uninstalling the JDK on Linux - - On RPM-based systems, you can uninstall the JDK using the yum - command. - - - - Uninstalling the JDK on Windows - - On Windows systems, check the JDK entry in the Start menu for an uninstall command, or use Add/Remove Programs. - - -
- - diff --git a/docs/sources/src/main/resources/en-US/Common_Content/Preface.xml b/docs/sources/src/main/resources/en-US/Common_Content/Preface.xml deleted file mode 100644 index 52665c6ba6..0000000000 --- a/docs/sources/src/main/resources/en-US/Common_Content/Preface.xml +++ /dev/null @@ -1,16 +0,0 @@ - - -%BOOK_ENTITIES; -]> - - Preface - - - - - diff --git a/docs/sources/src/main/resources/en-US/Common_Content/Setting_the_JBOSS_HOME_Environment_Variable.xml b/docs/sources/src/main/resources/en-US/Common_Content/Setting_the_JBOSS_HOME_Environment_Variable.xml deleted file mode 100644 index 027960b6b1..0000000000 --- a/docs/sources/src/main/resources/en-US/Common_Content/Setting_the_JBOSS_HOME_Environment_Variable.xml +++ /dev/null @@ -1,120 +0,0 @@ - - -%BOOK_ENTITIES; - -]> -
- Setting the JBOSS_HOME Environment Variable - - The &PLATFORM_NAME; Platform (&PLATFORM_NAME;) is built on top of the JBoss Application Server (JBoss AS). You do not need to set the JBOSS_HOME environment variable to run any of the &PLATFORM_NAME; Platform servers unless JBOSS_HOME is already set. - - The best way to know for sure whether JBOSS_HOME was set previously or not is to perform a simple check which may save you time and frustration. - - Checking to See If JBOSS_HOME is Set on Unix - At the command line, echo - $JBOSS_HOME to see if it is currently defined in your environment: - - ~]$ echo $JBOSS_HOME - The &PLATFORM_NAME; Platform and most &PLATFORM_NAME; servers are built on top of the JBoss Application Server (JBoss AS). When the &PLATFORM_NAME; Platform or &PLATFORM_NAME; servers are built from source, then JBOSS_HOME must be set, because the &PLATFORM_NAME; files are installed into (or over top of if you prefer) a clean JBoss AS installation, and the build process assumes that the location pointed to by the JBOSS_HOME environment variable at the time of building is the JBoss AS installation into which you want it to install the &PLATFORM_NAME; files. - - This guide does not detail building the &PLATFORM_NAME; Platform or any &PLATFORM_NAME; servers from source. It is nevertheless useful to understand the role played by JBoss AS and JBOSS_HOME in the &PLATFORM_NAME; ecosystem. - - The immediately-following section considers whether you need to set JBOSS_HOME at all and, if so, when. The subsequent sections detail how to set JBOSS_HOME on Unix and Windows - - - - Even if you fall into the category below of not needing to set JBOSS_HOME, you may want to for various reasons anyway. Also, even if you are instructed that you do not need to set JBOSS_HOME, it is good practice nonetheless to check and make sure that JBOSS_HOME actually isn't set or defined on your system for some reason. This can save you both time and frustration. - - - You DO NOT NEED to set JBOSS_HOME if... - - - - ...you have installed the &PLATFORM_NAME; Platform binary distribution. - - - - - ...you have installed a &PLATFORM_NAME; server binary distribution which bundles JBoss AS. - - - - You MUST set JBOSS_HOME if... - - - - ...you are installing the &PLATFORM_NAME; Platform or any of the &PLATFORM_NAME; servers from source. - - - - - ...you are installing the &PLATFORM_NAME; Platform binary distribution, or one of the &PLATFORM_NAME; server binary distributions, which do not bundle JBoss AS. - - - - - Naturally, if you installed the &PLATFORM_NAME; Platform or one of the &PLATFORM_NAME; server binary releases which do not bundle JBoss AS, yet requires it to run, then you should install JBoss AS - before setting JBOSS_HOME or proceeding with anything else. - - - Setting the JBOSS_HOME Environment Variable on Unix - - The JBOSS_HOME environment variable must point to the directory which contains all of the files for the &PLATFORM_NAME; Platform or individual &PLATFORM_NAME; server that you installed. As another hint, this topmost directory contains a bin subdirectory. - - - - Setting JBOSS_HOME in your personal ~/.bashrc startup script carries the advantage of retaining effect over reboots. Each time you log in, the environment variable is sure to be set for you, as a user. On Unix, it is possible to set JBOSS_HOME as a system-wide environment variable, by defining it in /etc/bashrc, but this method is neither recommended nor detailed in these instructions. - - - To Set JBOSS_HOME on Unix... - - - Open the ~/.bashrc startup script, which is a hidden file in your home directory, in a text editor, and insert the following line on its own line while substituting for the actual install location on your system: - - export JBOSS_HOME="/home/<username>/<path>/<to>/<install_directory>" - - - - Save and close the .bashrc startup script. - - - - - You should source the .bashrc script to force your change to take effect, so that JBOSS_HOME becomes set for the current session - - Note that any other terminals which were opened prior to your having altered .bashrc will need to source - ~/.bashrc as well should they require access to JBOSS_HOME. - - . - - ~]$ source ~/.bashrc - - - - Finally, ensure that JBOSS_HOME is set in the current session, and actually points to the correct location: - - - - The command line usage below is based upon a binary installation of the &PLATFORM_NAME; Platform. In this sample output, JBOSS_HOME has been set correctly to the topmost_directory of the &PLATFORM_NAME; installation. Note that if you are installing one of the standalone &PLATFORM_NAME; servers (with JBoss AS bundled!), then JBOSS_HOME would point to the topmost_directory of your server installation. - - - ~]$ echo $JBOSS_HOME -/home/silas/&HOME_LIN; - - - - - Setting the JBOSS_HOME Environment Variable on Windows - - The JBOSS_HOME environment variable must point to the directory which contains all of the files for the &PLATFORM_NAME; Platform or individual &PLATFORM_NAME; server that you installed. As another hint, this topmost directory contains a bin subdirectory. - - - - For information on how to set environment variables in recent versions of Windows, refer to . - -
- - diff --git a/docs/sources/src/main/resources/en-US/Preface.xml b/docs/sources/src/main/resources/en-US/Preface.xml deleted file mode 100644 index ba32497eec..0000000000 --- a/docs/sources/src/main/resources/en-US/Preface.xml +++ /dev/null @@ -1,19 +0,0 @@ - - -%BOOK_ENTITIES; -]> - - Preface - - - diff --git a/docs/sources/src/main/resources/en-US/Revision_History.xml b/docs/sources/src/main/resources/en-US/Revision_History.xml deleted file mode 100644 index c1ef89a41b..0000000000 --- a/docs/sources/src/main/resources/en-US/Revision_History.xml +++ /dev/null @@ -1,55 +0,0 @@ - - -%BOOK_ENTITIES; -]> - - Revision History - - - - 4.0 - Mon Jan 24 2011 - - Tom - Wells - twells@redhat.com - - - - Publican valid edition of community documentation. - - - - - 3.0 - Thu Jun 11 2009 - - Jared - Morgan - jmorgan@redhat.com - - - - Second release of the "parameterized" documentation. - - - - - 2.0 - Fri Mar 06 2009 - - Douglas - Silas - dhensley@redhat.com - - - - First release of the "parameterized", and much-improved JBCP documentation. - - - - - - - diff --git a/docs/sources/src/main/resources/en-US/SIP_Servlets_Server_User_Guide.ent b/docs/sources/src/main/resources/en-US/SIP_Servlets_Server_User_Guide.ent deleted file mode 100644 index 98433b2d9e..0000000000 --- a/docs/sources/src/main/resources/en-US/SIP_Servlets_Server_User_Guide.ent +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/docs/sources/src/main/resources/en-US/SIP_Servlets_Server_User_Guide.xml b/docs/sources/src/main/resources/en-US/SIP_Servlets_Server_User_Guide.xml deleted file mode 100644 index 55425b0d84..0000000000 --- a/docs/sources/src/main/resources/en-US/SIP_Servlets_Server_User_Guide.xml +++ /dev/null @@ -1,32 +0,0 @@ - - -%BOOK_ENTITIES; -]> - - - - - - - - - - -Clustering and High Availability - - - - - - - - - - - - - - diff --git a/docs/sources/src/main/resources/en-US/bak/Author_Group.xml b/docs/sources/src/main/resources/en-US/bak/Author_Group.xml deleted file mode 100644 index 82fca215d1..0000000000 --- a/docs/sources/src/main/resources/en-US/bak/Author_Group.xml +++ /dev/null @@ -1,53 +0,0 @@ - - -%BOOK_ENTITIES; - -]> - - - Douglas - Silas - - dhensley@redhat.com - - - Eduardo - Martins - - &AUTHOR_EMAIL_EDUARDO; - - - Ivelin - Ivanov - - &AUTHOR_EMAIL_IVELIN; - - - Jared - Morgan - - jmorgan@redhat.com - - diff --git a/docs/sources/src/main/resources/en-US/bak/Book_Info.xml b/docs/sources/src/main/resources/en-US/bak/Book_Info.xml deleted file mode 100644 index a2462d30fb..0000000000 --- a/docs/sources/src/main/resources/en-US/bak/Book_Info.xml +++ /dev/null @@ -1,46 +0,0 @@ - - -%BOOK_ENTITIES; - -]> - - &PLATFORM_NAME; SIP Presence Service User Guide - - &PLATFORM_NAME; SIP Presence Service - &VERSION; - 3.0 - 1 - - The &PLATFORM_NAME; Platform is the first and only open source VoIP platform certified for JAIN SLEE 1.0 and SIP Servlets 1.1 compliance. &PLATFORM_NAME; serves as a high-performance core for Service Delivery Platforms (SDPs) and IP Multimedia Subsystems (IMSes) by leveraging J2EE to enable the convergence of data and video in Next-Generation Intelligent Network (NGIN) applications. - The &PLATFORM_NAME; SIP Presence Service, provides presence functionalities to SIP-based networks, and is built upon &PLATFORM_NAME; JAIN SLEE. - - - - - - - - Logo - - - - - &YEAR; - Red Hat, Inc. - - - - - - - diff --git a/docs/sources/src/main/resources/en-US/bak/Chapter-Installing_the_SIP_Presence_Service.xml b/docs/sources/src/main/resources/en-US/bak/Chapter-Installing_the_SIP_Presence_Service.xml deleted file mode 100644 index 208282767f..0000000000 --- a/docs/sources/src/main/resources/en-US/bak/Chapter-Installing_the_SIP_Presence_Service.xml +++ /dev/null @@ -1,201 +0,0 @@ - - -%BOOK_ENTITIES; - -]> - - Installing the &PLATFORM_NAME; SIP Presence Service -
- &PLATFORM_NAME; SIP Presence Service: Installing, Configuring and Running - There are multiple binary distributions of the &PLATFORM_NAME; SIP Presence Service. - - Description of the different &PLATFORM_NAME; SIP Presence Service Distributions - - The Integrated SIP Presence Service binary distribution with &PLATFORM_NAME; JAIN SLEE - - - These installation instructions detail the installation, running and configuring of the Integrated binary &PLATFORM_NAME; SIP Presence Service distribution. This distribution includes the XDM and SIP Presence Servers, the servers are pre-installed in a version of the &PLATFORM_NAME; JAIN SLEE Server, and the &PLATFORM_NAME; JAIN SLEE SIP11 and HTTP Servlet Resource Adaptors. Examples of JAIN SLEE applications interacting with the &PLATFORM_NAME; Integrated SIP Presence Service are also included and come pre-installed. - - - - The stand-alone &PLATFORM_NAME; XDM Server binary distribution with &PLATFORM_NAME; JAIN SLEE - - - Users who wish to deploy the &PLATFORM_NAME; XML Document Server on a different host or who do not require the &PLATFORM_NAME; Presence Server should install the stand-alone &PLATFORM_NAME; XDM Server binary distribution. The following installation, running and configuring instructions provide parallel instructions specific to the &PLATFORM_NAME; XDM Server. - - - - The &PLATFORM_NAME; SIP Presence Service binary distribution without &PLATFORM_NAME; JAIN SLEE - - Users who have already installed and set up a separate &PLATFORM_NAME; JAIN SLEE installation may want to install one or more servers of the &PLATFORM_NAME; SIP Presence Service. - - - - - - -
- Pre-Install Requirements and Prerequisites - You should ensure that a few requirements have been met before continuing with the install. - - Hardware Requirements - - Anything Java Itself Will Run On - - The &PLATFORM_NAME; SIP Presence Service is an 100% Java application. &PLATFORM_NAME; SIP Presence Service will run on the same hardware that the &PLATFORM_NAME; JAIN SLEE runs on. - - - - - Software Prerequisites - - JDK 5 - - A working installation of the Java Development Kit (JDK) version 5 is required in order to run the &PLATFORM_NAME; SIP Presence Service. - JDK 6 is not supported by the &PLATFORM_NAME; XDM Server - - - - Apache Ant 1.6 or later - - A working installation of the Apache Ant 1.6 or later is required in order to install the &PLATFORM_NAME; SIP Presence Service release without $PLATFORM_NAME JAIN SLEE. - - - - JBOSS_HOME Environment Variable - - The environment variable JBOSS_HOME, if set, must be pointing to the JBoss AS within &PLATFORM_NAME; JAIN SLEE. - - - -
-
- Downloading - You can download the latest version of the &PLATFORM_NAME; SIP Presence Service distribution you need from the &PLATFORM_NAME; Downloads page at . Click on the &PLATFORM_NAME; SIP Presence Service link to view all available distributions and downloads. The latest releases are nearer the top. - If you are unsure which distribution zip file to download, refer to , and then to the following list of release binaries. - - &PLATFORM_NAME; SIP Presence Service Binary Distribution Zip Files - - &RELEASE_INTEGRATED_FILENAME; - - Download this zip file to obtain the &PLATFORM_NAME; Integrated SIP Presence Service binary distribution, which includes the &PLATFORM_NAME; SIP Presence Server, the &PLATFORM_NAME; XDM Server, and the JBoss Application Server with &PLATFORM_NAME; JAIN SLEE, well as all required JAIN SLEE Resource Adaptors. - - - - &RELEASE_XDMS_FILENAME; - - Download this zip file to obtain the &PLATFORM_NAME; XDM Server binary distribution, which bundles the JBoss Application Server with &PLATFORM_NAME; JAIN SLEE. - - - -
-
- Configuring (and Setting JBOSS_HOME) - -
-
- Installing - Once the requirements and prerequisites have been met, and you have downloaded the correct zip file for the binary distribution you need, you are ready to install, please follow the instructions below. - - Installing a &PLATFORM_NAME; SIP Presence Service Binary Distribution bundled <emphasis>with</emphasis> <application>&PLATFORM_NAME; JAIN SLEE</application> - - Unzip the release file - - - Ensure that the environment variable JBOSS_HOME is either not set, or pointing to the <install_directory> directory extracted from the release file. - - - - Installing a &PLATFORM_NAME; SIP Presence Service Binary Distribution <emphasis>without</emphasis> &PLATFORM_NAME; JAIN SLEE - - Unzip the release file - - - Ensure that the environment variable JBOSS_HOME is set and pointing to the JBoss AS with the &PLATFORM_NAME; JAIN SLEE, where &PLATFORM_NAME; SIP Presence Service components should be installed. - - - Invoke the correct Apache Ant target in build.xml script to install: - Install the Integrated SIP Presence Service: - ~]$ ant integrated-deploy - Install the stand-alone XDM Server: - ~]$ ant xdms-deploy - - -
-
- Running - Once installed, you can run server(s) by executing the run.sh (Unix) or run.bat (Microsoft Windows) startup scripts in the <install_directory>/bin directory (on Unix or Windows). In the Unix terminal or Command Prompt, you will be able to tell that the server started successfully if the last line of output is similar to the following (ending with Started in 23s:648ms): - - By default the server(s) start and bind to 127.0.0.1 IP, to use a different hostname or IP use the -b HOST parameter when executing the startup script (e.g. run.sh -b 172.31.1.1). -
-
- Stopping - You can shut down the server(s) you can run server(s) by executing the shutdown.sh (Unix) or shutdown.bat (Microsoft Windows) scripts in the <install_directory>/bin directory (on Unix or Windows). Note that if you properly stop the server, you will see the following three lines as the last output in the Unix terminal or Command Prompt: - -
-
- Testing - TODO -
-
- Uninstalling - - Uninstalling a &PLATFORM_NAME; SIP Presence Service Binary Distribution bundled <emphasis>with</emphasis> <application>&PLATFORM_NAME; JAIN SLEE</application> - - To uninstall the SIP Presence Service or XDM Server, simply delete the directory you decompressed the binary distribution archive into. - - - - Uninstalling a &PLATFORM_NAME; SIP Presence Service Binary Distribution <emphasis>without</emphasis> &PLATFORM_NAME; JAIN SLEE - - Invoke the correct Apache Ant target in build.xml script to uninstall: - Uninstall the Integrated SIP Presence Service: - ~]$ ant integrated-undeploy - Uninstall the stand-alone XDM Server: - ~]$ ant xdms-undeploy - - -
-
- Building from Source Project - The source building process requires access to the Internet. It also requires an SVN Client (to sources checkout) and Apache Maven2 2.0.9+ (for the building process) installed. - The source project can be downloaded using SVN, the checkout URL is http://mobicents.googlecode.com/svn/tags/servers/sip-presence/mobicents-sip-presence-service-&VERSION; - To build the binaries from source, enter the release directory inside the directory used to checkout the source project and: - ~]$ ant -
-
- Binary Releases Daily Snapshots - Everyday a binary release snapshot is built using current sources in development trunk, those are accessible from http://hudson.jboss.org/hudson/view/Mobicents/job/MobicentsSipPresenceRelease/ -
-
-
- diff --git a/docs/sources/src/main/resources/en-US/bak/Chapter-Introduction_to_the_SIP_Presence_Service.xml b/docs/sources/src/main/resources/en-US/bak/Chapter-Introduction_to_the_SIP_Presence_Service.xml deleted file mode 100644 index 05152138ff..0000000000 --- a/docs/sources/src/main/resources/en-US/bak/Chapter-Introduction_to_the_SIP_Presence_Service.xml +++ /dev/null @@ -1,152 +0,0 @@ - - -%BOOK_ENTITIES; - -]> - - - Introduction to the &PLATFORM_NAME; SIP Presence Service - - - - - - - - &PLATFORM_NAME; SIP Presence Service relation with standard groups - - - - - The &PLATFORM_NAME; SIP Presence Service provides presence functionalities to SIP-based networks using standards developed by the Internet Engineering Task Force (IETF), the Open Mobile Alliance (OMA), the 3rd Generation Partnership Project (3GPP) and the European Telecommunications Standards Institute (ETSI). - -
- - Architecture of the &PLATFORM_NAME; SIP Presence Service - - - architecture - - - The SIP Presence Service is comprised of three separate but interrelated servers. - - - - - - - &PLATFORM_NAME; SIP Presence Service servers - - - - - - The Three Servers Comprising the SIP Presence Service - - The SIP Presence Server - - The &PLATFORM_NAME; SIP Presence Server (PS) is an entity that accepts, stores and distributes SIP Presence Information. The Presence Server performs the following functions: - - - It manages publications from one or multiple presence source(s) of a certain presentity. This includes refreshing presence information, replacing existing presence information with newly-published information, or removing presence information. - - - It manages subscriptions from watchers to presence information and generates notifications about presence information state changes, retrieving the presence authorization rules from the XDM Server. - - - It manages subscriptions from watcher information subscribers to watcher information and generates notifications about watcher information state changes. - - - - - - The XML Document Management Server - - The XML Document Management Server (XDMS) is a functional element of next-generation IP communications networks is responsible for handling the management of user XML documents stored on the network side, such as presence authorization rules, static presence information, contact and group lists (also known as resource lists), policy data, and many others. - - - - The Resource List Server - - The Resource List Server (RLS) handles subscriptions to presence lists. It creates and manages back-end subscriptions to all resources in the presence list. The list content is retrieved from the XDM Server. - - - - - - - - - - - - - &PLATFORM_NAME; SIP Presence Service Integrated server - - - - - A major advantage of the &PLATFORM_NAME; SIP Presence Service is that, depending on your needs, each server can be deployed separately, or all servers can be integrated on the same host. - - - - - The &PLATFORM_NAME; SIP Presence Service is built on top of &PLATFORM_NAME; JAIN SLEE, a high performance and scalable Application Server and uses many additional Java Enterprise (JEE) technologies, such as Java Persistence API (JPA) to manage data. - - - - - - - - - &PLATFORM_NAME; SIP Presence Service Integrated implementation - - - - - In addition, there are JAIN SLEE internal client interfaces available for interaction with each server, which distinguishes the &PLATFORM_NAME; SIP Presence Service from other presence services. - - - Resources and Further Information about the &PLATFORM_NAME; SIP Presence Service - For further information on the &PLATFORM_NAME; SIP Presence Service, here is a list of additional resources: - - - - Sources - - - Source Code Location - - - - - Community - - - Mobicents Community - - - - -
-
- diff --git a/docs/sources/src/main/resources/en-US/bak/Chapter-Resource_List_Server.xml b/docs/sources/src/main/resources/en-US/bak/Chapter-Resource_List_Server.xml deleted file mode 100644 index 446fa18352..0000000000 --- a/docs/sources/src/main/resources/en-US/bak/Chapter-Resource_List_Server.xml +++ /dev/null @@ -1,16 +0,0 @@ - - -%BOOK_ENTITIES; - -]> - - &PLATFORM_NAME; Resource List Server -   - - Resource List Server - The &PLATFORM_NAME; Resource List Server is currently tightly integrated with the &PLATFORM_NAME; SIP Presence Server, supporting RFC 5367 and OMA service uri template. - - - diff --git a/docs/sources/src/main/resources/en-US/bak/Chapter-SIP_Presence_Server.xml b/docs/sources/src/main/resources/en-US/bak/Chapter-SIP_Presence_Server.xml deleted file mode 100644 index 5608ae0ba0..0000000000 --- a/docs/sources/src/main/resources/en-US/bak/Chapter-SIP_Presence_Server.xml +++ /dev/null @@ -1,148 +0,0 @@ - - -%BOOK_ENTITIES; - -]> - - &PLATFORM_NAME; SIP Presence Server - The &PLATFORM_NAME; SIP Presence Server is a free and open source implementation of a SIP Presence Server, as defined by the Internet Engineering Task Force (IETF), the Open Mobile Alliance (OMA), the 3rd Generation Partnership Project (3GPP) and the European Telecommunications Standards Institute (ETSI). - The SIP Presence Server is an entity that accepts, stores and distributes SIP presence information. -
- Functional Architecture of the SIP Presence Server - - - - - - Functional Diagram of the &PLATFORM_NAME; SIP Presence Server - - - The SIP Presence Server is comprised of the following functional elements: - - - Presence Publication Control - - This functional element manages the publication of presence events, which includes not only the handling of new publications, but also the refreshing, modification or removal of, already-published information. - Because the presence resource, which is also called a presentity, can have multiple publications simultaneously, such as some state published by a user agent or device, and some location data published by a Presence Network Agent (on behalf of the presentity), this element is also responsible for composing all of the different publications for the same resource. - In some presence networks, it may be of interest to allow resources to have a static presence state which is stored in the XDM Server. In cases like these, Presence Publication Control may need to interface with the XDM Server to retrieve and subscribe to (learn about changes to) that information, and use it when composing the final presence information document. - - - - Presence Subscription Control - - This functional element handles subscriptions to presence events or to the list of subscribers (watchers), for any specific resource. It is, of course, responsible for emitting notifications related to those subscriptions. - Presence authorization rules, which define if a subscription is allowed or rejected and, if allowed, define which transformations to the original presence events are needed, are stored on the XDM Server by the user. Thus, Presence Subscription Control needs to retrieve and subscribe to that information. - - - - XDM Client Control - - This last element is responsible for interfacing with the XDM Server that manages the user's XML documents, and is related to the main functions of the presence server. It is capable not only of retrieving a document or part of one, but also of subscribing to either updates of a single, specific document, or to a full collection of documents of a specific type or application. - - - -
- Implementation Architecture of the &PLATFORM_NAME; SIP Presence Server - - - - - - - Implementation Architecture of the &PLATFORM_NAME; SIP Presence Server - - - - The implementation of the &PLATFORM_NAME; SIP Presence Server comprises the following functional elements: - - The Two Services Which Compose the SIP Presence Server - - Presence Publication Control Service - - This JAIN SLEE service includes the root Service Building Block (SBB), PresencePublicationControlSbb, which is the implementation of the abstract SIP event PublicationControlSbb. It handles publications on the presence event package. - The PresencePublicationControlSbb provides the following capabilities: - - - It provides the logic to authorize a publication; however, it only authorizes PUBLISH requests when the request URI matches the PIDF document entity attribute. - - - It provides JAXB unmarshallers to validate and parse the PIDF document for the abstract PublicationControlSbb. - - - It demands that notifying subscribers occur through a child relation to the root SBB of the Presence Subscription Control Service. - - - Finally, it also provides an SbbLocalObject interface that can be used, in JAIN SLEE child relations, to obtain the composed presence information for a specific resource. - - - - - - Presence Subscription Control Service. - - This JAIN SLEE service includes the root SBB PresenceSubscriptionControlSbb, which is the implementation of the abstract SIP Event SubscriptionControlSbb. It handles subscriptions on the presence event package. - The standout SBB logic item is the usage of presence-rules documents, obtained through the XDM Client SBB child relation, in order to authorize subscriptions and transform the content notifiedNote that this feature is not yet used.. It also defines a child relation to the root SBB of PresencePublicationService to retrieve the composed PIDF document for the subscription's notifier. - The SBB also provides an SbbLocalObject interface that can be used, in JAIN SLEE child relations, to make the presence event known to the subscribers of a specific resource. - - - - The implementation architecture of the SIP Presence Server also contains client-side components: - - - Presence Client SBB - - The PresenceClientSBB is the interface to a JAIN SLEE SBB intended to be used as a client for the &PLATFORM_NAME; SIP Presence Server (and other servers compliant with same standards), in JAIN SLEE child relations. - Two implementations of this interface are provided: the InternalPresenceClientSBB that is used with applications running in the &PLATFORM_NAME; SIP Presence Server JAIN SLEE container, and the ExternalPresenceClientSBB, used with applications running in a different JAIN SLEE container than the &PLATFORM_NAME; SIP Presence Server. - - - -
-
-
- &PLATFORM_NAME; Resource List Server - The &PLATFORM_NAME; Resource List Server is currently tightly integrated with the &PLATFORM_NAME; SIP Presence Server, supporting RFC 5367 and OMA service uri template. -
-
- Configuring The SIP Presence Server - TODO how to configure the SIP Publication and Subscription Interfaces -
-
- Resources and Further Information about the SIP Presence Server - For further information on the &PLATFORM_NAME; SIP Presence Server, see the following list of additional resources: - - - - - &PLATFORM_NAME; SIP Event Publication and Subscription Control Components - - - -
-
diff --git a/docs/sources/src/main/resources/en-US/bak/Chapter-XML_Document_Management_Server.xml b/docs/sources/src/main/resources/en-US/bak/Chapter-XML_Document_Management_Server.xml deleted file mode 100644 index a655932c67..0000000000 --- a/docs/sources/src/main/resources/en-US/bak/Chapter-XML_Document_Management_Server.xml +++ /dev/null @@ -1,255 +0,0 @@ - - -%BOOK_ENTITIES; - -]> - - &PLATFORM_NAME; XML Document Management Server - The &PLATFORM_NAME; XML Document Management Server (XDM Server) is part of the &PLATFORM_NAME; SIP Presence Service; it is the first free and open source implementation of an XML Document Management Server as defined in the . This functional element of next-generation IP communication networks is responsible for handling the management of user XML documents stored on the network side, such as presence authorization rules, contact and group lists (also known as resource lists), static presence information, and much more. -
- Functional Architecture of the XDM Server - The &PLATFORM_NAME; XDM Server includes the following XCAP application usages: - - - - IETF Presence Rules (RFC 5025) - - - - - OMA Presence Rules (OMA Presence Simple v1.1 Candidate Release) - - - - - IETF Resource Lists - - - - - IETF RLS Services (RFC 4826) - - - - - IETF XCAP-CAPS (RFC 4825) - - - - The SIP interface partially implements the XCAP Diff Event IETF draft, version 3. Subscriptions to a single document or usage by an entire application are supported. However, these differing usages do not extend to the single-XML element or attribute value level. Regarding the notifications, the diff-processing subscription parameter, if present, is ignored, and patching of content is not available at the moment, which means that only the document etags, new and/or old, will be provided. - - - - - - The &PLATFORM_NAME; XML Document Management Server - - - The XDM Server comprises the following functional elements: - - Functional Elements of the XDM Server - - Data Source - - The XDM Server data source is where all user XML documents are stored. Information related to the server itself is also stored in this element along with the user's provisioned data - The data source also handles subscriptions to updates on specific documents, or complete XCAP application usages. - - - - Aggregation Proxy - - The aggregation proxy is responsible for handling an XDM client's XCAP requests, which includes authentication of the requester. - - - - Request Processor - - This element includes the XCAP Server logic to process an XCAP request and return a proper response, including authorization for the authenticated user. - - - - XDM Event Subscription Control - - This element, using the SIP protocol, is responsible for handling subscriptions to documents managed by the XDM. Its functions include the authentication and authorization of a subscription, attachment to update events on specific documents or application usages, and the sending of notifications when documents change. - - - - - Implementation Architecture of the &PLATFORM_NAME; XML Document Management Server - The XDM Server is built on top of the &PLATFORM_NAME; JAIN SLEE container. This figure depicts the architecture of the XDM Server implementation. - - - - - - - &PLATFORM_NAME; XML Document Management Server Implementation - - - - The Functional Elements of the XML Document Management Server - - Data Source Resource Adapter - - This resource adapter implements the Data Source functional element. - The RA Type defines two activities objects, DocumentActivity and AppUsageActivity, both of which are used to fire events that signal that a document, element or attribute was updated. - The RA Type also defines a Service Building Block (SBB) RA interface to manage the users and documents stored in the XDM Server, and create activities, where events will be fired. The resource adapter will only fire events on activities that exist; that is, the RA won't create activities implicitly if a document is updated. - The RA Type also provides a base abstract implementation of the resource adapter, making it very simple to change the underlying resource used to store information, which is by default the internal JDBC datasource of the JBoss Application Server. - - - - AppUsage Cache Resource Adaptor - - This resource adapter stores the XCAP application usages installed in the server. - Each AppUsage is an object that includes the logic to validate XCAP documents that result from XCAP requests and are expensive to create; this resource adapter thus provides caching of AppUsages, using a pool model. - The resource adapter doesn't possess events or activities. - - - - AppUsage Service - - XCAP Application Usages are installed through a JAIN SLEE service, making it possible to add and/or remove application usages while the server is running. - - - - Aggregation Proxy Service - - This JAIN SLEE service implements the aggregation proxy functional element. It handles events fired by the &PLATFORM_NAME; HTTP Servlet resource adapter and then uses two child SBBs: the User Profile Enabler SBB to retrieve information regarding the user needed for authentication/authorization of the XCAP request, and the Request Processor SBB, which handles the XCAP request. - - - - Request Processor SBB - - The Request Processor SBB implements the request processor functional element, providing a synchronous SBB interface to process XCAP requests. It uses the AppUsage Cache resource adapter to borrow AppUsage objects, and the Data Source resource adapter to retrieve or set documents stored in the server's data source. - - - - User Profile Enabler SBB - - This SBB provides a synchronous SBB interface used in JAIN SLEE child relations in order to retrieve user information, to be used on user authentication. Two different implementations of the interface are provided: the first considers whether the information is stored in the XDM Data Source, another interfaces with a Diameter Sh Server, such as IMS HSS. - - - - XCAP Diff Subscription Control Service - - This JAIN SLEE Service extends the abstract SIP Event Subscription Control component to handle SIP subscriptions on the xcap-diff event package. - - - - The implementation architecture figure also contains client-side components: - - Client-Side Components of the XML Document Management Server - - XCAP Client - - The XCAP client is a simple API to interact with an XCAP Server that internally uses the Apache HTTP Client. - -   - - - - XCAP Client Resource Adaptor - - The XCAP Client Resource Adapter adapts the XCAP Client API into the JAIN SLEE domain. It provides methods to interact with the XCAP server in both synchronous and asynchronous ways. - The RA Type description and code snippets using the RA can be found here. - - - - XDM Client SBB - - The XDMClientSBB is an interface of a JAIN SLEE SBB to be used as a client to the &PLATFORM_NAME; XDM Server (and others compliant with same standards), in JAIN SLEE child relations. - Two implementations of this interface are provided: - - - - InternalXDMClientSBB is intended to be used on applications running in the &PLATFORM_NAME; XDM Server JAIN SLEE container, and - - - - ExternalXDMClientSBB, which is intended to be used on applications in a different JAIN SLEE container than the &PLATFORM_NAME; XDM Server. - - - - - -
- -
- Configuring the XDM Server - -
- Configuring the XDM Server XCAP root - The &PLATFORM_NAME; XDM Server comes pre-configured for an XCAP root of http://<hostname>:8080/mobicents, hostname being the host/IP used to start the server (127.0.0.1 by default). It is possible to change the last path segment: - - - Rename $JBOSS_HOME/server/<server_profile>/deploy/mobicents.war to the desired last path segment in the XCAP root (e.g. rename to xcap-root.war for an XCAP root of http://<hostname>:8080/xcap-root). The <server_profile> is the server configuration/profile used in the underlying JBoss AS, by default it is default - - - Edit properties file $JBOSS_HOME/server/<server_profile>/deploy/msps-xdms-ds-ra-DU-&VERSION;.jar/library/msps-xdms-core-sbb-&VERSION;.jar/org/mobicents/slee/xdm/server/configuration.properties, define the new XCAP root last path segment through the property XCAP_ROOT, don't forget to use a leading / . Again the <server_profile> is the server configuration/profile used in the underlying JBoss AS. - - -
- -
- XDM Server User Profile Provisioning - XCAP interface is public, used by users to manage their information such as buddy list, presence authorization rules, etc. thus it needs to enforce user authentication. To do the user authentication, the server relies on the User Profile Enabler managed data, such as the users passwords, and this information must be provisioned, this can be done in two ways, both requiring the server to be running: - - - User Provisioning through an JMX Client - - Users can be added/removed through the MBean named slee:userprofile=UserProfileControl - - - - User Provisioning through the JBoss AS default datasource. - - Users can be added/removed through adding/removing rows of the table named MOBICENTS_SLEE_ENABLER_USERPROFILES. - - - -
-
- -
- Resources and Further Information about the XDM Server - For further information on the &PLATFORM_NAME; XDM Server, here is a list of additional resources: - - - - XCAP Client API Documentation - - - - - XCAP Client RA Type Description and Example Code Snippets - - - -
-
diff --git a/docs/sources/src/main/resources/en-US/bak/Revision_History.xml b/docs/sources/src/main/resources/en-US/bak/Revision_History.xml deleted file mode 100644 index 042e329820..0000000000 --- a/docs/sources/src/main/resources/en-US/bak/Revision_History.xml +++ /dev/null @@ -1,54 +0,0 @@ - - -%BOOK_ENTITIES; - -]> - - Revision History - - - - - 3.0 - Fri Jul 10 2009 - - Eduardo - Martins - - - - Major update to include XDM Server authentication and authorization, creation of XCAP Application Usages, SIP Client configuration examples and Resource List Server. - - - - - 2.0 - Fri Mar 06 2009 - - Douglas - Silas - - - - First release of the "parameterized" and much-improved &PLATFORM_NAME; documentation. - - - - - 1.0 - Tue Jan 20 2009 - - Douglas - Silas - - - - Creation of the &PLATFORM_NAME; SIP Presence User Guide separate from the &PLATFORM_NAME; Platform User Guide. - - - - - - diff --git a/docs/sources/src/main/resources/en-US/bak/SIP_Presence_Service_User_Guide.xml b/docs/sources/src/main/resources/en-US/bak/SIP_Presence_Service_User_Guide.xml deleted file mode 100644 index 54cff2b123..0000000000 --- a/docs/sources/src/main/resources/en-US/bak/SIP_Presence_Service_User_Guide.xml +++ /dev/null @@ -1,46 +0,0 @@ - - -%BOOK_ENTITIES; -]> - - - - - - - - - - - - - - - diff --git a/docs/sources/src/main/resources/en-US/bak/mss/jbcp-task-section-Java_Development_Kit-Installing_Configuring_and_Running.xml b/docs/sources/src/main/resources/en-US/bak/mss/jbcp-task-section-Java_Development_Kit-Installing_Configuring_and_Running.xml deleted file mode 100644 index 6aa8901355..0000000000 --- a/docs/sources/src/main/resources/en-US/bak/mss/jbcp-task-section-Java_Development_Kit-Installing_Configuring_and_Running.xml +++ /dev/null @@ -1,253 +0,0 @@ - - -%BOOK_ENTITIES; -]> -
- Java Development Kit: Installing, Configuring and Running - - The JBoss Communications Platform is written in Java; therefore, before running any JBCP server, you must have a working Java Runtime Environment (JRE) or Java Development Kit (JDK) installed on your system. In addition, the JRE or JDK you are using to run JBCP must be version 5 or higher - - At this point in time, it is possible to run most JBCP servers, such as the JAIN SLEE Server, using a Java 6 JRE or JDK. Be aware, however, that presently the XML Document Management Server does not run on Java 6. We suggest checking the Mobicents web site, forums or discussion pages if you need to inquire about the status of running the XML Document Management Server with Java 6. - - - - - Should I Install the JRE or JDK? - - Although you can run JBCP servers using the Java Runtime Environment, we assume that most users are developers interested in developing Java-based, JBCP-driven solutions. Therefore, in this guide we take the tact of showing how to install the full Java Development Kit. - - - - Should I Install the 32-Bit or the 64-Bit JDK, and Does It Matter? - - Briefly stated: if you are running on a 64-Bit Linux or Windows platform, you should consider installing and running the 64-bit JDK over the 32-bit one. Here are some heuristics for determining whether you would rather run the 64-bit Java Virtual Machine (JVM) over its 32-bit cousin for your application: - - - - - - Wider datapath: the pipe between RAM and CPU is doubled, which improves the performance of memory-bound applications when using a 64-bit JVM. - - - - - 64-bit memory addressing gives virtually unlimited (1 exabyte) heap allocation. However large heaps affect garbage collection. - - - - - Applications that run with more than 1.5 GB of RAM (including free space for garbage collection optimization) should utilize the 64-bit JVM. - - - - - Applications that run on a 32-bit JVM and do not require more than minimal heap sizes will gain nothing from a 64-bit JVM. Barring memory issues, 64-bit hardware with the same relative clock speed and architecture is not likely to run Java applications faster than their 32-bit cousin. - - - - - Note that the following instructions detail how to download and install the 32-bit JDK, although the steps are nearly identical for installing the 64-bit version. - - - - - Downloading - - You can download the Sun JDK 5.0 (Java 2 Development Kit) from Sun's website: . Click on the Download link next to "JDK 5.0 Update <x>" (where <x> is the latest minor version release number). On the next page, select your language and platform (both architecture—whether 32- or 64-bit—and operating system), read and agree to the Java Development Kit 5.0 License Agreement, and proceed to the download page. - - - - The Sun website will present two download alternatives to you: one is an RPM inside a self-extracting file (for example, jdk-1_5_0_16-linux-i586-rpm.bin), and the other is merely a self-extracting file (e.g. jdk-1_5_0_16-linux-i586.bin). If you are installing the JDK on Red Hat Enterprise Linux, Fedora, or another RPM-based Linux system, we suggest that you download the self-extracting file containing the RPM package, which will set up and use the SysV service scripts in addition to installing the JDK. We also suggest installing the self-extracting RPM file if you will be running JBCP in a production environment. - - - - Installing - - The following procedures detail how to install the Java Development Kit on both Linux and Windows. - - - - Installing the JDK on Linux - - - Regardless of which file you downloaded, you can install it on Linux by simply making sure the file is executable and then running it: - - - ~]$ chmod +x "jdk-1_5_0_<minor_version>-linux-<architecture>-rpm.bin" -~]$ ./"jdk-1_5_0_<minor_version>-linux-<architecture>-rpm.bin" - - - - - You Installed Using the Non-RPM Installer, but Want the SysV Service Scripts - - If you download the non-RPM self-extracting file (and installed it), and you are running on an RPM-based system, you can still set up the SysV service scripts by downloading and installing one of the -compat packages from the JPackage project. Remember to download the -compat package which corresponds correctly to the minor release number of the JDK you installed. The compat packages are available from . - - - - - You do not need to install a -compat package in addition to the JDK if you installed the self-extracting RPM file! The -compat package merely performs the same SysV service script set up that the RPM version of the JDK installer does. - - - - Installing the JDK on Windows - - - Using Explorer, simply double-click the downloaded self-extracting installer and follow the instructions to install the JDK. - - - - - - - Configuring - - Configuring your system for the JDK consists in two tasks: setting the JAVA_HOME environment variable, and ensuring that the system is using the proper JDK (or JRE) using the alternatives command. Setting JAVA_HOME usually overrides the values for java, javac and java_sdk_1.5.0 in alternatives, but we will set them all just to be safe and consistent. - - - - - Setting the JAVA_HOME Environment Variable on Generic Linux - - - After installing the JDK, you must ensure that the JAVA_HOME environment variable exists and points to the location of your JDK installation. - - - Setting the <envar>JAVA_HOME</envar> Environment Variable on Linux - - You can determine whether JAVA_HOME is set on your system by echoing it on the command line: - - - - ~]$ echo $JAVA_HOME - - If JAVA_HOME is not set already, then you must set its value to the location of the JDK installation on your system. You can do this by adding two lines to your personal ~/.bashrc configuration file. Open ~/.bashrc (or create it if it doesn't exist) and add a line similar to the following one anywhere inside the file: - - - export JAVA_HOME="/usr/lib/jvm/jdk1.5.0_<version>" - - - You should also set this environment variable for any other users who will be running JBCP (any environment variables exported from ~/.bashrc files are local to that user). - - - - - Setting java, javac and java_sdk_1.5.0 Using the alternatives command - - - Selecting the Correct System JVM on Linux using <command>alternatives</command> - - - On systems with the alternatives command, including Red Hat Enterprise Linux and Fedora, you can easily choose which JDK (or JRE) installation you wish to use, as well as which java and javac executables should be run when called. - - - - As the root user, call /usr/sbin/alternatives with the option to select between JDKs and JREs installed on your system: - - - root@localhost ~]$ /usr/sbin/alternatives --config java - -There are 3 programs which provide 'java'. - - Selection Command ------------------------------------------------ - 1 /usr/lib/jvm/jre-1.5.0-gcj/bin/java - 2 /usr/lib/jvm/jre-1.6.0-sun/bin/java -*+ 3 /usr/lib/jvm/jre-1.5.0-sun/bin/java - - -Enter to keep the current selection[+], or type selection number: - - - In our case, we want to use the Sun JDK, version 5, that we downloaded and installed, to run the java executable. In the alternatives information printout above, a plus (+) next to a number indicates the one currently being used. As per alternatives' instructions, pressing Enter will simply keep the current JVM, or you can enter the number corresponding to the JVM you would prefer to use. - - - Repeat the procedure above for the javac command and the java_sdk_1.5.0 environment variable, as the root user: - - - ~]$ /usr/sbin/alternatives --config javac - - ~]$ /usr/sbin/alternatives --config java_sdk_1.5.0 - - - - Setting the JAVA_HOME Environment Variable on Windows - - - For information on how to set environment variables in Windows, refer to . - - - - - - - Testing - - Finally, to make sure that you are using the correct JDK or Java version (5 or higher), and that the java executable is in your PATH, run the java - command in the terminal from your home directory: - - - - ~]$ java -version -java version "1.5.0_16" -Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_16-b03) -Java HotSpot(TM) Client VM (build 1.5.0_16-b03, mixed mode, sharing) - - - - Uninstalling - - There is usually no reason (other than space concerns) to remove a particular JDK from your system, given that you can switch between JDKs and JREs easily using alternatives, and/or by setting JAVA_HOME. - - - - Uninstalling the JDK on Linux - - On RPM-based systems, you can uninstall the JDK using the yum - command. - - - - Uninstalling the JDK on Windows - - On Windows systems, check the JDK entry in the Start menu for an uninstall command, or use Add/Remove Programs. - - -
- - diff --git a/docs/sources/src/main/resources/en-US/bak/mss/jbcp-task-section-Setting_the_JBOSS_HOME_Environment_Variable.xml b/docs/sources/src/main/resources/en-US/bak/mss/jbcp-task-section-Setting_the_JBOSS_HOME_Environment_Variable.xml deleted file mode 100644 index 60922452b3..0000000000 --- a/docs/sources/src/main/resources/en-US/bak/mss/jbcp-task-section-Setting_the_JBOSS_HOME_Environment_Variable.xml +++ /dev/null @@ -1,116 +0,0 @@ - - -%BOOK_ENTITIES; - -]> -
- Setting the JBOSS_HOME Environment Variable - - The JBoss Communications Platform (JBCP) is built on top of the JBoss Enterprise Application Platform (JBoss EAP). You do not need to set the JBOSS_HOME environment variable to run any of the JBoss Communications Platform servers unless JBOSS_HOME is already set. - - - The best way to know for sure whether JBOSS_HOME was set previously or not is to perform a simple check which may save you time and frustration. - - - Checking to See If JBOSS_HOME is Set on Linux - - At the command line, echo - $JBOSS_HOME to see if it is currently defined in your environment: - - - - ~]$ echo $JBOSS_HOME - - Silence on the command line (a completely blank line) means that it is not set, in which case you can proceed with running the JBoss Communications Platform. - - - Checking to See if JBOSS_HOME is Set on Windows - - For information on determining whether environment variables are set in recent versions of Windows, refer to . - - - - If JBOSS_HOME is already set on your system, then you have three options: - - - - - unset it, which only takes effect for the current session and is therefore not advised; - - - - - find where JBOSS_HOME is defined, such as in your local ~/.bashrc startup script in Linux, or, possibly, system-wide in /etc/bashrc, and remove it or comment it out; - - - - - or point it to the correct location, in which case you should refer to the following instructions on how to set JBOSS_HOME. - - - - - Setting the JBOSS_HOME Environment Variable on Linux - - The JBOSS_HOME environment variable must point to the directory which contains all of the files for the JBoss Communications Platform that you installed. As another hint, this topmost directory contains a bin subdirectory. - - - - Setting JBOSS_HOME in your personal ~/.bashrc startup script carries the advantage of retaining effect over reboots. Each time you log in, the environment variable is sure to be set for you, as a user. On Linux, it is possible to set JBOSS_HOME as a system-wide environment variable, by defining it in /etc/bashrc, but this method is neither recommended nor detailed in these instructions. - - - To Set JBOSS_HOME on Linux... - - - Open the ~/.bashrc startup script, which is a hidden file in your home directory, in a text editor, and insert the following line on its own line while substituting for the actual install location on your system: - - - export JBOSS_HOME="/home/<username>/<path>/<to>/<install_directory>" - - - - Save and close the .bashrc startup script. - - - - - You should source the .bashrc script to force your change to take effect, so that JBOSS_HOME becomes set for the current session - - Note that any other terminals which were opened prior to your having altered .bashrc will need to source - ~/.bashrc as well should they require access to JBOSS_HOME. - - . - - - ~]$ source ~/.bashrc - - - - Finally, ensure that JBOSS_HOME is set in the current session, and actually points to the correct location: - - - - The command line usage below is based upon a binary installation of the JBoss Communications Platform. In this sample output, JBOSS_HOME has been set correctly to the topmost_directory of the JBCP installation. Note that if you are installing one of the standalone JBCP servers (with JBoss AS bundled!), then JBOSS_HOME would point to the topmost_directory of your server installation. - - - - ~]$ echo $JBOSS_HOME -/home/silas/&JBCP_JBOSS_HOME_LIN; - - - - - Setting the JBOSS_HOME Environment Variable on Windows - - The JBOSS_HOME environment variable must point to the directory which contains all of the files for the JBoss Communications Platform that you installed. As another hint, this topmost directory contains a bin subdirectory. - - - - For information on how to set environment variables in recent versions of Windows, refer to . - - -
diff --git a/docs/sources/src/main/resources/en-US/bak/mss/mob-task-section-Java_Development_Kit-Installing_Configuring_and_Running.xml b/docs/sources/src/main/resources/en-US/bak/mss/mob-task-section-Java_Development_Kit-Installing_Configuring_and_Running.xml deleted file mode 100644 index 3a8476ac57..0000000000 --- a/docs/sources/src/main/resources/en-US/bak/mss/mob-task-section-Java_Development_Kit-Installing_Configuring_and_Running.xml +++ /dev/null @@ -1,200 +0,0 @@ - - -%BOOK_ENTITIES; -]> -
- Java Development Kit: Installing, Configuring and Running - The MobicentsJBCP platform is written in Java. A working Java Runtime Environment (JRE) or Java Development Kit (JDK) must be installed prior to running the server. The required version must be version 5 or higher. - It is possible to run most MobicentsJBCP servers, such as the JAIN SLEE Server, using a Java 6 JRE or JDK. However, the XML Document Management Server does not run on Java 6. Check the public support forum and project road map pages to verify Java 6 support prior to running the XML Document Management Server with Java 6. - - - JRE or JDK? - - Although MobicentsJBCP servers are capable of running on the Java Runtime Environment, this guide assumes the audience is mainly developers interested in developing Java-based, MobicentsJBCP-driven solutions. Therefore, installing the Java Development Kit is covered due to the anticipated audience requirements. - - - - 32-Bit or 64-Bit JDK - If the system uses 64-Bit Linux or Windows architecture, the 64-bit JDK is strongly recommended over the 32-bit version. The following heuristics should be considered in determining whether the 64-bit Java Virtual Machine (JVM) is suitable: - - - - Wider datapath: the pipe between RAM and CPU is doubled, which improves the performance of memory-bound applications when using a 64-bit JVM. - - - 64-bit memory addressing provides a virtually unlimited (1 exabyte) heap allocation. Note that large heaps can affect garbage collection. - - - Applications that run with more than 1.5 GB of RAM (including free space for garbage collection optimization) should utilize the 64-bit JVM. - - - Applications that run on a 32-bit JVM and do not require more than minimal heap sizes will gain nothing from a 64-bit JVM. Excluding memory issues, 64-bit hardware with the same relative clock speed and architecture is not likely to run Java applications faster than the 32-bit version. - - - - The following instructions describe how to download and install the 32-bit JDK, however the steps are nearly identical for installing the 64-bit version. - - - Downloading - Download the Sun JDK 5.0 (Java 2 Development Kit) from Sun's website: . Click the Download link next to "JDK 5.0 Update <x>" (where <x> is the latest minor version release number). - - - The Sun website offers two download options: - - - A self-extracting RPM (for example, jdk-1_5_0_16-linux-i586-rpm.bin) - - - A self-extracting file (e.g. jdk-1_5_0_16-linux-i586.bin) - - - - If installing the JDK on Red Hat Enterprise Linux, Fedora, or another RPM-based Linux system, it is recommended that the self-extracting file containing the RPM package is selected. This option will set up and use the SysV service scripts in addition to installing the JDK. The RPM option is also recommended if the MobicentsJBCP platform is being set up in a production environment. - - - Installing - - The following procedures detail how to install the Java Development Kit on both Linux and Windows. - - - - Installing the JDK on Linux - - Ensure the file is executable, then run it: - ~]$ chmod +x "jdk-1_5_0_<minor_version>-linux-<architecture>-rpm.bin" -~]$ ./"jdk-1_5_0_<minor_version>-linux-<architecture>-rpm.bin" - - - - Setting up SysV Service Scripts for Non-RPM Files - If the non-RPM self-extracting file is selected for an RPM-based system, the SysV service scripts can be configured by downloading and installing one of the -compat packages from the JPackage project. Download the -compat package that corresponds correctly to the minor release number of the installed JDK. The compat packages are available from . - - - A -compat package is not required for RPM installations. The -compat package performs the same SysV service script set up that the RPM version of the JDK installer does. - - - - Installing the JDK on Windows - - Using Explorer, double-click the downloaded self-extracting installer and follow the instructions to install the JDK. - - - - Configuring - - Configuring the system for the JDK consists of two tasks: setting the JAVA_HOME environment variable, and ensuring the system is using the proper JDK (or JRE) using the alternatives command. Setting JAVA_HOME generally overrides the values for java, javac and java_sdk_1.5.0 in alternatives, however it is recommended to specify the value for consistency. - - - - - Setting the JAVA_HOME Environment Variable on Generic Linux - - - After installing the JDK, ensure the JAVA_HOME environment variable exists and points to the location of the JDK installation. - - - Setting the <envar>JAVA_HOME</envar> Environment Variable on Linux - Determine whether JAVA_HOME is set by executing the following command: - - ~]$ echo $JAVA_HOME - - If JAVA_HOME is not set, the value must be set to the location of the JDK installation on the system. This can be achieved by adding two lines to the ~/.bashrc configuration file. Open ~/.bashrc (or create it if it does not exist) and add a line similar to the following one anywhere inside the file: - - export JAVA_HOME="/usr/lib/jvm/jdk1.5.0_<version>" - - The changes should also be applied for other users who will be running the MobicentsJBCP on the machine (any environment variables exported from ~/.bashrc files are local to that user). - - - - - Setting java, javac and java_sdk_1.5.0 using the alternatives command - - On systems with the alternatives command, including Red Hat Enterprise Linux and Fedora, it is possible to choose which JDK (or JRE) installation to use, as well as which java and javac executables should be run when called. - As the superuser, call /usr/sbin/alternatives with the option to select between JDKs and JREs installed on your system: - -home]$ sudo /usr/sbin/alternatives --config java - -There are 3 programs which provide 'java'. - - Selection Command ------------------------------------------------ - 1 /usr/lib/jvm/jre-1.5.0-gcj/bin/java - 2 /usr/lib/jvm/jre-1.6.0-sun/bin/java -*+ 3 /usr/lib/jvm/jre-1.5.0-sun/bin/java - -Enter to keep the current selection[+], or type selection number: - - The Sun JDK, version 5, is required to run the java executable. In the alternatives information printout above, a plus (+) next to a number indicates the option currently being used. Press Enter to keep the current JVM, or enter the number corresponding to the JVM to select that option. - - As the superuser, repeat the procedure above for the javac command and the java_sdk_1.5.0 environment variable: - home]$ sudo /usr/sbin/alternatives --config javac - home]$ sudo /usr/sbin/alternatives --config java_sdk_1.5.0 - - - - Setting the JAVA_HOME Environment Variable on Windows - - For information on how to set environment variables in Windows, refer to . - - - - - Testing - - To ensure the correct JDK or Java version (5 or higher), and that the java executable is in the PATH environment variable, run the java -version command in the terminal from the home directory: - - - -home]$ java -version -java version "1.5.0_16" -Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_16-b03) -Java HotSpot(TM) Client VM (build 1.5.0_16-b03, mixed mode, sharing) - - Uninstalling - - It is not necessary to remove a particular JDK from a system, because the JDK and JRE version can be switched as required using the alternatives command, and/or by setting JAVA_HOME. - - - Uninstalling the JDK on Linux - - On RPM-based systems, uninstall the JDK using the yum remove <jdk_rpm_name> command. - - - Uninstalling the JDK on Windows - - On Windows systems, check the JDK entry in the Start menu for an uninstall option, or use Add/Remove Programs. - - -
diff --git a/docs/sources/src/main/resources/en-US/bak/mss/mob-task-section-Setting_the_JBOSS_HOME_Environment_Variable.xml b/docs/sources/src/main/resources/en-US/bak/mss/mob-task-section-Setting_the_JBOSS_HOME_Environment_Variable.xml deleted file mode 100644 index d248cf84f1..0000000000 --- a/docs/sources/src/main/resources/en-US/bak/mss/mob-task-section-Setting_the_JBOSS_HOME_Environment_Variable.xml +++ /dev/null @@ -1,114 +0,0 @@ - - -%BOOK_ENTITIES; -]> -
- Setting the JBOSS_HOME Environment Variable - - The Mobicents Platform (Mobicents) is built on top of the JBoss Application Server (JBoss AS). You do not need to set the JBOSS_HOME environment variable to run any of the Mobicents Platform servers unless JBOSS_HOME is already set. - - The best way to know for sure whether JBOSS_HOME was set previously or not is to perform a simple check which may save you time and frustration. - - Checking to See If JBOSS_HOME is Set on Linux - At the command line, echo - $JBOSS_HOME to see if it is currently defined in your environment: - - ~]$ echo $JBOSS_HOME - The Mobicents Platform and most Mobicents servers are built on top of the JBoss Application Server (JBoss AS). When the Mobicents Platform or Mobicents servers are built from source, then JBOSS_HOME must be set, because the Mobicents files are installed into (or "over top of" if you prefer) a clean JBoss AS installation, and the build process assumes that the location pointed to by the JBOSS_HOME environment variable at the time of building is the JBoss AS installation into which you want it to install the Mobicents files. - - This guide does not detail building the Mobicents Platform or any Mobicents servers from source. It is nevertheless useful to understand the role played by JBoss AS and JBOSS_HOME in the Mobicents ecosystem. - - The immediately-following section considers whether you need to set JBOSS_HOME at all and, if so, when. The subsequent sections detail how to set JBOSS_HOME on Linux and Windows - - - - Even if you fall into the category below of not needing to set JBOSS_HOME, you may want to for various reasons anyway. Also, even if you are instructed that you do not need to set JBOSS_HOME, it is good practice nonetheless to check and make sure that JBOSS_HOME actually isn't set or defined on your system for some reason. This can save you both time and frustration. - - - You DO NOT NEED to set JBOSS_HOME if... - - - - ...you have installed the Mobicents Platform binary distribution. - - - - - ...you have installed a Mobicents server binary distribution which bundles JBoss AS. - - - - You MUST set JBOSS_HOME if... - - - - ...you are installing the Mobicents Platform or any of the Mobicents servers from source. - - - - - ...you are installing the Mobicents Platform binary distribution, or one of the Mobicents server binary distributions, which do not bundle JBoss AS. - - - - - Naturally, if you installed the Mobicents Platform or one of the Mobicents server binary releases which do not bundle JBoss AS, yet requires it to run, then you should install JBoss AS before setting JBOSS_HOME or proceeding with anything else. - - - Setting the JBOSS_HOME Environment Variable on Linux - - The JBOSS_HOME environment variable must point to the directory which contains all of the files for the Mobicents Platform or individual Mobicents server that you installed. As another hint, this topmost directory contains a bin subdirectory. - - - - Setting JBOSS_HOME in your personal ~/.bashrc startup script carries the advantage of retaining effect over reboots. Each time you log in, the environment variable is sure to be set for you, as a user. On Linux, it is possible to set JBOSS_HOME as a system-wide environment variable, by defining it in /etc/bashrc, but this method is neither recommended nor detailed in these instructions. - - - To Set JBOSS_HOME on Linux... - - - Open the ~/.bashrc startup script, which is a hidden file in your home directory, in a text editor, and insert the following line on its own line while substituting for the actual install location on your system: - - export JBOSS_HOME="/home/<username>/<path>/<to>/<install_directory>" - - - - Save and close the .bashrc startup script. - - - - - You should source the .bashrc script to force your change to take effect, so that JBOSS_HOME becomes set for the current session - - Note that any other terminals which were opened prior to your having altered .bashrc will need to source - ~/.bashrc as well should they require access to JBOSS_HOME. - - . - - ~]$ source ~/.bashrc - - - - Finally, ensure that JBOSS_HOME is set in the current session, and actually points to the correct location: - - - - The command line usage below is based upon a binary installation of the Mobicents Platform. In this sample output, JBOSS_HOME has been set correctly to the topmost_directory of the Mobicents installation. Note that if you are installing one of the standalone Mobicents servers (with JBoss AS bundled!), then JBOSS_HOME would point to the topmost_directory of your server installation. - - - ~]$ echo $JBOSS_HOME -/home/silas/&MOB_JBOSS_HOME_LIN; - - - - Setting the JBOSS_HOME Environment Variable on Windows - - The JBOSS_HOME environment variable must point to the directory which contains all of the files for the Mobicents Platform or individual Mobicents server that you installed. As another hint, this topmost directory contains a bin subdirectory. - - - - For information on how to set environment variables in recent versions of Windows, refer to . - -
diff --git a/docs/sources/src/main/resources/en-US/concept-chapter-AS7-mss.xml b/docs/sources/src/main/resources/en-US/concept-chapter-AS7-mss.xml deleted file mode 100644 index 789b008cc6..0000000000 --- a/docs/sources/src/main/resources/en-US/concept-chapter-AS7-mss.xml +++ /dev/null @@ -1,540 +0,0 @@ - - -%BOOK_ENTITIES; -]> - - -
- Getting Started with &SHORT_PLATFORM_NAME; for JBoss AS7 - - - - - Features not yet available on &SHORT_PLATFORM_NAME; for JBoss AS7 - * SIP Clustering and Failover - * SNMP - * Jopr Monitoring - - - -Some of the features mentioned above will likely be added in the future. As of the time of this writing, they are not available. Even though Jopr monitoring is not available, there is a Command Line Interface (CLI), which will be discussed further down. As the features become available, this guide will be updated to reflect the changes. - - - - -
- -Downloading and Starting &SHORT_PLATFORM_NAME; for JBoss AS7 - - -If you have been working with JBoss for some time, you will quickly notice that the JBoss AS7 iteration has gone through a lot of changes. This guide will help you understand how you can quickly get started with JBoss AS7 within the &SHORT_PLATFORM_NAME; framework. - - - - -You can go to the link below to download the latest &SHORT_PLATFORM_NAME; for JBoss AS7: Download Latest Version of &SHORT_PLATFORM_NAME; for JBoss AS7 - - - -You will need to extract the content of the file into a directory on your local system. The root directory of the &SHORT_PLATFORM_NAME; for JBoss AS7 that you downloaded will be referred to in this guide as $JBOSS_HOME. - - - - -If this is your first time working with &SHORT_PLATFORM_NAME; for JBoss, you will need to make sure you have Java Run Time or JDK installed on your computer. You will also need to have the environment variables set. See the links below to learn how to get JRE or JDK setup on your system. - - - -Installing and Configuring JDK - - - - - - -Setting Environment Variables - - - - - - - Starting &SHORT_PLATFORM_NAME; for JBoss AS7 -To start the server do the following: - - -$JBOSS_HOME/bin/standalone.sh - - - -During the startup process, you will notice that the final part of the log output will be similar to the truncated output below. Notice that the Admin Console interface can be accessed at http://172.0.0.1:9990. This will be explained later. - - -14:28:43,972 INFO [org.jboss.as] (Controller Boot Thread) JBAS015951: Admin console listening on http://127.0.0.1:9990 -14:28:43,974 INFO [org.jboss.as] (Controller Boot Thread) JBAS015874: JBoss AS 7.1.2.Final "Steropes" -started in 22148ms - Started 222 of 306 services (83 services are passive or on-demand) - - - -You will notice that the startup is very fast. The reason for this is that JBoss was rewritten from the ground up for speed with services being started concurrently and non critical services remain passive until first use. This provides better system resource management. With the simple startup above, you will be able to enter the default web interface of the application server by going to this url http://127.0.0.1:8080. The result will show a screenshot similar to the one below. - - - - -
- JBoss Application Server 7 Welcome Page - - - - - -
- -
- - -With the standard startup script, you will not have access to any SIP functionalities. This is because of the modular approach implemented in JBoss AS7. There is a configuration file that needs to be used to activate additional functionalities like SIP and High Availability. - - - - -In order to start the &SHORT_PLATFORM_NAME; for JBoss AS7 with SIP functionalities, you need to append the startup script with the SIP configuration file. The configuration files are located in the $JBOSS_HOME/standalone/configuration directory. You can see the content of the directory below - - -application-roles.properties mgmt-users.properties standalone-ha.xml -application-users.properties mss-sip-stack.properties standalone-sip.xml -dars standalone-full-ha.xml standalone.xml -logging.properties standalone-full.xml standalone_xml_history - - - -Starting &SHORT_PLATFORM_NAME; for JBoss AS7 with SIP - - - -If you want to start &SHORT_PLATFORM_NAME; with SIP services activated, you need to go to the $JBOSS_HOME/bin directory. Type the following command: - - - -./standalone.sh -c standalone-sip.xml - - - - - You will see a message similar to the one below once the server is successfully started - - - -20:43:21,487 INFO [org.jboss.as.server] (ServerService Thread Pool -- 37) JBAS018559: Deployed "click2call.war" -20:43:21,489 INFO [org.jboss.as.server] (ServerService Thread Pool -- 37) JBAS018559: Deployed "sip-servlets-management.war" -20:43:21,647 INFO [org.jboss.as] (Controller Boot Thread) JBAS015951: Admin console listening on http://127.0.0.1:9990 -20:43:21,648 INFO [org.jboss.as] (Controller Boot Thread) JBAS015874: JBoss AS 7.1.2.Final "Steropes" started in 26560ms - Started 232 of 321 services (88 services are passive or on-demand) - - - - - -The click2call SIP sample application bundled with &SHORT_PLATFORM_NAME; will become available at this url http://127.0.0.1:8080/click2call. You can configure multiple SIP softphones to use the sample application. See the section below for how to configure and test the SIP sample application. - -
- -
-Testing Click2Call with &SHORT_PLATFORM_NAME; for JBOSS AS7 - - -Once the server is started as stated in the previous section, you can configure multiple instances of any SIP softphone you prefer. In this example, Linphone will be used. - - - -(configuring two instances of Linphone) - -start Linphone -go to the Options menu - -On the Network Settings tab, - SIP (UDP) port to 5061. (leave the rest as default) -On the Manage SIP Accounts tab, - click the add button - Your SIP identity: = sip:linphone@127.0.0.1:5080 - SIP Proxy address: = sip 127.0.0.1:5080 - -Leave the rest of the settings as default. - - -Configuring Linphone (on the second shell) - -go to the Options menu - -On the Network Settings tab, - SIP (UDP) port to 5062. (leave the rest as default) -On the Manage SIP Accounts tab, - click the add button - Your SIP identity: = sip:linphone2@127.0.0.1:5080 - SIP Proxy address: = sip 127.0.0.1:5080 - -Leave the rest of the settings as default. - - - -A correctly configured Linphone will look like the screenshot below. - - - -
- Successfully Configured Linphone - - - - - -
- -
- - - - -Once the phones are successfully registered with the &SHORT_PLATFORM_NAME; for JBoss AS7 server, you can check the result in the sample SIP application at this url, http://127.0.0.1:8080/click2call - - - - -
- Click2call SIP Registered Softphones - - - - - -
- -
- - - -You can make calls from the sample click2call application and see the logs in the shell terminal you used to start the &SHORT_PLATFORM_NAME; for JBoss AS7 server. - - - -
- - - - - -
- - Command Line Interface for &SHORT_PLATFORM_NAME; JBoss AS7 - - - -Part of the task of any administrator who has to manage a JBoss server will be to monitor services offered to clients. There is a command line interface bundled with JBoss AS7 which can be accessed by going to the $JBOSS_HOME/bin directory. - - - - You need to make sure that the JBoss server is running on your system and listening on port 9999. The section below will work you through steps to familiarize yourself with the CLI. - - - -There are so many features available with the &SHORT_PLATFORM_NAME; for JBoss AS7 CLI. The example below will concentrate on getting data from the SIP you started using the ./standalone.sh -c standalone-sip.xml script. - - - - -In the $JBOSS_HOME/bin directory, type - - - -./jboss-cli.sh - - -(This will show the message below) - - - -You are disconnected at the moment. -Type 'connect' to connect to the server or -'help' for the list of supported commands. - - -At the [disconnected /] command prompt, type - - -connect - - - -When you see the [standalone@localhost:9999 /] at the prompt, you are successfully connected to the server. - - - -Navigating the CLI -Moving around the &SHORT_PLATFORM_NAME; for JBoss AS7 CLI is similar to normal file system with a few exceptions. You can use commands like, (ls, cd, cd..) to navigate around the CLI - - - - - - - -Follow the steps below to access SIP information from the CLI - - - - - -At the prompt type (ls) - -[standalone@localhost:9999 /] ls -core-service deployment extension -interface path socket-binding-group -subsystem system-property launch-type=STANDALONE -management-major-version=1 management-minor-version=2 name=linux-fedora -namespaces=[] process-type=Server product-name=undefined -product-version=undefined profile-name=undefined release-codename=Steropes -release-version=7.1.2.Final running-mode=NORMAL schema-locations=[] -server-state=running - -[standalone@localhost:9999 /] cd deployment - -[standalone@localhost:9999 deployment] ls -click2call.war sip-servlets-management.war - -[standalone@localhost:9999 deployment] cd click2call.war - -[standalone@localhost:9999 deployment=click2call.war] ls -subdeployment -subsystem -content=[{"path" => "deployments/click2call.war","relative-to" => "jboss.server.base.dir","archive" => true}] -enabled=true -name=click2call.war -persistent=false -runtime-name=click2call.war -status=OK - -[standalone@localhost:9999 deployment=click2call.war] cd subsystem - -[standalone@localhost:9999 subsystem] ls -sip web - -[standalone@localhost:9999 subsystem] cd sip - - -[standalone@localhost:9999 subsystem=sip] ls -servlet -active-sip-application-sessions=7 -active-sip-sessions=8 -app-name=org.mobicents.servlet.sip.example.SimpleApplication -expired-sip-application-sessions=25 -expired-sip-sessions=26 -max-active-sip-sessions=-1 -rejected-sip-application-sessions=0 -rejected-sip-sessions=0 -sip-application-session-avg-alive-time=180 -sip-application-session-max-alive-time=230 -sip-application-sessions-created=32 -sip-application-sessions-per-sec=0.0 -sip-session-avg-alive-time=162 -sip-session-max-alive-time=180 -sip-sessions-created=34 -sip-sessions-per-sec=0.0 - - - - - -No SIP data on the CLI - -The data from the SIP subsystem are only available if you have the click2call -sample application running and your softphones are connected to the server. - - - - - - - SIP Servlets Management Console - - - -There is also a SIP servlets management console that is available at this url http://127.0.0.1:8080/sip-servlets-management. The resulting page will be similar to the screenshot below. More information will be provided about the SIP servlets management console in later chapters of this guide. - - -
- JBoss Application Server 7 Management Console - - - - - -
- -
- - -
- - - -
-Accessing Management Console - - -&SHORT_PLATFORM_NAME; for JBoss AS7 provides a management console that can be useful for accessing vital information about your server. In the welcome page that appears when you access http://127.0.0.1:8080, there is a link that points to the Administration Console. - - - -If you don't have a user account for the management console, you will see a screenshot like the one below. It contains instructions about how to create a user account. - - - - - - -
- Administration Console Error Page - - - - - -
- -
- - - - Creating a User Account - - - -Go to the $JBoss_HOME/bin directory and run the ./add-user.sh script. You can follow the interactive user mode to create an account for the Administration Console. - - - -Once the user account has been created, you can access the Administration Console at this address http://127.0.0.1:9990/console/ - - - -The screenshot below shows you what the Administration Console looks like. - - - - -
- Administration Console - - - - - -
- -
- - - - - - - Deleting Administration Console User Account - -Deleting the user account isn't very intuitive. In the event that you will need to remove an account and create another one, you can remove the account from the mgmt-users.properties file. It is located in the $&SHORT_PLATFORM_NAME;_JBoss_HOME/standalone/configuration directory. If you are running in the domain mode, you will need to check the corresponding configuration directory. - - - -
- Installing the &SHORT_PLATFORM_NAME; for JBoss Binary Distribution on <productname>Windows</productname> - - - - For this procedure, it is assumed that the downloaded archive is saved in the My Downloads folder. - - Create a directory in My Downloads to extract the zip file's contents into. For ease of identification, it is recommended that the version number of the binary is included in the folder name. For example, &SHORT_PLATFORM_NAME;-jboss-<version>. - - - Extract the contents of the archive, specifying the destination folder as the one created in the previous step. You can either use Winzip or the opensource tool called 7-Zip to extract the content of the donwloaded &SHORT_PLATFORM_NAME; for JBoss AS7 file - - - - It is recommended that the folder holding the &SHORT_PLATFORM_NAME; for JBoss files (in this example, the folder named &CMD_PLATFORM_NAME;-jboss-<version>) is moved to a user-defined location for storing executable programs. For example, the Program Files folder. - - ---> - - - - - - - Running &SHORT_PLATFORM_NAME; for JBoss on <productname>Windows</productname> - There are several ways to start &SHORT_PLATFORM_NAME; for JBoss on Windows. All of the following methods accomplish the same task. - - Using Windows Explorer, navigate to the bin subdirectory in the installation directory. - - - The preferred way to start &SHORT_PLATFORM_NAME; for JBoss from the Command Prompt. The command line interface displays details of the startup process, including any problems encountered during the startup process. - Open the Command Prompt via the Start menu and navigate to the correct folder: - C:\Users\<user>My Downloads> cd "&CMD_PLATFORM_NAME;-jboss-<version>" - - - Start the JBoss Application Server by executing one of the following files: - - - run.bat batch file: - C:\Users\<user>My Downloads\&CMD_PLATFORM_NAME;-jboss-<version>>bin\run.bat - - - run.jar executable Java archive: - C:\Users\<user>My Downloads\&CMD_PLATFORM_NAME;-jboss-<version>>java -jar bin\run.jar - - - - - - - -
- - - - - -
- - - - - - -
- - - diff --git a/docs/sources/src/main/resources/en-US/concept-chapter-Advanced_Features_of_the_SIP_Servlets_Server.xml b/docs/sources/src/main/resources/en-US/concept-chapter-Advanced_Features_of_the_SIP_Servlets_Server.xml deleted file mode 100644 index 214436aa01..0000000000 --- a/docs/sources/src/main/resources/en-US/concept-chapter-Advanced_Features_of_the_SIP_Servlets_Server.xml +++ /dev/null @@ -1,47 +0,0 @@ - - -%BOOK_ENTITIES; -]> - - Advanced Features of the SIP Servlets Server - The advanced features of SIP Servlets include Concurrency and -Congestion Control, load balancing with the &PLATFORM_NAME; Load Balancer, and, exclusively for &SHORT_PLATFORM_NAME; for JBoss, clustering and failover support. - - - - - - - - - -
- Eclipse IDE Tools - The SIP Servlets Eclipse tools assist developers in creating JSR-289 applications with &PLATFORM_NAME;. You can use the Dynamic Web Project wizard for converged applications to get started with an empty project, and then test your application with a real SIP Phone right from the IDE. -
- SIP Servlets Eclipse IDE Tools - - - - - -
-
- Pre-Install requirements - Eclipse 3.4 is required. -
-
- Installation - The standard Eclipse update site installation mechanism is leveraged. The &PLATFORM_NAME; Update Site is at the following location: http://mobicents.googlecode.com/svn/downloads/sip-servlets-eclipse-update-site. After adding this update site to Eclipse you can proceed with the regular Eclipse Plug-in Installation. If you need help, the process is demonstrated in this video. -
-
- SIP Servlets Core Plug-in - This plug-in allows you to create Dynamic Web Projects with the SIP Facet. There are a number of new Dynamic Web Project configurations for Converged applications. It is best to use the ones marked as "recommended". After you complete the wizard, a complete converged project skeleton will be generated. Working with this type of project is similar to working with normal Web projects. You can see a demo here. -
-
- SIP Phone Plug-in - The SIP Phone plug-in integrates a SIP phone inside your Eclipse IDE. You can use the phone to test your SIP or Media applications. The phone uses the microphone and speakers on your computer and allows you to simulate real-world scenarios. -
-
-
diff --git a/docs/sources/src/main/resources/en-US/concept-chapter-Appendix.xml b/docs/sources/src/main/resources/en-US/concept-chapter-Appendix.xml deleted file mode 100644 index 52e6939f3c..0000000000 --- a/docs/sources/src/main/resources/en-US/concept-chapter-Appendix.xml +++ /dev/null @@ -1,414 +0,0 @@ - - -%BOOK_ENTITIES; -]> - - - - Apendix - -
- Java Development Kit (<acronym>JDK</acronym>): Installing, Configuring and Running - - The &PLATFORM_NAME; Platform is written in Java; therefore, before running any &PLATFORM_NAME; server, you must have a working Java Runtime Environment (JRE) or Java Development Kit (JDK) installed on your system. In addition, the JRE or JDK you are using to run &PLATFORM_NAME; must be version 5 or higher - - At this point in time, it is possible to run most &PLATFORM_NAME; servers, such as the JAIN SLEE Server, using a Java 6 JRE or JDK. Be aware, however, that presently the XML Document Management Server does not run on Java 6. We suggest checking the &PLATFORM_NAME; web site, forums or discussion pages if you need to inquire about the status of running the XML Document Management Server with Java 6. - - . - - - -
- JRE versus JDK - 32-Bit versus 64-Bit - - Should I Install the JRE or JDK? - - Although you can run &PLATFORM_NAME; servers using the Java Runtime Environment, we assume that most users are developers interested in developing Java-based, &PLATFORM_NAME;-driven solutions. Therefore, in this guide we take the tact of showing how to install the full Java Development Kit. - - - - Should I Install the 32-Bit or the 64-Bit JDK, and Does It Matter? - - Briefly stated: if you are running on a 64-Bit Linux or Windows platform, you should consider installing and running the 64-bit JDK over the 32-bit one. Here are some heuristics for determining whether you would rather run the 64-bit Java Virtual Machine (JVM) over its 32-bit cousin for your application: - - - - - - Wider datapath: the pipe between RAM and CPU is doubled, which improves the performance of memory-bound applications when using a 64-bit JVM. - - - - - 64-bit memory addressing gives virtually unlimited (1 exabyte) heap allocation. However large heaps affect garbage collection. - - - - - Applications that run with more than 1.5 GB of RAM (including free space for garbage collection optimization) should utilize the 64-bit JVM. - - - - - Applications that run on a 32-bit JVM and do not require more than minimal heap sizes will gain nothing from a 64-bit JVM. Barring memory issues, 64-bit hardware with the same relative clock speed and architecture is not likely to run Java applications faster than their 32-bit cousin. - - - - - Note that the following instructions detail how to download and install the 32-bit JDK, although the steps are nearly identical for installing the 64-bit version. - -
- - -
- -Downloading JDK - - - You can download the Sun JDK 5.0 (Java 2 Development Kit) from Sun's website: . Click on the Download link next to "JDK 5.0 Update <x>" (where <x> is the latest minor version release number). On the next page, select your language and platform (both architecture—whether 32- or 64-bit—and operating system), read and agree to the Java Development Kit 5.0 License Agreement, and proceed to the download page. - - - - The Sun website will present two download alternatives to you: one is an RPM inside a self-extracting file (for example, jdk-1_5_0_16-linux-i586-rpm.bin), and the other is merely a self-extracting file (e.g. jdk-1_5_0_16-linux-i586.bin). If you are installing the JDK on Red Hat Enterprise Linux, Fedora, or another RPM-based Linux system, we suggest that you download the self-extracting file containing the RPM package, which will set up and use the SysV service scripts in addition to installing the JDK. We also suggest installing the self-extracting RPM file if you will be running &PLATFORM_NAME; in a production environment. - - - Installing - - The following procedures detail how to install the Java Development Kit on both Linux and Windows. - - - - Installing the JDK on Linux - - - Regardless of which file you downloaded, you can install it on Linux by simply making sure the file is executable and then running it: - - ~]$ chmod +x "jdk-1_5_0_<minor_version>-linux-<architecture>-rpm.bin" -~]$ ./"jdk-1_5_0_<minor_version>-linux-<architecture>-rpm.bin" - - - - - Moving from Non-RPM Installer to SysV Service Scripts - - If you download the non-RPM self-extracting file (and installed it), and you are running on an RPM-based system, you can still set up the SysV service scripts by downloading and installing one of the -compat packages from the JPackage project. Remember to download the -compat package which corresponds correctly to the minor release number of the JDK you installed. The compat packages are available from . - - - - - You do not need to install a -compat package in addition to the JDK if you installed the self-extracting RPM file! The -compat package merely performs the same SysV service script set up that the RPM version of the JDK installer does. - - - -
- -
- -Installing JDK on Windows - - - - - Using Explorer, simply double-click the downloaded self-extracting installer and follow the instructions to install the JDK. - - - - - - Configuring - - Configuring your system for the JDK consists in two tasks: setting the JAVA_HOME environment variable, and ensuring that the system is using the proper JDK (or JRE) using the alternatives command. Setting JAVA_HOME usually overrides the values for java, javac and java_sdk_1.5.0 in alternatives, but we will set them all just to be safe and consistent. - - - - -
- -
- -Setting Linux JAVA_HOME Environment Variables - - - - Setting the JAVA_HOME Environment Variable on Generic Linux - - - After installing the JDK, you must ensure that the JAVA_HOME environment variable exists and points to the location of your JDK installation. - - - Setting the <envar>JAVA_HOME</envar> Environment Variable on Linux - - You can determine whether JAVA_HOME is set on your system by echoing it on the command line: - - - ~]$ echo $JAVA_HOME - - If JAVA_HOME is not set already, then you must set its value to the location of the JDK installation on your system. You can do this by adding two lines to your personal ~/.bashrc configuration file. Open ~/.bashrc (or create it if it doesn't exist) and add a line similar to the following one anywhere inside the file: - - - export JAVA_HOME="/usr/lib/jvm/jdk1.5.0_<version>" - - - You should also set this environment variable for any other users who will be running &PLATFORM_NAME; (any environment variables exported from ~/.bashrc files are local to that user). - - - - - -
- -
- -Setting the Correct Java Version - - - -Setting java, javac and java_sdk_1.5.0 Using the alternatives command - - - Selecting the Correct System JVM on Linux using <command>alternatives</command> - - - On systems with the alternatives command, including Red Hat Enterprise Linux and Fedora, you can easily choose which JDK (or JRE) installation you wish to use, as well as which java and javac executables should be run when called. - - - - As the root user, call /usr/sbin/alternatives with the option to select between JDKs and JREs installed on your system: - - - root@localhost ~]$ /usr/sbin/alternatives --config java - -There are 3 programs which provide 'java'. - - Selection Command ------------------------------------------------ - 1 /usr/lib/jvm/jre-1.5.0-gcj/bin/java - 2 /usr/lib/jvm/jre-1.6.0-sun/bin/java -*+ 3 /usr/lib/jvm/jre-1.5.0-sun/bin/java - - -Enter to keep the current selection[+], or type selection number: - - - In our case, we want to use the Sun JDK, version 5, that we downloaded and installed, to run the java executable. In the alternatives information printout above, a plus (+) next to a number indicates the one currently being used. As per alternatives' instructions, pressing Enter will simply keep the current JVM, or you can enter the number corresponding to the JVM you would prefer to use. - - - Repeat the procedure above for the javac command and the java_sdk_1.5.0 environment variable, as the root user: - - - ~]$ /usr/sbin/alternatives --config javac - - ~]$ /usr/sbin/alternatives --config java_sdk_1.5.0 - - - - -
- -
- -Setting JAVA_HOME Environment Variables on Windows - - - - - -Setting the JAVA_HOME Environment Variable on Windows - - - For information on how to set environment variables in Windows, refer to . - - - - -
- - -
- Uninstalling JDK on Linux and Windows - - Uninstalling - - There is usually no reason (other than space concerns) to remove a particular JDK from your system, given that you can switch between JDKs and JREs easily using alternatives, and/or by setting JAVA_HOME. - - - - Uninstalling the JDK on Linux - - On RPM-based systems, you can uninstall the JDK using the yum - command. - - - - Uninstalling the JDK on Windows - - On Windows systems, check the JDK entry in the Start menu for an uninstall command, or use Add/Remove Programs. - - -
- - -
- Setting the JBOSS_HOME Environment Variable - - The &PLATFORM_NAME; Platform (&PLATFORM_NAME;) is built on top of the JBoss Application Server (JBoss AS). You do not need to set the JBOSS_HOME environment variable to run any of the &PLATFORM_NAME; Platform servers unless JBOSS_HOME is already set. - - The best way to know for sure whether JBOSS_HOME was set previously or not is to perform a simple check which may save you time and frustration. - - Checking to See If JBOSS_HOME is Set on Unix - At the command line, echo - $JBOSS_HOME to see if it is currently defined in your environment: - - ~]$ echo $JBOSS_HOME - The &PLATFORM_NAME; Platform and most &PLATFORM_NAME; servers are built on top of the JBoss Application Server (JBoss AS). When the &PLATFORM_NAME; Platform or &PLATFORM_NAME; servers are built from source, then JBOSS_HOME must be set, because the &PLATFORM_NAME; files are installed into (or over top of if you prefer) a clean JBoss AS installation, and the build process assumes that the location pointed to by the JBOSS_HOME environment variable at the time of building is the JBoss AS installation into which you want it to install the &PLATFORM_NAME; files. - - This guide does not detail building the &PLATFORM_NAME; Platform or any &PLATFORM_NAME; servers from source. It is nevertheless useful to understand the role played by JBoss AS and JBOSS_HOME in the &PLATFORM_NAME; ecosystem. - - The immediately-following section considers whether you need to set JBOSS_HOME at all and, if so, when. The subsequent sections detail how to set JBOSS_HOME on Unix and Windows - - - - Even if you fall into the category below of not needing to set JBOSS_HOME, you may want to for various reasons anyway. Also, even if you are instructed that you do not need to set JBOSS_HOME, it is good practice nonetheless to check and make sure that JBOSS_HOME actually isn't set or defined on your system for some reason. This can save you both time and frustration. - - - You DO NOT NEED to set JBOSS_HOME if... - - - - ...you have installed the &PLATFORM_NAME; Platform binary distribution. - - - - - ...you have installed a &PLATFORM_NAME; server binary distribution which bundles JBoss AS. - - - - You MUST set JBOSS_HOME if... - - - - ...you are installing the &PLATFORM_NAME; Platform or any of the &PLATFORM_NAME; servers from source. - - - - - ...you are installing the &PLATFORM_NAME; Platform binary distribution, or one of the &PLATFORM_NAME; server binary distributions, which do not bundle JBoss AS. - - - - - Naturally, if you installed the &PLATFORM_NAME; Platform or one of the &PLATFORM_NAME; server binary releases which do not bundle JBoss AS, yet requires it to run, then you should install JBoss AS - before setting JBOSS_HOME or proceeding with anything else. - - - Setting the JBOSS_HOME Environment Variable on Unix - - The JBOSS_HOME environment variable must point to the directory which contains all of the files for the &PLATFORM_NAME; Platform or individual &PLATFORM_NAME; server that you installed. As another hint, this topmost directory contains a bin subdirectory. - - - - Setting JBOSS_HOME in your personal ~/.bashrc startup script carries the advantage of retaining effect over reboots. Each time you log in, the environment variable is sure to be set for you, as a user. On Unix, it is possible to set JBOSS_HOME as a system-wide environment variable, by defining it in /etc/bashrc, but this method is neither recommended nor detailed in these instructions. - - - To Set JBOSS_HOME on Unix... - - - Open the ~/.bashrc startup script, which is a hidden file in your home directory, in a text editor, and insert the following line on its own line while substituting for the actual install location on your system: - - export JBOSS_HOME="/home/<username>/<path>/<to>/<install_directory>" - - - - Save and close the .bashrc startup script. - - - - - You should source the .bashrc script to force your change to take effect, so that JBOSS_HOME becomes set for the current session - - Note that any other terminals which were opened prior to your having altered .bashrc will need to source - ~/.bashrc as well should they require access to JBOSS_HOME. - - . - - ~]$ source ~/.bashrc - - - - Finally, ensure that JBOSS_HOME is set in the current session, and actually points to the correct location: - - - - The command line usage below is based upon a binary installation of the &PLATFORM_NAME; Platform. In this sample output, JBOSS_HOME has been set correctly to the topmost_directory of the &PLATFORM_NAME; installation. Note that if you are installing one of the standalone &PLATFORM_NAME; servers (with JBoss AS bundled!), then JBOSS_HOME would point to the topmost_directory of your server installation. - - - ~]$ echo $JBOSS_HOME -/home/silas/&HOME_LIN; - - - - - Setting the JBOSS_HOME Environment Variable on Windows - - The JBOSS_HOME environment variable must point to the directory which contains all of the files for the &PLATFORM_NAME; Platform or individual &PLATFORM_NAME; server that you installed. As another hint, this topmost directory contains a bin subdirectory. - - - - For information on how to set environment variables in recent versions of Windows, refer to . - -
- - - -
- -Setting CATALINA_HOME on Linux and Windows - - - Setting the <envar>CATALINA_HOME</envar> Environment Variable on Linux - - The CATALINA_HOME environment variable must point to the location of your Tomcat installation. Any &PLATFORM_NAME; server which runs on top of the Tomcat servlet container has a topmost directory, i.e. the directory in which you unzipped the zip file to install the server, and underneath that directory, a bin directory. CATALINA_HOME must be set to the topmost directory of your &PLATFORM_NAME; server installation. - Setting this variable in your personal ~/.bashrc file has the advantage that it will always be set (for you, as a user) each time you log in or reboot the system. To do so, open ~/.bashrc in a text editor (or create the file if it doesn't already exist) and insert the following line anywhere in the file, taking care to substitute <sip_server> for the topmost directory of the &PLATFORM_NAME; server you installed: - export CATALINA_HOME="/home/<username>/<path>/<to>/<sip_server>" - Save and close .bashrc. - - - You can—and should—source your .bashrc file to make your change take effect (so that CATALINA_HOME is set) for the current session: - ~]$ source ~/.bashrc - - - Finally, make sure that CATALINA_HOME has been set correctly (that it leads to the right directory), and has taken effect in the current session. - The following command will show the path to the directory pointed to by CATALINA_HOME: - ~]$ echo $CATALINA_HOME - To be absolutely sure, change your directory to the one pointed to by CATALINA_HOME: - ~]$ cd $CATALINA_HOME && pwd - - - - Setting the <envar>CATALINA_HOME</envar> Environment Variable on Windows - - The CATALINA_HOME environment variable must point to the location of your Tomcat installation. Any &PLATFORM_NAME; server which runs on top of the Tomcat servlet container has a topmost directory, i.e. the directory in which you unzipped the zip file to install the server, and underneath that directory, a bin directory. CATALINA_HOME must be set to the topmost directory of your &PLATFORM_NAME; server installation. - If you are planning on running the Tomcat container as the Administrator, then you should, of course, set the CATALINA_HOME environment variable as the administrator, and if you planning to run Tomcat as a normal user, then set CATALINA_HOME as a user environment variable. - For information on how to set environment variables in Windows, refer to . - - - - - -
- -
- - - - - - -
diff --git a/docs/sources/src/main/resources/en-US/concept-chapter-Best_Practices.xml b/docs/sources/src/main/resources/en-US/concept-chapter-Best_Practices.xml deleted file mode 100644 index d7228e5ec6..0000000000 --- a/docs/sources/src/main/resources/en-US/concept-chapter-Best_Practices.xml +++ /dev/null @@ -1,267 +0,0 @@ - - -%BOOK_ENTITIES; -]> - - Best Practices - This chapter discusses Best Practices related to &PLATFORM_NAME; - SIP Servlets usage in real world deployments. -
- &PLATFORM_NAME; SIP Servlets Performance Tips - Because the default profile of &PLATFORM_NAME; SIP Servlets is targeted at a - development environment, some tuning is required to make the server performance suitable for a production environment. - A useful presentation from OKI Japan -
- Tuning JBoss - To ensure the server is finely tuned for a production envirionment, certain configuration must be changed. Visit the JBoss Application Server Tuning wiki page to learn about optimization techniques. - - While it is preferable to have a fast Application Server, most of the information doesn't apply to &PLATFORM_NAME;. In summary, the most important optimization technique is to remove logs, leaving only what is required. - Check the log configuration file in - the following location and review the information. - - - - - - - - - - -
-
- Tuning &PLATFORM_NAME; SIP Servlets - - - Congestion Control: It is recommended that this feature is enabled to avoid overload of the server and that the sipMessageQueueSize and memoryThreshold parameters are tuned according to . - - - Concurrency : - Default Value: None. For better performance, it is recommended to leave this value set to None. - - -
-
- Tuning The JAIN SIP Stack - The stack can be fine-tuned by altering the SIP stack properties, defined in the external properties file specified by the sipStackPropertiesFile attribute as described in . - - - gov.nist.javax.sip.THREAD_POOL_SIZE - - Default value: 64 - This thread pool is - responsible for parsing SIP messages received from socket messages into - objects. - A smaller value will make the stack less responsive, since - new messages have to wait in a queue for free threads. In UDP, this - can lead to more retransmissions. - Large thread pool sizes result in allocating resources - that are otherwise not required. - - - gov.nist.javax.sip.REENTRANT_LISTENER - - Default value: true - This flag indicates whether the - SIP stack listener is executed by a single thread, or concurrently - by the threads that parse the messages. - &PLATFORM_NAME; SIP - Servlets expects this flag to be set to true, therefore do not change the value. - - - gov.nist.javax.sip.LOG_MESSAGE_CONTENT - - Default value: true - Set the parameter to false to disable message logging. - - - gov.nist.javax.sip.TRACE_LEVEL=0 - - Default value: 32. - Set the parameter to 0 to disable JAIN SIP stack logging. - - - gov.nist.javax.sip.RECEIVE_UDP_BUFFER_SIZE=65536 and gov.nist.javax.sip.SEND_UDP_BUFFER_SIZE=65536 - - Default value: 65536. - Those properties control the size of the UDP buffer used for SIP messages. Under load, if the buffer capacity is overflown the messages are dropped causing retransmissions, further increasing the load and causing even more retransmissions. - - - gov.nist.javax.sip.MAX_MESSAGE_SIZE=10000 - - Default value: 10000. - This property controls the maximum size of content that can be read for a SIP Message on UDP. The default is 65536. The average UDP message size is quite lower than this so reducing this property will benefit memory usage since a byte buffer of this size is created for every message received. - It also defines the maximum size of content that a TCP connection can read. Must be at least 4K. Default is "infinity" -- ie. no limit. This is to prevent DOS attacks launched by writing to a TCP connection until the server chokes. - - - gov.nist.javax.sip.TCP_POST_PARSING_THREAD_POOL_SIZE=30 - - Default value: 30. - Use 0 or do not set this option to disable it. When using TCP, your phones/clients usually connect independently, creating their own TCP sockets. Sometimes however SIP devices are allowed to tunnel multiple calls over a single socket. This can also be simulated with SIPP by running "sipp -t t1". - In the stack, each TCP socket has it's own thread. When all calls are using the same socket they all use a single thread, which leads to severe performance penalty, especially on multi-core machines. This option instructs the SIP stack to use a thread pool and split the CPU load between many threads. The number of the threads is specified in this parameter. - The processing is split immediately after the parsing of the message. It cannot be split before the parsing because in TCP the SIP message size is in the Content-Length header of the message and the access to the TCP network stream has to be synchronized. - Additionally, in TCP the message size can be larger. This causes most of the parsing for all calls to occur in a single thread, which may have impact on the performance in trivial applications using a single socket for all calls. In most applications it doesn't have performance impact. If the phones/clients use separate TCP sockets for each call, this option doesn't have much impact, except the slightly increased memory footprint caused by the thread pool. It is recommended to disable this option in this case by setting it 0 or not setting it at all. You can simulate multi-socket mode with "sipp -t t0". With this option also we avoid closing the TCP socket when something fails, because we must keep processing other messages for other calls. Note: This option relies on accurate Content-Length headers in the SIP messages. It cannot recover once a malformed message is processed, because the stream iterator will not be aligned any more. Eventually the connection will be closed. - - - The full list of JAIN SIP stack properties is available from - the SIP Stack Properties Home Page - and the full list of implementation specific properties are available - from the SIP Stack Implementation Home Page. -
-
- Tuning The JVM - The following tuning information applies to Sun JDK 1.6, however the information should also apply - to Sun JDK 1.5. - - For more information on tuning &PLATFORM_NAME; SIP Servlets performance, refer to the OKI Japan Presentation. - For more information on performance, refer to the Performance White Paper. - - To pass arguments to the JVM, change - $JBOSS_HOME/bin/standalone.conf (Linux) or $JBOSS_HOME/bin/standalone.bat (Windows). - - - Garbage Collection - JVM - ergonomics automatically attempt to select the best garbage collector. The - default behaviour is to select the throughput collector, however a disadvantage of the throughput collector is that it can have long pauses times, which - ultimately blocks JVM processing. - For low-load implementations, consider using the incremental, low-pause, garbage collector - (activated by specifying - -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode - ). Many SIP applications can benefit from this garbage collector type because it reduces the retransmission amount. - For more - information please read: Garbage Collector Tuning - - - Heap Size - Heap size is an important consideration for - garbage collection. Having an unnecessarily large heap can stop the JVM for - seconds, to perform garbage collection. - Small heap sizes are not - recommended either, because they put unnecessary pressure on the garbage - collection system. - - -
-
- Tuning The Operating System - The following tuning information is provided for Red Hat Enterprise Linux (RHEL) servers that are running high-load configurations. The tuning information should also apply to other Linux distributions. - After you have configured RHEL with the tuning information, you must restart the operating system. You should see improvements in I/O response times. With SIP, the - performance improvement can be as high as 20%. - - - Large Memory Pages - Setting large memory pages - can reduce CPU utilization by up to 5%. - Ensure that the option - - -XX:+UseLargePages - is passed and ensure that the following Java - HotSpot(TM) Server VM warning does not occur: - Failed to reserve shared memory (errno = 22)" when starting JBoss. It means that the number of pages at OS level is still not enough. - To learn - more about large memory pages, and how to configure them, refer to - Java Support for Large Memory Pages and Andrig's Miller blog post. - - - Network buffers - You can - increase the network buffers size by adding the following lines to - your /etc/sysctl.conf file: - - - net.core.rmem_max = 16777216 - - - net.core.wmem_max = 16777216 - - - net.ipv4.tcp_rmem = 4096 87380 16777216 - - - net.ipv4.tcp_wmem = 4096 65536 16777216 - - - net.core.netdev_max_backlog = 300000 - - - - - Execute the following command to set the network interface address: - sudo ifconfig [eth0] txqueuelen 1000 # - Replace [eth0] with the correct name of the - actual network interface you are setting up. - - -
-
-
- NAT Traversal - In a production environment, it is common to see SIP and Media - data passing through different kinds of Network Address Translation (NAT) to reach the - required endpoints. Because NAT Traversal is a complex topic, refer to the following information to help determine the most effective method to handle NAT issues. -
- STUN - STUN (Session Traversal Utilities for NAT) is not generally - considered a viable solution for enterprises because STUN cannot be used - with symmetric NATs. - Most enterprise-grade - firewalls are symmetric, therefore STUN support must be provided in the SIP Clients themselves. - - Most of the proxy and media gateways installed by VoIP providers - recognize the public IP address the packets have originated from. When both SIP end points are behind a NAT, they can act as - gateways to clients behind NAT. -
-
- TURN - TURN (Traversal Using Relay NAT) is an IETF standard, which - implements media relays for SIP end-points. The standard overcomes the problems of - clients behind symmetric NATs which cannot rely on STUN to solve NAT - traversal. - TURN connects clients behind a NAT to a single peer, providing the same protection offered by symmetric NATs and - firewalls. The TURN server acts as a relay; any data received is - forwarded. - This type of implementation is not ideal. It assumes the clients - have a trust relationship with a TURN server, and a request session - allocation based on shared credentials. - This can result in scalability issues, - and requires changes in the SIP clients. It is also impossible to determine - when a direct, or TURN, connection is appropriate. -
-
- ICE - ICE (Interactive Connection Establishment) leverages both - STUN and TURN to solve the NAT traversal issues. - It allows devices to - probe for multiple paths of communication, by attempting to use different - port numbers and STUN techniques. If ICE support is present in both - devices, it is quite possible that the devices can initiate and maintain communication - end-to-end, without any intermediary media relay. - Additionally, ICE can - detect cases where direct communication is impossible and automatically initiate fall-back to a media relay. - ICE is not currently in widespread use in SIP devices, because ICE capability must be embedded within - the SIP devices. - Depending - on the negotiated connection, a reINVITE may be required during a session, which adds more - load to the SIP network and more latency to the call. - If the - initiating ICE client attempts to call a non-ICE client, then the call - setup-process will revert to a conventional SIP call requiring NAT - traversal to be solved by other means. -
-
- Other Approaches - While the above is a good solution to circumvent NAT issues. There might be cases where it is not possible to use those solutions at all. - Other approaches include using proxy and media that can act as - gateways, Session Border Controllers, enhanced Firewall with Application - Layer Gateway (ALG) and Tunnelling. - - Here is more information on Session Border Controllers and how they can resolve NAT issues when above solutions - are not possible - -
-
-
diff --git a/docs/sources/src/main/resources/en-US/concept-chapter-Enterprise-Monitoring-Operations-Management.xml b/docs/sources/src/main/resources/en-US/concept-chapter-Enterprise-Monitoring-Operations-Management.xml deleted file mode 100644 index c2487d6593..0000000000 --- a/docs/sources/src/main/resources/en-US/concept-chapter-Enterprise-Monitoring-Operations-Management.xml +++ /dev/null @@ -1,536 +0,0 @@ - - -%BOOK_ENTITIES; -]> - - Enterprise Monitoring and Management - There is two ways of monitoring &PLATFORM_NAME; Sip Servlets : - - Through JMX - Through the industry standard Simple Network Management Protocol - SNMP - Through the &PLATFORM_NAME; Sip Servlets Management Console. - - - - -
- JMX Monitoring - - The default mechanism for monitoring &PLATFORM_NAME; Sip Servlets is using the Java Management Extensions (JMX) technology. - The Oracle website includes the list of options and how to configure JMX Remote on Java 7 - http://docs.oracle.com/javase/7/docs/technotes/guides/management/agent.html - - - Please find below, the list of SIP Specific metrics that can be monitored through JMX - -
- SIP Stack Monitoring Metrics - JMX Name Domain=org.mobicents.jain.sip,name=Mobicents-SIP-Servlets,type=sip-stack provides the following metrics : - - - NumberOfClientTransactions : Active number of SIP Client Transactions. - - - NumberOfServerTransactions : Active number of SIP Server Transactions. - - - NumberOfDialogTransactions : Active number of SIP Dialogs. - - - LocalMode : whether the stack is using replication or not. - - -
-
- Container SIP Core Router (SipApplicationDispatcher) Monitoring Metrics - JMX Name Domain=<server_name>,type=SipApplicationDispatcher provides the following metrics : - - - RequestsProcessedByMethod : Number of incoming SIP requests that have been processed by SIP Method name (INVITE, BYE, INFO, ...). - - - ResponsesProcessedByStatusCode : Number of incoming SIP responses that have been processed by status code (1xx, 2xx, 3xx, ...). - - - - - RequestsSentByMethod : Number of outgoing SIP requests that have been sent by SIP Method name (INVITE, BYE, INFO, ...). - - - ResponsesSentByStatusCode : Number of outgoing SIP responses that have been sent by status code (1xx, 2xx, 3xx, ...). - - -
-
- Application Level Monitoring Metrics - JMX Name Domain=<server_name>,path=<application_context_name>,type=SipManager,host=<host_name> provides the following metrics : - - - expiredSipSessions : Number of SIP sessions that have expired - - - expiredSipApplicationSessions : Number of SIP Application sessions that have expired - - - sipSessionAverageAliveTime : the average time (in seconds) that expired SIP sessions had been alive. - - - sipApplicationSessionAverageAliveTime : the average time (in seconds) that expired SIP Application sessions had been alive. - - - sipSessionCounter : Number of SIP Sessions created. - - - sipApplicationSessionCounter : Number of SIP Application Sessions created. - - - activeSipSessions : Number of currently active SIP Sessions. - - - activeSipApplicationSessions : Number of currently active SIP Application Sessions. - - - rejectedSipSessions : Number of SIP session creations that failed due to maxActiveSipSessions. - - - rejectedSipApplicationSessions : Number of SIP Application session creations that failed due to maxActiveSipApplicationSessions. - - - numberOfSipSessionCreationPerSecond : Number of SIP sessions per second that have been created. - - - numberOfSipApplicationSessionCreationPerSecond : Number of SIP Application sessions per second that have been created. - - -
-
- JMX Monitoring for &SHORT_PLATFORM_NAME; for JBoss AS7/EAP6 - - Follow the link To Connect JConsole to JMX on AS7/EAP6. - - - - SNMP Monitoring for &SHORT_PLATFORM_NAME; for JBoss AS7 - - The SNMP feature is not yet implemented in &SHORT_PLATFORM_NAME; for JBoss AS7. This guide will be updated when SNMP monitoring feature become available. - In the meantime, see the chapter below for information about the CLI. - - - - - - - - -
-
- JMX Monitoring for &SHORT_PLATFORM_NAME; for Tomcat 7 - - Follow the link To Connect JConsole to JMX on Tomcat 7. - - - SNMP Monitoring for &SHORT_PLATFORM_NAME; for Tomcat 7 - - The SNMP feature is not yet implemented in &SHORT_PLATFORM_NAME; for Tomcat 7. This guide will be updated when SNMP monitoring feature become available. - - -
-
- - - - - - - -
diff --git a/docs/sources/src/main/resources/en-US/concept-chapter-JSR289-Errata.xml b/docs/sources/src/main/resources/en-US/concept-chapter-JSR289-Errata.xml deleted file mode 100644 index 1087dee6fa..0000000000 --- a/docs/sources/src/main/resources/en-US/concept-chapter-JSR289-Errata.xml +++ /dev/null @@ -1,27 +0,0 @@ - - -%BOOK_ENTITIES; -]> - - JSR 289 Errata - This chapter discusses deviations from the JSR 289 specification by &PLATFORM_NAME; - SIP Servlets after feedback on usage in real world deployments and from the community. -
- &PLATFORM_NAME; SIP Servlets Deviations from JSR 289 - - - Correlation of Responses to Proxy Branches : It seems the javadoc for Speed Dial contains an error, SipServlet.doBranchResponse() shouldn't be included as it contradicts the last sentence from the spec 10.2.4.2 Correlating responses to proxy branches : - "Note that if the doBranchResponse() is not overridden then doResponse() method will be invoked only for the best final response as before", - If SipServlet.doBranchResponse() handling is done in SipServlet.doResponse() and the servlet overrides SipServlet.doResponse() then it will receive intermediate final responses - as well as the best final response which is not the desired behavior, so the doBranchResponse() handling is done in SipServlet.doService() method allowing applications - not overriding doResponse or doService to receive both intermediate final responses on the doBranchResponse as well as the best final response on doResponse but this fixes the issue of intermediate final responses being delivered to doResponse in case the servlet overrides it. - - - - SipServletResponse typo : - SipServletResponse.SC_TEMPORARLY_UNAVAILABLE should be replaced by SC_TEMPORARILY_UNAVAILABLE. - - -
-
diff --git a/docs/sources/src/main/resources/en-US/concept-chapter-SS_Examples.xml b/docs/sources/src/main/resources/en-US/concept-chapter-SS_Examples.xml deleted file mode 100644 index a90e99f1e6..0000000000 --- a/docs/sources/src/main/resources/en-US/concept-chapter-SS_Examples.xml +++ /dev/null @@ -1,160 +0,0 @@ - - -%BOOK_ENTITIES; -]> - -SIP Servlet Example Applications -The SIP Servlet Server has a selection of examples that demonstrate particular capabilities of the server. lists the available examples, their location, and a brief description about the functionality each example demonstrates. The examples can also provide a useful starting point for developing SIP Applications, therefore it is encouraged to experiment and adapt the base examples. Each example is available in both binary and source formats. - -Available Examples - - - - - -Example -Description - - - - - - - -Demonstrates how to block calls by specifying that the INVITE SIP Extension checks the From address to see if it is specified in the block list. If the blocked SIP address matches, the Call Blocking application send a FORBIDDEN response. - - - - - -Demonstrates how to forward calls by specifying that the INVITE SIP Extension checks the To address to see if it is specified in the forward list. If the SIP address matches, the application acts as a back-to-back user agent (B2BUA). - - - - - -Call Blocking and Call Forwarding are merged to create a new service. - - - -Speed Dial - -Demonstrates how to implement speed dialing for SIP addresses. The demonstration uses a static list of speed dial numbers. The numbers are translated into a complete address based on prior configuration. The SIP addresses are proxied without record-routing, or supervised mode. - - - - - -Demonstrates a location service that performs a lookup based on the request URI, into a hard-coded list of addresses. The request is proxied to the set of destination addresses associated with that URI. - - - -Composed Speed Dial and Location - -Speed Dial and Location are merged to create a new service. Speed Dial proxies the speed dial number to a SIP address, then Location Service proxies the call to the actual location of the call recipient. - - - -Click to Call - -Demonstrates how SIP Servlets can be used along with HTTP servlets as a converged application to place calls from a web portal. The example is a modified version of the click to dial example from the Sailfin project, but has been reworked to comply with JSR 289. - - - -Chat Server - -Demonstrates MESSAGE SIP Extension support. This example is based on the chatroom server demonstration from the BEA dev2dev project, and has been modified to meet JSR 289 requirements. - - - -Media JSR 309 Example - -Demonstrates how the Sip Servlets Application Developers can leverage the JSR-309 API, which provides to application developers multimedia capabilities with a generic media server (MS) abstraction interface. This example is only compatible with JBoss AS5. The solution is know to work with Twinkle and linphone SIP soft-phones. - - - -Shopping - -Demonstrates integration with Seam and Java Enterprise Edition (JEE), and JSR 309 Media integration with text to speech (TTS) and dual-tone multi-frequency (DTMF) tones. The demonstration builds on the Converged Demo example, and adds support for the SIP Servlets v1.1 specification. - - - - - - -Demonstrates how the Diameter Event Charging, and the Location service, can be used to perform fixed-rated charging of calls (event charging). When a call is initiated, a debit of ten euros is applied to the A Party account. If the call is rejected by the B Party, or A Party hangs up before B Party can answer the call, the ten euro charge is credited to the A Party account. - - - -Diameter Sh OpenIMS Integration - -Demonstrates the integration between &PLATFORM_NAME; and OpenIMS, using the Diameter Sh interface to receive profile updates and SIP. - - - -Diameter Ro/Rf IIntegration - -A Diameter Ro/Rf service that performs online call charging. - - - -Conference - -Demonstrates the capabilities of the Media Server, such as endpoint composition and conferencing, as well as proving that SIP Servlets are capable of working seamlessly with any third-party web framework, without repackaging or modifying the deployment descriptors. The demonstration uses Google's GWT Ajax framework with server-push updates to provide a desktop-like user interface experience and JSR 309 for Media Control. - - - - -Alerting Application - -This application was developed so that the JBoss RHQ/Jopr Enterprise Management Solution would be able to notify system administrators when a monitoring alert is fired by Jopr/RHQ. - - - -SIP Presence Client Application - -A Call Blocking application interoperating with the PLATFORM_NAME; SIP Presence Service (Technology Preview) to fetch the blocked contacts through XCAP. - - - -
- -
- diff --git a/docs/sources/src/main/resources/en-US/concept-chapter-SS_click2call.xml b/docs/sources/src/main/resources/en-US/concept-chapter-SS_click2call.xml deleted file mode 100644 index db3a87d18b..0000000000 --- a/docs/sources/src/main/resources/en-US/concept-chapter-SS_click2call.xml +++ /dev/null @@ -1,332 +0,0 @@ - - -%BOOK_ENTITIES; -]> - -
-Tomcat Servlet Click2call Windows Setup - -&PLATFORM_NAME; SIP Servlets Server can be run on a JBoss Application Server or on the Tomcat Servlet Container. Here is how -to install and configure both JBoss a Microsoft Windows based system. - - - -Tomcat Servlet running on Microsoft Windows -The &PLATFORM_NAME; Platform is based on Java, so you need to make sure you have both the Java Runtime Environment (JRE) -and, or the Java Development Kit (JDK) installed on your Windows based system. - - -You can download the Java Runtime Environment here . - - - - -If you are a developer, you can get the Java Development Kit here . -It is recommended that you install the latest version of JDK. You can opt for the JDK Java SE (Standard Edition) for test purposes. -Once you have downloaded JDK, you will see an executable like the one below in your download folder. - - - - -Do to the following to open the cmd window - menu > Start > Run > CMD -In the black CMD window type 'java -version' You should see something similar to the screenshot below -
-Testing if Java is installed and running - - - - - -
- -
-
- - - -Double-click the .exe file and follow the menu to complete your installation. Jdk-(version)-windows-i586.exe - - -
-JDK executable file - - - - - -
-
- - - -JAVA_Home enviroment variable. -In order for applications to interact with your Java installation, you need to specify the install location by setting the JAVA_HOME environment variable. -Start the 'cmd' without the quotes and press Enter - -Start > Run > cmd - - -In the CMD window, type - -Set JAVA_HOME=C:\Java\jdk1.7.0_02 - - - -
-Set environment variable - - - - - -
-
- -This will set the environment variable for your session. The C:\Java\jdk1.7.0_02 is the root folder where your JDK files are installed. You can go to this Microsoft page to see how set your environment variable and make it permanent. -If you want to make sure the JDK environment variable is set, type c:\> Set - - - - -Installing &PLATFORM_NAME; Tomcat on Windows. It is recommended that you install the latest &PLATFORM_NAME; Sip Servlets. -You can download the &PLATFORM_NAME; SIP Servlets for Tomcat here -Make sure you download the latest Tomcat and not the JBoss. - -
-Download &PLATFORM_NAME; SIP Servlets for Tomcat - - - - - -
- -The downloaded file will appear similar to this screenshot below - -
-Downloaded Tomcat File - - - - - -
- -The extracted file will look similar to this folder -
-Content of Tomcat Directory - - - - - -
-
- - - -Once you have extracted the content of the MSS Tomcat server zip file, you need to set the CATALINA_HOME environment variable. Open the 'cmd' window - Start > run > cmd -In this example, the environment variable is set as follows: - set CATALINA_HOME=C:\tomcat\&VERSION; - -Start the MSS Tomcat Server - -The \bin directory in the root of your Tomcat folder holds the executables you need to work with the MSS server application. -To start the server, you need to execute the startup.bat file. First, start the cmd window as follows: - -Start > run > cmd - - - - -
-Start Tomcat Server - - - - - -
- - -This will open another cmd.exe window similar to the one below - - -
-Tomcat Server Started - - - - - -
- -Note that the server is started and you can now begin to use the application. -
- - - - - -Once the MSS Tomcat server is up and running, you should be able to go to http://localhost:8080/ -and see the web server in action. If the page doesn’t open or you get an error message saying page -is not found, the 8080 port might be in use by another service. You will have to change the port -in the server.xml file located in the c:\TOMCAT_ROOT_FOLDER\conf\server.xml. You will need a text editor like Notepad++ to change the connector. -Here is a screenshot of the server.xml file with the default port 8080. - - -
-Tomcat Default Http Port - - - - - -
- - -The port number must be higher than 1024. In the example below, the port number for the connector has been change to 8040 - -
-Change Default Http Port to 8040 - - - - - -
- -
- - - -You can use your internet browser to see the result by going to http://localhost:8040 -You will see a page similar to the screenshot below - -
-Localhost Homepage - - - - - -
- -In order to manage the Click2call sip servlet clients, you need to navigate to the http://localhost:8040/click2call -If you get an error message that says, page cannot be displayed, you need to make sure the -MSS Tomcat server is running by executing the startup.bat file in the MSS_Tomcat_root_folder\bin\startup.bat -Here is a screenshot of what the Click2call applet will look like without any registered soft phone clients - - -
-Click2call Homepage - - - - - -
- -
- - -At the moment there are no registered users. That is because you need to get the softphone clients to register with the Tomcat server you started above. -You need to install a minimum of two soft phones in order to be able to run the sip servlet Click2Call sample. -In this example, we shall be using 2 soft phones clients, WengoPhone and 3CXPhone. -Download the latest version of the soft phones, install and configure them like the screenshots below: - -
-Wengo Softphone Configuration - - - - - -
- -
- - -You can use any username and password you desire. The MSS Tomcat server is listening for calls on the 127.0.0.1:5080 port - - - Configuring the 3CXPhone -After the installation is complete, you can start up the 3CXPhone, you will see the screen below prompting you to create a profile. Click on the Create Profile Button. - -
-3CXphone Profile - - - - - -
- -In the Accounts window choose the 'New' button and configure as follows - -
-3CXphone Softphone Configuration - - - - - -
-
- - - - -Once the 2 soft phone clients are configured with the SIP details, -you can go back to the http://localhost:8040/click2call/index.jsp page and you will see the clients registered with the server. - - -
-Registered Sip Clients - - - - - -
- -Before you can make calls, you will need to specify the contact details of the person you want to call. It is just like entering the phone number. -Because this is a SIP based setting, you will need to enter the SIP address instead of the phone number. - - - -
- - Testing the Soft Phones on Click2Call -In order to be able to make a call from one phone to the other, you need to create a contact user. -Because you will be using the SIP protocol, you will need to type the contact details with the testphone1 SIP pointing to the testphone2@127.0.0.1 - -
-Wengo Phone Contact User Details - - - - - -
-
- -You need to do the same on the 3CXPhone contact. The phone contact number will be sip:testphone1@127.0.0.1:5080 -
-3CXPhone Contact User Details - - - - - -
-Once you have both contact sip details configured, you can start to make calls and fully use the Click2call application. - -
- -
- diff --git a/docs/sources/src/main/resources/en-US/concept-chapter-Security.xml b/docs/sources/src/main/resources/en-US/concept-chapter-Security.xml deleted file mode 100644 index 4f561db651..0000000000 --- a/docs/sources/src/main/resources/en-US/concept-chapter-Security.xml +++ /dev/null @@ -1,24 +0,0 @@ - - -%BOOK_ENTITIES; -]> - - - Security - - The information present in SIP requests often contains sensitive user - information. To protect user information, SIP Security can be enabled on the - server, and within the SIP application to mitigate the risk of unauthorised - access to the information. - - There are essentially two levels of security that can be enabled on - the server, the communication between the server and other SIP entities and - securing the application and its content. - - - - diff --git a/docs/sources/src/main/resources/en-US/concept-chapter-Services_for_SIP_Servlets.xml b/docs/sources/src/main/resources/en-US/concept-chapter-Services_for_SIP_Servlets.xml deleted file mode 100644 index 516bcd45ce..0000000000 --- a/docs/sources/src/main/resources/en-US/concept-chapter-Services_for_SIP_Servlets.xml +++ /dev/null @@ -1,1516 +0,0 @@ - - -%BOOK_ENTITIES; -]> - -
-Operating the Example Applications - - - Important Information - -Before trying out the examples in this section, you must have installed, configured and have &SHORT_PLATFORM_NAME; for JBoss or &SHORT_PLATFORM_NAME; for Tomcat AS7 running on your system. - - - -See the chapters below for detailed instructions. - - - - - - - - - - -
-The Location Service -The &PLATFORM_NAME; Location Service contains a list of mappings of -request URIs to destination addresses. When the Location Service receives -a request, it performs a lookup on that mapping and proxies the request -simultaneously to the destination address (or addresses) associated with -that URI. - -The Location Service Mappings Cannot Currently Be Configured -The Location Service currently performs a lookup on a hard-coded -list of addresses. This model is evolving toward the eventual use of a -database. - -Regardless of whether you are using the JBoss Application Server or -the Tomcat Servlet Container as the Servlets Server, the application, -container and Location Service perform the following steps: - - -A user—let us call her Alice—makes a call to -sip:receiver@sip-servlets.com. The -INVITE is received by the servlet container, which -then starts the Location Service. - - -The Location Service, using non-SIP means, determines that the -callee (i.e. the receiver) is registered at two locations, identified -by the two SIP URIs, sip:receiver@127.0.0.1:5090 -and sip:receiver@127.0.0.1:6090. - - -The Location Service proxies to those two destinations in -parallel, without record-routing, and without making use of supervised -mode. - - -One of the destinations returns a 200 OK -status code; the second proxy is then canceled. - - -The 200 OK is forwarded to Alice, and call -setup is completed as usual. - - -Here is the current list of hard-coded contacts and their location -URIs: - -sip:receiver@sip-servlets.com - -sip:receiver@127.0.0.1:5090 - - -sip:receiver@127.0.0.1:6090 - - -
- - - - - - -Downloading -The Location Service is comprised of two archive files, a Web -Archive (WAR) and a Default Application Router (DAR) configuration -file, which you need to add to your installed SIP Servlets Server. For -more information about WAR files, refer to the JBoss Application Server Administration and Development Guide. For -more information about DAR files, refer to the JSR 289 spec, Appendix C. - -Download the Location Service's WAR file from here: . -Download the Location Service's DAR file from here: . - - - -Installing -Both the location-service-&VERSION;.war WAR file -and the locationservice-dar.properties DAR file -that you downloaded should be placed into different directories in -your SIP Servlet Server installation hierarchy. Which directory -depends on whether you are using the Location Service with &SHORT_PLATFORM_NAME; for -JBoss or with &SHORT_PLATFORM_NAME; for Tomcat: - - - - -&SHORT_PLATFORM_NAME; for JBoss AS7 - -Place location-service-&VERSION;.war into the -$JBOSS_HOME/standalone/deployments/ -directory, and locationservice-dar.properties -into the -$JBOSS_HOME/standalone/configuration/dars/ - -directory. - - - -&SHORT_PLATFORM_NAME; for Tomcat AS7 - -Place location-service-&VERSION;.war into the -$CATALINA_HOME/webapps/ -directory, and locationservice-dar.properties -into the -$CATALINA_HOME/conf/dars/ -directory. - - - - -Configuration - - - - - - - -&SHORT_PLATFORM_NAME; for JBoss - - - - -Editing &SHORT_PLATFORM_NAME; for JBoss's standalone-sip.xml for the Location Service - - - - - - -In the $JBOSS_HOME/standalone/configuration/standalone-sip.xml file search for the line - - <subsystem xmlns="urn:org.mobicents:sip-servlets-as7:1.0" -application-router="dars/mobicents-dar.properties" - -and replace it with the line below - - <subsystem xmlns="urn:org.mobicents:sip-servlets-as7:1.0" - application-router="dars/locationservice-dar.properties" - - - - - - -&SHORT_PLATFORM_NAME; for Tomcat - -Open the -$CATALINA_HOME/conf/server.xml -configuration file and find the Service -element. Add an attribute to it called -darConfigurationFileLocation, and set it to -conf/dars/locationservice-dar.properties: - -Editing &SHORT_PLATFORM_NAME; for Tomcat's server.xml for the Location Service -<Service -name="Sip-Servlets" -className="org.mobicents.servlet.sip.startup.SipStandardService" -sipApplicationDispatcherClassName="org.mobicents.servlet.sip.core.SipApplicationDispatcherImpl" -darConfigurationFileLocation="conf/dars/locationservice-dar.properties" -sipStackPropertiesFile="conf/mss-sip-stack.properties"> - -Make sure that the configuration file only contains one -darConfigurationFileLocation attribute: your -new one. - - - - -Running -Once the WAR and DAR files have been placed in the right -directories, and the JBoss Application Server or Tomcat Servlet -Container knows where to find them (which you specified in the standalone-sip.xml and -server.xml file), then you should go ahead and -run the SIP Servlets Server. - - - - -Testing -The following procedure shows how to test the Location -Service. - - - -<step> -<para>Start two SIP soft-phones. The first phone should be set up as -<userinput>sip:receiver@sip-servlets.com</userinput> at the IP address -<userinput>127.0.0.1</userinput> on port -<userinput>5090</userinput>. The second phone can be set up in any -way you like. Note that the SIP phones do not have to be -registered.</para> -</step> -<step> -<para>Using the second phone, make a call to -<literal>sip:receiver@sip-servlets.com</literal>. If the Location -Service has been set up correctly and is running, the first phone—as -the receiver or callee—should now be ringing.</para> -</step> -</procedure> -<!--<formalpara -id="sfss-binary-Location_Service-Using"> -<title>Using -  - - - -Stopping -To learn how to stop the SIP Servlets-enabled JBoss Application -Server, refer to . - -To learn how to stop the SIP Servlets-enabled Tomcat Container, -refer to . - -Uninstalling -Unless disk space is at a premium, there is usually no need to -uninstall the Location Service. However, if you will not be using it -again, you may want to unset or reset the -darConfigurationFileLocation attribute of the -Service element, which you set in the -server.xml configuration file in . - -You may also wish to delete the WAR and DAR files for the Location -Service, which you installed in . - ---> -
-
-
-The Diameter Event-Changing Service -The Diameter Event-Changing Service is based on the Location -Service, which performs call-charging at a fixed rate. Upon the initiation -of a call, a debit of €10.00 occurs. In the cases of a call being rejected -or the caller disconnecting (hanging up) before an answer is received, the -caller's account is refunded. -Note that an &SHORT_PLATFORM_NAME; for JBoss installation is required to run this -example; it will not work with &SHORT_PLATFORM_NAME; for Tomcat. -Provided here is a step-by-step description of the procedure as -performed by the application and container: - -Diameter Event-Changing Service Step-By-Step - - A user, Alice, makes a call to -sip:receiver@sip-servlets.com. The -INVITE is received by the servlet container, which -sends a request to debit Alice's account to the Charging Server. The -servlet container then invokes the location service. - - - The Location Service determines, without using the SIP protocol -itself, where the callee—or receiver—is registered. The callee may be -registered at two locations identified by two SIP URIs: -sip:receiver@127.0.0.1:5090 and -sip:receiver@127.0.0.1:6090. - - - The Location Service proxies to those two destinations -simultaneously, without record-routing and without using the supervised -mode. - - - One of the destinations returns 200 (OK), and -so the container cancels the other. - - - The 200 (OK) is forwarded upstream to Alice, -and the call setup is carried out as usual. - - - If none of the registered destinations accepts the -call, a Diameter Accounting-Request for refund is sent to the Diameter -Charging Server in order to debit the already-credited €10.00 - - -
-Diameter Event-Changing Service: Installing, Configuring and Running -Preparing your &SHORT_PLATFORM_NAME; for JBoss server to run the Diameter -Event-Changing example requires downloading a WAR archive, a DAR -archive, the Ericsson Charging Emulator, setting an attribute in JBoss's -standalone-sip.xml configuration file, and then running -JBoss AS. Detailed instructions in the section below. - -Pre-Install Requirements and Prerequisites -The following requirements must be met before installation can begin. - - -Software Prerequisites - -One &SHORT_PLATFORM_NAME; for JBoss Installation - -Before proceeding, you should follow the instructions for -installing, configuring, running and testing &SHORT_PLATFORM_NAME; for JBoss from -the binary distribution. - - - - -Downloading -The following procedure describes how to download the required files. - - - -First, download the latest Web Application Archive -(WAR) file corresponding to this example, the -current version of which is named -diameter-event-charging-*.war, from . - - -Secondly, download the corresponding Disk Archive -(DAR) configuration file here: -. - - -Finally, you will need to download the Ericsson Charging -Emulator, version 1.0, from . - - - - - -Installing -The following procedure describes how to install the downloaded files. - - - -Place the diameter-event-charging-&VERSION;.war -WAR archive into the -$JBOSS_HOME/standalone/deployments/ -directory. - - -Place the -diametereventcharging-dar.properties DAR file -in your -$JBOSS_HOME/standalone/configuration/dars/ -directory. - - -Finally, open the terminal, move into the directory to which -you downloaded the Ericsson Charging SDK (for the sake of this -example, we will call this directory -charging_sdk), and then unzip the downloaded -zip file (you can use Java's jar command for this: -~]$ cd charging_sdk -charging_sdk]$ jar -xvf ChargingSDK-1_0_D31E.zip -Alternatively, you can use Linux's unzip -command to do the dirty work: -charging_sdk]$ unzip ChargingSDK-1_0_D31E.zip - - - -Configuration - - - - - - - - - -&SHORT_PLATFORM_NAME; for JBoss - - - - -Editing the standalone-sip.xml for the Diameter Event-Changer Service - - - - -In the $JBOSS_HOME/standalone/configuration/standalone-sip.xml -make sure the application router is pointing the mobicents-dar.properties file as follows. - - <subsystem xmlns="urn:org.mobicents:sip-servlets-as7:1.0" -application-router="dars/mobicents-dar.properties" - - - - - - - - - - - - - - - - - - - - -Running -The following procedure describes how to run the Diameter Event-Changing Service. - - -Diameter Event-Changing Service - - - -Then, run the Ericsson Charging Emulator. Open a terminal, -change the working directory to the location of the unzipped -Charging Emulator files (in -ChargingSDK-1_0_D31E or a similarly-named -directory), and run it with the java -jar PPSDiamEmul.jar command: -~]$ java -jar PPSDiamEmul.jar - - - -Using -Using the Event-Changing service means, firstly, inserting some -parameters into the Charging Emulator, and then, by using two SIP -(soft)phones, calling one with the other. The following sequential -instructions show you how. - - -SIP (Soft)Phone? Which? -The &PLATFORM_NAME; team recommends one of the following SIP phones, -and has found that they work well: the 3CX Phone, the SJ Phone or the -WengoPhone. - - -Using the Diameter Event-Changing Service - -Configure the Ericsson SDK Charging Emulator -Once you have started the Charging Emulator, you should -configure it exactly as portrayed in . -
-Configuring the Charging Emulator - - - - - -
- - -Set the Peer ID to: -aaa://127.0.0.1:21812 - - -Set the Realm to: -mobicents.org - - -Set the Host IP to: -127.0.0.1 - - -
- -Start two SIP (soft)phones. You should set the first phone up -with the following parameters: -sip:receiver@sip-servlets on IP address -127.0.0.1 on port -5090. The other phone can be set up any way -you like. - - -Before making a call, open the -Config -Options - dialog window, as shown in the image. -
-Configuring Accounts in the Charging Emulator - - - - - -
- In the Account Configuration window of -the Charging Emulator, you can see the user's balances. Select a -user to watch the balance. You can also stretch the window -lengthwise to view the user's transaction history. -
- -Time to call! From the second, -any-configuration phone, make a call to -sip:receiver@sip-servlets.com. Upon doing so, the -other phone should ring or signal that it is being contacted -. - - - You should be able to see a request—immediately following the -invite and before the other party (i.e. you) accepts or rejects the -call—sent to the Charging Emulator. That is when the debit of the -user's account is made. In the case that the call is rejected, or -the caller gives up, a second, new Diameter request is sent to -refund the initial amount charged by the call. On the other hand, if -the call is accepted, nothing else related to Diameter happens, and -no second request takes place. -Please note that this is not the correct way to do -charging, as Diameter provides other means, such as unit -reservation. However, for the purpose of a demonstration it is -sufficient to show the debit and follow-up credit working. Also, -this is a fixed-price call, regardless of the duration. Charging -can, of course, be configured so that it is time-based. - -
-
-
- - -
-The Call-Blocking Service -The &PLATFORM_NAME; Call-Blocking Service, upon receiving an -INVITE request, checks to see whether the sender's -address is a blocked contact. If so, it returns a -FORBIDDEN reply; otherwise, call setup proceeds as -normal. - -Blocked Contacts Cannot Currently Be Configured -Blocked contacts are currently hard-coded addresses. This model is -evolving towards the eventual use of a database. - -Here is the current hard-coded list of blocked contacts: - - -sip:blocked-sender@sip-servlets.com - - -sip:blocked-sender@127.0.0.1 - - -
-The Call-Blocking Service: Installing, Configuring and Running -  - -Software Prerequisites - -Either an &SHORT_PLATFORM_NAME; for JBoss or an &SHORT_PLATFORM_NAME; for Tomcat Installation - -The Call-Blocking Service requires either an &SHORT_PLATFORM_NAME; for JBoss -or an &SHORT_PLATFORM_NAME; for Tomcat binary installation. -You can find detailed instructions on installing &SHORT_PLATFORM_NAME; for -JBoss here: . - -You can find detailed instructions on installing &SHORT_PLATFORM_NAME; for -Tomcat here: . - - - - - - - -Downloading - - -The Call-Blocking Service is comprised of two archive files, a -Web Archive (WAR) and a Default Application Router (DAR) configuration -file, which you need to add to your installed SIP Servlets Server. For -more information about WAR files, refer to the JBoss Application Server Administration and Development Guide. For -more information about DAR files, refer to the JSR 289 spec, Appendix C. - - -Download the Call-Blocking Service's WAR file from here: . -Download the Call-Blocking Service's DAR file from here: . - - - -Installing -Both the call-blocking-&VERSION;.war WAR file and -the call-blocking-servlet-dar.properties DAR file -that you downloaded should be placed into different directories in -your SIP Servlet Server installation hierarchy. Which directory depends -on whether you are using the Call-Blocking Service with &SHORT_PLATFORM_NAME; for JBoss -or with &SHORT_PLATFORM_NAME; for Tomcat: - - - -&SHORT_PLATFORM_NAME; for JBoss - -Place call-blocking-&VERSION;.war into the -$JBOSS_HOME/standalone/deployments/ -directory, and -call-blocking-servlet-dar.properties into the -$JBOSS_HOME/standalone/configuration/dars/ -directory. - - - -&SHORT_PLATFORM_NAME; for Tomcat - -Place -call-blocking-servlet-dar.properties into the -$CATALINA_HOME/webapps/ -directory, and -call-blocking-servlet-dar.properties into the -$CATALINA_HOME/conf/dars/ -directory. - - - - - - -Configuring - - - - -&SHORT_PLATFORM_NAME; for JBoss - - - - -Editing the standalone-sip.xml file for Call Blocking - - - - -In the $JBOSS_HOME/standalone/configuration/standalone-sip.xml search for the line below - - <subsystem xmlns="urn:org.mobicents:sip-servlets-as7:1.0" - application-router="dars/mobicents-dar.properties" - -change it to the following - - <subsystem xmlns="urn:org.mobicents:sip-servlets-as7:1.0" - application-router="dars/call-blocking-servlet-dar.properties" - - - - - - - - - - - - - - - - -&SHORT_PLATFORM_NAME; for Tomcat - -Open the -$CATALINA_HOME/conf/server.xml -configuration file and find the Service -element. Add an attribute to it called -darConfigurationFileLocation, and set it to -conf/dars/call-blocking-servlet-dar.properties: - -Editing &SHORT_PLATFORM_NAME; for Tomcat's server.xml for the Call-Blocking Service -<Service -name="Sip-Servlets" -className="org.mobicents.servlet.sip.startup.SipStandardService" -sipApplicationDispatcherClassName="org.mobicents.servlet.sip.core.SipApplicationDispatcherImpl" -darConfigurationFileLocation="conf/dars/call-blocking-servlet-dar.properties" -sipStackPropertiesFile="conf/mss-sip-stack.properties"> - -Make sure that the configuration file only contains one -darConfigurationFileLocation attribute: your -new one. - - - - - - - -Running -Once the WAR and DAR files have been placed in the right -directories, and the JBoss Application Server or Tomcat Servlet -Container knows where to find them (which you specified in a -server.xml and the standalone-sip.xml files), then you should go ahead and -run the SIP Servlets Server. - - - - -Testing -The following procedure shows how to test the Call-Blocking -Service. - - -Testing the Call Blocking Service - -Start a SIP softphone of your choice. The account name should -be blocked-sender. The From Header should list one of the following addresses: -sip:blocked-sender@sip-servlets.com or -sip:blocked-sender@127.0.0.1. The SIP -softphone does not need to be registered. - - -Make a call to any address, and you should receive a -FORBIDDEN response. - - - - -
-
-
-The Call-Forwarding Service -The &PLATFORM_NAME; Call-Forwarding Service, upon receiving an -INVITE request, checks to see whether the sender's -address is among those in a list of addresses which need to be forwarded. -If so, then the Call-Forwarding Service acts as a Back-to-Back User Agent -(B2BUA), and creates a new call leg to the destination. When the response -is received from the new call leg, it sends it an acknowledgment -(ACK) and then responds to the original caller. If, on -the other hand, the server does not receive an ACK, -then it tears down the new call leg with a BYE. Once -the BYE is received, then it answers -OK directly and sends the BYE to -the new call leg. - -Contacts to Forward Cannot Currently Be Configured -Contacts to forward are currently hard-coded addresses. This model -is evolving toward the eventual use of a database. - -Here is the current hard-coded list of contacts to forward: - - -sip:receiver@sip-servlets.com - - -sip:receiver@127.0.0.1 - - -
-The Call-Forwarding Service: Installing, Configuring and Running -  - -Pre-Install Requirements and Prerequisites -The following requirements must be met before installation can begin. - - - - -Downloading -The Call-Forwarding Service is comprised of two archive files, a -Web Archive (WAR) and a Data Archive (DAR), which you need to add to -your installed SIP Servlets Server. For more information about WAR and -DAR files, refer to the JBoss Application Server Administration and Development Guide. - -Download the Call-Forwarding Service's WAR file from here: . -Download the Call-Forwarding Service's DAR file from here: . - -Installing -Both the call-forwarding-&VERSION;.war WAR file -and the call-forwarding-servlet-dar.properties -DAR file that you downloaded should be placed into different -directories in your SIP Servlet Server installation hierarchy. Which -directory depends on whether you are using the Call-Forwarding Service -with &SHORT_PLATFORM_NAME; for JBoss or with &SHORT_PLATFORM_NAME; for Tomcat: - - - -&SHORT_PLATFORM_NAME; for JBoss - -Place call-forwarding-&VERSION;.war into the -$JBOSS_HOME/standalone/deployments/ -directory, and -call-forwarding-servlet-dar.properties into -the -$JBOSS_HOME/standalone/configuration/dars/ -directory. - - - -&SHORT_PLATFORM_NAME; for Tomcat - -Place call-forwarding-&VERSION;.war into the -$CATALINA_HOME/webapps/ -directory, and -call-forwarding-servlet-dar.properties into -the $CATALINA_HOME/conf/dars/ -directory. - - - - - -Configuring - - - - - - -&SHORT_PLATFORM_NAME; for JBoss - - - - - - -Editing &SHORT_PLATFORM_NAME; for JBoss's standalone-sip.xml for the Call-Forwarding Service - - -In the $JBOSS_HOME/standalone/configuration/standalone-sip.xml search for the line below - - <subsystem xmlns="urn:org.mobicents:sip-servlets-as7:1.0" - application-router="dars/mobicents-dar.properties" - -change it to the following - - <subsystem xmlns="urn:org.mobicents:sip-servlets-as7:1.0" - application-router="dars/call-forwarding-b2bua-servlet-dar.properties" - - - - - - - - - - - - - - - - - - -&SHORT_PLATFORM_NAME; for Tomcat - -Open the -$CATALINA_HOME/conf/server.xml -configuration file and find the Service -element. Add an attribute to it called -darConfigurationFileLocation, and set it to -conf/dars/call-forwarding-b2bua-servlet-dar.properties: - -Editing &SHORT_PLATFORM_NAME; for Tomcat's server.xml for the Call-Forwarding Service -<Service -name="Sip-Servlets" -className="org.mobicents.servlet.sip.startup.SipStandardService" -sipApplicationDispatcherClassName="org.mobicents.servlet.sip.core.SipApplicationDispatcherImpl" -darConfigurationFileLocation="conf/dars/call-forwarding-b2bua-servlet-dar.properties" -sipStackPropertiesFile="conf/mss-sip-stack.properties"> - -Make sure that the configuration file only contains one -darConfigurationFileLocation attribute: your -new one. - - - - - -Running -Once the WAR and DAR files have been placed in the right -directories, and the JBoss Application Server or Tomcat Servlet -Container knows where to find them (which you specified in a -standalone-sip.xml and server.xml files), then you should go ahead and -run the SIP Servlets Server. - - - - -Testing -The following procedure shows how to test the Call-Forwarding -Service. - - - -<step> -<para>Start two SIP soft-phones of your choice. Set the account -settings of the first SIP softphone to:</para> -<itemizedlist> -<listitem> -<para>Account name: -<userinput>forward-receiver</userinput></para> -</listitem> -<listitem> -<para>IP address: <userinput>127.0.0.1</userinput></para> -</listitem> -<listitem> -<para>Port: <userinput>5090</userinput></para> -</listitem> -</itemizedlist> -<para>Neither of the SIP soft-phones needs to be registered.</para> -</step> -<step> -<para>From the second phone, make a call to -<literal>sip:receiver@sip-servlets.com</literal>. The first phone, -"forward-receiver", should now be ringing.</para> -</step> -</procedure> -<!--<formalpara -id="sfss-binary-Call-Forwarding_Service-Using"> -<title>Using -  - - -Stopping -To learn how to stop the SIP Servlets-enabled JBoss Application -Server, refer to . - -To learn how to stop the SIP Servlets-enabled Tomcat Container, -refer to . - -Uninstalling -Unless disk space is at a premium, there is usually no need to -uninstall the Call-Forwarding Service. However, if you will not be -using it again, you may want to unset or reset the -darConfigurationFileLocation attribute of the -Service element, which you set in the -server.xml configuration file in . - -You may also wish to delete the WAR and DAR files for the -Call-Forwarding Service, which you installed in . ---> - -
-
-
-The Call-Controller Service -The Call-Controller service is a composition of two other services: -Call-Blocking and Call-Forwarding. Essentially, it performs the services -of both call-forwarding and call-blocking. - - -To learn about how the Call-Blocking service works, refer to -. - - -To learn about how the Call-Forwarding service works, refer to -. - - - -Blocked Contacts and Contacts to Forward Cannot Currently Be Configured -Both the list of blocked contacts and the list of contacts to -forward are currently both hard-coded. However, both of those models are -evolving toward the eventual use of databases. - -
-The Call-Controller Service: Installing, Configuring and Running -The Call-Controller service requires the two WAR files for the -Call-Blocking and Call-Forwarding services to be placed in the correct -directory inside your &PLATFORM_NAME; SIP Servlets Server binary installation. -However, the Call-Controller service does not -require their corresponding DAR files: you need only to download and -install a DAR file customized for the Call-Controller service. The -instructions below show you how to do precisely this; there is no need, -therefore, to first install either the Call-Blocking or the -Call-Forwarding services, though it is helpful to at least be familiar -with them. - -Pre-Install Requirements and Prerequisites -The following requirements must be met before installation can begin. - - - - -Downloading -The Call-Controller Service is comprised of two WAR files, one -for the Call-Forwarding service and one for Call-Blocking, and a -customized Call-Controller DAR file. You do not need to install the -DAR files for the Call-Forwarding or the Call-Blocking services. For -more information about WAR files, refer to the JBoss Application Server Administration and Development Guide. For -more information about DAR files, refer to the JSR 289 spec, Appendix C - -Download the Call-Blocking Service's WAR file from here: . -Download the Call-Forwarding Service's WAR file from here: . -Download the Call-Controller Service's DAR file from here: . - -Installing -The call-blocking-&VERSION;.war, -call-forwarding-&VERSION;.war and -call-controller-servlet-dar.properties archive -files that you downloaded should be placed into different directories -in your SIP Servlet Server installation hierarchy. Which directory -depends on whether you are using the Call-Controller Service with &SHORT_PLATFORM_NAME; -for JBoss or with &SHORT_PLATFORM_NAME; for Tomcat: - - - -&SHORT_PLATFORM_NAME; for JBoss - -Place call-blocking-&VERSION;.war and -call-forwarding-&VERSION;.war into the -$JBOSS_HOME/standalone/deployments/ -directory, and -call-controller-servlet-dar.properties into -the -$JBOSS_HOME/standalone/configuration/dars/ -directory. - - - -&SHORT_PLATFORM_NAME; for Tomcat - -Place call-blocking-&VERSION;.war and -call-forwarding-&VERSION;.war into the -$CATALINA_HOME/webapps/ -directory, and -call-controller-servlet-dar.properties into -the $CATALINA_HOME/conf/dars/ -directory. - - - - - -Configuring - - - - - ---> -&SHORT_PLATFORM_NAME; for JBoss - - - - -Editing &SHORT_PLATFORM_NAME; for JBoss's standalone-sip.xml for the Call-Controller Service - - -In the $JBOSS_HOME/standalone/configuration/standalone-sip.xml search for the line below - - <subsystem xmlns="urn:org.mobicents:sip-servlets-as7:1.0" - application-router="dars/mobicents-dar.properties" - -change it to the following - - <subsystem xmlns="urn:org.mobicents:sip-servlets-as7:1.0" - application-router="dars/call-controller-servlet-dar.properties" - - - - - - - - - -Make sure that the configuration file only contains one -darConfigurationFileLocation attribute: your -new one. - - - -&SHORT_PLATFORM_NAME; for Tomcat - -Open the -$CATALINA_HOME/conf/server.xml -configuration file and find the Service -element. Add an attribute to it called -darConfigurationFileLocation, and set it to -conf/dars/call-controller-servlet-dar.properties : - - -Editing &SHORT_PLATFORM_NAME; for Tomcat's server.xml for the Call-Controller Service - -<Service -name="Sip-Servlets" -className="org.mobicents.servlet.sip.startup.SipStandardService" -sipApplicationDispatcherClassName="org.mobicents.servlet.sip.core.SipApplicationDispatcherImpl" -darConfigurationFileLocation="conf/dars/call-controller-servlet-dar.properties " -sipStackPropertiesFile="conf/mss-sip-stack.properties"> - - - -Make sure that the configuration file only contains one -darConfigurationFileLocation attribute: your -new one. - - - - -Running -Once the WAR and DAR files have been placed in the right -directories, and the JBoss Application Server or Tomcat Servlet -Container knows where to find them (which you specified in a -server.xml file), then you should go ahead and -run the SIP Servlets Server. - - - -Testing -Two use-cases can be distinguished for the Call-Controller -service: one in which a call is blocked, and another in which a call -is forwarded. Therefore, we have two cases for which we can test the -Call-Controller. - - -Blocking a Call with Call-Controller - -Start two SIP soft-phones of your choice. Set the account -settings of the SIP soft-phones to: - -Relevant First Softphone Settings - -Account name: -forward-receiver - - -IP address: 127.0.0.1 - - -Port: 5090 - - - -Relevant Second Softphone Settings - -Account name: blocked-sender - - -Neither of the SIP soft-phones needs to be registered. - - -From the second phone, blocked-sender, make -a call to sip:receiver@sip-servlets.com. You -should receive a FORBIDDEN response. - - - -Forwarding a Call with Call-Controller - -Start two SIP soft-phones of your choice. Set the account -settings of the SIP soft-phones to: - -Relevant First Softphone Settings - -Account name: -forward-receiver - - -IP address: 127.0.0.1 - - -Port: 5090 - - - -Relevant Second Softphone Settings - -Account name: forward-sender - - -Neither of the SIP soft-phones needs to be registered. - - -From the second softphone, forward-sender, -make a call to sip:receiver@sip-servlets.com. The -first phone, forward-receiver, should now be -ringing. - - - - - -provides more information about other service examples -available. - -
-
- - -
- - diff --git a/docs/sources/src/main/resources/en-US/concept-chapter-ittsss-Introduction_to_the_SIP_Servlets_Server.xml b/docs/sources/src/main/resources/en-US/concept-chapter-ittsss-Introduction_to_the_SIP_Servlets_Server.xml deleted file mode 100644 index a047a44950..0000000000 --- a/docs/sources/src/main/resources/en-US/concept-chapter-ittsss-Introduction_to_the_SIP_Servlets_Server.xml +++ /dev/null @@ -1,176 +0,0 @@ - - -%BOOK_ENTITIES; -]> - - -Introduction - -
- -Overview of &PLATFORM_NAME; SIP Servlets within the Telecommunications Industry - - - - -The Mobicents Communication Platform is the best architecture to create, deploy and manage services and applications integrating voice, video and data across a range of IP and legacy communications networks. It drives convergence with the following key enablers: - - - -
- Mobicents Architecture Overview - - - - - -
- -
- - - - - -
- - -
- -Overview of SIP Servlets Server - - - -&PLATFORM_NAME; SIP Servlets is a modern communications middleware platform. &PLATFORM_NAME; SIP Servlets facilitates the shift towards Cloud Communications by enabling deployment and autoscaling of real time SIP Servlets apps across all major IaaS (Infrastructure as a Service) providers and also brings realtime communications (voice and video) to your Browser using HTML5 WebRTC and SIP Over WebSockets ! - - - -The &PLATFORM_NAME; HTML5 WebRTC Client allows you to make video calls from and to any Web Browser supporting WebRTC , (only Google Chrome supports it so far but all major browsers should support it in the next 6 months) as well as SIP Endpoints. - - -&PLATFORM_NAME; SIP Servlets enables turnkey SaaS offerings such as RestComm . - - -&PLATFORM_NAME; SIP Servlets implements the latest SIP Servlet v1.1 (JSR 289) standard. It can be plugged into any Application Server container (currently 7.X and JBoss 7.X) and also offers High Availability and Failover. - - -&PLATFORM_NAME; SIP Servlets is lead by TeleStax, Inc . and developed collaboratively by a community of individual and enterprise contributors. - - - - - -
- Mobicents WebRTC SIP Stack - - - - - -
- -
-
- - - - -
diff --git a/docs/sources/src/main/resources/en-US/concept-section-SS_CDI_Telco_Framework.xml b/docs/sources/src/main/resources/en-US/concept-section-SS_CDI_Telco_Framework.xml deleted file mode 100644 index 0c10ca68df..0000000000 --- a/docs/sources/src/main/resources/en-US/concept-section-SS_CDI_Telco_Framework.xml +++ /dev/null @@ -1,20 +0,0 @@ - - -%BOOK_ENTITIES; -]> -
- CDI Telco Framework - CDI is the Java standard for dependency injection and contextual lifecycle management, led by Gavin King for Red Hat, Inc. and is a Java Community Process(JCP) specification that integrates cleanly with the Java EE platform. Any Java EE 6-compliant application server provides support for JSR-299 (even the web profile). It seemed a natural fit create a new framework based on CDI for the Telco world. - CDI-Telco-Framework (CTF) from &PLATFORM_NAME; brings the power and productivity benefits of CDI into the &PLATFORM_NAME; Sip Servlets platform providing dependency injection and contextual lifecycle management for converged HTTP/SIP applications. This new framework is intended to become a replacement for our previous Seam Telco Framework. - CTF mission statement is to simplify SipServlets development by introducing a component based programming model, ease of development by making available SIP utilities out of the box, and finally providing dependency injection and contextual lifecycle management to the SipServlets. -
- CDI Telco Framework Extension - - - - - -
- More information about the CTF can be found on the CDI Telco Framework Documentation. -
diff --git a/docs/sources/src/main/resources/en-US/concept-section-SS_Concurrency_and_Congestion_Control.xml b/docs/sources/src/main/resources/en-US/concept-section-SS_Concurrency_and_Congestion_Control.xml deleted file mode 100644 index 6ba7810356..0000000000 --- a/docs/sources/src/main/resources/en-US/concept-section-SS_Concurrency_and_Congestion_Control.xml +++ /dev/null @@ -1,396 +0,0 @@ - - -%BOOK_ENTITIES; -]> - -
- Concurrency and Congestion Control - Concurrency and Congestion control refer to settings that - define the way in which messages are processed under heavy load. The way &PLATFORM_NAME; SIP Servlets Server processes messages in a production environment is crucial to ensure quality of service for customers. - Concurrency control mode tuning affects the way in which - the SIP Servlets Server processes messages, whereas Congestion Control tuning affects the point at which the server - begins rejecting new requests. Both of these parameters can be set using the following methods: - - - Through the SIP Servlets Management Console. - - - Editing - the server's server.xml or standalone-sip.xml configuration file. - - - From the - dispatcher MBean. - - - From the Embedded Jopr integrated - management platform. - - - - Concurrency Control - The JSR 289 expert group does not specify how concurrency control should be implemented. - - &PLATFORM_NAME; SIP Servlets for JBoss and &PLATFORM_NAME; SIP Servlets for Tomcat have concurrency control implemented as - a configurable mode, which defines the way in which the SIP Servlets Server processes messages. - It has to be noted that this concurrency control mechanism is not cluster aware and will work per node only, it is not a cluster wide lock. - The following modes are provided, and cater for the particular setup required in an implementation: - - - None - - All SIP messages are processed as soon as possible in a thread - from the global thread pool. - When two messages - belong to the same SipSession, they can be concurrently processed. Ensure that SIP Messages that access shared resources (such as the session attribute) concurrently are synchronized in a - thread-safe manner. - - - - Transaction - - Bypass the SIP Servlets request/response executors, and utilize the JAIN SIP built-in Transaction serialization to manage race conditions on the same transaction. - By default, the SIP Servlets server uses a ThreadPoolExecutor linked to a LinkedBlockingQueue to dispatch the request/response threads. The container can thus handles two different response (for example a 180 Ringing and a 200 OK) concurrently, a race condition can occur where the second response overtakes the first one (200 OK dispatched to the application before the 180 Ringing). - - - - - SipSession - - SIP messages are processed as soon as possible except for messages originating from the same SipSession. These messages are excluded from any simultaneous processing. - Messages from the same - SipSession are processed sequentially, in the order they originally arrived. - Two (or more) messages from different - SipSession instances in the same - SipApplicationSession may be processed - simultaneously. For this reason, ensure that SIP Messages that access shared resources (such as the session attribute) concurrently are synchronized in a - thread-safe manner. - Thread-safety is particularly important in Back-to-Back User Agent (B2BUA) cases, where each communication leg of the - B2BUA consists of a different SipSession in the - same SipApplicationSession. - - - - SipApplicationSession - - SIP messages are processed as soon as possible, with the - guarantee that no two messages from the same - SipSession or from the same - SipApplicationSession will ever be processed - simultaneously. Of all the available methods, this mode is the best choice for guaranteed thread-safety. - If applications access shared resources in an unmanaged - way (for example, by accessing a SipSession attribute - from an unmanaged thread, or from an Enterprise JavaBean) access will not be synchronized. - - - - - - - - Congestion Control - &PLATFORM_NAME; Sip Servlets currently provides the following congestion - control mechanisms: - - - - -Changing Congestion Control Settings - -All the settings and congifurations starting with gov.nist.javax.sip are located in the $JBOSS-HOME/standalone/configuration/mss-sip-stack.properties file. The section below will provide further details. - - - - - - Congestion control is largely application-specific and it is implemented in a pipeline. - First messages arrive in the JAIN SIP message queue where they will wait on the locks needed - before they can be processed. To avoid keeping too many messages in the queue and potentially - running out of memory, older messages are discarded without any error indication. This prevents - spam and flood DoS attacks to accumulate large backlog and render the server unresponsive. It also - guranatees flood recovery time of 20 seconds or less, in the mean time retransmissions are - already queuing so that normal SIP calls can continue without dropping them. After the request has passed the first - queue it enters the SIP transaction layer where there is a customizable optional congestion control logic. - There is one packaged congestion control algorithm which can be enabled by setting the following property - gov.nist.javax.sip.SIP_MESSAGE_VALVE=gov.nist.javax.sip.stack.CongestionControlMessageValve. - For this algorithm you can set the limit value by the following property - gov.nist.javax.sip.MAX_SERVER_TRANSACTIONS=2000. - You can also implement your own algorithm and change the class name in gov.nist.javax.sip.SIP_MESSAGE_VALVE to activate it. - - There is also another optional legacy congestion - control stage with another queue where messages can be discarded based on dynamic parameters - such as available JVM heap memory or number of messages in the queue. This method will be deprecated and is not recommended. All SIP messages which - cannot be processed immediately are put - into a queue, and wait for either a free thread or for the lock - on their session to be released. The size of the SIP message - queue is a tunable parameter, which defaults to - 1500. - - - If the SIP Message queue becomes full, the - container immediately begins rejecting new SIP requests until the queue clears. This is achieved by using one of the following methods: - - - Sending a 503 SIP error code to the originating application. - - - Dropping incoming - messages (according to the specified congestion control policy). - - - - - If the container exceeds the configurable memory threshold (90% by default), new SIP requests are rejected until the - memory usage falls below the specified memory threshold. This is achieved by using one of the following methods: - - - Sending a 503 SIP error code to the originating application. - - - Dropping incoming - messages (according to the specified congestion control policy). - - - - - A background task gathers information about the current server congestion. The data collection interval can be adjusted, and congestion control deactivated, by setting the interval to 0 or a - negative value. - The congestion control policy defines how an incoming - message is handled when the server is overloaded. The following parameters are configurable: - - - DropMessage - drop any incoming message - - - ErrorResponse - send a 503 - Service Unavailable response to any - incoming request (Default). - - - - Configuring the Concurrency and Congestion Control Settings - The concurrency and congestion control settings can be configured - through the SIP Servlets Management Console, using the following methods: - - - - Through the SIP Servlets Management Console. - - - Editing - the server's server.xml or the standalone-sip.xml configuration file. - - - From the - dispatcher MBean. - - - From the Embedded Jopr integrated - management platform. - - - - - Tuning Parameters with the SIP Servlets Management Console - - The easiest way to configure the SIP Message Queue Size and Concurrency Control Mode - tunable parameters is to open the SIP Servlets Management Console in your browser (by going to ), making - your changes, and then clicking Apply. -
- SIP Servlets Management Console Concurrency and Congestion Control Tuning Parameters - - - - - -
- - Persistent Settings - Concurrency and congestion control settings altered through the SIP Servlets Management Console are not saved to the server.xml on Tomcat, only on JBoss AS7 through the standalone-sip.xmlconfiguration file. - To make settings persistent, append the settings to the server.xml file directly. - -
-
- - Making your changes permanent in standalone-sip.xml or server.xml by manual editing - - Alternatively, you can edit your server's - standalone-sip.xml or server.xml configuration file, which has the - benefit of making your chosen settings changes permanent for Tomcat. Instructions - follow, grouped by the SIP Servlets Server you are running: - - Tuning &PLATFORM_NAME; SIP Servlets for JBoss Server Settings for Concurrency and Congestion Control - - Open standalone-sip.xml File - Open the - $JBOSS_HOME/standalone/configuration/standalone-sip.xml - configuration file in a text editor. - - - - - - - -Extract from stanalone-sip.xml file with conccurency configuration - - - - - - - - - - - -]]> - - - - - - - - - - - - - - Tuning &PLATFORM_NAME; SIP Servlets for Tomcat Server Settings for Concurrency and Congestion Control - - Open server.xml File - Open the - $CATALINA_HOME/conf/server.xml - configuration file in your text editor. - - - Add Parameters to <service> Element - Locate the <service> element, and add the - concurrencyControlMode and/or - sipMessageQueueSize attributes. - Possible values for the - concurrencyControlMode attribute include: - None, - SipSession or - SipApplicationSession. - SipSession is the value of this - attribute when it is not present—and overridden—in - server.xml. - - - Define the Correct Attribute Values - The following default values for the concurrency and congestion control parameters are used regardless of whether the attributes are defined in the server.xml file: - - - sipMessageQueueSize="1500" - - - backToNormalSipMessageQueueSize="1300" - - - congestionControlCheckingInterval="30000" (30 seconds, in milliseconds) - - - memoryThreshold="95" (in percentage) - - - backToNormalMemoryThreshold="90" (in percentage) - - - congestionControlPolicy="ErrorResponse" - - - Experimentation is required for these tuning parameters depending on the operating system and server. - - - - - - Tuning Parameters from the dispatcher MBean - - Navigate to the dispatcher MBean from - &PLATFORM_NAME; SIP Servlets for JBoss's JMX console. - All changes performed - at run time are effective immediately, but do not persist across - reboots for Tomcat, only on JBoss AS7. the server.xml must be appended with the settings in order to make the configuration persistent. - When editing the dispatcher MBean from - &PLATFORM_NAME; SIP Servlets for JBoss's JMX console, values allowed for the - concurrency control mode are None, - SipSession or - SipApplicationSession. - - - -
-
diff --git a/docs/sources/src/main/resources/en-US/concept-section-SS_Diameter_Support.xml b/docs/sources/src/main/resources/en-US/concept-section-SS_Diameter_Support.xml deleted file mode 100644 index d53b17417c..0000000000 --- a/docs/sources/src/main/resources/en-US/concept-section-SS_Diameter_Support.xml +++ /dev/null @@ -1,10 +0,0 @@ - - -%BOOK_ENTITIES; -]> -
- Diameter Support - The Diameter Protocol (RFC 3588) is a computer networking protocol for Authentication, Authorization, and Accounting (AAA). The Diameter version included in &PLATFORM_NAME; SIP Servlets currently support Base, Sh, Ro and Rf. - For more information regarding Diameter support, refer to the Diameter Home Page. For a list of Diameter examples, refer to . -
diff --git a/docs/sources/src/main/resources/en-US/concept-section-SS_JRuby_Teclo_Integration.xml b/docs/sources/src/main/resources/en-US/concept-section-SS_JRuby_Teclo_Integration.xml deleted file mode 100644 index aa498324b6..0000000000 --- a/docs/sources/src/main/resources/en-US/concept-section-SS_JRuby_Teclo_Integration.xml +++ /dev/null @@ -1,22 +0,0 @@ - - -%BOOK_ENTITIES; -]> -
- JRuby/Rails Integration with Torquebox Telco Framework - &PLATFORM_NAME; Sip Servlets is compatible with the Torquebox Telco Framework JRuby on - Rails integration. The framework allows you to create powerful, pure or converged VoIP JRuby - on Rails applications. - JRuby features a powerful and well - deployed scripting language that allows you to modify your application at - runtime (this is true even for the SIP and Media part that &PLATFORM_NAME; SIP - Servlets offer) without restarting the server. In addition, TorqueBox is a new kind of Ruby application - platform that integrates popular technologies such as Ruby-on-Rails, while - extending the footprint of Ruby applications to include support for Job - Scheduling, Task Queues, SOAP Handling, and other capabilities. - To obtain more information about building pure JRuby-Rails applications that - leverage &PLATFORM_NAME; SIP Servlets SIP and media capabilities, refer to the Torquebox User Documentation. - Check this blog post to help you create your first pure Torquebox JRuby Telco - application and our pure JRuby on Rails TorqueBox Telco example showcasing this integration. -
diff --git a/docs/sources/src/main/resources/en-US/concept-section-SS_JSLEE_Interop.xml b/docs/sources/src/main/resources/en-US/concept-section-SS_JSLEE_Interop.xml deleted file mode 100644 index 7736d44443..0000000000 --- a/docs/sources/src/main/resources/en-US/concept-section-SS_JSLEE_Interop.xml +++ /dev/null @@ -1,139 +0,0 @@ - - -%BOOK_ENTITIES; -]> -
- SIP Servlets - JAIN SLEE Interoperability - JAIN SLEE is a more complex specification than SIP Servlets, and it - has been know as heavyweight and with a steep learning curve. However JAIN - SLEE has standardized a high performing event driven application server, an - execution environment with a good concurrency model and powerful protocol - agnostic capabilities thus covering a variety of Telco protocols. - SIP Servlets on the other hand is much simpler and easier to get started - with. Its focus is on extending the HTTP Servlets and Java EE hosting - environments with SIP capabilities. SIP Servlets is more of a SIP - programming framework, while JSLEE is a complete, self sufficient application - platform. The fact that SIP Servlets is focused on SIP and - Java EE makes it a natural fit to build JEE converged applications. - - JSLEE and SIP Servlets target different audiences with different needs, - but they can be complementary in a number of real world cases. - SIP Servlets focuses on SIP and its integration with Java EE. It is - also more of a SIP framework within Java EE. JSLEE is an event driven - application server with protocol agnostic architecture, spanning any legacy - or potential future protocols. SIP Servlets applications are generally - simpler to implement and accelerate time to market for Web and SIP - deployment scenarios. JSLEE has a steeper learning curve and covers a wider - set of target deployment environments. - As JBoss is the only vendor to implement both specifications through - &PLATFORM_NAME;, this makes it a natural fit to build converged and interoperable - JSLEE/SIP Servlets applications that are able to comply with standards in a - portable manner. We built an application that could leverage standards all - the way without resorting to vendor proprietary extensions by making SIP - Servlets and JSLEE work together. Our "JSLEE and SIP-Servlets Interoperability with Mobicents Communication Platform" paper describes our approach and the possible different - approaches we have identified to achieve the goal of interoperability - between SIP Servlets and JSLEE. - You can also use our JSLEE/SIP Servlets interoperability example, showcasing our approach. -
diff --git a/docs/sources/src/main/resources/en-US/concept-section-SS_JSR289_Extensions.xml b/docs/sources/src/main/resources/en-US/concept-section-SS_JSR289_Extensions.xml deleted file mode 100644 index 3ee64d98aa..0000000000 --- a/docs/sources/src/main/resources/en-US/concept-section-SS_JSR289_Extensions.xml +++ /dev/null @@ -1,11 +0,0 @@ - - -%BOOK_ENTITIES; -]> - -
- &PLATFORM_NAME; vendor-specific Extensions to JSR 289 - &PLATFORM_NAME; provide Extensions for applications or external systems to interact with the &PLATFORM_NAME; SIP Servlets container as well as Extensions not defined in the specification in the JSR 289 specification that can prove useful and might be proposed for inclusion in a next release of the SIP Servlets specification - Javadoc for &PLATFORM_NAME; JSR 289 Extensions -
diff --git a/docs/sources/src/main/resources/en-US/concept-section-SS_Load_Balancer.xml b/docs/sources/src/main/resources/en-US/concept-section-SS_Load_Balancer.xml deleted file mode 100644 index 0ae621913c..0000000000 --- a/docs/sources/src/main/resources/en-US/concept-section-SS_Load_Balancer.xml +++ /dev/null @@ -1,661 +0,0 @@ - - -%BOOK_ENTITIES; -]> -
- Load Balancer -
- Star Cluster Topology. - - - - - -
- The SIP Load Balancer is used to balance the load of SIP service requests and responses between nodes in a SIP Servlets Server cluster. Both &SHORT_PLATFORM_NAME; for JBoss and &SHORT_PLATFORM_NAME; for Tomcat servers can be used in conjunction with the SIP Load Balancer to increase the performance and availability of SIP services and applications. - In terms of functionality, the SIP Load Balancer is a simple stateless proxy server that intelligently forwards SIP session requests and responses between User Agents (UAs) on a Wide Area Network (WAN), and SIP Servlets Server nodes, which are almost always located on a Local Area Network (LAN). All SIP requests and responses pass through the SIP Load Balancer. -
- SIP Load Balancer: Installing, Configuring and Running -   -
- Pre-Install Requirements and Prerequisites -   - - Software Prerequisites - - A JAIN SIP HA-enabled application server such as &PLATFORM_NAME; JAIN SLEE or &PLATFORM_NAME; SIP Servlets is required. - - Running the SIP Load Balancer requires at least two instances of the application server as cluster nodes nodes. Therefore, before configuring the SIP Load Balancer, we should make sure we've installed a the SIP application server first. The &PLATFORM_NAME; SIP load balancer will work with a SIP Servlets-enabled JBoss Application Server or a JAIN SLEE application server with SIP RA. - SIP Servlets containers based on Tomcat are also supported but the session replication is not available there, thus mid-call failover will not work. - - - To install a SIP Servlet-enabled JBoss Application Server, follow the instructions here: . - - - To install a SIP Servlet-enabled Tomcat Servlet Container, follow these instructions: . - - - - - -
-
- Downloading - The load balancer is located in the sip-balancer top-level directory of the &SHORT_PLATFORM_NAME; distribution. You will find the following files in the directory: - - - SIP load balancer executable JAR file - - This is the binary file with all dependencies - - - - SIP load balancer Configuration Properties file - - This is the properties files with various settings - - - -
-
- Installing - The SIP load balancer executable JAR file can be extracted anywhere in the file system. It is recommended that the file is placed in the directory containing other JAR executables, so it can be easily located in the future. -
-
- Configuring - Configuring the SIP load balancer and the two SIP Servlets-enabled Server nodes is described in . - - Configuring the &PLATFORM_NAME; SIP Load Balancer and SIP Server Nodes - - Configure lb.properties Configuration Properties File - Configure the SIP Load Balancer's Configuration Properties file by substituting valid values for your personal setup. shows a sample lb.properties file, with key element descriptions provided after the example. The lines beginning with the pound sign are comments. - - Complete Sample lb.properties File - &PLATFORM_NAME; &PLATFORM_NAME; - - - - - host - - Local IP address, or interface, on which the SIP load balancer will listen for incoming requests. - - - - externalPort - - Port on which the SIP load balancer listens for incoming requests from SIP User Agents. - - - - internalPort - - Port on which the SIP load balancer forwards incoming requests to available, and healthy, SIP Server cluster nodes. - - - - rmiRegistryPort - - Port on which the SIP load balancer will establish the RMI heartbeat connection to the application servers. When this connection fails or a disconnection instruction is received, an application server node is removed and handling of requests continues without it by redirecting the load to the lie nodes. - - - - httpPort - - Port on which the SIP load balancer will accept HTTP requests to be distributed across the nodes. - - - - internalTransport - - Transport protocol for the internal SIP connections associated with the internal SIP port of the load balancer. Possible choices are UDP, TCP and TLS. - - - - externalTransport - - Transport protocol for the external SIP connections associated with the external SIP port of the load balancer. Possible choices are UDP, TCP and TLS. It must match the transport of the internal port. - - - - externalIpLoadBalancerAddress - - Address of the IP load balancer (if any) used for incoming requests to be distributed in the direction of the application server nodes. This address may be used by the SIP load balancer to be put in SIP headers where the external address of the SIP load balancer is needed. - - - - externalIpLoadBalancerPort - - The port of the external IP load balancer. Any messages arriving at this port should be distributed across the external SIP ports of a set of SIP load balancers. - - - - internalIpLoadBalancerAddresst - - Address of the IP load balancer (if any) used for outgoing requests (requests initiated from the servers) to be distributed in the direction of the clients. This address may be used by the SIP load balancer to be put in SIP headers where the internal address of the SIP load balancer is needed. - - - - internalIpLoadBalancerPort - - The port of the internal IP load balancer. Any messages arriving at this port should be distributed across the internal SIP ports of a set of SIP load balancers. - - - - extraServerNodes - - Comma-separated list of hosts that are server nodes. You can put here alternative names of the application servers here and they will be recognized. Names are important, because they might be used for direction-analysis. Requests coming from these server will go in the direction of the clients and will not be routed back to the cluster. - - - - algorithmClass - - The fully-qualified Java class name of the balancing algorithm to be used. There are three algorithms to choose from and you can write your own to implement more complex routing behaviour. Refer to the sample configuration file for details about the available options for each algorithm. Each algorithm can have algorithm-specific properties for fine-grained configuration. - - - - nodeTimeout - - In milliseonds. Default value is 5100. If a server node doesnt check in within this time (in ms), it is considered dead. - - - - heartbeatInterval - - In milliseconds. Default value is 150 milliseonds. The hearbeat interval must be much smaller than the interval specified in the JAIN SIP property on the server machines - org.mobicents.ha.javax.sip.HEARTBEAT_INTERVAL - - - - - The remaining keys and properties in the configuration properties file can be used to tune the JAIN SIP stack, but are not specifically required for load balancing. To assist with tuning, a comprehensive list of implementing classes for the SIP Stack is available from the Interface SIP Stack page on nist.gov. For a comprehensive list of properties associated with the SIP Stack implementation, refer to Class SipStackImpl page on nist.gov. - - - - Configure logging - The SIP load balancer uses Log4J as a logging mechanism. You can configure it through the typical log4j xml configuration file and specify the path as follows -DlogConfigFile=./log4j.xml. - Please refer to Log4J documentation for more information on how to configure the logging. A shortcut exists if you want to switch between INFO/DEBUG/WARN logging levels. The JVM option - -DlogLevel=DEBUG will allow you to switch all loggig categories to the specified log level. - - - Configure the container configuration file - Ensure the following attributes are configured for the <service> element in server.xml for Tomcat or in the mobicents subsystem element for JBoss AS7. - - - The sipPathName attribute must contain the following value org.mobicents.ha.balancing.only to indicate that the server will be using the &PLATFORM_NAME; JAIN SIP HA SIP Stack which is an extension of the JAIN SIP Stack offering integration with the Mobicents Load Balancer and transparent replication. - - - - - Configure the <filename>mss-sip-stack.properties</filename> configuration file - - - The org.mobicents.ha.javax.sip.cache.MobicentsSipCache.cacheName property must contain the name of the cache that will be responsible for holding the replicated data of the SIP Stack layer (namely the established SIP dialog data). The value has to be one of the cache name present in the jboss-cache-manager-jboss-beans.xml file of the jboss-cache-manager JBoss Service of the container. The default value is standard-session-cache - - - The org.mobicents.ha.javax.sip.BALANCERS property must be configured with the list of load balancer IP address and internal ports. As an example, suppose a single &THIS.PLATFORM; SIP Load Balancer is running with IP 192.168.0.1 and internal port 5065, the property would be set with value 192.168.0.1:5065. To specify multiple balancers use ; as separator. If this property is used the balancers attribute located in server.xml should not be used as it is a replacement for it. - - - The org.mobicents.ha.javax.sip.LoadBalancerHeartBeatingServiceClassName property is optional, it defines the class name of the HeartBeating service implementation, currently the only one available is org.mobicents.ha.javax.sip.LoadBalancerHeartBeatingServiceImpl - - - The org.mobicents.ha.javax.sip.LoadBalancerElector property is optional, it defines the class of the load balancer elector from JAIN SIP HA Stack. The elector is used to define which load balancer will receive outgoing requests, which are out of dialog or in dialog with null state. Currently only one elector implementation is available, org.mobicents.ha.javax.sip.RoundRobinLoadBalancerElector, which, as the class name says, uses round robin algorythm to select the balancer. - - - - -
- - Configuration File Locations - On &SHORT_PLATFORM_NAME; for Tomcat server installations, server.xml is located in <install_directory>/conf. - On &SHORT_PLATFORM_NAME; for JBoss server installations, the default standalone-sip.xml configuration file is located - in standalone/configuration or the default domain-sip.xml configuration file located - in domain/configuration for cluster configurations - - - - Easy Node Configuration with JMX - Both SIP Servlet-enabled JBoss and Tomcat have JMX (Java Management Extensions) interfaces that allow for easy server configuration. The JMX Console is available once the server has been started by navigating to . - - Both the balancers and heartBeatInterval attribute values are available under name=&PLATFORM_NAME;-SIP-Servlets,type=load-balancer-heartbeat-service in the JMX Console. - - - - balancers - - Host names of the SIP load balancer(s) with corresponding addBalancerAddress and removeBalancerAddress methods. - - - - heartBeatInterval - - Interval at which each heartbeat is sent to the SIP load balancer(s). - - - -
-
- Converged Load Balancing -
- Apache HTTP Load Balancer - The &SHORT_PLATFORM_NAME; SIP Load Balancer can work in concert with HTTP load balancers such as mod_jk. Whenever an HTTP session is bound to a particular node, an instruction is sent to the SIP Load Balancer to direct the SIP calls from the same application session to the same node. - - It is sufficient to configure mod_jk to work for HTTP in JBoss in order to enable cooperative load balancing. &SHORT_PLATFORM_NAME; will read the configuration and will use it without any extra configuration. You can read more about configuring mod_jk with JBoss in your JBoss Application Server documentation. - Alternatively you may disable this behaviour and make the HTTP load balancer follow the decisions made by the SIP load balancer with the httpFollowsSip flag. This is - achieved by changing the jvmRoute part of the session ID cookie used internally by mod_jk. - -
- The httpFollowsSip flag - The httpFollowsSip flag in the service configuration makes the application server aware of how different mod_jk and SIP load balancers have assigned - request affinity for each application session. The application servers assign exactly one node to each Sip Servlets application session and this node is the node where the - last SIP request associated with the application session has landed (decised by the SIP load balancer). Then the application server will actively update the session ID - cookie (the jvmRoute part) of any HTTP request that arrives at - the wrong node. The application server will do so with a specially composed HTTP redirect response or with a HTML refresh hint. As a backup strategy, if the request is bound to seek - non-existing node forever and it will let the request be served by a new node. This avoids having a client stuck reloading the same page over and over. - One problem with this flag is that if you have two or more SIP sessions associated with the same application session and the load balancer has decided to send SIP requests - to different nodes, which might happend if you use Call-ID based affinity, then the application server will have to change the jvmRoute very often for every SIP request resulting - in significant overhead. It is generally not adviced to enable this flag if you have more than 1 SIP session per application session and the means to guarantee all SIP sessions - from the application session will land on the same node. - This is an example how to enable the option. It is disabled by default. - <Connector port="5080" - ipAddress = "${jboss.bind.address}" - ... - httpFollowsSip="true" /> - -
- -
-
- Integrated HTTP Load Balancer - To use the integrated HTTP Load Balancer, no extra configuration is needed. If a unique jvmRoute is specified and enabled in each application server, it will behave exactly as the apache balancer. If jvmRoute is not present, it will use the session ID as a hash value and attempt to create a sticky session. The integrated balancer can be used together with the apache balancer at the same time. - - In addition to the apache behavior, there is a consistent hash balancer algorithm that can be enabled for both HTTP and SIP messages. For both HTTP and SIP messages, there is a configurable affinity key, which is evaluated and hashed against each unassigned request. All requests with the same hash value will always be routed to the same application server node. For example, the SIP affinity key could be the callee user name and the HTTP affinity key could the appsession HTTP GET parameter of the request. If the desired behaviour group these requests, we can just make sure the affinity values (user name and GET parameter) are the same. -
- Ensuring SIP and HTTP requests are being grouped by common affinity value. - - - - - -
-
-
-
-
- Running - - Running the SIP Load Balancer and SIP Server Nodes - - Start the SIP Load Balancer - Start the SIP load balancer, ensuring the Configuration Properties file (lb.properties in this example) is specified. In the Linux terminal, or using the Windows Command Prompt, the SIP Load Balancer is started by issuing a command similar to this one: - java -jar sip-balancer-jar-with-dependencies.jar lb-configuration.properties - Executing the SIP load balancer produces output similar to the following example: - home]$ java -jar sip-balancer-jar-with-dependencies.jar lb-configuration.properties -Oct 21, 2008 1:10:58 AM org.mobicents.tools.sip.balancer.SIPBalancerForwarder start -INFO: Sip Balancer started on address 127.0.0.1, external port : 5060, port : 5065 -Oct 21, 2008 1:10:59 AM org.mobicents.tools.sip.balancer.NodeRegisterImpl startServer -INFO: Node registry starting... -Oct 21, 2008 1:10:59 AM org.mobicents.tools.sip.balancer.NodeRegisterImpl startServer -INFO: Node expiration task created -Oct 21, 2008 1:10:59 AM org.mobicents.tools.sip.balancer.NodeRegisterImpl startServer -INFO: Node registry started - The output shows the IP address on which the SIP Load Balancer is listening, as well as the external and internal listener ports. - - - Configure SIP Server Nodes - SIP Servlets Server nodes can run on the JBoss Application Server, or the Tomcat Servlet Container. The SIP Servlets Server binary distributions define the type of SIP Servlets Server nodes used, and should already be installed from . - The Tomcat's server.xml or JBoss's standalone-sip.xml file specifies the nodes used. Because there is more then one client node specified, unique listener ports must be specified for each node to monitor HTTP and/or SIP connections. describes the affected element in the configuration file. - - - - Start Load Balancer Client Nodes - Start all SIP load balancer client nodes. - - -
-
- Testing - To test load balancing, the same application must be deployed manually on each node, and two SIP Softphones must be installed. - - Testing Load Balancing - - Deploy an Application - Ensure that for each node, the DAR file is the same. - Deploy the Location service manually on both nodes. - - - Start the "Sender" SIP softphone - Start a SIP softphone client with the SIP address of sip:sender@sip-servlets-com, listening on port 5055. The outbound proxy must be specified as the sip-balancer (http://127.0.0.1:5060) - - - Start the "Receiver" SIP softphone - Start a SIP softphone client with the SIP address of sip:receiver-failover@sip-servlets-com, listening on port 5090. - - - Initiate two calls from "Sender" SIP softphone - Initiate one call from sip:sender@sip-servlets-com to sip:receiver-failover@sip-servlets-com. Tear down the call once completed. - Initiate a second call using the same SIP address, and tear down the call once completed. Notice that the call is handled by the second node. - - -
-
- Stopping - Assuming that you started the JBoss Application Server as a foreground process in the Linux terminal, the easiest way to stop it is by pressing the - Ctrl - C - key combination in the same terminal in which you started it. - This should produce similar output to the following: - ^COct 21, 2008 1:11:57 AM org.mobicents.tools.sip.balancer.SipBalancerShutdownHook run -INFO: Stopping the sip forwarder -
-
- Uninstalling - To uninstall the SIP load balancer, delete the JAR file you installed. -
-
-
- IP Load Balancing -
- IP Load Balancers - An IP load-balancer is a network appliance that distributes traffic to an application server (or actual servers) using a load-balancing algorithm. IP load-balancing is often used when the other load-balancers' capacity is exceeded and can not scale further without hardware upgrades. - Routing decisions are made based on OSI Layer 2, 3 or 4 data. This type of load balancer only examines low-level TCP, UDP or ethernet packet structures including MAC addresses, IP addresses, ports, and protocol types (TCP or UDP or other). - An IP load balancer never reads the payload of the TCP/IP packets and therefore never parses SIP or HTTP (or any protocol above OSI Layer 4). Because an IP load balancing device is not SIP or HTTP aware in any way, it is much more performant than mod_jk or the &SHORT_PLATFORM_NAME; SIP load-balancer. - - -
-
- Technical overview - In its simplest form, the IP load-balancer usually "owns" the public-facing IP address (known as a VIP). The traffic is routed to actual servers in it's private network similar to NAT. It is also possible to not change the IP address and just work on the MAC address by assuming that all actual servers are configured to accept packets for the VIP address. The features offered by the IP load balancer depend largely on the vendor. - Some examples of Linux-based software load balancers include Red Hat Cluster Suite (RHCS) and Linux Virtual Server (LVS). There are many hardware vendors as well. - One main drawback relating to IP load balancers is that they can not make routing decisions based on SIP messages and (with some exceptions) they can not work cooperatively with HTTP or other load balancers. -
-
- Configuring &SHORT_PLATFORM_NAME; Cluster for pure IP Load Balancing - - Pure IP load balancing is not a recommented option. It is advised to use a distributed load balancer instead. Proper operation with pure IP load balancing depends on the ability of the IP load balancer to establish request affinity based on IP addresses and ports. - - First you need to remove the SIP load balancers from any configuration in &SHORT_PLATFORM_NAME;. In particular the org.mobicents.ha.javax.sip.BALANCERS - attribute in mss-sip-stack.properties. You should remove the balancers attribute from the Service tag of - jboss.web service. This simply removes the default load balancer from the system and the traffic bypasses the SIP load-balancer. Next you must configure - &SHORT_PLATFORM_NAME; to put the IP load balancer IP address in the Via, Contact and other system headers where - the IP address of the server machine is required. This will ensure that any responses or subsequent SIP requests follow the same path, but always hit - the load balancer instead of particular cluster node that may fail. To specify the IP load balancer address in &SHORT_PLATFORM_NAME; your should edit - this file on Tomcat CATALINA_HOME/conf/server.xml and specify staticServerAddress such as: - <Connector port="5080" - ipAddress = "${jboss.bind.address}" - ... -staticServerAddress="122.122.122.122" staticServerPort="44" -useStaticAddress="true"/> - - and edit this file on JBoss JBOSS_HOME/standalone/configuration/standalone-sip.xml and specify staticServerAddress such as: - <socket-binding name="sip-udp" port="5080" - ... -staticServerAddress="122.122.122.122" staticServerPort="44" -useStaticAddress="true"/> - - - Depending on your reliability requirements you can omit the configuration described in this section and let the servers use their own IP address in the SIP messages. - -
-
-
- SIP Load Balancing Basics - All User Agents send SIP messages, such as INVITE and MESSAGE, to the same SIP URI (the IP address and port number of the SIP Load Balancer on the WAN). The Load Balancer then parses, alters, and forwards those messages to an available node in the cluster. If the message was sent as a part of an existing SIP session, it will be forwarded to the cluster node which processed that User Agent's original transaction request. - - The SIP Server that receives the message acts upon it and sends a response back to the SIP Load Balancer. The SIP Load Balancer reparses, alters and forwards the message back to the original User Agent. This entire proxying and provisioning process is carried out independent of the User Agent, which is only concerned with the SIP service or application it is using. - - By using the Load Balancer, SIP traffic is balanced across a pool of available SIP Servers, increasing the overall throughput of the SIP service or application running on either individual nodes of the cluster. In the case of a &SHORT_PLATFORM_NAME; server with </distributed> capabilities, load balancing advantages are applied across the entire cluster. - - The SIP Load Balancer is also able to failover requests mid-call from unavailable nodes to available ones, thus increasing the reliability of the SIP service or application. The Load Balancer increases throughput and reliability by dynamically provisioning SIP service requests and responses across responsive nodes in a cluster. This enables SIP applications to meet the real-time demand for SIP services. - -
-
- HTTP Load Balancing Basics - In addition to the SIP load balancing, there are several options for coordinated or cooperative load balancing with other protocols such as HTTP. - - Typically, a JBoss Application Server will use apache HTTP server with mod_jk, mod_proxy, mod_cluster or similar extension installed as an HTTP load balancer. This apache-based load balancer will parse incoming HTTP requests and will look for the session ID of those requests in order to ensure all requests from the same session arrive at the same application server. - - By default, this is done by examining the jsessionid HTTP cookie or GET parameter and looking for the jvmRoute assigned to the session. The typical jsessionid value is of the form <sessionId>.<jvmRoute>. The very first request for each new HTTP session does not have a session ID assigned; the apache routes the request to a random application server node. - - When the node responds it assigns a session ID and jvmRoute to the response of the request in a HTTP cookie. This response goes back to the client through apache, which keeps track of which node owns each jvmRoute. Once the very first request is served this way, the subsequent requests from this session will carry the assigned cookie, and the apache load balancer will always route the requests to the node, which advertised itself as the jvmRoute owner. - - Instead of using apache, an integrated HTTP Load Balancer is also available. The SIP Load Balancer has a HTTP port where you can direct all incoming HTTP requests. The integrated HTTP load balancer behaves exactly like apache by default, but this behavior is extensible and can be overridden completely with the pluggable balancer algorithms. The integrated HTTP load balancer is much easier to configure and generally requires no effort, because it reuses most SIP settings and assumes reasonable default values. - - Unlike the native apache, the integrated HTTP Load Balancer is written completely in Java, thus a performance penalty should be expected when using it. However, the integrated HTTP Balancer has an advantage when related SIP and HTTP requests must stick to the same node. - -
-
- Pluggable balancer algorithms - The SIP/HTTP Load Balancer exposes an interface to allow users to customize the routing decision making for special purposes. By default there are three built-in algorithms. Only one algorithm is active at any time and it is specified with the algorithmClass property in the configuration file. - It is up to the algorithm how and whether to support distributed architecture or how to store the information needed for session affinity. The algorithms will be called for every SIP and HTTP request and other significant events to make more informed decisions. - - - Users must be aware that by default requests explicitly addressed to a live server node passing through the load balancer will be forwarded directly to the server node. This allows for pre-specified routing use-cases, where the target node is known by the SIP client through other means. If the target node is dead, then the node selection algorithm is used to route the request to an available node. - - - The following is a list of the built-in algorithms: - - - org.mobicents.tools.sip.balancer.CallIDAffinityBalancerAlgorithm - - This algorithm is not distributable. It selects nodes randomly to serve a give Call-ID extracted from the requests and responses. It keeps a map with Call-ID -> nodeId associations and this map is not shared with other load balancers which will cause them to make different decisions. For HTTP it behaves like apache. - - - - org.mobicents.tools.sip.balancer.HeaderConsistentHashBalancerAlgorithm - - This algorithm is distributable and can be used in distributed load balancer configurations. It extracts the hash value of specific headers from SIP and HTTP messages to decide which application server node will handle the request. Information about the options in this algorithms is available in the balancer configuration file comments. - - - - org.mobicents.tools.sip.balancer.PersistentConsistentHashBalancerAlgorithm - - This algorithm is distributable and is similar to the previous algorithm, but it attempts to keep session affinity even when the cluster nodes are removed or added, which would normally cause hash values to point to different nodes. - - - - org.mobicents.tools.sip.balancer.ClusterSubdomainAffinityAlgorithm - - This algorithm is not distributable, but supports grouping server nodes to act - as a subcluster. Any call of a node that belongs to a cluster group will be preferentially - failed over to a node from the same group. To configure a group you can just add the - subclusterMap property in the load balancer properties and listing - the IP addresses of the nodes. The groups are enclosed in parentheses and the IP - addresses are separate by commas as follows: - subclusterMap=( 192.168.1.1, 192.168.1.2 ) ( 10.10.10.10, 20.20.20.20, 30.30.30.30) - The nodes specified in a group do not have to alive and nodes that are not specified are still allowed to join the cluster. Otherwise the algorthim behaves exactly as the default Call-ID affinity algorthim. - - - -
-
- Distributed load balancing - When the capacity of a single load balancer is exceeded, multiple load balancers can be used. With the help of an IP load balancer the traffic can be distributed between all SIP/HTTP load balancers based on some IP rules or round-robin. With consistent hash and jvmRoute-based balancer algorithms it doesn't matter which SIP/HTTP load balancer will process the request, because they would all make the same decisions based on information in the requests (headers, parameters or cookies) and the list of available nodes. With consistent hash algorithms there is no state to be preserved in the SIP/HTTP balancers. -
- Example deployment: IP load balancers serving both directions for incoming/outgoing requests in a cluster - - - - - -
-
-
- Implementation of the &PLATFORM_NAME; Load Balancer - Each individual &PLATFORM_NAME; SIP Server in the cluster is responsible for contacting the SIP load balancer and relaying its health status and regular "heartbeats". - - From these health status reports and heartbeats, the SIP Load Balancer creates and maintains a list of all available and healthy nodes in the cluster. The Load Balancer forwards SIP requests between these cluster nodes, providing that the provisioning algorithm reports that each node is healthy and is still sending heartbeats. - - If an abnormality is detected, the SIP Load Balancer removes the unhealthy or unresponsive node from the list of available nodes. In addition, mid-session and mid-call messages are failed over to a healthy node. - - The SIP Load Balancer first receives SIP requests from endpoints on a port that is specified in its Configuration Properties configuration file. The SIP Load Balancer, using a round-robin algorithm, then selects a node to which it forwards the SIP requests. The Load Balancer forwards all same-session requests to the first node selected to initiate the session, providing that the node is healthy and available. - -
-
- SIP Message Flow - The SIP Load Balancer appends itself to the Via header of each request, so that returned responses are sent to the SIP Balancer before they are sent to the originating endpoint. - - The Load Balancer also adds itself to the path of subsequent requests by adding Record-Route headers. It can subsequently handle mid-call failover by forwarding requests to a different node in the cluster if the node that originally handled the request fails or becomes unavailable. The SIP load balancer immediately fails over if it receives an unhealthy status, or irregular heartbeats from a node. - - In advanced configurations, it is possible to run more than one SIP Load Balancer. Simply edit the balancers connection string in your SIP Server - the list is separated with semi-colon. - describes a basic IP and Port Cluster Configuration. In the diagram, the SIP Load balancer is the server with the IP address of 192.168.1.1. -
- Basic IP and Port Cluster Configuration - - - - - -
-
-
diff --git a/docs/sources/src/main/resources/en-US/concept-section-SS_MSS_STUN.xml b/docs/sources/src/main/resources/en-US/concept-section-SS_MSS_STUN.xml deleted file mode 100644 index 23475b3ce1..0000000000 --- a/docs/sources/src/main/resources/en-US/concept-section-SS_MSS_STUN.xml +++ /dev/null @@ -1,66 +0,0 @@ - - -%BOOK_ENTITIES; -]> -
- STUN - The Session Traversal Utilities for NAT (STUN) prococol is used in Network Address Translation (NAT) traversal for real-time voice, video, messaging, and related interactive IP application communications. This light-weight, client-server protocol allows applications passing through a NAT to obtain the public IP address for the UDP connections the application uses to connect to remote hosts. - STUN support is provided at the SIP connector level, using the STUN for Java project. The STUN for Java project provides a Java implementation of the STUN Protocol (RFC3489), which allows each SIP connector to select whether it should use STUN to discover a public IP address, and then use this address in the SIP messages sent through the connector. - To make a SIP connector STUN-enabled, three attributes must be appended to the <connector> tag in the server.xml file. The properties are: - - - useStun="true" - Enables STUN support for this connector. Ensure that the ipAddress attribute is not set to 127.0.0.1. - - - stunServerAddress="<public_STUN_Server>" - STUN server address used to discover the public IP address of this SIP Connector. See the table below for a suggested list of public STUN servers. - - - stunServerPort="3478" - STUN server port of the STUN server used in the stunServerAddress attribute. Both TCP and UDP protocols communicate with STUN servers using this port only. - - - - A list of available SIP connector attributes and their descriptions is located in the section of this user guide. - A number of public STUN servers are available, and can be specified in the stunServerAddress. Depending on the router firmware used, the MAPPED_ADDRESS in STUN reply packets may be changed to the router's WAN port as they pass through particular router brands. To alleviate this problem, certain public STUN servers provide XOR_MAPPED_ADDRESS support. A selection of the public STUN servers is provided below. - - - - - - - Server AddressXOR SupportDNS SRV Record - - - stun.ekiga.netYesYes - - - stun.fwdnet.netNoYes - - - stun.ideasip.comNoYes - - - stun01.sipphone.comYesNo - - - stun.softjoys.comNoNo - - - stun.voipbuster.comNoNo - - - stun.voxgratia.orgNoNo - - - stun.xten.comYesYes - - - stunserver.orgYesYes - - - - -
diff --git a/docs/sources/src/main/resources/en-US/concept-section-SS_Media_IPBX.xml b/docs/sources/src/main/resources/en-US/concept-section-SS_Media_IPBX.xml deleted file mode 100644 index 84f390901e..0000000000 --- a/docs/sources/src/main/resources/en-US/concept-section-SS_Media_IPBX.xml +++ /dev/null @@ -1,72 +0,0 @@ - - -%BOOK_ENTITIES; -]> -
- Media IPBX - The Media IPBX provides an extensible and customizable SIP PBX solution, based on the Seam Telco Framework (STF). While the PBX is currently provided as a capability demonstration, the ultimate goal is to transition Media IPBX into a fully-fledged SIP PBX solution. - Media IPBX terminates all calls to &PLATFORM_NAME; Media Server conference endpoints, which provides flexibility in manipulating established calls including server-side conferencing and ring-back tones. The PBX can also be implemented as a Session Border Controller. - - Media IPBX is compatible with &PLATFORM_NAME; SIP Servlets with JBoss AS 4.2.3. Versions prior to this release do not support Media IPBX. - - Media IPBX provides the following major features: - - - User authentication. - - - SIP phone registration. - - - System configuration. - - - Individual user views. - - - Call monitoring and management. - - - Multiple SIP phone instances per user. - - - Status-based SIP phone assignment for incoming calls. - - - Public Switched Telephone Network (PSTN) support, including administrative functions. - - - Support for SIP REGISTER requests to automatically add phones by matching the username, or username and hostname (in 'strict mode' only). - - - Optionally specify local or online sources for announcements and ringback tones. - - - Session Border Controller capability. - - - Full conferencing support, including: - - - Privacy functions, including mute and closed-calls. - - - Call status announcement. - - - Ringback tones when waiting for other participants to join the conference. - - - Joining incoming calls to a conference. - - - Parking calls and isolating a single speaker using dual-tone multi-frequency (DTMF) tones. This feature is currently experimental. - - - - - - Many of the features in Media IPBX are presented to the user as hints on the GUI portal pages. It is recommended that you install Media IPBX and experiment with the demonstration to gain an understanding of how the solution works. - For information about installing and running Media IPBX, including binary and source code locations, visit the Media IPBX homepage. -
diff --git a/docs/sources/src/main/resources/en-US/concept-section-SS_Media_Support.xml b/docs/sources/src/main/resources/en-US/concept-section-SS_Media_Support.xml deleted file mode 100644 index a44acf179f..0000000000 --- a/docs/sources/src/main/resources/en-US/concept-section-SS_Media_Support.xml +++ /dev/null @@ -1,39 +0,0 @@ - - -%BOOK_ENTITIES; -]> -
- Media Support - &PLATFORM_NAME; SIP Servlets provides support for applications to set up - calls through SIP by implementing the SIP Servlets - 1.1 Specification. - As most Telco services have the need for managing and - controlling media (for example, to play announcements, mix calls and recognize - DTMF), &PLATFORM_NAME; SIP Servlets allows applications to control media through JSR 309. -
- JSR 309: Media Server Control API - This specification is a protocol agnostic API for Media Server - Control. It provides a portable interface to create media rich - applications with IVR, Conferencing, Speech Recognition, and similar - features. - &PLATFORM_NAME; Media Server provides an implementation of the JSR 309 specification using the MGCP protocol, to - allow any Media Server (located in the same Virtual Machine or - on a remote server) supporting MGCP to be controlled. - The following examples demonstrate its usage: - - - Media Example : a SIP Servlet application showing how to use media - capabilities (Media playback, Recording, Text to Speech with FreeTTS and DTMF detection). - - - Conference Demo : a Conference Media Server demo application built on GWT - with server-push updates. - - - Shopping Example : a Converged JEE Application showing SEAM - integration, JEE, Media integration with TTS and DTMF support. - - -
-
diff --git a/docs/sources/src/main/resources/en-US/concept-section-SS_SIP_Extensions.xml b/docs/sources/src/main/resources/en-US/concept-section-SS_SIP_Extensions.xml deleted file mode 100644 index ae86fe2ecf..0000000000 --- a/docs/sources/src/main/resources/en-US/concept-section-SS_SIP_Extensions.xml +++ /dev/null @@ -1,157 +0,0 @@ - - -%BOOK_ENTITIES; - -]> -
- SIP and IMS Extensions - SIP Extensions in the SIP Servlets Server are based on the Internet Engineering Task Force's (IETF) Request for Comments (RFC) protocol recommendations. lists the supported RFCs for the SIP Servlets Server. - - Supported SIP Extensions - - - - - - - Extension - RFC Number - Description - - - - - DNSRFC 3263SIP: Locating SIP Servers - - - ENUMRFC 2916E.164 number and DNS - - - INFORFC 2976The SIP INFO Method - - - IPv6RFC 2460Internet Protocol, Version 6 (IPv6) Specification - - - JOINRFC 3911The SIP "Join" Header - - - MESSAGERFC 3428SIP Extension for Instant Messaging - - - PATHRFC 3327SIP Extension Header Field for Registering Non-Adjacent Contacts - - - PRACKRFC 3262Reliability of Provisional Responses in the SIP - - - PUBLISHRFC 3903SIP Extension for Event State Publication - - - REASONRFC 3326The Reason Header Field for the Session Initiation Protocol (SIP) - - - REFERRFC 3515The SIP Refer Method - - - REPLACESRFC 3891The SIP "Replaces" Header - - - STUNRFC 3489STUN - Simple Traversal of User Datagram Protocol (UDP) through Network Address Translators (NATs) - - - SUBSCRIBE/NOTIFYRFC 3265SIP-specific Event Notification - - - Symmetric Response RoutingRFC 3581An Extension to the Session Initiation Protocol (SIP) for Symmetric Response Routing - - - Multipart typeRFC 4662A Session Initiation Protocol (SIP) Event Notification - - - To/From Header Modification RFC 4916Connected Identity in the Session Initiation Protocol (SIP) - - - - - -
- IMS Private Header (P-Header) Extensions are provided according to the recommendations of the 3rd Generation Partnering Project (3GPP) and the IETF. P-Header extensions are primarily used to store information about the networks a call traverses, including security or call charging details. - describes the list of supported P-Headers, including links to the relevant ITEF memorandum where available. - - IMS P-Header Extensions - - - - - - Extension - Description - - - - - AuthorizationHeaderIMSDefines a new auth-param for the Authorization header used in REGISTER requests. - - - PAccessNetworkInfoHeaderContains information regarding the access network the User Agent (UA) uses to connect to the SIP Proxy. The information contained in this header may be sensitive, such as the cell ID, so it is important to secure all SIP application that interface with this header. - - - PAssertedIdentityHeaderContains an identity resulting from an authentication process, derived from a SIP network intermediary. The identity may be based on SIP Digest authentication. - - - PAssertedServiceHeaderContains information used by "trust domains", according to Spec(T) specifications detailed in RFC 3324. - - - PAssociatedURIHeaderContains a list of URIs that are allocated to the user. The header is defined in the 200 OK response to a REGISTER request. It allows the User Agent Client (UAC) to determine the URIs the service provider has associated to the user's address-of-record URI. - - - PathHeaderSIP Extension header, with syntax similar to the RecordRoute header. Used in conjunction with SIP REGISTER requests and 200 class messages in response to REGISTER responses. - - - PCalledPartyIDHeaderTypically inserted en-route into an INVITE request by the proxy, the header is populated with the Request_URI received by the proxy in the request. The header allows the User Agent Server (UAS) to identify which address-of-record the invitation was sent to, and can be used to render distinctive audio-visual alert notes based on the URI. - - - PChargingFunctionAddressesHeaderContains a list of one or more of the Charging Collection Function (CCF) and the Event Charging Function (ECF) addresses. The CCF and ECF addresses may be passed during the establishment of a dialog, or in a standalone transaction. - - - PChargingVectorHeaderContains a unique charging identifier and correlation information, which is used by network operators to correctly charge for routing events through their networks. - - - PMediaAuthorizationHeaderContains one or more session-specific media authorization tokens, which are used for QoS of the media streams. - - - PPreferredIdentityHeaderContains a SIP URI and an optional display-name. For example, "James May" <sip:james@domain.com>. This header is used by trusted proxy servers to identify the user to other trusted proxies, and can be used to select the correct SIP URI in the case of multiple user identities. - - - PPreferredServiceHeaderUsed by the PAssertedService Header to determine the preferred user service. Multiple PPreferreedService headers may be present in a single request. - - - PProfileKeyHeaderContains a key used by a proxy to query the user database for a given profile. The key may contain wildcards that are used as part of the query into the database. - - - PrivacyHeaderContains values that determine whether particular header information is deemed as private by the UA for requests and responses. - - - PServedUserHeaderContains an identity of the user that represents the served user. The header is added to the initial requests for a dialog or standalone request, which are then routed between nodes in a trusted domain. - - - PUserDatabaseHeaderContains the address of the HSS handling the user that generated the request. The header field is added to request routed from an Interrogating Call Session Control Function (I-CSCF) to a Serving Call Session Control Function (S-CSCF). - - - PVisitedNetworkIDHeaderContains the identifier of a visited network. The identifier is a text string or token than it known by both the registrar or the home proxy at the home network, and the proxies in the visited network. - - - SecurityClientHeader, SecurityServerHeader, SecurityVerifyHeaderContains information used to negotiate the security mechanisms between a UAC, and other SIP entities including UAS, proxy and registrar. - - - ServiceRouteHeaderContains a route vector that will direct requests through a specified sequence of proxies. The header may be included by a registrar in response to a REGISTER request. - - - WWWAuthenticateHeaderImsExtends the WWWAuthenticateResponse header functionality by defining an additional authorization parameter (auth-param). - - - -
-
diff --git a/docs/sources/src/main/resources/en-US/concept-section-SS_SIP_Servlet_Security.xml b/docs/sources/src/main/resources/en-US/concept-section-SS_SIP_Servlet_Security.xml deleted file mode 100644 index f59f4e4512..0000000000 --- a/docs/sources/src/main/resources/en-US/concept-section-SS_SIP_Servlet_Security.xml +++ /dev/null @@ -1,246 +0,0 @@ - - -%BOOK_ENTITIES; -]> - -
- SIP Servlets Application Security - - Application security varies depending on the server type used. The - following procedures describe how to configure the JBoss AS7 - and Tomcat servers to enable Security. - - - - - Enable SIP Application Security in JBoss AS7 - - - Add Security Policy to Server Configuraton - - - - Open the configuration file located in $JBOSS_HOME/standalone/configuration/standalone-sip.xml - - - - Append a security domain to the under the <security-domains>: - - - - - - - - - - - - - - -]]> - - - - - - - Create SIP Server User Properties File - - - - Open a terminal and navigate to the $JBOSS_HOME/standalone/configuration directory: - - home]$ cd standalone/configuration - - - - Create and open a sip-servlets-users.properties file and - append the user lines to the file: - - - # A sample users.properties file, this line creates user "admin" with - # password "admin" for "sip-servlets-realm" - admin=<A1_cryptographic_string> - - - - - To create <A1_cryptographic_string>, execute the - following command in a terminal: - - home]$ java -cp ../../modules/system/layers/base/org/picketbox/main/picketbox-4.0.15.Final.jar org.jboss.security.auth.callback.RFC2617Digest admin sip-servlets <password> - - - - Copy the A1 hash, and paste it into the admin parameter in the - previous step. - - - - Save and close sip-servlets-users.properties. - - - - - - Create the SIP Server Roles File - - - - - Create and open sip-servlets-roles.properties (using - your preferred editor) and append the following information to the - file: - - -# A sample roles.properties file for use with some roles -# Each line in this file assigns roles to the users defined in -# sip-servlets-users.properties -admin=caller,role1,role2,.. - - - - - - - Add the Security Domain to the SIP Application - - - - Open the jboss-web.xml file for the SIP - application to which security is required. - - - - Add the <security-domain> element as a - child of the <jboss-web> element: - - - - sip-servlets - -]]> - - - - - - - Add Security Constraints to the SIP Application - - - - Open the sip.xml file for the SIP - application. - - - - Add the <security-domain> element as a - child of the <sip-app> element: - - - - REGISTER Method Security Constraint - - SimpleSipServlet - Require authenticated REGSITER requests - SimpleSipServlet - REGISTER - - - caller - - - - - DIGEST - sip-servlets - ]]> - - - - - - - - - Enable SIP Application Security in Tomcat Server - - - Activate the Memory Realm in Catalina: - - - - Open a terminal and navigate to the /conf - directory: - - home]$ cd server/default/<tomcat_home>/conf/ - - - - Open server.xml and uncomment the following - line: - - <!--<Realm className="org.apache.catalina.realm.MemoryRealm"/>--> - - - - - - Update SIP Server User Properties File - - - - In the /conf directory, open - tomcat-users.xml (using your preferred editor) - and append the following <user> child - element: - - <user name="user" password="password" roles="caller"/> - - - - - - Add Security Constraints to the SIP Application - - - - Open the sip.xml file for the SIP - application to which security is required. - - - - Add the <security-domain> child element - to the <jboss-web> element: - - -<security-constraint> - <display-name>REGISTER Method Security Constraint</display-name> - <resource-collection> - <resource-name>SimpleSipServlet</resource-name> - <description>Require authenticated REGISTER requests</description> - <servlet-name>SimpleSipServlet</servlet-name> - <sip-method>REGISTER</sip-method> - </resource-collection> - <auth-constraint> - <role-name>caller</role-name> - </auth-constraint> -</security-constraint> -<login-config> - <auth-method>DIGEST</auth-method> - <realm-name>sip-servlets-realm</realm-name> -</login-config> - - - - - -
diff --git a/docs/sources/src/main/resources/en-US/concept-section-SS_STUN_Support.xml b/docs/sources/src/main/resources/en-US/concept-section-SS_STUN_Support.xml deleted file mode 100644 index 04aaa5bd66..0000000000 --- a/docs/sources/src/main/resources/en-US/concept-section-SS_STUN_Support.xml +++ /dev/null @@ -1,117 +0,0 @@ - - -%BOOK_ENTITIES; -]> -
- STUN Support - The Session Traversal Utilities for NAT (STUN) prococol is used in - Network Address Translation (NAT) traversal for real-time voice, video, - messaging, and related interactive IP application communications. This - light-weight, client-server protocol allows applications passing through a - NAT to obtain the public IP address for the UDP connections the application - uses to connect to remote hosts. - STUN support is provided at the SIP connector level, using the STUN for Java project. The STUN - for Java project provides a Java implementation of the STUN Protocol (RFC - 3489), which allows each SIP connector to select whether it should use STUN - to discover a public IP address, and then use this address in the SIP messages - sent through the connector. - To make a SIP connector STUN-enabled, three attributes must be - appended to the <connector> child element in the server.xml or <socket-binding> child element in standalone-sip.xml - file. The properties are: - - useStun="true" - Enables STUN support for this connector. Ensure that the - ipAddress attribute is not set to - 127.0.0.1. - - - stunServerAddress="<Public_STUN_Server>" - STUN server address used to discover the public IP address of - this SIP Connector. See for a suggested list of public - STUN servers. - - - stunServerPort="3478" - STUN server port of the STUN server used in the - stunServerAddress attribute. Both TCP and UDP - protocols communicate with STUN servers using this port only. - - - - A complete list of available SIP connector attributes and their - descriptions is located in the - section of this guide. - - A number of public STUN servers are available, and can be specified in - the stunServerAddress. Depending on the router firmware used, the STUN reply - packets' MAPPED_ADDRESS may be changed to the router's WAN port. To - alleviate this problem, certain public STUN servers provide - XOR_MAPPED_ADDRESS support. - provides a selection of public STUN servers. - - Public STUN Servers - - - - - - - Server Address - XOR Support - DNS SRV Record - - - - - stun.ekiga.net - Yes - Yes - - - stun.fwdnet.net - No - Yes - - - stun.ideasip.com - No - Yes - - - stun01.sipphone.com - Yes - No - - - stun.softjoys.com - No - No - - - stun.voipbuster.com - No - No - - - stun.voxgratia.org - No - No - - - stun.xten.com - Yes - Yes - - - stunserver.org - Yes - Yes - - - -
- - For more information about NAT traversal best practices, refer to . - -
diff --git a/docs/sources/src/main/resources/en-US/concept-section-SS_Seam_Telco_Framework.xml b/docs/sources/src/main/resources/en-US/concept-section-SS_Seam_Telco_Framework.xml deleted file mode 100644 index a3e848e248..0000000000 --- a/docs/sources/src/main/resources/en-US/concept-section-SS_Seam_Telco_Framework.xml +++ /dev/null @@ -1,36 +0,0 @@ - - -%BOOK_ENTITIES; -]> -
- Seam Telco Framework - The Seam Telco Framework (STF) is a telecommunications application framework based on the JSR-289 specification, and JBoss Seam. The framework plugs the SIP Servlets 1.1 stack into new or existing JBoss Seam applications. Media is achieved through JSR-309. This allows Seam components to implement both the Web and telecommunication logic of the applications. - The primary goals of the STF are to: - - Unify Web, SIP, and media telecommunication applications. - Allow complex enterprise applications to be built using the same programming model. - Keep logical associations between SIP, Media and Web sessions. - - From an integration perspective, JBoss Seam provides access to different frameworks. These frameworks are made available to the telecommunication-specific applications for a particular role using the same context. - - - The STF manages SipServletRequests and Media Server events, while utilizing existing JBoss Seam framework benefits, including: - - - Bijection - Inversion of Control (IoC) - Interceptors - Scoping - Transaction management - - Other advantages associated with the STF include: - - Enterprise Java Beans (EJB) and Plain Old Java Objects (POJO) support. - Loosely-coupled, asynchronous telecommunication component support. - Web-layer interaction support. - Synchronous and asynchronous light-weight message passing using @Observer-annotated methods. - Integration with existing Seam IDE tools and infrastructure syntax. - - More information about the STF can be found on the STF homepage. For information about JBoss Seam, refer to the community documentation. -
diff --git a/docs/sources/src/main/resources/en-US/concept-section-SS_TLS.xml b/docs/sources/src/main/resources/en-US/concept-section-SS_TLS.xml deleted file mode 100644 index c0620a9019..0000000000 --- a/docs/sources/src/main/resources/en-US/concept-section-SS_TLS.xml +++ /dev/null @@ -1,353 +0,0 @@ - - -%BOOK_ENTITIES; -]> - -
- TLS - - In order to configure TLS you will have to obtain a public/private key, a X.509 certificate, - add those to the Java keystore and optionally add certificates from a known CA (certicate - authority). The entire process can be confusing but in order to get a basic setup for - testing purposes up and running with minimal effort, this section starts off with a simple - quick start. However, for production environment you need to obtain an officially signed - certificate from a known CA and that process is outlined in section Production Setup. - - -
- Quick Start - - This section shows how to create a self signed certificate, how to - add that to the Java keystore and how to configure the SIP Servlet - Container to make use of this configuration. Note, this section should - only be used in a development environment and the main reason for this - quickstart section is to get you going right away as well as get you - comfortable with generating keys and certificates and adding them to the - Java keystore. - - - Server Side Authentication - - At a high-level, we will execute the following three steps: - - Generate a public/private key pair and a self signed certificate and - add those to the Java keystore. - - - Configure the SIP Servlet Container to load our certificate from the - keystore. - - - Test! - - - - - - Generate certificate - Generating a new key-pair and a certificate can be done in a few different ways with a - few different tools but here we will just use the java keytool that comes with the JDK. - Simple issue the following command, which will generate a new public and private key, - generate a self-signed certificate and add it all to the Java keystore: - - keytool -genkeypair -alias myserver -keyalg RSA -keysize 1024 -keypass secret -validity 365 -storetype jks -keystore myserver.jks -storepass secret -v -dname "CN=James Smith, OU=Engineering, O=My Company, L=My City, S=My State, C=US" - - -keystore specifies which keystore we should use/update. If the keystore doesn't - exist, a new one will be created for one. In the above example, we named the keystore - myserver.jks and it will be saved in the current directory - - - -keypass and -storepass should be chosen wisely since with bad passwords you won't - have much protection anyway. Also, normally you should never passwords on the - command prompt, it is too easy for other people to steal. If you leave these two - options out, the keytool command will ask you for it. - - -keyalg specifies which algorithm to use when generating the keys and the keysize - how long those keys should be. - - Note: the command -genkeypair is new in JDK 6 and was previously named -genkey. The - keytool in JDK 6 has some improvements over the previous versions so it is - recommended to use it instead. - - See more about the Java keytool here: http://docs.oracle.com/javase/6/docs/technotes/tools/solaris/keytool.html - - - - Configure the SIP Servlet Container - The SIP Servlet Container relies on the JAIN SIP stack to support it with TLS - capabilities. As such, it is the JAIN SIP stack that we need to configure to - have it read our certificate we added to the key store. The various - configuration options are described in the javadoc of the SipStackImpl - class but for this quickstart, we will be using the following ones: - - - - javax.net.ssl.keyStore – the filename and location of the keystore to use. - javax.net.ssl.keyStorePassword – the password to the keystore. - javax.net.ssl.trustStore – the filename and location of the truststore to use. - javax.net.ssl.trustStorePassword – the password to the truststore. - gov.nist.javax.sip.TLS_CLIENT_AUTH_TYPE – which type of authentication we will require of the - client (for now, the client authentication type will be set to Disabled). - - - - The configuration options are JVM parameters and you will have to add these to the - command line when you start the server: - ./bin/run.sh -Djavax.net.ssl.keyStorePassword=mysecret -Dgov.nist.javax.sip.TLS_CLIENT_AUTH_TYPE=Disabled -Djavax.net.ssl.keyStore=/path/to/your/keystore/myserver.jks -Djavax.net.ssl.trustStorePassword=mysecret -Djavax.net.ssl.trustStore=/path/to/your/keystore/myserver.jks - - - Once the server is up, we are ready to verify that we can get a TLS connection using the - certificate we previously added in the first step. - - Note: for this first part of the quickstart we will not require a certificate from the - client since this involves more configuration. This is controlled by the - gov.nist.javax.sip.TLS_CLIENT_AUTH_TYPE parameter. - - - - - Test! - To verify your setup there are a few different tools that you can use. - - openssl is an open source SSL toolkit and contains a generic SSL/TLS test - client - - - SIPp – an open source SIP load testing tool that is capable of using TLS. - However, it requires some additional steps that we have not addressed in the first - parf of this quickstart so therefore we willl not be using SIPp. - - - Using your favorite SIP client. Most SIP clients out there are capable of - establishing a TLS connection but you will have to consult its documentation of how - to configure TLS. - - - - Using openssl: - - Assuming that your server is running on localhost and is listening for TLS on port 5081 - the command would be: - openssl s_client -host 127.0.0.1 -port 5081 - - - If you are successful you should see an output from openssl displaying information about - the server certificate (which should be the one we generated in Step 1). If there are any - issues with the setup, openssl is pretty good about giving out information about what it - thinks is wrong. - - Tip: if you add the following JVM parameter as well you will get a lot of useful debug - information: -Djavax.net.debug=ssl - - - - - Server Side Authentication - - In the first part of this quickstart we generated a public and private key along with a - self-signed certificate and added them all into the Java keystore. The server was then - configured to use this information and when a client connected, our certificate was served - up to the client. However, normally, the client and the server would like to verify each - others certificate to make sure they both trust each other and if not, either of them will - terminate the connection. In the first part of the quickstart, the server did not require - the client to present a certificate when connecting (remember that we set the gov.nist.javax.sip.TLS_CLIENT_AUTH_TYPE to disabled) so let's do - that now. - - At a high-level, these are the tasks we need to execute: - - Generate a public/private key pair for the client along with a - certificate. - - - The server need to add the client certificate to its keystore as a - trusted certificate. - - - Start the server with client authenticating enabled. - - - - - - Generate Client Certificate - We will use the Java keytool for this step in the same we did for for the server side - in the previous quikstart. The command is exactly the same and the only - difference is that we store the information in a new keystore called - myclient.jks. - keytool -genkeypair -alias myclient -keyalg RSA -keysize 1024 -keypass secret -validity 365 -storetype jks -keystore myclient.jks -storepass secret -v -dname "CN=John Doe, OU=Engineering, O=Some Work, L=Some City, S=Some State, C=US" - We have now generated a new keystore containing the clients authentication - information. However, the server needs to import the client certificate into its - trusted keystore so we need to extract the certificate out of the client key - store. This can also be done using the Java keytool. - keytool -exportcert -alias myclient -file client.cert -keystore myclient.jks -storepass secret -rfcThe - certificate is saved in file 'client.cert' and we will use this file in the next - step. - - - - Re-configure the server - Simply change the gov.nist.javax.sip.TLS_CLIENT_AUTH_TYPE from 'Disabled' to 'Enabled' and start the server again. - - - - Test - We will once again use openssl to verify our setup but now that the client - will be forced to present a certificate as well, we do need the certificate's - private key as well. The private key is embedded into the keystore and was - generated when we issued the 'kenkeypair' keytool-command. Unfortunately, the - keytool does not have an option for exporting the private key so we will have to - write a small java program to extract it for us. Luckily, it is not a lot of - code: - import java.io.FileInputStream; - import java.security.Key; - import java.security.KeyStore; - import sun.misc.BASE64Encoder; - - /** - * Code originally posted on Sun's developer forums but - * can now only be found at stackoverflow: - * http://stackoverflow.com/questions/150167/how-do-i-list-export-private-keys-from-a-keystore - */ - public class DumpPrivateKey { - - static public void main(String[] args) - throws Exception { - if(args.length < 3) { - throw new IllegalArgumentException("expected args: Keystore filename, Keystore password, alias, <key password: default same than keystore"); - } - final String keystoreName = args[0]; - final String keystorePassword = args[1]; - final String alias = args[2]; - final String keyPassword = getKeyPassword(args,keystorePassword); - KeyStore ks = KeyStore.getInstance("jks"); - ks.load(new FileInputStream(keystoreName), keystorePassword.toCharArray()); - Key key = ks.getKey(alias, keyPassword.toCharArray()); - String b64 = new BASE64Encoder().encode(key.getEncoded()); - System.out.println("-----BEGIN PRIVATE KEY-----"); - System.out.println(b64); - System.out.println("-----END PRIVATE KEY-----"); - } - - private static String getKeyPassword(final String[] args, final String keystorePassword) - { - String keyPassword = keystorePassword; // default case - if(args.length == 4) { - keyPassword = args[3]; - } - return keyPassword; - } - } - - Copy and paste the above code into a file call DumpPrivateKey.java and then compile it: - - javac DumpPrivateKey.java - and then use it to extract the private key: - java DumpPrivateKey myclient.jks secret myclient > clientprivate.key - -Now that we have the private key of the client we can use openssl to verify the setup again: - - openssl s_client -host 127.0.0.1 -port 5081 -cert client.cert -certform PEM -key clientprivate.key - -If all goes well you should successfully establish a connection and openssl will dump - information about the certificate exchange. - - -
- -
- Production Setup - In a production environment it is important that you run with an officially signed - certificate from a known CA. It is this certificate that you will load into your - keystore and the process is very similar to the one outlined in the quick start. - - - Generate a PKCS#12 Storage - Assuming that you already have a private key and a signed certificate from a known CA - you first have to wrap these two into a pkcs#12 storage (pkcs#12 is a file format - for storing X.509 public certificates along with the private key), and then load - that into the Java keystore. To create a pkcs#12 storage you can use the openssl pkcs12 command: - - openssl pkcs12 -inkey myprivate.key -in mycertificate.pem -export -out mystorage.pkcs12 -passout mysecret - - where myprivate.key is the private key, mycertificate.pem is the X.509 - certificate. The password for the storage is 'mysecret' and the name of the - storage file is mystorage.pkcs12. - - - - Generate the Java Keystore - - Once the pkcs#12 has been created, use the Java keytool to load the pkcs12 storage - and convert it into a java keystore. - - keytool -importkeystore -srckeystore mystorage.pkcs12 -srcstoretype PKCS12 -destkeystore myserver.jks -deststorepass mysecret -srcstorepass mysecret - - A few things to point out: - - - -srcstoretype is important and tells the Java keytool which format the key store that we are importing is in. In the previous step, we generated a pkcs#12 store so in this example, the store type must be PKCS12. - - - - -srcstorepass is the password for the pkcs#12 storage and in the above example it is the same as the destination key store (-deststorepass) but most likely they will be different. - - - - - Re-configure and Test - Now that we have a java keystore the server configuration is exactly the same as - described in the quick start, i.e., simply set the java properties - javax.net.ssl.keyStore and javax.net.ssl.trustStore to point to this key keystore file and then set the - password through the property javax.net.ssl.keyStorePassword and javax.net.ssl.trustStorePassword. Once the server - has been re-started you can use openssl to verify the setup. - - - -
- - -
- Production Setup - In addition to securing your SIP TLS, you may want to secure your HTTPS and SIP Over WebSockets Connectors too. - - - Secure HTTPS on JBoss 7/EAP 6 - Assuming that you already followed the previous steps, you now have a private key and a self signed certificate. - You will need to configure your $JBOSS_HOME/standalone/configuration/standalone-sip.xml to enable HTTPS connector: - - - <subsystem xmlns="urn:jboss:domain:web:1.4" default-virtual-server="default-host" native="false"> - <connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http"/> - <connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" secure="true"> - <ssl protocol="TLSv1,TLSv1.1,TLSv1.2" certificate-key-file="/path/to/myserver.jks" certificate-file="/path/to/myserver.jks" password="secret"/> - </connector> - - - - - Add SIP Over WebSockets Secure Connector - - Make sure the following connector is present in $JBOSS_HOME/standalone/configuration/standalone-sip.xml - <connector name="sip-wss" protocol="SIP/2.0" scheme="sip" socket-binding="sip-wss"/> - Make sure the following socket-binding is present in $JBOSS_HOME/standalone/configuration/standalone-sip.xml - <socket-binding name="sip-wss" port="5083"/>. - - - - For self-signed certificates, import the pkcs file to your Browser - To make that the WebSockets connection is not refused with a self-signed certificate, - you need to import the pkcs file generated in 7.2.2 to Google Chrome (Settings => Show Advanced Settings => Manage Certificates Button, then import your - mystorage.pkcs12 file) or Firefox. - - - - Test! - Go to your WebRTC favorite example through https://localhost:8443/webrtc/, and use wss://localhost:5083 to connect over Secure SIP Over WebSockets. - - -
- - -
\ No newline at end of file diff --git a/docs/sources/src/main/resources/en-US/concept-section-SS_TLS2.xml b/docs/sources/src/main/resources/en-US/concept-section-SS_TLS2.xml deleted file mode 100644 index 09d406d96a..0000000000 --- a/docs/sources/src/main/resources/en-US/concept-section-SS_TLS2.xml +++ /dev/null @@ -1,197 +0,0 @@ - - -%BOOK_ENTITIES; -]> - -
- TLS - - In order to configure TLS you will have to obtain a public/private key, a X.509 certificate, - add those to the Java keystore and optionally add certificates from a known CA (certicate - authority). The entire process can be confusing but in order to get a basic setup for - testing purposes up and running with minimal effort, this section starts off with a simple - quick start. However, for production environment you need to obtain an officially signed - certificate from a known CA and that process is outlined in section Production Setup. - - -
- Quick Start - - This section shows how to create a self signed certificate, how to - add that to the Java keystore and how to configure the SIP Servlet - Container to make use of this configuration. Note, this section should - only be used in a development environment and the main reason for this - quickstart section is to get you going right away as well as get you - comfortable with generating keys and certificates and adding them to the - Java keystore. - - - - Server Side Authentication - - In the first part of this quickstart we generated a public and private key along with a - self-signed certificate and added them all into the Java keystore. The server was then - configured to use this information and when a client connected, our certificate was served - up to the client. However, normally, the client and the server would like to verify each - others certificate to make sure they both trust each other and if not, either of them will - terminate the connection. In the first part of the quickstart, the server did not require - the client to present a certificate when connecting (remember that we set the gov.nist.javax.sip.TLS_CLIENT_AUTH_TYPE to disabled) so let's do - that now. - - At a high-level, these are the tasks we need to execute: - - Generate a public/private key pair for the client along with a - certificate. - - - The server need to add the client certificate to its keystore as a - trusted certificate. - - - Start the server with client authenticating enabled. - - - - - - Generate Client Certificate - We will use the Java keytool for this step in the same we did for for the server side - in the previous quikstart. The command is exactly the same and the only - difference is that we store the information in a new keystore called - myclient.jks. - keytool -genkeypair -alias myclient -keyalg RSA -keysize 1024 -keypass secret -validity 365 -storetype jks -keystore myclient.jks -storepass secret -v -dname "CN=John Doe, OU=Engineering, O=Some Work, L=Some City, S=Some State, C=US" - We have now generated a new keystore containing the clients authentication - information. However, the server needs to import the client certificate into its - trusted keystore so we need to extract the certificate out of the client key - store. This can also be done using the Java keytool. - keytool -exportcert -alias myclient -file client.cert -keystore myclient.jks -storepass secret -rfcThe - certificate is saved in file 'client.cert' and we will use this file in the next - step. - - - - Re-configure the server - Simply change the gov.nist.javax.sip.TLS_CLIENT_AUTH_TYPE from 'Disabled' to 'Enabled' and start the server again. - - - - Test - We will once again use openssl to verify our setup but now that the client - will be forced to present a certificate as well, we do need the certificate's - private key as well. The private key is embedded into the keystore and was - generated when we issued the 'kenkeypair' keytool-command. Unfortunately, the - keytool does not have an option for exporting the private key so we will have to - write a small java program to extract it for us. Luckily, it is not a lot of - code: - import java.io.FileInputStream; - import java.security.Key; - import java.security.KeyStore; - import sun.misc.BASE64Encoder; - - /** - * Code originally posted on Sun's developer forums but - * can now only be found at stackoverflow: - * http://stackoverflow.com/questions/150167/how-do-i-list-export-private-keys-from-a-keystore - */ - public class DumpPrivateKey { - - static public void main(String[] args) - throws Exception { - if(args.length < 3) { - throw new IllegalArgumentException("expected args: Keystore filename, Keystore password, alias, <key password: default same than keystore"); - } - final String keystoreName = args[0]; - final String keystorePassword = args[1]; - final String alias = args[2]; - final String keyPassword = getKeyPassword(args,keystorePassword); - KeyStore ks = KeyStore.getInstance("jks"); - ks.load(new FileInputStream(keystoreName), keystorePassword.toCharArray()); - Key key = ks.getKey(alias, keyPassword.toCharArray()); - String b64 = new BASE64Encoder().encode(key.getEncoded()); - System.out.println("-----BEGIN PRIVATE KEY-----"); - System.out.println(b64); - System.out.println("-----END PRIVATE KEY-----"); - } - - private static String getKeyPassword(final String[] args, final String keystorePassword) - { - String keyPassword = keystorePassword; // default case - if(args.length == 4) { - keyPassword = args[3]; - } - return keyPassword; - } - } - - Copy and paste the above code into a file call DumpPrivateKey.java and then compile it: - - javac DumpPrivateKey.java - and then use it to extract the private key: - java DumpPrivateKey myclient.jks secret myclient > clientprivate.key - -Now that we have the private key of the client we can use openssl to verify the setup again: - - openssl s_client -host 127.0.0.1 -port 5081 -cert client.cert -certform PEM -key clientprivate.key - -If all goes well you should successfully establish a connection and openssl will dump - information about the certificate exchange. - - -
- -
- Production Setup - In a production environment it is important that you run with an officially signed - certificate from a known CA. It is this certificate that you will load into your - keystore and the process is very similar to the one outlined in the quick start. - - - Generate a PKCS#12 Storage - Assuming that you already have a private key and a signed certificate from a known CA - you first have to wrap these two into a pkcs#12 storage (pkcs#12 is a file format - for storing X.509 public certificates along with the private key), and then load - that into the Java keystore. To create a pkcs#12 storage you can use the openssl pkcs12 command: - - openssl pkcs12 -inkey myprivate.key -in mycertificate.pem -export -out mystorage.pkcs12 -passout mysecret - - where myprivate.key is the private key, mycertificate.pem is the X.509 - certificate. The password for the storage is 'mysecret' and the name of the - storage file is mystorage.pkcs12. - - - - Generate the Java Keystore - - Once the pkcs#12 has been created, use the Java keytool to load the pkcs12 storage - and convert it into a java keystore. - - keytool -importkeystore -srckeystore mystorage.pkcs12 -srcstoretype PKCS12 -destkeystore myserver.jks -deststorepass mysecret -srcstorepass mysecret - - A few things to point out: - - - -srcstoretype is important and tells the Java keytool which format the key store that we are importing is in. In the previous step, we generated a pkcs#12 store so in this example, the store type must be PKCS12. - - - - -srcstorepass is the password for the pkcs#12 storage and in the above example it is the same as the destination key store (-deststorepass) but most likely they will be different. - - - - - Re-configure and Test - Now that we have a java keystore the server configuration is exactly the same as - described in the quick start, i.e., simply set the java properties - javax.net.ssl.keyStore and javax.net.ssl.trustStore to point to this key keystore file and then set the - password through the property javax.net.ssl.keyStorePassword and javax.net.ssl.trustStorePassword. Once the server - has been re-started you can use openssl to verify the setup. - - - -
- - - -
diff --git a/docs/sources/src/main/resources/en-US/concept-section-SS_for_JBoss-Clustering_Support.xml b/docs/sources/src/main/resources/en-US/concept-section-SS_for_JBoss-Clustering_Support.xml deleted file mode 100644 index c42abfe039..0000000000 --- a/docs/sources/src/main/resources/en-US/concept-section-SS_for_JBoss-Clustering_Support.xml +++ /dev/null @@ -1,346 +0,0 @@ - - -%BOOK_ENTITIES; -]> - -
- Understanding &PLATFORM_NAME; High Availabilty - - -High Availability in &SHORT_PLATFORM_NAME; for JBoss AS7 - -Clustering and Failover features as described below are not yet implemented in &SHORT_PLATFORM_NAME; for JBoss AS7. This guide will be updated when the feature becomes available. - - - - - - - High Availability - - -Is a term used to describe software and hardware based strategies that are implemented to ensure optimal performance and continuous system operation in case of failure. High availability encompasses, clustering, failover and load balancing - - - - - Clustering - -Is a technique used to ensure continuous service availability by having two or more servers communicate with each other and share configuration and application data (replication) on fixed, predetermined intervals. This produces two or more application servers with identical setup. There is often a primary server within a clustered cloud from which data is replicated to the secondary. The application servers within a clustered environment will use what is called a heartbeat to ensure that all servers within are alive and functioning. In the case of failure, another server (secondary) will take over the task of responding to client's requests without impacting user experience. In some clustered ecosystem, load balancing is used as explained below. - - - - Load Balancing - -This is ultimately about performance. All request from clients are evenly distributed by the (load balancer) to multiple application servers that are running similar configurations.This type of setup often includes fault tolerance or failover. When one of the nodes, application server instance is not available, all traffic will be directed to the remaining servers. This ensures continuity albeit performance can degrade. Load balancing allows a single point of entry for multiple clients. - - - - Failover - - -Failover is a way to provide continuous service to clients connecting to an application server in case of system, software or hardware failure. Connections to an unresponsive server is directed (failed over) to a backup server. This is often done within the scope of a clustered configuration aided by a load balancer. - - - -It is important to note that clustering is also a way to provide failover and enhance server performance. The same can be said of load balancing. The idea behind all the above mentioned techniques is to provide high availability to connecting clients connecting to applications running on &PLATFORM_NAME;. In a nutshell, high availability englobes all the above mentioned techniques. - - - -
diff --git a/docs/sources/src/main/resources/en-US/concept-section-SS_for_JBoss-Failover_Support.xml b/docs/sources/src/main/resources/en-US/concept-section-SS_for_JBoss-Failover_Support.xml deleted file mode 100644 index b4e2603069..0000000000 --- a/docs/sources/src/main/resources/en-US/concept-section-SS_for_JBoss-Failover_Support.xml +++ /dev/null @@ -1,173 +0,0 @@ - - -%BOOK_ENTITIES; -]> -
- &PLATFORM_NAME; SIP Servlets for JBoss: Transparent Failover - A &PLATFORM_NAME; SIP Servlets Server for JBoss cluster does not employ any standby nodes. - Typically, proxies and registrars must share the user location table by using a database cluster. - The &PLATFORM_NAME; SIP Load Balancer, which is a SIP Call ID-aware load balancer, is used as the intermediary. - The SIP Load Balancer forwards stateful transaction requests to cluster nodes based on its provisioning algorithm. - The SIP Load Balancer acts as an entry-point to the cluster, and distributes the incoming requests between nodes. - It is always advised to use a SIP load balancer or an IP load balancer in a cluster configuration. - This choice of implementation has many benefits: - - - There is no need for standby nodes, because the remaining nodes in a degraded cluster automatically and transparently (to the user) take on the load of the failed node. This can be done because both the SIP Load Balancer and SIP Servlet-enabled JBoss Application Servers support mid-call or call setup failover (respectively Established SIP Dialog and Early SIP Dialog). - - - There is no need to ensure that requests are directed to the correct node, because in a SIP Servlets-enabled JBoss Application Server (or &PLATFORM_NAME; JAIN SLEE server) cluster, any node can serve any request to any User Agent (UA). - - - All hardware is in use, reducing costs. - - - Maintenance is easier, due to all nodes having nearly-identical configurations. - - - -
- &PLATFORM_NAME; Failover Capabilities - The SIP Stack used by the &PLATFORM_NAME; SIP Servlets for JBoss supports two modes: - - - ESTABLISHED SIP DIALOG failover. This means that failover can occur only on established calls (SIP Dialogs which are in the CONFIRMED state as per RFC 3261) and calls that are in the process of being setup will not be failed over (SIP Dialogs which are in the EARLY state as per RFC 3261). -
- Established Dialog Failover - - - - - -
- This is the default configuration. - - Optimization Note - - To maximize performance it is recommended to use a load balancer with SIP affinity enabled, so that all messages related to the same call go to the same node even though &PLATFORM_NAME; Sip Servlets supports the case where SIP transactions for a given SIP Dialog go to different nodes. - - -
- - EARLY SIP DIALOG failover. This means that failover can occur after an informational response (1xx) is received with a To Tag. For example, calls that are in the process of being setup will be failed over (SIP Dialogs which are in the EARLY state as per RFC 3261). -
- Early Dialog Failover - - - - - -
- - As Early Dialog failover means replicating some transaction states, it can introduce some overhead in terms of network replication as well. The failover granularity is configurable to best fit applications on their usage and optimize the performance. The following property, org.mobicents.ha.javax.sip.REPLICATION_STRATEGY=EarlyDialog, needs to be added to the SIP Stack Stack properties, defined in the external properties file specified by the sipStackPropertiesFile attribute as described in . - - - Optimization Note - - To maximize performance it is recommended to use a Load Balancer with SIP affinity enabled so that all messages related to the same SIP transaction (and even SIP call) go to the same node even though &PLATFORM_NAME; Sip Servlets supports the case where SIP transactions for a given SIP Dialog go to different nodes. - - -
-
-
-
- &SHORT_PLATFORM_NAME; for JBoss Cluster: Installing, Configuring and Running - There are a number of options you can specify for &SHORT_PLATFORM_NAME; clustering. By default, most of them are configured in the "all" server configuration, which is ready to use. In this chapter we will cover the most common configuration options you might need. -
- Downloading -   -
-
- Installing -   -
-
- Configuring -   -
-
- Running -   -
-
- Using -   -
-
- Testing -   -
-
- Uninstalling -   -
-
-
diff --git a/docs/sources/src/main/resources/en-US/concept-section-Working_with_the_SIP_Servlets_Management_Console.xml b/docs/sources/src/main/resources/en-US/concept-section-Working_with_the_SIP_Servlets_Management_Console.xml deleted file mode 100644 index 1480df5a92..0000000000 --- a/docs/sources/src/main/resources/en-US/concept-section-Working_with_the_SIP_Servlets_Management_Console.xml +++ /dev/null @@ -1,52 +0,0 @@ - - -%BOOK_ENTITIES; -]> -
- Working with the SIP Servlets Management Console - Once installed, the &SHORT_PLATFORM_NAME; for JBoss or &SHORT_PLATFORM_NAME; for Tomcat instance can be accessed and configured using the SIP Servlets Management Console. The management console is available at . -
- The SIP Servlets Management Console - - - - - -
- Information on how to use the SIP Servlets Management Console is available from the Help link on the top main menu bar. Clicking Help displays a Default Application Router Help pop-up that can be repositioned and resized by dragging. -
- SIP Servlets Management Console: Default Application Router Help - - - - - -
- Recent versions of the SIP Servlets Management Console feature a Server Settings tab, in which concurrency and congestion control settings can be tuned. -
- Tunable SIP Servlets Server Settings - - - - - -
- For more information on concurrency and congestion control tuning, refer to . -
diff --git a/docs/sources/src/main/resources/en-US/images/CDI_Telco_Framework_Extension.png b/docs/sources/src/main/resources/en-US/images/CDI_Telco_Framework_Extension.png deleted file mode 100644 index e1553b6509..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/CDI_Telco_Framework_Extension.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/MMS.bmp b/docs/sources/src/main/resources/en-US/images/MMS.bmp deleted file mode 100644 index 4dff281408..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/MMS.bmp and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/admin-console-AS7-homepage.png b/docs/sources/src/main/resources/en-US/images/admin-console-AS7-homepage.png deleted file mode 100644 index f33e66f5a0..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/admin-console-AS7-homepage.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/admin-console-error-page.png b/docs/sources/src/main/resources/en-US/images/admin-console-error-page.png deleted file mode 100644 index 383029571d..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/admin-console-error-page.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/bidirectional-distributed-sip-lb.gif b/docs/sources/src/main/resources/en-US/images/bidirectional-distributed-sip-lb.gif deleted file mode 100644 index a3fb51ad63..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/bidirectional-distributed-sip-lb.gif and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/click2call-JbossAS7-registered-clients.png b/docs/sources/src/main/resources/en-US/images/click2call-JbossAS7-registered-clients.png deleted file mode 100644 index e0d86acb3d..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/click2call-JbossAS7-registered-clients.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/click2call-tomcat-AS7-application.png b/docs/sources/src/main/resources/en-US/images/click2call-tomcat-AS7-application.png deleted file mode 100644 index 4ecdcb853f..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/click2call-tomcat-AS7-application.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/click2call_3cxphone_contact_user_detail.png b/docs/sources/src/main/resources/en-US/images/click2call_3cxphone_contact_user_detail.png deleted file mode 100644 index 09a98109f5..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/click2call_3cxphone_contact_user_detail.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/click2call_3cxphone_softphone_configuration.png b/docs/sources/src/main/resources/en-US/images/click2call_3cxphone_softphone_configuration.png deleted file mode 100644 index 3ca145d98e..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/click2call_3cxphone_softphone_configuration.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/click2call_3cxphone_softphone_profile.png b/docs/sources/src/main/resources/en-US/images/click2call_3cxphone_softphone_profile.png deleted file mode 100644 index 09aab147c5..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/click2call_3cxphone_softphone_profile.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/click2call_changing_tomcat_http_default_port.png b/docs/sources/src/main/resources/en-US/images/click2call_changing_tomcat_http_default_port.png deleted file mode 100644 index f1fd3138ef..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/click2call_changing_tomcat_http_default_port.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/click2call_content_mss_tomcat_directory.png b/docs/sources/src/main/resources/en-US/images/click2call_content_mss_tomcat_directory.png deleted file mode 100644 index cd66268956..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/click2call_content_mss_tomcat_directory.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/click2call_download_latest_version_tomcat.png b/docs/sources/src/main/resources/en-US/images/click2call_download_latest_version_tomcat.png deleted file mode 100644 index 4857dcc919..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/click2call_download_latest_version_tomcat.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/click2call_install_mobicents_tomcat_windows.png b/docs/sources/src/main/resources/en-US/images/click2call_install_mobicents_tomcat_windows.png deleted file mode 100644 index e6bb6c01a2..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/click2call_install_mobicents_tomcat_windows.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/click2call_jdk_download_executable.png b/docs/sources/src/main/resources/en-US/images/click2call_jdk_download_executable.png deleted file mode 100644 index c86aa7c9f0..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/click2call_jdk_download_executable.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/click2call_localhost_http_homepage.png b/docs/sources/src/main/resources/en-US/images/click2call_localhost_http_homepage.png deleted file mode 100644 index 4b31e95128..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/click2call_localhost_http_homepage.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/click2call_mobicents_sip_servlets_registered_clients.png b/docs/sources/src/main/resources/en-US/images/click2call_mobicents_sip_servlets_registered_clients.png deleted file mode 100644 index 50e484aeaf..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/click2call_mobicents_sip_servlets_registered_clients.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/click2call_mss_tomcat_server_started.png b/docs/sources/src/main/resources/en-US/images/click2call_mss_tomcat_server_started.png deleted file mode 100644 index 34338b9a78..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/click2call_mss_tomcat_server_started.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/click2call_set_env_variable_windows.png b/docs/sources/src/main/resources/en-US/images/click2call_set_env_variable_windows.png deleted file mode 100644 index e76d24981e..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/click2call_set_env_variable_windows.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/click2call_sip_servlets_sample_application.png b/docs/sources/src/main/resources/en-US/images/click2call_sip_servlets_sample_application.png deleted file mode 100644 index 03f0745408..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/click2call_sip_servlets_sample_application.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/click2call_starting_tomcat_server.png b/docs/sources/src/main/resources/en-US/images/click2call_starting_tomcat_server.png deleted file mode 100644 index cbfe4eff7c..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/click2call_starting_tomcat_server.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/click2call_updated_tomcat_http_port.png b/docs/sources/src/main/resources/en-US/images/click2call_updated_tomcat_http_port.png deleted file mode 100644 index eeb264bda7..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/click2call_updated_tomcat_http_port.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/click2call_wengo_softphone_configuration.png b/docs/sources/src/main/resources/en-US/images/click2call_wengo_softphone_configuration.png deleted file mode 100644 index bfbf227919..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/click2call_wengo_softphone_configuration.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/click2call_wengo_softphone_user_contact.png b/docs/sources/src/main/resources/en-US/images/click2call_wengo_softphone_user_contact.png deleted file mode 100644 index 119678df73..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/click2call_wengo_softphone_user_contact.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/click2call_windows_cmd_test_java_running.png b/docs/sources/src/main/resources/en-US/images/click2call_windows_cmd_test_java_running.png deleted file mode 100644 index ff5c1f46e2..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/click2call_windows_cmd_test_java_running.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/click2callasync-tomcat-registered-clients.png b/docs/sources/src/main/resources/en-US/images/click2callasync-tomcat-registered-clients.png deleted file mode 100644 index 3777abc663..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/click2callasync-tomcat-registered-clients.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/converged-integrated-lb.png b/docs/sources/src/main/resources/en-US/images/converged-integrated-lb.png deleted file mode 100644 index 3d643f1278..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/converged-integrated-lb.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/icon.svg b/docs/sources/src/main/resources/en-US/images/icon.svg deleted file mode 100644 index c471a607db..0000000000 --- a/docs/sources/src/main/resources/en-US/images/icon.svg +++ /dev/null @@ -1,3936 +0,0 @@ - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - id="path2858" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/sources/src/main/resources/en-US/images/linphone-connected-call.png b/docs/sources/src/main/resources/en-US/images/linphone-connected-call.png deleted file mode 100644 index 0fdf2ec938..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/linphone-connected-call.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/linphone-registration-port-5080.png b/docs/sources/src/main/resources/en-US/images/linphone-registration-port-5080.png deleted file mode 100644 index 36d688adde..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/linphone-registration-port-5080.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mobicents_intro_architecture.png b/docs/sources/src/main/resources/en-US/images/mobicents_intro_architecture.png deleted file mode 100644 index 55eaa7509c..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mobicents_intro_architecture.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-DiameterEventChanging-ss-ChargingAccountConfig.png b/docs/sources/src/main/resources/en-US/images/mss-DiameterEventChanging-ss-ChargingAccountConfig.png deleted file mode 100644 index e7693aabae..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-DiameterEventChanging-ss-ChargingAccountConfig.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-DiameterEventChanging-ss-ChargingEmulatorConfig.png b/docs/sources/src/main/resources/en-US/images/mss-DiameterEventChanging-ss-ChargingEmulatorConfig.png deleted file mode 100644 index dc5e8ba575..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-DiameterEventChanging-ss-ChargingEmulatorConfig.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-MSSSIPLoadBalancer-dia-ClusterIPsAndPorts.jpg b/docs/sources/src/main/resources/en-US/images/mss-MSSSIPLoadBalancer-dia-ClusterIPsAndPorts.jpg deleted file mode 100644 index 71e45cac16..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-MSSSIPLoadBalancer-dia-ClusterIPsAndPorts.jpg and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-MSSSIPLoadBalancer-dia-StarNetworkTopology.jpg b/docs/sources/src/main/resources/en-US/images/mss-MSSSIPLoadBalancer-dia-StarNetworkTopology.jpg deleted file mode 100644 index 218de6e572..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-MSSSIPLoadBalancer-dia-StarNetworkTopology.jpg and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-MSSSManagementConsole-ss-Help.png b/docs/sources/src/main/resources/en-US/images/mss-MSSSManagementConsole-ss-Help.png deleted file mode 100644 index 9c3804df72..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-MSSSManagementConsole-ss-Help.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-MSSSManagementConsole-ss-ManagementConsole.png b/docs/sources/src/main/resources/en-US/images/mss-MSSSManagementConsole-ss-ManagementConsole.png deleted file mode 100644 index 7d98003c76..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-MSSSManagementConsole-ss-ManagementConsole.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-MSSSManagementConsole-ss-ServerSettings.png b/docs/sources/src/main/resources/en-US/images/mss-MSSSManagementConsole-ss-ServerSettings.png deleted file mode 100644 index e2357ecd3b..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-MSSSManagementConsole-ss-ServerSettings.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-confirmed-failover.png b/docs/sources/src/main/resources/en-US/images/mss-confirmed-failover.png deleted file mode 100644 index 934274b70e..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-confirmed-failover.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-early-failover.png b/docs/sources/src/main/resources/en-US/images/mss-early-failover.png deleted file mode 100644 index 8708bb4f13..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-early-failover.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-embjopr-applications.png b/docs/sources/src/main/resources/en-US/images/mss-embjopr-applications.png deleted file mode 100644 index d3c391cd38..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-embjopr-applications.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-embjopr-config.png b/docs/sources/src/main/resources/en-US/images/mss-embjopr-config.png deleted file mode 100644 index 42fe1cb4f3..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-embjopr-config.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-embjopr-config.png.bak b/docs/sources/src/main/resources/en-US/images/mss-embjopr-config.png.bak deleted file mode 100644 index 9f25623a3b..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-embjopr-config.png.bak and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-embjopr-control.png b/docs/sources/src/main/resources/en-US/images/mss-embjopr-control.png deleted file mode 100644 index 7a0182cacb..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-embjopr-control.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-embjopr-home.png b/docs/sources/src/main/resources/en-US/images/mss-embjopr-home.png deleted file mode 100644 index 7fd0711e4c..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-embjopr-home.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-embjopr-metrics.png b/docs/sources/src/main/resources/en-US/images/mss-embjopr-metrics.png deleted file mode 100644 index 58052be719..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-embjopr-metrics.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-embjopr-session-metrics.png b/docs/sources/src/main/resources/en-US/images/mss-embjopr-session-metrics.png deleted file mode 100644 index 605ba09607..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-embjopr-session-metrics.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-ide-screen.png b/docs/sources/src/main/resources/en-US/images/mss-ide-screen.png deleted file mode 100644 index 226d9ee2f1..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-ide-screen.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-jopr-applications.png b/docs/sources/src/main/resources/en-US/images/mss-jopr-applications.png deleted file mode 100644 index 5ab9c31dad..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-jopr-applications.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-jopr-auto-disc.png b/docs/sources/src/main/resources/en-US/images/mss-jopr-auto-disc.png deleted file mode 100644 index d5e9754678..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-jopr-auto-disc.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-jopr-concurrency.png b/docs/sources/src/main/resources/en-US/images/mss-jopr-concurrency.png deleted file mode 100644 index 085c758d76..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-jopr-concurrency.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-jopr-configure-metrics.png b/docs/sources/src/main/resources/en-US/images/mss-jopr-configure-metrics.png deleted file mode 100644 index d20b0166cd..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-jopr-configure-metrics.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-jopr-jboss-web.png b/docs/sources/src/main/resources/en-US/images/mss-jopr-jboss-web.png deleted file mode 100644 index 67a57d20e2..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-jopr-jboss-web.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-jopr-lb-config.png b/docs/sources/src/main/resources/en-US/images/mss-jopr-lb-config.png deleted file mode 100644 index 75f9babc32..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-jopr-lb-config.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-jopr-lb-dash-added.png b/docs/sources/src/main/resources/en-US/images/mss-jopr-lb-dash-added.png deleted file mode 100644 index 6f5baa6b49..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-jopr-lb-dash-added.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-jopr-lb-dashboard.png b/docs/sources/src/main/resources/en-US/images/mss-jopr-lb-dashboard.png deleted file mode 100644 index 46492d477b..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-jopr-lb-dashboard.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-jopr-lb-metrics.png b/docs/sources/src/main/resources/en-US/images/mss-jopr-lb-metrics.png deleted file mode 100644 index e3504ed76d..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-jopr-lb-metrics.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-jopr-lb-monitor.png b/docs/sources/src/main/resources/en-US/images/mss-jopr-lb-monitor.png deleted file mode 100644 index b5788630ab..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-jopr-lb-monitor.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-jopr-lb-ops.png b/docs/sources/src/main/resources/en-US/images/mss-jopr-lb-ops.png deleted file mode 100644 index 00142c9116..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-jopr-lb-ops.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-jopr-metrics.png b/docs/sources/src/main/resources/en-US/images/mss-jopr-metrics.png deleted file mode 100644 index f4dea788a4..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-jopr-metrics.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-jopr-monitor.png b/docs/sources/src/main/resources/en-US/images/mss-jopr-monitor.png deleted file mode 100644 index 0b0afc76ae..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-jopr-monitor.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-jopr-queue.png b/docs/sources/src/main/resources/en-US/images/mss-jopr-queue.png deleted file mode 100644 index 7ef8858f72..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-jopr-queue.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-jopr-resources.png b/docs/sources/src/main/resources/en-US/images/mss-jopr-resources.png deleted file mode 100644 index b7c2906df3..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-jopr-resources.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-jopr-session-metrics.png b/docs/sources/src/main/resources/en-US/images/mss-jopr-session-metrics.png deleted file mode 100644 index e5b874788f..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-jopr-session-metrics.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss-jopr-sip-apps.png b/docs/sources/src/main/resources/en-US/images/mss-jopr-sip-apps.png deleted file mode 100644 index 0c00f67471..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss-jopr-sip-apps.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/mss_webrtc_stack.png b/docs/sources/src/main/resources/en-US/images/mss_webrtc_stack.png deleted file mode 100644 index de4e238131..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/mss_webrtc_stack.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/sip-servlets-management-console-AS7.png b/docs/sources/src/main/resources/en-US/images/sip-servlets-management-console-AS7.png deleted file mode 100644 index 989d4ee3de..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/sip-servlets-management-console-AS7.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/welcome-page-MSS-Tomcat-7.png b/docs/sources/src/main/resources/en-US/images/welcome-page-MSS-Tomcat-7.png deleted file mode 100644 index 5d8994fb08..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/welcome-page-MSS-Tomcat-7.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/images/welcome-page-Mss-JBoss-AS7.png b/docs/sources/src/main/resources/en-US/images/welcome-page-Mss-JBoss-AS7.png deleted file mode 100644 index 63361c9721..0000000000 Binary files a/docs/sources/src/main/resources/en-US/images/welcome-page-Mss-JBoss-AS7.png and /dev/null differ diff --git a/docs/sources/src/main/resources/en-US/task-chapter-Application_Router.xml b/docs/sources/src/main/resources/en-US/task-chapter-Application_Router.xml deleted file mode 100644 index 8415b95f40..0000000000 --- a/docs/sources/src/main/resources/en-US/task-chapter-Application_Router.xml +++ /dev/null @@ -1,15 +0,0 @@ - - -%BOOK_ENTITIES; -]> - - - Application Router - Application Routing is - performed within the &PLATFORM_NAME; Sip Servlets container by the Default - Application Router. The following sections describe the Default Application Router, and how other JSR 289 compliant Application Router implementations - can be installed. - - - diff --git a/docs/sources/src/main/resources/en-US/task-chapter-SIP_Servlets_Server-Installing_Configuring_and_Running.xml b/docs/sources/src/main/resources/en-US/task-chapter-SIP_Servlets_Server-Installing_Configuring_and_Running.xml deleted file mode 100644 index a129d7101e..0000000000 --- a/docs/sources/src/main/resources/en-US/task-chapter-SIP_Servlets_Server-Installing_Configuring_and_Running.xml +++ /dev/null @@ -1,25 +0,0 @@ - - -%BOOK_ENTITIES; -]> - - -SIP Servlets Server-Installing, Configuring and Running - - - - - - - - - - - diff --git a/docs/sources/src/main/resources/en-US/task-section-Default-Application-Router.xml b/docs/sources/src/main/resources/en-US/task-section-Default-Application-Router.xml deleted file mode 100644 index 4890048c71..0000000000 --- a/docs/sources/src/main/resources/en-US/task-section-Default-Application-Router.xml +++ /dev/null @@ -1,323 +0,0 @@ - - -%BOOK_ENTITIES; -]> -
- Default Application Router - The Application Router is called by the container to select a SIP - Servlet application to service an initial request. It embodies the logic - used to choose which applications to invoke. -
- Role of the Application Router - An Application Router is required for a container to function, but - it is a separate logical entity from the container. The Application Router - is responsible for application selection and does not implement - application logic. For example, the Application Router cannot modify a - request or send a response. - There is no direct interaction between the Application Router and - applications, only between the SIP Servlets Container and the Application - Router. - The - SIP Servlets container is responsible for passing the required information to the Application Router within the initial request so the Application Router can make informed routing decisions. The Application Router is free to make use of any information or data stores, except for the information passed by the container. It is up to the individual implementation how the Application Router makes use of the information or data stores. - The - deployer in a SIP Servlet environment controls application composition by - defining and deploying the Application Router implementation. Giving the - deployer control over application composition is desirable because the deployer is solely responsible for the services available to subscribers. - Furthermore, the SIP Servlets - specification intentionally allows the Application Router implementation - to consult arbitrary information or data stores. This is because the - deployer maintains subscriber information and this information is often - private and valuable. -
-
- &PLATFORM_NAME; Default Application Router - &PLATFORM_NAME; SIP Servlets provides an implementation of the Default - Application Router (DAR) as defined in the SIP Servlets 1.1 specification, - Appendix C. -
- The DAR Configuration File - The Default Application Router (DAR) obtains its operational parameters from a - configuration text file that is modeled as a Java properties file. The configuration file - contains the information needed by the Application Router to select - which SIP Servlet application will handle an incoming initial request. - - In the case of &PLATFORM_NAME; - SIP Servlets, it is also possible to configure the DAR through the - server.xml configuration file (see and ). - The properties file has the following characteristics and requirements: - - - It must be made available to the DAR. - - - It must allow the contents and file structure to be accessible from a hierarchical - URI supplied as a system property - javax.servlet.sip.ar.dar.configuration. - - - It is first read by the container when it - loads up and is refreshed each time an application is - deployed and undeployed. - - - It has a simple format in which the name of - the property is the SIP method and the value is a comma-separated string value for the SipApplicationRouterInfo - object. - INVITE: (sip-router-info-1), (sip-router-info-2).. -SUBSCRIBE: (sip-router-info-3), (sip-router-info-4).. -ALL: (sip-router-info-5), (sip-router-info-6).. - &PLATFORM_NAME; SIP Servlets defines a new keyword called ALL. The keyword - allows mapping between the sip-router-info data, and all methods - supported by the container (for example, INVITE, REGISTER, SUBSCRIBE). This mapping can - save time when configuring an application that listens to all - incoming methods. - - - - If ALL, and a specific method are defined in - the DAR file, the specific method takes precedence over ALL. When the specific method no longer has applications to serve, ALL is enabled again. - - The sip-router-info data specified in the properties file is a - string value version of the SipApplicationRouterInfo object. It consists - of the following information: - - - The name of the application as known to the container. The application name can be obtained from the <app-name> element of the sip.xml deployment - descriptor of the application, or the @SipApplication - annotation. - - - The identity of the subscriber that the DAR returns. The DAR can - return any header in the SIP request using the DAR directive - DAR:SIP_HEADER. For example, DAR:From would return the SIP URI in the From - header. The DAR can alternatively return any string from the SIP request. - - - The routing region, which consists of one of the following strings: ORIGINATING, - TERMINATING or NEUTRAL. This information is not currently used - by the DAR to make routing decisions. - - - A SIP URI indicating the route as returned by the Application - Router, which can be used to route the request externally. The value may be an empty string. - - - A route modifier, which consists of one of the following strings: ROUTE, - ROUTE_BACK or NO_ROUTE. The route modifier is used in conjunction with the - route information to route a request externally. - - - A string representing the order in which applications must be - invoked (starts at 0). The string is removed later on in the routing process, and substituted with the order positions of sip-router-info data. - - - - An optional string that contains &PLATFORM_NAME;-specific parameters. Currently, only the DIRECTION and REGEX parameters are supported. - - - - The field can contain unsupported key=value properties that may be supported in future releases. The unsupported properties will be ignored during parsing, until support for the attributes is provided. - - - - The syntax is demonstrated in . - - - - - The DIRECTION parameter specifies whether an application serves external(INBOUND) requests or initiates (OUTBOUND) requests. - - - If an application is marked DIRECTION=INBOUND, it will not be called for requests initiated by applications behaving as UAC. To mark an application as UAC, specify DIRECTION=INBOUND in the optional parameters in the DAR. - - - Applications that do not exist in the DAR list for the container are assumed to be OUTBOUND. Because undefined applications are incapable of serving external requests, they must have self-initiated the request. The Sip Servlets Management Console can be used to specify the DIRECTION parameter. - - - If an application is marked DIRECTION=UAC_ROUTE_BACK, the Application that acted as UAC will be called back if it present in the list of applications to be called for that particular message SIP method. - - - - - The REGEX parameter specifies a regular expression to be matched against the initial request passed to the Application Router. - - - If the regular expression matches a part of the initial request, the application is called. If it does not, it is skipped. - - - For example, in the following sip-router-info data: INVITE - ("org.mobicents.servlet.sip.testsuite.SimpleApplication", "DAR:From", "ORIGINATING", "", "NO_ROUTE", "0", "REGEX=From:.*sip:.*@sip-servlets\.com") - only incoming initial requests with a From Header with a SIP URI that belongs to the sip-servlets.com domain will be passed to the SimpleApplication. - - - - - - - DIRECTION Example - In this example, two applications are declared for the - INVITE - request. The - LocationServiceApplication is called for requests coming from outside the container, but it - will not be - called for the requests initiated by the UAC application - Click2DialApplication. - -INVITE: ("org.mobicents.servlet.sip.testsuite.Click2DialApplication", "DAR:From", -"ORIGINATING", "", "NO_ROUTE", "0", "DIRECTION=OUTBOUND"), \ -("org.mobicents.servlet.sip.testsuite.LocationServiceApplication", "DAR\:From", -"ORIGINATING", "", "NO_ROUTE", "0", "DIRECTION=INBOUND") - This type of configuration is useful in cases where different application must be responsible for both requests initiated by the container, and external requests received by the container. - - - - ORIGINATING/TERMINATING DAR Example - In this example, the DAR is configured to invoke two applications on - receipt of an INVITE request; one each in the originating and the terminating halves. The applications are identified by their application deployment descriptor names. - INVITE: ("OriginatingCallWaiting", "DAR:From", "ORIGINATING", "", "NO_ROUTE", "0"), ("CallForwarding", "DAR:To", "TERMINATING", "","NO_ROUTE", "1") - For this example, the returned subscriber identity is the URI from each application's - From and To headers respectively. The DAR does - not return any route to the container, and maintains the invocation state - in the stateInfo as the index of the last application in the - list. - -
-
- Routing of SIP Messages to Applications -
- Initial Requests and Application Selection Process - Initial Requests are those that can essentially be dialog - creating (such as, INVITE, SUBSCRIBE and NOTIFY), and not part of an already existing dialog. - Initial requests are routed to applications deployed in - the container according to the SIP Servlets 1.1 specification, Section - 15.4.1 Procedure for Routing an Initial Request. - - There are - some other corner cases that apply to initial requests. Refer to Appendix B, Definition of an Initial Request in the SIP Servlets 1.1 - specification. - - - INVITE Routing - The following example describes how the DAR routes an INVITE to two applications deployed in a container. The applications in this example are a - Location Service and a Call Blocking application. - In the example, the assumption of a request coming to the server is described. However, applications can act as a UAC, and generate initial requests - on their own. For routing purposes, it is not necessary for - the specified application initiating the request to have an entry in the DAR file. - The DAR file contains the required information for the two - applications to be invoked in the correct order. - INVITE: ("LocationService", "DAR:From", "ORIGINATING", "", "NO_ROUTE", "0"), ("CallBlocking", "DAR:To", "TERMINATING", "","NO_ROUTE", "1") - Processing occurs in the following order: - - - A new INVITE (not a re-INVITE) arrives at the container. - The INVITE is a dialog creating request, and is not part of any - dialog. - - - The Application Router is called. - From the INVITE information, the first - application to invoke is the Location Service. - - - The Application Router returns the application invocation order - information to the container (along with the rest of the - sip-router-info data) so the container knows which application to - invoke. - - - The container invokes the LocationService that proxies the - INVITE. - The proxied INVITE is considered as a new INVITE to the known IP Address of the registered user for the Request - URI - For further information regarding INVITE handling, refer to "Section 15.2.2 Sending an Initial Request" in the SIP - Servlets 1.1 Specification. - - - Because the INVITE has been proxied, the container invokes the - Application Router for the proxied INVITE to see if any more - applications are interested in the event. - - - From the proxied invite, the Application Router determines that the second application to invoke is the Call Blocking application. - - - - The Application Router returns information regarding the Call Blocking application to the container (along with the - rest of the sip-router-info data) so the container knows which - application to invoke. - - - The container routes the INVITE for the Call Blocking application to the next application in the chain. - - - The Call Blocking application determines that the user that initiated the call is black listed. The application rejects the - call with a "Forbidden" response. - - - Because the Call Blocking application acts as a UAS, - the Application Selection Process is stopped for the original INVITE. - - - The path the INVITE has taken (that is, LocationService to - CallBlocking) is called the application path. The routing of the - responses will now occur as explained in the next section. - -
-
- Response Routing - Responses always follow the reverse of the path taken by the - corresponding request. In our case, the Forbidden response will first - go back to the LocationService, and then back to the caller. This is true for - responses to both initial and subsequent requests. The application - path is a logical concept and as such may or may not be explicitly - represented within containers. - Another possible outcome could have been that the Call Blocking - application, instead of sending a Forbidden response, allowed the call - and proxied the INVITE to the same Request URI chosen by the Location - Service. Then when the callee sends back the 200 OK Response, this - response goes back the same way through the application path (so in - the present case Call Blocking, then Location Service, then back to - the caller). - - The Call Blocking application cannot just do nothing with the - request and expect the container to route the request in its place - (either to a next application in chain if another one is present or - to the outside world if none is present). The Application has to do - something with request (either proxy it or act as a UAS). - -
-
- Subsequent Requests - Subsequent requests are all requests that are not - Initial. - The second scenario, where the Call Blocking application allowed - the call, will be used in this section to showcase subsequent requests. - The caller has received the 200 OK response back. Now, according to - the SIP specification (RFC 3261), it sends an ACK. The ACK arrives at - the container, and is not a dialog creating request and is already part - of an ongoing dialog (early dialog) so the request is detected as a - Subsequent request and will follow the application path created by the - initial request. The ACK will go through Location Service, Call - Blocking, and finally to the callee. -
-
-
-
- Limitations of the Default Application Router - The DAR is a minimalist Application Router implementation that is part of the reference implementation. While it could be used instead of a production Application Router, it offers no - processing logic except for the declaration of the application order. - In real world deployments, the Application Router plays - an extremely important role in application orchestration and composition. - It is likely that the Application Router would make use of complex rules and diverse data - repositories in future implementations. -
-
diff --git a/docs/sources/src/main/resources/en-US/task-section-SIP_Servlets_Server-Configuring.xml b/docs/sources/src/main/resources/en-US/task-section-SIP_Servlets_Server-Configuring.xml deleted file mode 100644 index 86f603909d..0000000000 --- a/docs/sources/src/main/resources/en-US/task-section-SIP_Servlets_Server-Configuring.xml +++ /dev/null @@ -1,669 +0,0 @@ - - -%BOOK_ENTITIES; -]> - - -
- Sip Connectors - - -&PLATFORM_NAME; comes with default settings that are designed to get your system up and running without the need to know about all the detailed configurations. That said, there are situations in which you might like to fine-tune your setttings to adapt it to your needs. That is what the following section will help you achieve. You will get a better understand of SIP connectors and how to make them work for you. - - -   - -
- - Configuring SIP Connectors and Bindings - - - -There are two important configuration files that you might need to modifying depending on your system needs. The standalone-sip.xml file in &SHORT_PLATFORM_NAME; for JBoss AS7 and the server.xml file in &SHORT_PLATFORM_NAME; for Tomcat. The extracts below will give you a snapshot of default configurations. - - - - - For JBoss - - - -Changing the ports and other configuration for the SIP connector can be done in the standalone-sip.xml file. -Below is an extract : - - - - Adding a SIP Connector to $JBOSS_HOME/standalone/configuration/standalone-sip.xml - - - - - - - - - - - - - - - - - - - - - - - - - -]]> - - - - -If you need to add a connector for the same protocol, a new socket-binding should be created. A naming convention should be followed for the name attribute of the new socket-binding. -The convention is <name>-sip-<protocol>. By example, - -]]> - - - - SIP <connector> Attributes - - port (defined at the socket-binding element) - - The port number on which the container will be able to receive SIP messages. - - - - protocol - - Specifies the connector is a SIP Connector and not an HTTP Connector. There is no need to change this property. - - - - signalingTransport (use socket-binding element) - - Specifies the transport on which the container will be able to receive SIP messages. Supported Values are "udp", "tcp", "tls" and "ws". - - - - use-stun - - Enables Session Traversal Utilities for NAT (STUN) support for this Connector. The attribute defaults to "false". If set to "true", ensure that the ipAddress attribute is not set to 127.0.0.1. Refer to for more information about STUN. - - - - stun-server-address - - Specifies the STUN server address used to discover the public IP address of the SIP Connector. This attribute is only required if the useStun attribute is set to "true". Refer to for more information about STUN and public STUN servers. - - - - stun-server-port - - Specifies the STUN server port of the STUN server used in the stunServerAddress attribute. You should rarely need to change this attribute; also, it is only needed if the useStun attribute is set to "true". Refer to for more information about STUN. - - - - use-static-address - - Specifies whether the settings in staticServerAddress and staticServerPort are activated. The default value is "false" (deactivated). - - - - static-server-address - - Specifies what load-balancer server address is inserted in Contact/Via headers for server-created requests. This parameter is useful for cluster configurations where requests should be bound to a load-balancer address, rather than a specific node address. - - - - static-server-port - - Specifies the port of the load-balancer specified in staticServerAddress. This parameter is useful in cluster configurations where requests should be bound to a load-balancer address rather than a specific node address. - - - - http-follow-sip - - - Makes the application server aware of how the SIP Load Balancers assign request affinity, and stores this information in the application session. - - - When the HTTP Load Balancer sends HTTP requests that are not associated with the application session, the application server will force the HTTP request to be repeated until it lands on the correct node. - - - - - - - For Tomcat - - - -Changing the ports and other configuration for the SIP connector can be done in the server.xml file. Below is an extract. - - - - Adding a SIP Connector to $CATALINA_HOME/conf/server.xml - - ]]> - - - - - - SIP <connector> Attributes - - port - - The port number on which the container will be able to receive SIP messages. - - - - ipAddress - - The IP address at which the container will be able to receive SIP messages. The container can be configured to listen to all available IP addresses by setting ipAddress to 0.0.0.0 <sipPathName>. - - - - protocol - - Specifies the connector is a SIP Connector and not an HTTP Connector. There is no need to change this property. - - - - signalingTransport - - Specifies the transport on which the container will be able to receive SIP messages. For example, "udp". - - - - useStun - - Enables Session Traversal Utilities for NAT (STUN) support for this Connector. The attribute defaults to "false". If set to "true", ensure that the ipAddress attribute is not set to 127.0.0.1. Refer to for more information about STUN. - - - - stunServerAddress - - Specifies the STUN server address used to discover the public IP address of the SIP Connector. This attribute is only required if the useStun attribute is set to "true". Refer to for more information about STUN and public STUN servers. - - - - stunServerPort - - Specifies the STUN server port of the STUN server used in the stunServerAddress attribute. You should rarely need to change this attribute; also, it is only needed if the useStun attribute is set to "true". Refer to for more information about STUN. - - - - useStaticAddress - - Specifies whether the settings in staticServerAddress and staticServerPort are activated. The default value is "false" (deactivated). - - - - staticServerAddress - - Specifies what load-balancer server address is inserted in Contact/Via headers for server-created requests. This parameter is useful for cluster configurations where requests should be bound to a load-balancer address, rather than a specific node address. - - - - staticServerPort - - Specifies the port of the load-balancer specified in staticServerAddress. This parameter is useful in cluster configurations where requests should be bound to a load-balancer address rather than a specific node address. - - - - httpFollowsSip - - - Makes the application server aware of how the SIP Load Balancers assign request affinity, and stores this information in the application session. - - - When the HTTP Load Balancer sends HTTP requests that are not associated with the application session, the application server will force the HTTP request to be repeated until it lands on the correct node. - - - - - - A comprehensive list of implementing classes for the SIP Stack is available from the Class SipStackImpl page on nist.gov. - -
-
- Application Routing and Service Configuration - The application router is called by the container to select a SIP Servlet application to service an initial request. It embodies the logic used to choose which applications to invoke. An application router is required for a container to function, but it is a separate logical entity from the container. - The application router is responsible for application selection and must not implement application logic. For example, the application router cannot modify a request or send a response. - For more information about the application router, refer to the following sections of the JSR 289 specification: Application Router Packaging and Deployment, Application Selection Process, and Appendix C. - - - - - - - -See the example chapters for more information about the Application Router Configuration for SIP &SHORT_PLATFORM_NAME; for JBoss AS7 - - - - - - - - - - In order to configure the application router for Tomcat, you should edit the Service element in the container's server.xml configuration file - - - - Configuring the Service Element in the Container's server.xml - ]]> - - - -For &SHORT_PLATFORM_NAME; for JBoss AS7 this is located in standalone-sip.xml file : - - - Configuring the Mobicents SubSystem Element in the Container's standalone.xml - - - - - ]]> - - - - - SIP Service element attributes - - className - - This attribute specifies that the servlet container is a converged (i.e. SIP + HTTP) servlet container. - - - - sipApplicationDispatcherClassName (Tomcat) - app-dispatcher-class (JBoss/EAP) - - This attribute specifies the class name of the org.mobicents.servlet.sip.core.SipApplicationDispatcher implementation to use. The routing algorithm and application selection process is performed in that class. - - - - darConfigurationFileLocation (Tomcat) - application-router (JBoss/EAP) - - The default application router file location. This is used by the default application router to determine the application selection logic. Refer to Appendix C of the JSR 289 specification for more details. - - - - sipStackPropertiesFile (Tomcat) - stack-properties (JBoss/EAP) - - Specifies the location of the file containing key value pairs corresponding to the SIP Stack configuration properties. This attribute is used to further tune the JAIN SIP Stack. If this property is omitted, the following default values are assumed: - - - gov.nist.javax.sip.LOG_MESSAGE_CONTENT=true - - - gov.nist.javax.sip.TRACE_LEVEL=32 - - - gov.nist.javax.sip.DEBUG_LOG=logs/mss-jsip-debuglog.txt - - - gov.nist.javax.sip.SERVER_LOG=logs/mss-jsip-messages.xml - - - javax.sip.STACK_NAME=&PLATFORM_NAME;-SIP-Servlets - - - javax.sip.AUTOMATIC_DIALOG_SUPPORT=off - - - gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY=true - - - gov.nist.javax.sip.THREAD_POOL_SIZE=64 - - - gov.nist.javax.sip.REENTRANT_LISTENER=true - - - gov.nist.javax.sip.MAX_FORK_TIME_SECONDS=0. Dialog forking is not enabled by default as it has an impact on memory. If set to a value greater than 0, Dialog Forking will be enabled on &PLATFORM_NAME; Sip Servlets. - - - gov.nist.javax.sip.AUTOMATIC_DIALOG_ERROR_HANDLING=false. Merged requests Loop Detection is turned off by default - - - SIP Servlets also adds its own properties to allow for even more configuration and flexibility: - - - If the property org.mobicents.servlet.sip.SERVER_HEADER is set, a server header will be added to all SIP Responses leaving the container. - - - If the property org.mobicents.servlet.sip.USER_AGENT_HEADER is set, a server header will be added to all SIP Requests leaving the container. - - - - - - usePrettyEncoding (Tomcat) - use-pretty-encoding (JBoss/EAP) - - Allows Via, Route, and RecordRoute header field information to be split into multiple lines, rather than each header field being separating with a comma. The attribute defaults to "true". Leaving this attribute at the default setting may assist in debugging non-RFC3261 compliant SIP servers. - - - - additionalParameterableHeaders (Tomcat) - additional-parameterable-headers (JBoss/EAP) - - Comma separated list of header names that are treated as parameterable by the container. The specified headers are classed as valid, in addition to the standard parameterable headers defined in the Sip Servlets 1.1 Specification. - Setting and getting parameters is allowed for both the standard and the additional parameters. Parameters that are not specified in additionalParameterableHeaders will result in a ServletParseException error. - - - - - baseTimerInterval (Tomcat) - base-timer-interval (JBoss/EAP) - - Specifies the T1 Base Timer Interval, which allows the SIP Servlets container to adjust its timers depending on network conditions. The default interval is 500 (milliseconds). - For more information about available timers, refer to the RFC326 "Table of Timer Values"1, and the document contained in the 3GPP-IMS TS 24.229 v9.1.0 specification ZIP archive. - All of the timers present in the tables depend on T1, T2, T4, and Timer D. - - - - t2Interval (Tomcat) - t2-interval (JBoss/EAP) - - Specifies the T2 Interval, which allows the SIP Servlets container to adjust its timers depending on network conditions. The default interval is 4000 (milliseconds). - For more information about available timers, refer to the RFC326 "Table of Timer Values"1, and the document contained in the 3GPP-IMS TS 24.229 v9.1.0 specification ZIP archive. - All of the timers present in the tables depend on T1, T2, T4, and Timer D. - - - - t4Interval (Tomcat) - t4-interval (JBoss/EAP) - - Specifies the T4 Interval, which allows the SIP Servlets container to adjust its timers depending on network conditions. The default interval is 5000 (milliseconds). - For more information about available timers, refer to the RFC326 "Table of Timer Values"1, and the document contained in the 3GPP-IMS TS 24.229 v9.1.0 specification ZIP archive. - All of the timers present in the tables depend on T1, T2, T4, and Timer D. - - - - timerDInterval (Tomcat) - timerD-interval (JBoss/EAP) - - Specifies the Timer D Interval, which allows the SIP Servlets container to adjust its timers depending on network conditions. The default interval is 32000 (milliseconds). - For more information about available timers, refer to the RFC326 "Table of Timer Values"1, and the document contained in the 3GPP-IMS TS 24.229 v9.1.0 specification ZIP archive. - All of the timers present in the tables depend on T1, T2, T4, and Timer D. - - - - - dialogPendingRequestChecking (Tomcat) - dialog-pending-request-checking (JBoss/EAP) - - This property enables and disables error checking when SIP transactions overlap. If within a single dialog an INVITE request arrives while there is antoher transaction proceeding, the container will send a 491 error response. The default value is false. - - - - callIdMaxLength (Tomcat) - call-id-max-length (JBoss/EAP) - - This property allows to shorten the size of Call-ID Header. This is useful when integrating with Lync (which has a limit of 32 in size) or older SIP Servers - - - - tagHashMaxLength (Tomcat) - tag-hash-max-length (JBoss/EAP) - - This property allows to shorten the size of tags in From and To Header. This is useful when integrating with Lync (which has a limit of 10 in size) or older SIP Servers - - - - dnsServerLocatorClass (Tomcat) - dns-server-locator-class (JBoss/EAP) - - Specifies the org.mobicents.ext.javax.sip.dns.DNSServerLocator implementation class that will be used by the container to perform DNS lookups compliant with RFC 3263 : Locating SIP Servers and E.164 NUmber Mapping. The default class used by the container is org.mobicents.ext.javax.sip.dns.DefaultDNSServerLocator, but any class implementing the org.mobicents.ext.javax.sip.dns.DNSServerLocator interface. To disable DNS lookups, this attribute should be left empty. - - - - dnsResolverClass (Tomcat) - dns-resolver-class (JBoss/EAP) - - Specifies the org.mobicents.javax.servlet.sip.dns.DNSResolver implementation class that will be used by the container to perform DNS lookups compliant with RFC 3263 : Locating SIP Servers and E.164 NUmber Mapping. The default class used by the container is org.mobicents.servlet.sip.dns.MobicentsDNSResolver, but any class implementing the org.mobicents.servlet.sip.dns.DNSResolver interface. To disable DNS lookups, this attribute should be left empty. - - - - addressResolverClass (Tomcat) - address-resolver-class (JBoss/EAP) - - Specifies the gov.nist.core.net.AddressResolver implementation class that will be used by the container to perform DNS lookups. The default class used by the container is org.mobicents.servlet.sip.core.DNSAddressResolver, but any class implementing the gov.nist.core.net.AddressResolver NIST SIP Stack interface and having a constructor with a org.mobicents.servlet.sip.core.SipApplicationDispatcher parameter can be used. To disable DNS lookups, this attribute should be left empty. - This attribute has been deprecated in favor of dnsServerLocatorClass attribute which provides better compliance with RFC 3263 : Location SIP Servers and ENUM support - - - - canceledTimerTasksPurgePeriod (Tomcat) - canceled-timer-tasks-purge-period (JBoss/EAP) - - Defines a period to due a purge in the container timer schedulers. The purge may prevent excessive memory usage for apps that cancel most of the timers it sets. - - - -
- - -
- SIP Servlets Server Logging - - -Logging is an important part of working with &PLATFORM_NAME;. There are a few files that you need to be familiar with in order to successfully troubleshoot and adapt &SHORT_PLATFORM_NAME; server monitoring and logging to your environment. - - - -Logging Files for &SHORT_PLATFORM_NAME; for JBoss AS7 - - - -$JBOSS/standalone/configuration/logging.properties - - -$JBOSS/standalone/configuration/mss-sip-stack.properties - - - -$JBOSS/standalone/configuration/standalone-sip.xml - - - - -Setting the log file name in $JBOSS/standalone/configuration/standalone-sip.xml - - - - - - - - -]]> - - - - - - -The configuration above produces SIP logs that can be found in the $JBOSS_HOME/standalone/log directory. Below is an extract of the log files. - - - - - server.log.2012-08-14 server.log.2012-08-24 -server.log server.log.2012-08-16 server.log.2012-08-25 -server.log.2012-08-07 server.log.2012-08-21 server.log.2012-08-26 -server.log.2012-08-13 server.log.2012-08-22 - - - - -Logging Files for &SHORT_PLATFORM_NAME; for Tomcat - - - -If you are working with Tomcat, the log configuration files are located in the $CATALINA_HOME/conf/ directory. The log4j configuration file is located in $CATALINA_HOME/lib/ directory - - - - -$CATALINA_HOME/conf/logging.properties - - -$CATALINA_HOME/conf/mss-sip-stack.properties - - - -$CATALINA_HOME/conf/server.xml - - - -$CATALINA_HOME/lib/log4j.xml - - - -Truncated Sample Configuration from Server.xml - - - - -Setting the log file name $CATALINA_HOME/conf/server.xml - - - - - - -]]> - - - - - - -Truncated Sample Configuration from log4j.xml - - - - -Configuring the log file name $CATALINA_HOME/lib/log4j.xml - - - - - - - - -]]> - - - - - -The result of the extracted configuration above that is taken from the log4j.xml file and can be found in the $CATALINA_HOME/logs directory. - - -JAIN-SIP Stack Logging - There are two separate levels of logging: - - - Logging at the container level, which can be configured using the log4j.xml or standalone-sip.xml configuration file seen above - - - Logging of the JAIN SIP stack, which is configured through the container logging and the SIP stack properties themselves - - - You can setup the logging so that the JAIN SIP Stack will log into the container logs. - To use LOG4J in JAIN SIP Stack in Tomcat, you need to define a category in CATALINE_HOME/lib/jboss-log4j.xml and set it to DEBUG. - - Configuring the JAIN SIP Stack to log into the Tomcat Container's logs - - - ]]> - - - To use LOG4J in JAIN SIP Stack in JBoss, you need to define a logger in JBOSS_HOME/standalone/configuration/standalone-sip.xml and set it to DEBUG. - - Configuring the JAIN SIP Stack to log into the JBoss Container's logs - - - ]]> - - - For this category to be used in &SHORT_PLATFORM_NAME;, you need to specify it in JBOSS_HOME/standalone/configuration/mss-sip-stack.properties or CATALINE_HOME/conf/mss-sip-stack.properties, add the gov.nist.javax.sip.LOG4J_LOGGER_NAME=gov.nist property, and set the gov.nist.javax.sip.TRACE_LEVEL=LOG4J property. -
- - -
diff --git a/docs/sources/src/main/resources/en-US/task-section-binary-SIP_Servlets_Server_with_JBoss-Installing_Configuring_and_Running.xml b/docs/sources/src/main/resources/en-US/task-section-binary-SIP_Servlets_Server_with_JBoss-Installing_Configuring_and_Running.xml deleted file mode 100644 index f107bfa251..0000000000 --- a/docs/sources/src/main/resources/en-US/task-section-binary-SIP_Servlets_Server_with_JBoss-Installing_Configuring_and_Running.xml +++ /dev/null @@ -1,328 +0,0 @@ - - -%BOOK_ENTITIES; -]> -
- SIP Servlet-Enabled JBoss Application Server: Installing, Configuring and Running - The &PLATFORM_NAME; SIP Servlets Server can run on either the JBoss Application Server or the Tomcat Servlet Container. This section details how to install the SIP Servlets Server on top of the JBoss Application Server. For installation instructions for the Tomcat Servlet Container, refer to - - - It is recommended that the SIP Servlets Server is run on the JBoss platform. Some functionality, including the ability to execute some SIP Extension examples, is not available in the Tomcat version. - - - Differences Between a Standard JBoss Installation and the &PLATFORM_NAME; SIP Servlets Version - Provided here is a list of differences between a standard JBoss Application Server installation one customized for SIP Servlets. The differences include: - - - - The server/default/deploy directory contains both HTTP and SIP Servlet applications. - - - The server/default/deploy/jbossweb.sar units have been modified to provide extended classes to the standard JBoss container classes, in order to allow SIP applications to be loaded and the SIP stack to be started. - - - The server/default/deploy/jbossweb.sar context.xml files have been modified to allow the extended manager to manage SIP sessions and SIP application sessions in addition to HTTP sessions. - - - The server/default/deploy/jbossweb.sar/ server.xml file has been modified to provide extended classes to common JBoss Web containers. The classes allow SIP applications to be loaded, and the SIP stack to be started. - - - The server/default/deploy/jbossweb.sar/ jboss-beans.xml file has been modified to allow the JBoss container to process SIP messages. - - - The server/default/deployers/ metadata-deployer-jboss-beans.xml file has been modified to allow JBoss to parse sip.xml deployment descriptors and SIP metadata annotations. - - - The server/default/deployers/jbossweb.deployer/META-INF/war-deployers-jboss-beans.xml file have been modified so that it is now possible for JBoss containers to correctly deploy SIP servlets and converged applications. - - - A dars directory containing all of the Default Application Router (DAR) properties files for using the various SIP Servlets applications (which come bundled with the release) has been added to the server/default/conf directory. - - - Additional JAR files have been added to enable SIP Servlet functionality; these are located in the server/default/deploy/jbossweb.sar/, server/default/deployers/jbossweb.deployer/ and common/libdirectories. - - - -
- Pre-install Requirements and Prerequisites -   - - Hardware Requirements - - Sufficient Disk Space - - Once unzipped, version &VERSION; of the &SHORT_PLATFORM_NAME; for JBoss binary release requires a minimum of &SSS_MSS4J_SIZE; free disk space. - - - - Anything Java Itself Will Run On - - &SHORT_PLATFORM_NAME; for JBoss is 100% Java and will run on the same hardware that the JBoss Application Server runs on. - - - - - Software Prerequisites - - JDK 5 or Higher - - A working installation of the Java Development Kit (<acronym>JDK</acronym>) version 5 or higher is currently required in order to run &SHORT_PLATFORM_NAME; for JBoss binary distribution. For instructions on how to install the JDK, refer to - - - -
-
- Downloading - The latest version of &PLATFORM_NAME; SIP Servlets for JBoss is available from . - Each version of the SIP Servlets Server is comprised of tree separate binary distribution files: one which is &SHORT_PLATFORM_NAME; for JBoss, one which is &SHORT_PLATFORM_NAME; for EAP and the other which is &SHORT_PLATFORM_NAME; for Tomcat. Download SIP Servlets Server for JBoss and continue with the following instructions. -
-
- Installing - Once the requirements and prerequisites have been met and you have downloaded the binary distribution zip file, you are ready to install the &SHORT_PLATFORM_NAME; for JBoss binary distribution. Follow the instructions below for the selected platform, whether Linux or Windows. - - Version Numbers - For clarity, the command line instructions presented in this chapter use specific version numbers and directory names. Ensure this information is substituted with the binary distribution's version numbers and file names. - - - Installing the &SHORT_PLATFORM_NAME; for JBoss Binary Distribution on Linux - It is assumed that the downloaded archive is saved in the home directory, and that a terminal window is open displaying the home directory - - Create a subdirectory to extract the &SHORT_PLATFORM_NAME; for JBoss files into. For ease of identification, it is recommended that the version number of the binary is included in this directory name. - ~]$ mkdir "&CMD_PLATFORM_NAME;-jboss-<version>" - - - Move the downloaded zip file into the directory. - ~]$ mv "&SSS_MSS4J_ZIP;" "&CMD_PLATFORM_NAME;-jboss-<version>" - - - Move into the directory. - ~]$ cd "&CMD_PLATFORM_NAME;-jboss-<version>" - - - Extract the files into the current directory by executing one of the following commands. - - - Java: &CMD_PLATFORM_NAME;-jboss-<version>]$ jar -xvf "&SSS_MSS4J_ZIP;" - - - Linux: &CMD_PLATFORM_NAME;-jboss-<version>]$ unzip "&SSS_MSS4J_ZIP;" - - - - You can also use unzip'-d <unzip_to_location> to extract the zip file's contents to a location other than the current directory. - - - - To free disk space, you may want to delete the zip file once you've extracted its contents: - &CMD_PLATFORM_NAME;-jboss-<version>]$ rm "&SSS_MSS4J_ZIP;" - - - - - Installing the &SHORT_PLATFORM_NAME; for JBoss Binary Distribution on <productname>Windows</productname> - For this procedure, it is assumed that the downloaded archive is saved in the My Downloads folder. - - Create a directory in My Downloads to extract the zip file's contents into. For ease of identification, it is recommended that the version number of the binary is included in the folder name. For example, &SHORT_PLATFORM_NAME;-jboss-<version>. - - - Extract the contents of the archive, specifying the destination folder as the one created in the previous step. - - - Alternatively, execute the jar -xvf command to extract the binary distribution files from the zip archive. - - - Move the downloaded zip file from My Downloads to the folder created in the previous step. - - - Open the Windows Command Prompt and navigate to the folder that contains the archive using the cd command - - - Execute the jar -xvf command to extract the archive contents into the current folder. - C:\Users\<user>\My Downloads\&CMD_PLATFORM_NAME;-jboss-<version>>jar -xvf "&SSS_MSS4J_ZIP;" - - - - - It is recommended that the folder holding the &SHORT_PLATFORM_NAME; for JBoss files (in this example, the folder named &CMD_PLATFORM_NAME;-jboss-<version>) is moved to a user-defined location for storing executable programs. For example, the Program Files folder. - - - Consider deleting the archive, if free disk space is an issue. - C:\Users\<user>\My Downloads\&CMD_PLATFORM_NAME;-jboss-<version>>delete "&SSS_MSS4J_ZIP;" - - -
-
- Setting the JBOSS_HOME Environment Variable - Configuring &SHORT_PLATFORM_NAME; for JBoss consists of setting the JBOSS_HOME environment variable and optionally customizing the &SHORT_PLATFORM_NAME; for JBoss server by adding SIP Connectors, configuring the application router, and logging. - After setting JBOSS_HOME according to the instructions in the following section, refer to to learn how to configure &SHORT_PLATFORM_NAME; for JBoss. - Alternatively, after having set JBOSS_HOME, the &SHORT_PLATFORM_NAME; for JBoss server can be run. Return to this section to configure it later. - -
-
- Configuring - To configure &SHORT_PLATFORM_NAME; for JBoss, refer to . -
-
- Running - To start the server, execute one of the startup scripts in the bin directory (on Linux or Windows), or by double-clicking the run.bat executable batch file in that same directory (on Windows only). It is recommended that the JBoss Application Server is started using the terminal or Command Prompt because the messages displayed during startup can be used to debug, and subsequently correct, any problems. In the Linux terminal or Command Prompt, a successfully started server will return the following information : - &PLATFORM_NAME; - revision started.]]> - Detailed instructions are given below, arranged by platform. - - Running &SHORT_PLATFORM_NAME; for JBoss on Linux - - Change the working directory to &SHORT_PLATFORM_NAME; for JBoss's installation directory (the one in which the zip file's contents was extracted to) - downloads]$ cd "&CMD_PLATFORM_NAME;-jboss-<version>" - - - (Optional) Ensure that the bin/run.sh start script is executable. - &CMD_PLATFORM_NAME;-jboss-<version>]$ chmod +x bin/run.sh - - - Execute the run.sh Bourne shell script. - &CMD_PLATFORM_NAME;-jboss-<version>]$ ./bin/run.sh - - - - Instead of executing the Bourne shell script to start the server, the run.jar executable Java archive can be executed from the bin directory: - &CMD_PLATFORM_NAME;-jboss-<version>]$ java -jar bin/run.jar - - - Running &SHORT_PLATFORM_NAME; for JBoss on <productname>Windows</productname> - There are several ways to start &SHORT_PLATFORM_NAME; for JBoss on Windows. All of the following methods accomplish the same task. - - Using Windows Explorer, navigate to the bin subdirectory in the installation directory. - - - The preferred way to start &SHORT_PLATFORM_NAME; for JBoss from the Command Prompt. The command line interface displays details of the startup process, including any problems encountered during the startup process. - Open the Command Prompt via the Start menu and navigate to the correct folder: - C:\Users\<user>My Downloads> cd "&CMD_PLATFORM_NAME;-jboss-<version>" - - - Start the JBoss Application Server by executing one of the following files: - - - run.bat batch file: - C:\Users\<user>My Downloads\&CMD_PLATFORM_NAME;-jboss-<version>>bin\run.bat - - - run.jar executable Java archive: - C:\Users\<user>My Downloads\&CMD_PLATFORM_NAME;-jboss-<version>>java -jar bin\run.jar - - - - - -
-
- Using - Once the server is running, access the SIP Servlets Management Console by opening . -
-
- Testing - After installation, there should be one pre-configured sample application deployed in the default server onfiguration. You can use it to verify that the server is installed and running correctly. The application name is org.mobicents.servlet.sip.example.SimpleApplication. From the Sip Servlets Management Console you can make sure it is subscribed to receive INVITE and REGISTER SIP requests. It is a simple Click2Call application allowing SIP registration and calling phones from the Web user interface. - The scenario for this example consists of the following steps: - - - Alice and Bob each register a SIP Softphone - - - Alice clicks on the "Call" link to place a call to Bob - - - Alice's phone rings - - - When Alice picks up her phone, Bob's phone rings - - - When Bob answers his phone, the call is connected - - - When one of them hangs up, the other one is also disconnected - - - - Testing the Click2Call sample application - - Open up a browser to http://localhost:8080/click2call/. If you have no registered SIP clients you will be asked to register at least two. - - - Configure your SIP clients to use the sip servlets server as a register and proxy. (IP address : 127.0.0.1, port: 5080) -By default it will accept any password - - - After the registration you will see a table where each cell will initiate a call between the corresponding clients. - - - Close the calls. - - - Navigate to http://localhost:8080/click2call/simplecall.html, which is a simplified version that doesn't require registered clients. - - - - Enter the URIs of the two SIP phones you just started and click "Submit" - - - The phones should be ringing again. You can pick them up and you will know that the SIP and the HTTP containers are working properly. - - -
-
- Stopping - Detailed instructions for stopping the JBoss Application Server are given below, arranged by platform. If the server is correctly stopped, the following three lines are displayed as the last output in the Linux terminal or Command Prompt: - [Server] Shutdown complete -Shutdown complete -Halting VM - - Stopping &SHORT_PLATFORM_NAME; for JBoss on Linux - - Change the working directory to the binary distribution's install directory. - ~]$ cd "&CMD_PLATFORM_NAME;-jboss-<version>" - - - (Optional) Ensure that the bin/shutdown.sh start script is executable: - &CMD_PLATFORM_NAME;-jboss-<version>]$ chmod +x bin/shutdown.sh - - - Run the shutdown.sh executable Bourne shell script with the option (the short option for ) as a command line argument: - &CMD_PLATFORM_NAME;-jboss-<version>]$ ./bin/shutdown.sh -S - - - - The shutdown.jar executable Java archive with the option can also be used to shut down the server: - &CMD_PLATFORM_NAME;-jboss-<version>]$ java -jar bin/shutdown.jar -S - - - Stopping &CMD_PLATFORM_NAME; for JBoss on Windows - - Stopping the JBoss Application Server on Windows consists in executing either the shutdown.bat or the shutdown.jar executable file in the bin subdirectory of the &SHORT_PLATFORM_NAME; for JBoss binary distribution. Ensure the option (the short option for ) is included in the command line argument. - C:\Users\<user>\My Downloads\&CMD_PLATFORM_NAME;-jboss-<version>>bin\shutdown.bat -S - - - The shutdown.jar executable Java archive with the option can also be used to shut down the server: - C:\Users\<user>\My Downloads\&CMD_PLATFORM_NAME;-jboss-<version>>java -jar bin\shutdown.jar -S - - - - -
-
- Uninstalling - To uninstall &SHORT_PLATFORM_NAME; for JBoss, delete the directory containing the binary distribution. -
-
diff --git a/docs/sources/src/main/resources/en-US/task-section-binary-SIP_Servlets_Server_with_Tomcat-Installing_Configuring_and_Running.xml b/docs/sources/src/main/resources/en-US/task-section-binary-SIP_Servlets_Server_with_Tomcat-Installing_Configuring_and_Running.xml deleted file mode 100644 index dad8166a23..0000000000 --- a/docs/sources/src/main/resources/en-US/task-section-binary-SIP_Servlets_Server_with_Tomcat-Installing_Configuring_and_Running.xml +++ /dev/null @@ -1,552 +0,0 @@ - - -%BOOK_ENTITIES; -]> - - - - -
-Getting Started with &SHORT_PLATFORM_NAME; for Tomcat 7 - - -You can download the latest &SHORT_PLATFORM_NAME; for Tomcat 7 Download Latest Version of &SHORT_PLATFORM_NAME; for Tomcat 7 - - - -The content of the downloaded file can be extracted to any location you prefer on your computer. The root directory to which the content of the download is extracted will be referred to as $CATALINA_HOME. - - - -The content of the $CATALINA_HOME/bin is similar to the output below. - - - -bootstrap.jar cpappend.bat startup.bat -catalina.bat daemon.sh startup.sh -catalina.sh digest.bat tomcat-juli.jar -catalina-tasks.xml digest.sh tomcat-native.tar.gz -commons-daemon.jar setclasspath.bat tool-wrapper.bat -commons-daemon-native.tar.gz setclasspath.sh tool-wrapper.sh -configtest.bat shutdown.bat version.bat -configtest.sh shutdown.sh version.sh - - - - - -You can start &SHORT_PLATFORM_NAME; for Tomcat 7 by going to $CATALINA_HOME/bin directory and typing the following: - - - - - -sudo ./catalina.sh run - - - -The startup process is slightly different from &SHORT_PLATFORM_NAME; for JBoss AS7. If you see an output like the one below, you know that Tomcat is correctly started. This is a truncated log from the startup process. - - - - -2012-08-21 22:23:41,025 INFO [SipApplicationDispatcherImpl] (main) SipApplicationDispatcher Started -2012-08-21 22:23:41,025 INFO [SipStandardService] (main) SIP Standard Service Started. -Aug 21, 2012 10:23:41 PM org.apache.catalina.startup.Catalina start -INFO: Server startup in 3608 ms - - - - - - - - -If you get an error message about environment variables or Java, make sure you have the CATALINA environment variables set. - - - -Setting Environment Variables - JAVA and CATALINA - - - - - - -
-Testing Click2CallAsync with &SHORT_PLATFORM_NAME; for Tomcat 7 - - -If &SHORT_PLATFORM_NAME; for Tomcat 7 is started and running, you should be able to use your web browser to access the welcome page at this url http://127.0.0.1:8080/ This will show you a screenshot similar to the one below. - - - - -
- JBoss Application Server 7 Welcome Page - - - - - -
- -
- - -Deploying your application once the server is running is simple. You need to copy your .War files to the $CATALINA_HOME/webapps directory. - - - - There is a pre-installed sample SIP application that you can use to test your &SHORT_PLATFORM_NAME; Tomcat 7 configuration. The application is also located in the $CATALINA_HOME/webapps directory - - - -Start your web browser and go to the link, http://127.0.0.1:8080/Click2CallAsync/ - - - - Sample Application Name - -Note that the application name is case-sensitive and will not work if you try to access it as http://127.0.0.1:8080/click2callasync/ - - - -The sample SIP application page will be similar to the screenshot below. - - - - - -
- SIP Sample Click2CallAsync Application - - - - - -
- -
- - - - -In order to use the application, you can download a softphone and start multiple instances of the phone on a single server. In this guide, the softphone that will be used is Linphone. The configuration is as follows: - - - - Multiple Instances of Linphone - -On some Linux systems, you might need to use a different user profile in order to start a second instance of Linphone. Ex. sudo linphone - - - - -(configuring two instances of Linphone) - -start Linphone -go to the Options menu - -On the Network Settings tab, - SIP (UDP) port to 5061. (leave the rest as default) -On the Manage SIP Accounts tab, - click the add button - Your SIP identity: = sip:linphone@127.0.0.1:5080 - SIP Proxy address: = sip 127.0.0.1:5080 - -Leave the rest of the settings as default. - - -Configuring Linphone (on the second shell) - -go to the Options menu - -On the Network Settings tab, - SIP (UDP) port to 5062. (leave the rest as default) -On the Manage SIP Accounts tab, - click the add button - Your SIP identity: = sip:linphone2@127.0.0.1:5080 - SIP Proxy address: = sip 127.0.0.1:5080 - -Leave the rest of the settings as default. - - - -Once the softphones are configured and are successfully registered with the &SHORT_PLATFORM_NAME; for Tomcat 7 server, you will see a screenshot like the one below in the web browser at this url http://127.0.0.1:8080/Click2CallAsync/ - - - -
- SIP Click2CallAsync with Registers Clients - - - - - -
- -
- - -You can make calls using the application and the softphones you configured will start ringing. It is important to start &SHORT_PLATFORM_NAME; for Tomcat 7 in a terminal using the (./catalina.sh run) script. It will help with troubleshooting SIP calls. The logs you see on the terminal will let you know when a softphone registers with the Tomcat server and you will also be able to see the status of call setup and shutdown. - - - - -Stopping &SHORT_PLATFORM_NAME; for Tomcat 7 - - -The best way to stop a server is using the CTRL-D on the terminal in which the server was started. If you started the &SHORT_PLATFORM_NAME; for Tomcat 7 server using the $CATALINA_HOME/bin/startup.sh, you can stop the server using $CATALINA_HOME/bin/shutdown.sh - - -
- - -
-Tomcat for Windows - - - - - - - - - - - -
- - Installing the &SHORT_PLATFORM_NAME; for Tomcat 7 Binary Distribution on Windows - - - For this example, we'll assume that you downloaded the binary distribution zip file to the My Downloads folder. First, using Windows Explorer, create a subdirectory in My Downloads to extract the zip file's contents into. When you name this folder, it is good practice to include the version number; if you do so, remember to correctly match it with the version of the &SHORT_PLATFORM_NAME; for Tomcat binary distribution you downloaded. In these instructions, we will refer to this folder as &CMD_PLATFORM_NAME;-tomcat-<version>. - - - Double-click the downloaded zip file, selecting as the destination folder the one you just created to hold the zip file's contents. - - - Alternatively, it is also possible to use Java's jar command to extract the binary distribution files from the zip archive. To use this method instead, first move the downloaded zip file from My Downloads to the folder that you just created to hold the SIP Servlets Server files. - - - Then, open the Windows Command Prompt and navigate to the folder holding the archive using the cd command. - - Opening the Command Prompt from Windows Explorer - If you are using Windows Vista®, you can open the Command Prompt directly from Explorer. Hold down the Shift key and right-click on either a folder, the desktop, or inside a folder. This will cause an Open Command Window Here context menu item to appear, which can be used to open the Command Prompt with the current working directory set to either the folder you opened, or opened it from. - - - - Finally, use the jar command to extract the archive contents into the current folder. - C:\Users\Me\My Downloads\&CMD_PLATFORM_NAME;-tomcat-<version>>jar -xvf "&SSS_MSS4T_ZIP;" - - - - - At this point, you may want to move the folder holding the &SHORT_PLATFORM_NAME; for Tomcat binary files (in this example, the folder named &CMD_PLATFORM_NAME;-tomcat-<version>) to another location. This step is not strictly necessary, but it is probably a good idea to move the installation folder from My Downloads to a user-defined location for storing runnable programs. Any location will suffice, however. - - - You may want to delete the zip file after extracting its contents in order to free disk space: - C:\Users\Me\My Downloads\&CMD_PLATFORM_NAME;-tomcat-<version>>delete "&SSS_MSS4T_ZIP;" - - -
- - - - - - - - -
- Configuring - Configuring &SHORT_PLATFORM_NAME; for Tomcat consists in setting the CATALINA_HOME environment variable and then, optionally, customizing your &SHORT_PLATFORM_NAME; for Tomcat container by adding SIP Connectors, configuring the application router, and configuring logging. See to learn what and how to configure &SHORT_PLATFORM_NAME; for Tomcat. - Alternatively, you can simply run your &SHORT_PLATFORM_NAME; for Tomcat container now and return to this section to configure it later. -
- - -
- Running - Once installed, you can run the Tomcat Servlet Container by executing the one of the startup scripts in the bin directory (on Linux or Windows), or by double-clicking the run.bat executable batch file in that same directory (on Windows only). However, we suggest always starting Tomcat using the terminal or Command Prompt because you are then able to read—and act upon—any startup messages, and possibly debug any problems that may arise. In the Linux terminal or Command Prompt, you will be able to tell that the container started successfully if the last line of output is similar to the following: - - Detailed instructions are given below, arranged by platform. - - - - Running &SHORT_PLATFORM_NAME; for Tomcat on Windows - - There are several different ways to start the Tomcat Servlet Container on Windows. All of the following methods accomplish the same task. - Using Windows Explorer, change your folder to the one in which you unzipped the downloaded zip file, and then to the bin subdirectory. - - - Although not the preferred way (see below), it is possible to start the Tomcat Servlet Container by double-clicking on the startup.bat executable batch file. - - - As mentioned above, the best way to start the Tomcat Servlet Container is by using the Command Prompt. Doing it this way will allow you to view all of the server startup details, which will enable you to easily determine whether any problems were encountered during the startup process. You can open the Command Prompt directly from the <topmost_directory>\bin folder in Windows Explorer, or you can open the Command Prompt via the Start menu and navigate to the correct folder: - C:\Users\Me\My Downloads> cd "&CMD_PLATFORM_NAME;-tomcat-<version>" - - - Start the Tomcat Servlet Container by running the executable startup.bat batch file: - C:\Users\Me\My Downloads\&CMD_PLATFORM_NAME;-tomcat-<version>>bin\startup.bat - - - - -
-
- Stopping - Detailed instructions for stopping the Tomcat Servlet Container are given below, arranged by platform. Note that if you properly stop the server, you will see the following three lines as the last output in the Linux terminal or Command Prompt (both running and stopping the Tomcat Servlet Container produces the same output): - - - - - Stopping &SHORT_PLATFORM_NAME; for Tomcat on Windows - - Stopping the Tomcat Servlet Container on Windows consists in executing the shutdown.bat executable batch script in the bin subdirectory of the SIP Servlets-customized Tomcat binary distribution: - C:\Users\Me\My Downloads\&CMD_PLATFORM_NAME;-tomcat-<version>>bin\shutdown.bat - - -
- - - -
-
diff --git a/docs/sources/src/main/resources/en-US/task-section-echarts-Application-Router.xml b/docs/sources/src/main/resources/en-US/task-section-echarts-Application-Router.xml deleted file mode 100644 index c292371126..0000000000 --- a/docs/sources/src/main/resources/en-US/task-section-echarts-Application-Router.xml +++ /dev/null @@ -1,82 +0,0 @@ - - -%BOOK_ENTITIES; -]> -
- DFC Application Router -   -
- Description of DFC Application Router - Instead of using the &PLATFORM_NAME; Default Application Router, any SIP - Servlets 1.1 compliant Application Router can be used, including the eCharts DFC Application Router. -
-
- Installing the DFC Application Router - -Detailed instructions are available from the eCharts website. The following procedure describe how to install the eCharts DFC Application Router (DFCAR) on a variety of SIP Servlet Server platforms. - - Installing DFCAR on Tomcat - - Deploy the DFCAR - Drop the dfcar.jar from the ECharts distribution package in the - TOMCAT_HOME/lib directory. - - - Remove the DAR - Remove the &PLATFORM_NAME; - Default Application Router located in - TOMCAT_HOME/lib/sip-servlets-application-router-*.jar. - - - - - -Please see the following link to learn how to deploy jar files in &SHORT_PLATFORM_NAME; for JBoss AS7. - - - - - - Installing DFCAR on JBoss AS7 - - - Deploy the DFCAR - Create a directory under JBOSS_HOME/modules/system/layers/base/org/echarts/ - Drop the dfcar.jar from the ECharts distribution package in the - JBOSS_HOME/modules/system/layers/base/org/echarts/ directory. - Create a module.xml file under the same directory with the following contents - - - - - - - - -]]> - - - Remove the DAR - Remove the &PLATFORM_NAME; Default Application Router - located in - JBOSS_HOME/modules/system/layers/base/org/mobicents/dar. - - - Use the DFC DAR - In JBOSS_HOME/modules/system/layers/base/org/jboss/as/web/main/module.xml, replace the following line - ]]> - by this one - ]]> - - - - - -
-
diff --git a/management/jopr-plugin-as-5/.ant-targets-build-binary.xml b/management/jopr-plugin-as-5/.ant-targets-build-binary.xml deleted file mode 100644 index ddb8ac95f0..0000000000 --- a/management/jopr-plugin-as-5/.ant-targets-build-binary.xml +++ /dev/null @@ -1,4 +0,0 @@ -build-mobicents-jopr-plugin -extract-embjopr -get-embjopr -init diff --git a/management/jopr-plugin-as-5/.classpath b/management/jopr-plugin-as-5/.classpath deleted file mode 100644 index ef9bc0b8d9..0000000000 --- a/management/jopr-plugin-as-5/.classpath +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/management/jopr-plugin-as-5/.project b/management/jopr-plugin-as-5/.project deleted file mode 100644 index 0cd10b48a6..0000000000 --- a/management/jopr-plugin-as-5/.project +++ /dev/null @@ -1,13 +0,0 @@ - - jopr-mobicents-sip-servlets-as-5-plugin - A plugin for managing Mobicents Sip Servlets on JBoss 5 servers. NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse. - - - - org.eclipse.jdt.core.javabuilder - - - - org.eclipse.jdt.core.javanature - - \ No newline at end of file diff --git a/management/jopr-plugin-as-5/.settings/org.eclipse.jdt.core.prefs b/management/jopr-plugin-as-5/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 4c85c68ffb..0000000000 --- a/management/jopr-plugin-as-5/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,5 +0,0 @@ -#Wed May 06 12:30:37 CEST 2009 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.source=1.5 -org.eclipse.jdt.core.compiler.compliance=1.5 diff --git a/management/jopr-plugin-as-5/pom.xml b/management/jopr-plugin-as-5/pom.xml deleted file mode 100644 index 54bc3bbbe9..0000000000 --- a/management/jopr-plugin-as-5/pom.xml +++ /dev/null @@ -1,266 +0,0 @@ - - - 4.0.0 - - - mobicents - org.mobicents - 1.19 - - org.mobicents.servlet.sip.management - jopr-mobicents-sip-servlets-as-5-plugin - 1.7-SNAPSHOT - jar - - Jopr Mobicents Sip Servlets Plugin For JBoss 5 - A plugin for managing Mobicents Sip Servlets on JBoss 5 servers - - - jboss-public-repository-group - JBoss Public Maven Repository Group - https://repository.jboss.org/nexus/content/groups/public - default - - true - never - - - true - never - - - - maven2-repository.dev.java.net - Java.net Repository for Maven - http://download.java.net/maven/2/ - default - - - - - scm:svn:http://mobicents.googlecode.com/svn/trunk/servers/sip-servlets - scm:svn:https://mobicents.googlecode.com/svn/trunk/servers/sip-servlets - http://code.google.com/p/mobicents/source/browse/trunk/servers/sip-servlets - - - - jboss-releases-repository - JBoss Releases Repository - https://repository.jboss.org/nexus/service/local/staging/deploy/maven2/ - - - jboss-snapshots-repository - JBoss Snapshots Repository - https://repository.jboss.org/nexus/content/repositories/snapshots/ - - - - - 2.2.0.GA - 1.2.0.GA - 2.1.0.SP1 - - - - - org.rhq - rhq-core-parent - ${rhq-version} - pom - - - - log4j - log4j - 1.2.14 - provided - - - - - commons-logging - commons-logging - 1.0.4 - provided - - - - commons-io - commons-io - 1.4 - provided - - - - mc4j - org-mc4j-ems - 1.2.5 - - - - - - org.jetbrains - annotations - 7.0.2 - - - - org.rhq - rhq-core-client-api - ${rhq-version} - provided - - - - org.rhq - rhq-core-plugin-api - ${rhq-version} - provided - - - - org.rhq - rhq-core-native-system - ${rhq-version} - provided - - - - org.rhq - rhq-jmx-plugin - ${rhq-version} - provided - - - - org.rhq - rhq-core-domain - ${rhq-version} - provided - - - - org.rhq - rhq-core-domain - ${rhq-version} - provided - - - - javax.persistence - persistence-api - 1.0 - - - - javax.persistence - persistence-api - 1.0 - - - - org.hibernate - hibernate-annotations - 3.3.0.ga - - - org.hibernate - hibernate-commons-annotations - 3.3.0.ga - - - - org.jboss.integration - jboss-profileservice-spi - 5.1.0.GA - provided - - - - org.jboss.man - jboss-managed - ${jboss-man.version} - provided - - - - org.jboss.man - jboss-metatype - ${jboss-man.version} - provided - - - - - - - org.apache.maven.plugins - maven-source-plugin - - - - jar - - - - - - maven-compiler-plugin - - - - - 1.5 - 1.5 - - - - org.apache.maven.plugins - maven-antrun-plugin - 1.1 - - - package - - - - - - - - run - - - - - - org.apache.maven.plugins - maven-dependency-plugin - - - copy-to-jboss-lib - package - - copy-dependencies - - - rhq-jmx-plugin - ${JBOSS_HOME}/server/default/deploy/admin-console.war/plugins/ - - - - - - - diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/api/AbstractPropertyListAdapter.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/api/AbstractPropertyListAdapter.java deleted file mode 100644 index d07f45263a..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/api/AbstractPropertyListAdapter.java +++ /dev/null @@ -1,43 +0,0 @@ - /* - * Jopr Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.rhq.plugins.jbossas5.adapter.api; - -import org.rhq.core.domain.configuration.PropertyList; -import org.rhq.core.domain.configuration.definition.PropertyDefinitionList; - -import org.jboss.metatype.api.values.MetaValue; - -/** - * A base class for PropertyList <-> ???MetaValue adapters. - * - * @author Mark Spritzler - */ -public abstract class AbstractPropertyListAdapter implements PropertyAdapter -{ - public PropertyList convertToProperty(MetaValue metaValue, PropertyDefinitionList propDefList) - { - PropertyList propList = new PropertyList(propDefList.getName()); - populatePropertyFromMetaValue(propList, metaValue, propDefList); - return propList; - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/api/AbstractPropertyMapAdapter.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/api/AbstractPropertyMapAdapter.java deleted file mode 100644 index 90bed18b08..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/api/AbstractPropertyMapAdapter.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Jopr Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.rhq.plugins.jbossas5.adapter.api; - -import org.jboss.metatype.api.values.MetaValue; - -import org.rhq.core.domain.configuration.PropertyMap; -import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap; - -/** - * A base class for PropertyMap <-> ???MetaValue adapters. - * - * @author Mark Spritzler - */ -public abstract class AbstractPropertyMapAdapter implements PropertyAdapter -{ - public PropertyMap convertToProperty(MetaValue metaValue, PropertyDefinitionMap propDefMap) - { - PropertyMap propMap = new PropertyMap(propDefMap.getName()); - populatePropertyFromMetaValue(propMap, metaValue, propDefMap); - return propMap; - } -} \ No newline at end of file diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/api/AbstractPropertySimpleAdapter.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/api/AbstractPropertySimpleAdapter.java deleted file mode 100644 index acaef53b26..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/api/AbstractPropertySimpleAdapter.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Jopr Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.rhq.plugins.jbossas5.adapter.api; - -import org.jboss.metatype.api.values.MetaValue; - -import org.rhq.core.domain.configuration.PropertySimple; -import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * A base class for {@link PropertySimple} <-> ???MetaValue adapters. - * - * @author Ian Springer - */ -public abstract class AbstractPropertySimpleAdapter implements PropertyAdapter -{ - private final Log log = LogFactory.getLog(this.getClass()); - - public PropertySimple convertToProperty(MetaValue metaValue, PropertyDefinitionSimple propDefSimple) - { - PropertySimple propSimple = new PropertySimple(propDefSimple.getName(), null); - populatePropertyFromMetaValue(propSimple, metaValue, propDefSimple); - return propSimple; - } - - public void populateMetaValueFromProperty(PropertySimple propSimple, MetaValue metaValue, - PropertyDefinitionSimple propDefSimple) - { - if (metaValue == null) - throw new IllegalArgumentException("MetaValue to be populated is null."); - String value; - if (propSimple == null || propSimple.getStringValue() == null) { - // Value is null (i.e. prop is unset) - figure out what to use as a default value. - String defaultValue = propDefSimple.getDefaultValue(); - if (defaultValue != null) { - log.debug("Simple property '" + propDefSimple.getName() - + "' has a null value - setting inner value of corresponding ManagedProperty's MetaValue to plugin-specified default ('" - + defaultValue + "')..."); - value = defaultValue; - } else { - if (metaValue.getMetaType().isPrimitive()) - // If it's a primitive, don't mess with the MetaValue - just let it keep whatever inner value it - // currently has. - return; - // It's a non-primitive - set its value to null. In most cases, this should tell the managed resource - // to use its internal default. - log.debug("Simple property '" + propDefSimple.getName() - + "' has a null value - setting inner value of corresponding ManagedProperty's MetaValue to null..."); - value = null; - } - } else { - value = propSimple.getStringValue(); - } - setInnerValue(value, metaValue, propDefSimple); - } - - protected abstract void setInnerValue(String propSimpleValue, MetaValue metaValue, PropertyDefinitionSimple propDefSimple); -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/api/MeasurementAdapter.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/api/MeasurementAdapter.java deleted file mode 100644 index a2023dfbb1..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/api/MeasurementAdapter.java +++ /dev/null @@ -1,34 +0,0 @@ - /* - * Jopr Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.rhq.plugins.jbossas5.adapter.api; - -import org.jboss.metatype.api.values.MetaValue; -import org.rhq.core.domain.measurement.MeasurementData; -import org.rhq.core.domain.measurement.MeasurementDefinition; -import org.rhq.core.domain.measurement.MeasurementScheduleRequest; -import org.rhq.core.domain.measurement.MeasurementReport; - -public interface MeasurementAdapter -{ - public void setMeasurementData(MeasurementReport report, MetaValue metaValue, MeasurementScheduleRequest request, MeasurementDefinition measurementDefinition); -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/api/MeasurementAdapterFactory.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/api/MeasurementAdapterFactory.java deleted file mode 100644 index c70d55d98b..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/api/MeasurementAdapterFactory.java +++ /dev/null @@ -1,101 +0,0 @@ - /* - * Jopr Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.rhq.plugins.jbossas5.adapter.api; - -import org.jboss.metatype.api.types.MetaType; -import org.rhq.plugins.jbossas5.adapter.impl.measurement.SimpleMetaValueMeasurementAdapter; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.util.Map; -import java.util.HashMap; - -public class MeasurementAdapterFactory -{ - - private static final Log LOG = LogFactory.getLog(MeasurementAdapterFactory.class); - - private static Map customAdapters = new HashMap(); - - { - // Add customAdapters to the map - customAdapters.put("NoClasses", "NoClasses"); - } - - public static MeasurementAdapter getMeasurementPropertyAdapter(MetaType metaType) - { - MeasurementAdapter measurementAdapter = null; - if (metaType.isSimple()) - { - measurementAdapter = new SimpleMetaValueMeasurementAdapter(); - } - else if (metaType.isGeneric()) - { - measurementAdapter = null; - } - else if (metaType.isComposite()) - { - measurementAdapter = null; - } - else if (metaType.isTable()) - { - measurementAdapter = null; - } - else if (metaType.isCollection()) - { - measurementAdapter = null; - } - else if (metaType.isArray()) - { - measurementAdapter = null; - } - - return measurementAdapter; - } - - public static MeasurementAdapter getCustomMeasurementPropertyAdapter(String measurementName) - { - MeasurementAdapter measurementAdapter = null; - String adapterClassName = customAdapters.get(measurementName); - if (adapterClassName != null && !adapterClassName.equals("")) - { - try - { - measurementAdapter = (MeasurementAdapter) Class.forName(adapterClassName).newInstance(); - } - catch (InstantiationException e) - { - LOG.error("Cannot instantiate adapter class called " + adapterClassName, e); - } - catch (IllegalAccessException e) - { - LOG.error("Cannot access adapter class called " + adapterClassName, e); - } - catch (ClassNotFoundException e) - { - LOG.error("Cannot find adapter class called " + adapterClassName, e); - } - } - return measurementAdapter; - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/api/PropertyAdapter.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/api/PropertyAdapter.java deleted file mode 100644 index 4053d91587..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/api/PropertyAdapter.java +++ /dev/null @@ -1,87 +0,0 @@ - /* - * Jopr Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.rhq.plugins.jbossas5.adapter.api; - -import org.jboss.metatype.api.types.MetaType; -import org.jboss.metatype.api.values.MetaValue; -import org.rhq.core.domain.configuration.Property; -import org.rhq.core.domain.configuration.definition.PropertyDefinition; - -/** - * An adapter that can convert back and forth between a specific type of {@link MetaValue} and a specific - * type of {@link Property}. - * - * @author Mark Spritzler - * @author Ian Springer - */ -public interface PropertyAdapter

-{ - /** - * Given a {@link Property} and its {@link PropertyDefinition}, as well as a {@link MetaValue}, populate that - * MetaValue so it corresponds to the Property. If the Property is a list or a map, all descendant Property's should - * be added as descendants of the MetaValue. - * - * @param property the property to be copied - * @param metaValue the MetaValue to be populated; should not be null - * @param propertyDefinition the property's definition - */ - public void populateMetaValueFromProperty(P property, MetaValue metaValue, D propertyDefinition); - - /** - * Given a {@link Property} and its {@link PropertyDefinition}, create and return a corresponding {@link MetaValue} - * with the specified {@link MetaType}. If the Property is a list or a map, all descendant Property's should - * be represented as descendants of the returned MetaValue. Generally this method can simply create an empty - * MetaValue object and then delegate the population of the guts of the object to - * {@link #populateMetaValueFromProperty(Property, MetaValue, PropertyDefinition)}. - * - * @param property the property to be converted - * @param propertyDefinition the property's definition - * @param metaType the type of MetaValue that should be created and returned - * @return the MetaValue representation of the given Property - */ - public MetaValue convertToMetaValue(P property, D propertyDefinition, MetaType metaType); - - /** - * Given a {@link Property} and its {@link PropertyDefinition}, as well as a {@link MetaValue}, populate the - * Property so it corresponds to the MetaValue. If the MetaValue is a from of list or map, all descendant - * MetaValue's should be added as descendants of the Property. - * - * @param property the property to be populated; should not be null - * @param metaValue the MetaValue to be copied - * @param propertyDefinition the property's definition - */ - public void populatePropertyFromMetaValue(P property, MetaValue metaValue, D propertyDefinition); - - /** - * Given a {@link MetaValue}, create and return a corresponding {@link Property} - * with the specified {@link PropertyDefinition}. If the MetaValue is a form of list or map, all descendant - * MetaValue's should be represented as descendants of the returned Property. Generally this method can simply - * create an empty Property object and then delegate the population of the guts of the object to - * {@link #populatePropertyFromMetaValue(Property, MetaValue, PropertyDefinition)}. - * - * @param metaValue the metaValue to be converted - * @param propertyDefinition the definition of the property to be created and returned - * @return the Property representation of the given MetaValue - */ - public P convertToProperty(MetaValue metaValue, D propertyDefinition); -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/api/PropertyAdapterFactory.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/api/PropertyAdapterFactory.java deleted file mode 100644 index 78f6c35712..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/api/PropertyAdapterFactory.java +++ /dev/null @@ -1,126 +0,0 @@ - /* - * Jopr Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.rhq.plugins.jbossas5.adapter.api; - - import org.apache.commons.logging.Log; - import org.apache.commons.logging.LogFactory; - - import org.jboss.metatype.api.types.MetaType; - import org.jboss.metatype.api.types.MapCompositeMetaType; - import org.jboss.metatype.api.types.PropertiesMetaType; - import org.jboss.metatype.api.values.MetaValue; - - import org.rhq.core.domain.configuration.PropertySimple; - import org.rhq.plugins.jbossas5.adapter.impl.configuration.PropertyListToArrayValueAdapter; - import org.rhq.plugins.jbossas5.adapter.impl.configuration.PropertyListToCollectionValueAdapter; - import org.rhq.plugins.jbossas5.adapter.impl.configuration.PropertyMapToMapCompositeValueSupportAdapter; - import org.rhq.plugins.jbossas5.adapter.impl.configuration.PropertyMapToTableValueAdapter; - import org.rhq.plugins.jbossas5.adapter.impl.configuration.PropertySimpleToSimpleValueAdapter; - import org.rhq.plugins.jbossas5.adapter.impl.configuration.PropertyMapToGenericValueAdapter; - import org.rhq.plugins.jbossas5.adapter.impl.configuration.PropertySimpleToEnumValueAdapter; - import org.rhq.plugins.jbossas5.adapter.impl.configuration.PropertyMapToCompositeValueSupportAdapter; - import org.rhq.plugins.jbossas5.adapter.impl.configuration.PropertyMapToPropertiesValueAdapter; - import org.jetbrains.annotations.Nullable; - - /** - * @author Mark Spritzler - */ -public class PropertyAdapterFactory -{ - private static final Log LOG = LogFactory.getLog(PropertyAdapterFactory.class); - - public static PropertyAdapter getPropertyAdapter(MetaValue metaValue) - { - if (metaValue == null) - { - LOG.debug("The MetaValue passed in is null."); - return null; - } - MetaType metaType = metaValue.getMetaType(); - return getPropertyAdapter(metaType); - } - - public static PropertyAdapter getPropertyAdapter(MetaType metaType) - { - PropertyAdapter propertyAdapter = null; - if (metaType.isSimple()) - { - propertyAdapter = new PropertySimpleToSimpleValueAdapter(); - } - else if (metaType.isGeneric()) - { - propertyAdapter = new PropertyMapToGenericValueAdapter(); - } - else if (metaType.isComposite()) - { - if (metaType instanceof MapCompositeMetaType) - propertyAdapter = new PropertyMapToMapCompositeValueSupportAdapter(); - else - propertyAdapter = new PropertyMapToCompositeValueSupportAdapter(); - } - else if (metaType.isTable()) - { - propertyAdapter = new PropertyMapToTableValueAdapter(); - } - else if (metaType.isCollection()) - { - propertyAdapter = new PropertyListToCollectionValueAdapter(); - } - else if (metaType.isArray()) - { - propertyAdapter = new PropertyListToArrayValueAdapter(); - } - else if (metaType.isEnum()) - { - propertyAdapter = new PropertySimpleToEnumValueAdapter(); - } - else if (metaType instanceof PropertiesMetaType) - { - propertyAdapter = new PropertyMapToPropertiesValueAdapter(); - } - else - { - LOG.warn("Unsupported MetaType: " + metaType); - } - return propertyAdapter; - } - - @Nullable - public static PropertyAdapter getCustomPropertyAdapter(PropertySimple customProp) - { - if (customProp == null) - return null; - String adapterClassName = customProp.getStringValue(); - PropertyAdapter propertyAdapter = null; - try - { - Class adapterClass = Class.forName(adapterClassName); - propertyAdapter = (PropertyAdapter) adapterClass.newInstance(); - } - catch (Exception e) - { - LOG.error("Unable to create custom adapter class for " + customProp + ".", e); - } - return propertyAdapter; - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/AbstractPropertyMapToCompositeValueAdapter.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/AbstractPropertyMapToCompositeValueAdapter.java deleted file mode 100644 index 339264556c..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/AbstractPropertyMapToCompositeValueAdapter.java +++ /dev/null @@ -1,114 +0,0 @@ -/* -* Jopr Management Platform -* Copyright (C) 2005-2009 Red Hat, Inc. -* All rights reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License, version 2, as -* published by the Free Software Foundation, and/or the GNU Lesser -* General Public License, version 2.1, also as published by the Free -* Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License and the GNU Lesser General Public License -* for more details. -* -* You should have received a copy of the GNU General Public License -* and the GNU Lesser General Public License along with this program; -* if not, write to the Free Software Foundation, Inc., -* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -package org.rhq.plugins.jbossas5.adapter.impl.configuration; - -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.jboss.metatype.api.types.MetaType; -import org.jboss.metatype.api.types.SimpleMetaType; -import org.jboss.metatype.api.values.CompositeValue; -import org.jboss.metatype.api.values.MetaValue; - -import org.rhq.core.domain.configuration.Property; -import org.rhq.core.domain.configuration.PropertyMap; -import org.rhq.core.domain.configuration.PropertySimple; -import org.rhq.core.domain.configuration.definition.PropertyDefinition; -import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap; -import org.rhq.plugins.jbossas5.adapter.api.AbstractPropertyMapAdapter; -import org.rhq.plugins.jbossas5.adapter.api.PropertyAdapter; -import org.rhq.plugins.jbossas5.adapter.api.PropertyAdapterFactory; - -/** - * This class provides code that maps back and forth between a {@link PropertyMap} and - * a {@link CompositeValue}. Subclasses exist for the two different implementations - * of CompositeValue. - * - * @author Mark Spritzler - * @author Ian Springer - */ -public abstract class AbstractPropertyMapToCompositeValueAdapter extends AbstractPropertyMapAdapter - implements PropertyAdapter { - private final Log log = LogFactory.getLog(this.getClass()); - - public void populateMetaValueFromProperty(PropertyMap propMap, MetaValue metaValue, PropertyDefinitionMap propDefMap) { - CompositeValue compositeValue = (CompositeValue)metaValue; - for (String mapMemberPropName : propMap.getMap().keySet()) { - Property mapMemberProp = propMap.get(mapMemberPropName); - PropertyDefinition mapMemberPropDef = propDefMap.get(mapMemberPropName); - MetaType mapMemberMetaType = compositeValue.getMetaType().getType(mapMemberPropName); - if (mapMemberMetaType == null) { - // this will occur when new map properties are added since they are not present - // in the original metaValue which we are using - mapMemberMetaType = SimpleMetaType.STRING; - } - PropertyAdapter adapter = PropertyAdapterFactory.getPropertyAdapter(mapMemberMetaType); - MetaValue mapMemberMetaValue = adapter.convertToMetaValue(mapMemberProp, mapMemberPropDef, mapMemberMetaType); - putValue(compositeValue, mapMemberPropName, mapMemberMetaValue); - } - } - - public MetaValue convertToMetaValue(PropertyMap propMap, PropertyDefinitionMap propDefMap, MetaType metaType) { - CompositeValue compositeValue = createCompositeValue(propDefMap, metaType); - populateMetaValueFromProperty(propMap, compositeValue, propDefMap); - return compositeValue; - } - - public void populatePropertyFromMetaValue(PropertyMap propMap, MetaValue metaValue, PropertyDefinitionMap propDefMap) { - if (metaValue == null) - return; - CompositeValue compositeValue = (CompositeValue)metaValue; - Set mapMemberPropNames = compositeValue.getMetaType().keySet(); - // There won't be any keys when loading a Configuration for the first time. - for (String mapMemberPropName : mapMemberPropNames) { - Property mapMemberProp = propMap.get(mapMemberPropName); - MetaValue mapMemberMetaValue = compositeValue.get(mapMemberPropName); - MetaType mapMemberMetaType = compositeValue.getMetaType().getType(mapMemberPropName); - PropertyAdapter propertyAdapter = PropertyAdapterFactory.getPropertyAdapter(mapMemberMetaType); - PropertyDefinition mapMemberPropDef = propDefMap.get(mapMemberPropName); - if (mapMemberProp == null) { - if (mapMemberPropDef != null) - mapMemberProp = propertyAdapter.convertToProperty(mapMemberMetaValue, mapMemberPropDef); - else { - // If the member prop has no associated prop def, this is an "open map". - if (!mapMemberMetaType.isSimple() && !mapMemberMetaType.isEnum()) { - log.debug("Map member prop [" + mapMemberMetaType + "] is not a simple type - skipping..."); - continue; - } - // Create a PropertySimple and populate it. - mapMemberProp = new PropertySimple(mapMemberPropName, null); - // NOTE: It's ok that the propDef is null - PropertySimple*Adapter.populatePropertyFromMetaValue() - // doesn't use it for anything. - propertyAdapter.populatePropertyFromMetaValue(mapMemberProp, mapMemberMetaValue, mapMemberPropDef); - } - propMap.put(mapMemberProp); - } - } - } - - protected abstract void putValue(CompositeValue compositeValue, String key, MetaValue value); - - protected abstract CompositeValue createCompositeValue(PropertyDefinitionMap propDefMap, MetaType metaType); -} \ No newline at end of file diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/PropertyListToArrayValueAdapter.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/PropertyListToArrayValueAdapter.java deleted file mode 100644 index 8184e57513..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/PropertyListToArrayValueAdapter.java +++ /dev/null @@ -1,93 +0,0 @@ - /* - * Jopr Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.rhq.plugins.jbossas5.adapter.impl.configuration; - -import org.jboss.metatype.api.types.MetaType; -import org.jboss.metatype.api.values.ArrayValueSupport; -import org.jboss.metatype.api.values.MetaValue; -import org.jboss.metatype.api.values.MetaValueFactory; -import org.rhq.core.domain.configuration.Property; -import org.rhq.core.domain.configuration.PropertyList; -import org.rhq.core.domain.configuration.definition.PropertyDefinition; -import org.rhq.core.domain.configuration.definition.PropertyDefinitionList; -import org.rhq.plugins.jbossas5.adapter.api.AbstractPropertyListAdapter; -import org.rhq.plugins.jbossas5.adapter.api.PropertyAdapter; -import org.rhq.plugins.jbossas5.adapter.api.PropertyAdapterFactory; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author Mark Spritzler - */ -public class PropertyListToArrayValueAdapter extends AbstractPropertyListAdapter implements PropertyAdapter -{ - //@todo need to implement this like the other List to Collection, but not until there is an actual property that needs this - public void populateMetaValueFromProperty(PropertyList property, MetaValue metaValue, PropertyDefinitionList propertyDefinition) - { - PropertyDefinition memberDefinition = propertyDefinition.getMemberDefinition(); - List properties = property.getList(); - if (metaValue != null) - { - ArrayValueSupport valueSupport = (ArrayValueSupport) metaValue; - MetaType listMetaType = valueSupport.getMetaType().getElementType(); - List values = new ArrayList(properties.size()); - for (Property propertyWithinList : properties) - { - MetaValue value = MetaValueFactory.getInstance().create(null); - PropertyAdapter propertyAdapter = PropertyAdapterFactory.getPropertyAdapter(listMetaType); - propertyAdapter.populateMetaValueFromProperty(propertyWithinList, value, memberDefinition); - values.add(value); - } - valueSupport.setValue(values.toArray()); - } - } - - //@todo need to implement this like the other List to Collection, but not until there is an actual property that needs this - public MetaValue convertToMetaValue(PropertyList property, PropertyDefinitionList propertyDefinition, MetaType type) - { - return null; - } - - public void populatePropertyFromMetaValue(PropertyList property, MetaValue metaValue, PropertyDefinitionList propertyDefinition) - { - PropertyDefinition memberDefinition = propertyDefinition.getMemberDefinition(); - List properties = property.getList(); - - // Since we want to load the PropertyList with fresh values, we want it cleared out - properties.clear(); - - if (metaValue != null) - { - ArrayValueSupport valueSupport = (ArrayValueSupport) metaValue; - MetaType listMetaType = valueSupport.getMetaType().getElementType(); - MetaValue[] metaValues = (MetaValue[]) valueSupport.getValue(); - PropertyAdapter propertyAdapter = PropertyAdapterFactory.getPropertyAdapter(listMetaType); - for (MetaValue value : metaValues) - { - Property propertyToAddToList = propertyAdapter.convertToProperty(value, memberDefinition); - properties.add(propertyToAddToList); - } - } - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/PropertyListToCollectionValueAdapter.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/PropertyListToCollectionValueAdapter.java deleted file mode 100644 index c9f14f5986..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/PropertyListToCollectionValueAdapter.java +++ /dev/null @@ -1,94 +0,0 @@ -/* -* Jopr Management Platform -* Copyright (C) 2005-2009 Red Hat, Inc. -* All rights reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License, version 2, as -* published by the Free Software Foundation, and/or the GNU Lesser -* General Public License, version 2.1, also as published by the Free -* Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License and the GNU Lesser General Public License -* for more details. -* -* You should have received a copy of the GNU General Public License -* and the GNU Lesser General Public License along with this program; -* if not, write to the Free Software Foundation, Inc., -* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -package org.rhq.plugins.jbossas5.adapter.impl.configuration; - -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.jboss.metatype.api.types.CollectionMetaType; -import org.jboss.metatype.api.types.MetaType; -import org.jboss.metatype.api.values.CollectionValue; -import org.jboss.metatype.api.values.CollectionValueSupport; -import org.jboss.metatype.api.values.MetaValue; - -import org.rhq.core.domain.configuration.Property; -import org.rhq.core.domain.configuration.PropertyList; -import org.rhq.core.domain.configuration.definition.PropertyDefinition; -import org.rhq.core.domain.configuration.definition.PropertyDefinitionList; -import org.rhq.plugins.jbossas5.adapter.api.AbstractPropertyListAdapter; -import org.rhq.plugins.jbossas5.adapter.api.PropertyAdapter; -import org.rhq.plugins.jbossas5.adapter.api.PropertyAdapterFactory; - -/** - * @author Mark Spritzler - * @author Ian Springer - */ -public class PropertyListToCollectionValueAdapter extends AbstractPropertyListAdapter implements PropertyAdapter { - private static final Log LOG = LogFactory.getLog(PropertyListToCollectionValueAdapter.class); - - public void populateMetaValueFromProperty(PropertyList property, MetaValue metaValue, PropertyDefinitionList propertyDefinition) { - PropertyDefinition listMemberPropDef = propertyDefinition.getMemberDefinition(); - List listMemberProps = property.getList(); - CollectionValueSupport collectionValue = (CollectionValueSupport)metaValue; - MetaType listMemberMetaType = collectionValue.getMetaType().getElementType(); - MetaValue[] listMemberValues = new MetaValue[listMemberProps.size()]; - PropertyAdapter propertyAdapter = PropertyAdapterFactory.getPropertyAdapter(listMemberMetaType); - int memberIndex = 0; - for (Property listMemberProp : listMemberProps) { - MetaValue listMemberValue = propertyAdapter.convertToMetaValue(listMemberProp, listMemberPropDef, listMemberMetaType); - listMemberValues[memberIndex++] = listMemberValue; - } - // Replace the existing elements with the new ones. - collectionValue.setElements(listMemberValues); - } - - public MetaValue convertToMetaValue(PropertyList propertyList, PropertyDefinitionList propertyListDefinition, MetaType metaType) { - LOG.debug("GetMetaValue for property: " + propertyList.getName() + " values: " + propertyList.getList().toString()); - CollectionMetaType collectionMetaType = (CollectionMetaType)metaType; - MetaType memberMetaType = collectionMetaType.getElementType(); - CollectionMetaType collectionType = new CollectionMetaType(propertyListDefinition.getName(), memberMetaType); - CollectionValue collectionValue = new CollectionValueSupport(collectionType); - populateMetaValueFromProperty(propertyList, collectionValue, propertyListDefinition); - return collectionValue; - } - - public void populatePropertyFromMetaValue(PropertyList propList, MetaValue metaValue, PropertyDefinitionList propDefList) { - PropertyDefinition memberPropDef = propDefList.getMemberDefinition(); - if (propList != null) { - // Since we want to load the PropertyList with fresh values, we want it cleared out. - propList.getList().clear(); - if (metaValue != null) { - CollectionValue collectionValue = (CollectionValue)metaValue; - MetaType listMemberMetaType = collectionValue.getMetaType().getElementType(); - MetaValue[] listMemberValues = collectionValue.getElements(); - PropertyAdapter propertyAdapter = PropertyAdapterFactory.getPropertyAdapter(listMemberMetaType); - for (MetaValue listMemberValue : listMemberValues) { - Property listMemberProp = propertyAdapter.convertToProperty(listMemberValue, memberPropDef); - propList.add(listMemberProp); - } - } - } - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/PropertyMapToCompositeValueSupportAdapter.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/PropertyMapToCompositeValueSupportAdapter.java deleted file mode 100644 index 767de35fb3..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/PropertyMapToCompositeValueSupportAdapter.java +++ /dev/null @@ -1,73 +0,0 @@ -/* -* Jopr Management Platform -* Copyright (C) 2005-2009 Red Hat, Inc. -* All rights reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License, version 2, as -* published by the Free Software Foundation, and/or the GNU Lesser -* General Public License, version 2.1, also as published by the Free -* Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License and the GNU Lesser General Public License -* for more details. -* -* You should have received a copy of the GNU General Public License -* and the GNU Lesser General Public License along with this program; -* if not, write to the Free Software Foundation, Inc., -* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -package org.rhq.plugins.jbossas5.adapter.impl.configuration; - -import org.jboss.metatype.api.types.MetaType; -import org.jboss.metatype.api.values.CompositeValue; -import org.jboss.metatype.api.values.CompositeValueSupport; -import org.jboss.metatype.api.values.MetaValue; -import org.jboss.metatype.plugins.types.MutableCompositeMetaType; - -import org.rhq.core.domain.configuration.PropertyMap; -import org.rhq.core.domain.configuration.definition.PropertyDefinition; -import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap; -import org.rhq.plugins.jbossas5.adapter.api.PropertyAdapter; -import org.rhq.plugins.jbossas5.util.ConversionUtils; - -/** - * This class provides code that maps back and forth between a {@link PropertyMap} and - * a {@link CompositeValueSupport}. A CompositeValueSupport is a - * {@link CompositeValue} implementation that contains items that may be of different - * types. - * - * @author Ian Springer - */ -public class PropertyMapToCompositeValueSupportAdapter extends AbstractPropertyMapToCompositeValueAdapter - implements PropertyAdapter { - protected void putValue(CompositeValue compositeValue, String key, MetaValue value) { - CompositeValueSupport compositeValueSupport = (CompositeValueSupport)compositeValue; - compositeValueSupport.set(key, value); - } - - protected CompositeValue createCompositeValue(PropertyDefinitionMap propDefMap, MetaType metaType) { - MutableCompositeMetaType compositeMetaType; - if (metaType != null) - compositeMetaType = (MutableCompositeMetaType)metaType; - else { - // TODO: See if this else block is actually necessary (I think it is needed for creates). - String name = (propDefMap != null) ? - propDefMap.getName() : "CompositeMetaType"; - String desc = (propDefMap != null && propDefMap.getDescription() != null) ? - propDefMap.getDescription() : "none"; - compositeMetaType = new MutableCompositeMetaType(name, desc); - if (propDefMap != null) { - for (PropertyDefinition mapMemberPropDef : propDefMap.getPropertyDefinitions().values()) { - String mapMemberDesc = (propDefMap.getDescription() != null) ? propDefMap.getDescription() : "none"; - MetaType mapMemberMetaType = ConversionUtils.convertPropertyDefinitionToMetaType(mapMemberPropDef); - compositeMetaType.addItem(mapMemberPropDef.getName(), mapMemberDesc, mapMemberMetaType); - } - } - } - return new CompositeValueSupport(compositeMetaType); - } -} \ No newline at end of file diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/PropertyMapToGenericValueAdapter.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/PropertyMapToGenericValueAdapter.java deleted file mode 100644 index fff0f522c3..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/PropertyMapToGenericValueAdapter.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -package org.rhq.plugins.jbossas5.adapter.impl.configuration; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.jboss.managed.api.ManagedObject; -import org.jboss.managed.api.ManagedProperty; -import org.jboss.managed.plugins.ManagedObjectImpl; -import org.jboss.managed.plugins.ManagedPropertyImpl; -import org.jboss.metatype.api.types.MetaType; -import org.jboss.metatype.api.types.GenericMetaType; -import org.jboss.metatype.api.values.MetaValue; -import org.jboss.metatype.api.values.SimpleValue; -import org.jboss.metatype.api.values.GenericValue; -import org.jboss.metatype.api.values.EnumValue; -import org.jboss.metatype.api.values.GenericValueSupport; - -import org.rhq.core.domain.configuration.PropertyMap; -import org.rhq.core.domain.configuration.PropertySimple; -import org.rhq.core.domain.configuration.Property; -import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap; -import org.rhq.core.domain.configuration.definition.PropertyDefinition; -import org.rhq.plugins.jbossas5.adapter.api.PropertyAdapter; -import org.rhq.plugins.jbossas5.adapter.api.PropertyAdapterFactory; -import org.rhq.plugins.jbossas5.adapter.api.AbstractPropertyMapAdapter; -import org.rhq.plugins.jbossas5.util.ConversionUtils; - -/** - * This class provides code that maps back and forth between a {@link PropertyMap} and - * a {@link GenericValue}. The GenericValue's value is assumed to be a {@link ManagedObject}. - * - * @author Ian Springer - */ -public class PropertyMapToGenericValueAdapter extends AbstractPropertyMapAdapter - implements PropertyAdapter { - private final Log log = LogFactory.getLog(this.getClass()); - - public void populateMetaValueFromProperty(PropertyMap propMap, MetaValue metaValue, PropertyDefinitionMap propDefMap) { - GenericValue genericValue = (GenericValue)metaValue; - if (!(genericValue.getValue() instanceof ManagedObject)) { - log.error("GenericValue's value [" + genericValue.getValue() + "] is not a ManagedObject - not supported!"); - return; - } - ManagedObject managedObject = (ManagedObject)genericValue.getValue(); - for(String propName : propMap.getMap().keySet()) { - Property mapMemberProp = propMap.get(propName); - ManagedProperty managedProp = managedObject.getProperty(propName); - MetaType metaType = managedProp.getMetaType(); - PropertyAdapter propertyAdapter = PropertyAdapterFactory.getPropertyAdapter(metaType); - PropertyDefinition mapMemberPropDef = propDefMap.get(propName); - if (managedProp.getValue() == null) - { - MetaValue managedPropMetaValue = propertyAdapter.convertToMetaValue(mapMemberProp, mapMemberPropDef, metaType); - managedProp.setValue(managedPropMetaValue); - } - else - { - MetaValue managedPropMetaValue = (MetaValue)managedProp.getValue(); - propertyAdapter.populateMetaValueFromProperty(mapMemberProp, managedPropMetaValue, mapMemberPropDef); - } - } - } - - public MetaValue convertToMetaValue(PropertyMap propMap, PropertyDefinitionMap propDefMap, MetaType metaType) { - //GenericMetaType genericMetaType = (GenericMetaType)metaType; - ManagedObjectImpl managedObject = new ManagedObjectImpl(propDefMap.getName()); - for (PropertyDefinition mapMemberPropDef : propDefMap.getPropertyDefinitions().values()) { - ManagedPropertyImpl managedProp = new ManagedPropertyImpl(mapMemberPropDef.getName()); - MetaType managedPropMetaType = ConversionUtils.convertPropertyDefinitionToMetaType(mapMemberPropDef); - managedProp.setMetaType(managedPropMetaType); - managedProp.setManagedObject(managedObject); - managedObject.getProperties().put(managedProp.getName(), managedProp); - } - GenericValue genericValue = new GenericValueSupport(new GenericMetaType(propDefMap.getName(), - propDefMap.getDescription()), managedObject); - populateMetaValueFromProperty(propMap, genericValue, propDefMap); - return genericValue; - } - - public void populatePropertyFromMetaValue(PropertyMap propMap, MetaValue metaValue, PropertyDefinitionMap propDefMap) { - GenericValue genericValue = (GenericValue)metaValue; - ManagedObject managedObject = (ManagedObject)genericValue.getValue(); - for (String propName : propDefMap.getPropertyDefinitions().keySet()) { - ManagedProperty managedProp = managedObject.getProperty(propName); - if (managedProp != null) { - MetaType metaType = managedProp.getMetaType(); - Object value; - if (metaType.isSimple()) { - SimpleValue simpleValue = (SimpleValue)managedProp.getValue(); - value = simpleValue.getValue(); - } else if (metaType.isEnum()) { - EnumValue enumValue = (EnumValue)managedProp.getValue(); - value = enumValue.getValue(); - } else { - log.error("Nested ManagedProperty's value [" + managedProp.getValue() - + "] is not a SimpleValue or EnumValue - unsupported!"); - continue; - } - propMap.put(new PropertySimple(propName, value)); - } - } - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/PropertyMapToMapCompositeValueSupportAdapter.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/PropertyMapToMapCompositeValueSupportAdapter.java deleted file mode 100644 index affcce2388..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/PropertyMapToMapCompositeValueSupportAdapter.java +++ /dev/null @@ -1,54 +0,0 @@ -/* -* Jopr Management Platform -* Copyright (C) 2005-2009 Red Hat, Inc. -* All rights reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License, version 2, as -* published by the Free Software Foundation, and/or the GNU Lesser -* General Public License, version 2.1, also as published by the Free -* Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License and the GNU Lesser General Public License -* for more details. -* -* You should have received a copy of the GNU General Public License -* and the GNU Lesser General Public License along with this program; -* if not, write to the Free Software Foundation, Inc., -* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -package org.rhq.plugins.jbossas5.adapter.impl.configuration; - -import org.jboss.metatype.api.types.MapCompositeMetaType; -import org.jboss.metatype.api.types.MetaType; -import org.jboss.metatype.api.values.CompositeValue; -import org.jboss.metatype.api.values.MapCompositeValueSupport; -import org.jboss.metatype.api.values.MetaValue; - -import org.rhq.core.domain.configuration.PropertyMap; -import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap; -import org.rhq.plugins.jbossas5.adapter.api.PropertyAdapter; - -/** - * This class provides code that maps back and forth between a {@link PropertyMap} and - * a {@link MapCompositeValueSupport}. A MapCompositeValueSupport is a - * {@link CompositeValue} implementation that contains items that are all of the same - * type. - * - * @author Ian Springer - */ -public class PropertyMapToMapCompositeValueSupportAdapter extends AbstractPropertyMapToCompositeValueAdapter implements PropertyAdapter { - protected void putValue(CompositeValue compositeValue, String key, MetaValue value) { - MapCompositeValueSupport mapCompositeValueSupport = (MapCompositeValueSupport)compositeValue; - mapCompositeValueSupport.put(key, value); - } - - protected CompositeValue createCompositeValue(PropertyDefinitionMap propDefMap, MetaType metaType) { - MapCompositeMetaType mapCompositeMetaType = (MapCompositeMetaType)metaType; - MetaType mapMemberMetaType = mapCompositeMetaType.getValueType(); - return new MapCompositeValueSupport(mapMemberMetaType); - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/PropertyMapToPropertiesValueAdapter.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/PropertyMapToPropertiesValueAdapter.java deleted file mode 100644 index 06c193be8e..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/PropertyMapToPropertiesValueAdapter.java +++ /dev/null @@ -1,84 +0,0 @@ -/* -* Jopr Management Platform -* Copyright (C) 2005-2009 Red Hat, Inc. -* All rights reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License, version 2, as -* published by the Free Software Foundation, and/or the GNU Lesser -* General Public License, version 2.1, also as published by the Free -* Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License and the GNU Lesser General Public License -* for more details. -* -* You should have received a copy of the GNU General Public License -* and the GNU Lesser General Public License along with this program; -* if not, write to the Free Software Foundation, Inc., -* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -package org.rhq.plugins.jbossas5.adapter.impl.configuration; - -import java.util.HashSet; -import java.util.Set; - -import org.rhq.core.domain.configuration.Property; -import org.rhq.core.domain.configuration.PropertyMap; -import org.rhq.core.domain.configuration.PropertySimple; -import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap; -import org.rhq.plugins.jbossas5.adapter.api.AbstractPropertyMapAdapter; -import org.rhq.plugins.jbossas5.adapter.api.PropertyAdapter; - -import org.jboss.metatype.api.types.MetaType; -import org.jboss.metatype.api.values.MetaValue; -import org.jboss.metatype.api.values.PropertiesMetaValue; - -/** - * This class provides code that maps back and forth between a {@link PropertyMap} and - * a {@link PropertiesMetaValue}. A PropertiesMetaValue extends - * java.util.Properties. Its associated PropertiesMetaType may or may not define - * member property names; since the RHQ Configuration system assumes a - * PropertyDefinitionMap either defines none of its member properties (i.e. an "open - * map") or defines all of them, we just ignore the PropertiesMetaType and always map - * to an open map. - * - * @author Ian Springer - */ -public class PropertyMapToPropertiesValueAdapter extends AbstractPropertyMapAdapter - implements PropertyAdapter { - public void populateMetaValueFromProperty(PropertyMap propMap, MetaValue metaValue, PropertyDefinitionMap propDefMap) { - PropertiesMetaValue propertiesValue = (PropertiesMetaValue)metaValue; - for (String mapMemberPropName : propMap.getMap().keySet()) { - Property mapMemberProp = propMap.get(mapMemberPropName); - propertiesValue.setProperty(mapMemberProp.getName(), ((PropertySimple)mapMemberProp).getStringValue()); - } - } - - public MetaValue convertToMetaValue(PropertyMap propMap, PropertyDefinitionMap propDefMap, MetaType metaType) { - PropertiesMetaValue propertiesValue = new PropertiesMetaValue(); - populateMetaValueFromProperty(propMap, propertiesValue, propDefMap); - return propertiesValue; - } - - public void populatePropertyFromMetaValue(PropertyMap propMap, MetaValue metaValue, PropertyDefinitionMap propDefMap) { - if (metaValue == null) - return; - PropertiesMetaValue propertiesValue = (PropertiesMetaValue)metaValue; - Set mapMemberPropNames = new HashSet(); - for (Object key : propertiesValue.keySet()) - mapMemberPropNames.add((String)key); - // There won't be any keys when loading a Configuration for the first time. - for (String mapMemberPropName : mapMemberPropNames) { - // We assume the PropertyMap is an "open map", since that's what PropertiesMetaValue maps to. - PropertySimple mapMemberProp = propMap.getSimple(mapMemberPropName); - // Create a PropertySimple and populate it. - if (mapMemberProp == null) { - mapMemberProp = new PropertySimple(mapMemberPropName, propertiesValue.getProperty(mapMemberPropName)); - propMap.put(mapMemberProp); - } - } - } -} \ No newline at end of file diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/PropertyMapToTableValueAdapter.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/PropertyMapToTableValueAdapter.java deleted file mode 100644 index b479013aee..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/PropertyMapToTableValueAdapter.java +++ /dev/null @@ -1,94 +0,0 @@ - /* - * Jopr Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.rhq.plugins.jbossas5.adapter.impl.configuration; - - import java.util.Collection; - import java.util.Map; - - import org.jboss.metatype.api.types.MetaType; - import org.jboss.metatype.api.values.CompositeValue; - import org.jboss.metatype.api.values.CompositeValueSupport; - import org.jboss.metatype.api.values.MetaValue; - import org.jboss.metatype.api.values.SimpleValueSupport; - import org.jboss.metatype.api.values.TableValueSupport; - - import org.rhq.core.domain.configuration.Property; - import org.rhq.core.domain.configuration.PropertyMap; - import org.rhq.core.domain.configuration.definition.PropertyDefinition; - import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap; - import org.rhq.plugins.jbossas5.adapter.api.AbstractPropertyMapAdapter; - import org.rhq.plugins.jbossas5.adapter.api.PropertyAdapter; - import org.rhq.plugins.jbossas5.adapter.api.PropertyAdapterFactory; - -/** - * @author Mark Spritzler - */ -public class PropertyMapToTableValueAdapter extends AbstractPropertyMapAdapter implements PropertyAdapter -{ - public PropertyMap convertToProperty(MetaValue metaValue, PropertyDefinitionMap propertyDefinition) - { - PropertyMap property = new PropertyMap(); - populatePropertyFromMetaValue(property, metaValue, propertyDefinition); - return property; - } - - //@todo need to implement this like the other Map to Composite, but not until there is an actual property that needs this - public void populateMetaValueFromProperty(PropertyMap property, MetaValue metaValue, PropertyDefinitionMap propertyDefinition) - { - if (metaValue != null) - { - TableValueSupport tableValueSupport = (TableValueSupport) metaValue; - Map map = propertyDefinition.getPropertyDefinitions(); - Map properties = property.getMap(); - for (String key : map.keySet()) - { - PropertyDefinition definition = map.get(key); - MetaValue[] getKey = new MetaValue[]{SimpleValueSupport.wrap(key)}; - MetaValue value = tableValueSupport.get(getKey); - Property innerProperty = properties.get(key); - PropertyAdapter adapter = PropertyAdapterFactory.getPropertyAdapter(value); - adapter.populateMetaValueFromProperty(innerProperty, value, definition); - } - } - } - - //@todo need to implement this like the other Map to Composite, but not until there is an actual property that needs this - public MetaValue convertToMetaValue(PropertyMap property, PropertyDefinitionMap propertyDefinition, MetaType type) - { - return null; - } - - public void populatePropertyFromMetaValue(PropertyMap property, MetaValue metaValue, PropertyDefinitionMap propertyDefinition) - { - // Not important at this moment to implement as there sin't a need for this mapping yet. - if (metaValue != null) - { - TableValueSupport valueSupport = (TableValueSupport) metaValue; - Collection values = valueSupport.values(); - for (CompositeValue value : values) - { - CompositeValueSupport support = (CompositeValueSupport) value; - } - } - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/PropertySimpleToEnumValueAdapter.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/PropertySimpleToEnumValueAdapter.java deleted file mode 100644 index 5be270f221..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/PropertySimpleToEnumValueAdapter.java +++ /dev/null @@ -1,62 +0,0 @@ - /* - * Jopr Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.rhq.plugins.jbossas5.adapter.impl.configuration; - -import org.jboss.metatype.api.values.MetaValue; -import org.jboss.metatype.api.values.EnumValueSupport; -import org.jboss.metatype.api.values.EnumValue; -import org.jboss.metatype.api.types.MetaType; -import org.jboss.metatype.api.types.EnumMetaType; - -import org.rhq.core.domain.configuration.PropertySimple; -import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple; -import org.rhq.plugins.jbossas5.adapter.api.AbstractPropertySimpleAdapter; -import org.rhq.plugins.jbossas5.adapter.api.PropertyAdapter; - -/** - * This class provides code that maps back and forth between a {@link PropertySimple} and - * an {@link EnumValueSupport}. - * - * @author Ian Springer - */ -public class PropertySimpleToEnumValueAdapter extends AbstractPropertySimpleAdapter implements PropertyAdapter -{ - public void populatePropertyFromMetaValue(PropertySimple propSimple, MetaValue metaValue, PropertyDefinitionSimple propDefSimple) - { - Object value = (metaValue != null) ? ((EnumValue) metaValue).getValue() : null; - propSimple.setValue(value); - } - - public MetaValue convertToMetaValue(PropertySimple propSimple, PropertyDefinitionSimple propDefSimple, MetaType metaType) - { - EnumValue enumValue = new EnumValueSupport((EnumMetaType) metaType, propSimple.getStringValue()); - populateMetaValueFromProperty(propSimple, enumValue, propDefSimple); - return enumValue; - } - - protected void setInnerValue(String propSimpleValue, MetaValue metaValue, PropertyDefinitionSimple propDefSimple) - { - EnumValueSupport enumValueSupport = (EnumValueSupport) metaValue; - enumValueSupport.setValue(propSimpleValue); - } -} \ No newline at end of file diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/PropertySimpleToSimpleValueAdapter.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/PropertySimpleToSimpleValueAdapter.java deleted file mode 100644 index 539e4bbb8f..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/PropertySimpleToSimpleValueAdapter.java +++ /dev/null @@ -1,95 +0,0 @@ - /* - * Jopr Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.rhq.plugins.jbossas5.adapter.impl.configuration; - - import java.io.Serializable; - - import org.rhq.core.domain.configuration.PropertySimple; - import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple; - import org.rhq.plugins.jbossas5.adapter.api.AbstractPropertySimpleAdapter; - import org.rhq.plugins.jbossas5.adapter.api.PropertyAdapter; - - import org.jboss.metatype.api.types.MetaType; - import org.jboss.metatype.api.types.SimpleMetaType; - import org.jboss.metatype.api.values.MetaValue; - import org.jboss.metatype.api.values.SimpleValue; - import org.jboss.metatype.api.values.SimpleValueSupport; - -/** - * This class provides code that maps back and forth between a {@link PropertySimple} and - * a {@link SimpleValueSupport}. - * - * @author Ian Springer - * @author Mark Spritzler - */ -public class PropertySimpleToSimpleValueAdapter extends AbstractPropertySimpleAdapter implements PropertyAdapter -{ - public void populatePropertyFromMetaValue(PropertySimple propSimple, MetaValue metaValue, PropertyDefinitionSimple propDefSimple) - { - Object value = (metaValue != null) ? ((SimpleValue) metaValue).getValue() : null; - propSimple.setValue(value); - } - - public MetaValue convertToMetaValue(PropertySimple propSimple, PropertyDefinitionSimple propDefSimple, MetaType metaType) - { - SimpleValue simpleValue = new SimpleValueSupport((SimpleMetaType) metaType, null); - populateMetaValueFromProperty(propSimple, simpleValue, propDefSimple); - return simpleValue; - } - - protected void setInnerValue(String propSimpleValue, MetaValue metaValue, PropertyDefinitionSimple propDefSimple) - { - SimpleValueSupport simpleValueSupport = (SimpleValueSupport) metaValue; - if (propSimpleValue == null) { - // A null value is the easiest case - just set the SimpleMetaValue's inner value to null. - simpleValueSupport.setValue(null); - return; - } - // String value is non-null, so we can massage it into the proper type for the SimpleMetaValue's inner value. - SimpleMetaType simpleMetaType = simpleValueSupport.getMetaType(); - Serializable innerValue; - if (simpleMetaType.equals(SimpleMetaType.STRING) || simpleMetaType.equals(SimpleMetaType.NAMEDOBJECT)) - innerValue = propSimpleValue; - else if (simpleMetaType.equals(SimpleMetaType.BOOLEAN) || simpleMetaType.equals(SimpleMetaType.BOOLEAN_PRIMITIVE)) - innerValue = Boolean.valueOf(propSimpleValue); - else if (simpleMetaType.equals(SimpleMetaType.BYTE) || simpleMetaType.equals(SimpleMetaType.BYTE_PRIMITIVE)) - innerValue = Byte.valueOf(propSimpleValue); - else if (simpleMetaType.equals(SimpleMetaType.CHARACTER) || simpleMetaType.equals(SimpleMetaType.CHARACTER_PRIMITIVE)) { - if (propSimpleValue.length() != 1) - throw new IllegalStateException("String value '" + propSimpleValue + " cannot be converted to a character."); - innerValue = propSimpleValue.charAt(0); - } else if (simpleMetaType.equals(SimpleMetaType.DOUBLE) || simpleMetaType.equals(SimpleMetaType.DOUBLE_PRIMITIVE)) - innerValue = Double.valueOf(propSimpleValue); - else if (simpleMetaType.equals(SimpleMetaType.FLOAT) || simpleMetaType.equals(SimpleMetaType.FLOAT_PRIMITIVE)) - innerValue = Float.valueOf(propSimpleValue); - else if (simpleMetaType.equals(SimpleMetaType.INTEGER) || simpleMetaType.equals(SimpleMetaType.INTEGER_PRIMITIVE)) - innerValue = Integer.valueOf(propSimpleValue); - else if (simpleMetaType.equals(SimpleMetaType.LONG) || simpleMetaType.equals(SimpleMetaType.LONG_PRIMITIVE)) - innerValue = Long.valueOf(propSimpleValue); - else if (simpleMetaType.equals(SimpleMetaType.SHORT) || simpleMetaType.equals(SimpleMetaType.SHORT_PRIMITIVE)) - innerValue = Short.valueOf(propSimpleValue); - else - throw new IllegalStateException("Unsupported MetaType: " + simpleMetaType); - simpleValueSupport.setValue(innerValue); - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/custom/JMSSecurityConfigAdapter.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/custom/JMSSecurityConfigAdapter.java deleted file mode 100644 index 199ec6ccdc..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/configuration/custom/JMSSecurityConfigAdapter.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Jopr Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.rhq.plugins.jbossas5.adapter.impl.configuration.custom; - -import org.rhq.core.domain.configuration.Property; -import org.rhq.core.domain.configuration.PropertyList; -import org.rhq.core.domain.configuration.PropertyMap; -import org.rhq.core.domain.configuration.PropertySimple; -import org.rhq.core.domain.configuration.definition.PropertyDefinitionList; -import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap; -import org.rhq.core.domain.configuration.definition.PropertyDefinition; -import org.rhq.plugins.jbossas5.adapter.api.AbstractPropertyListAdapter; -import org.rhq.plugins.jbossas5.adapter.api.PropertyAdapter; -import org.rhq.plugins.jbossas5.adapter.api.PropertyAdapterFactory; -import org.rhq.plugins.jbossas5.adapter.impl.configuration.PropertyMapToMapCompositeValueSupportAdapter; -import org.rhq.plugins.jbossas5.util.ConversionUtils; - -import org.jboss.metatype.api.types.CompositeMetaType; -import org.jboss.metatype.api.types.MetaType; -import org.jboss.metatype.api.types.MapCompositeMetaType; -import org.jboss.metatype.api.types.SimpleMetaType; -import org.jboss.metatype.api.values.CompositeValue; -import org.jboss.metatype.api.values.CompositeValueSupport; -import org.jboss.metatype.api.values.MapCompositeValueSupport; -import org.jboss.metatype.api.values.MetaValue; -import org.jboss.metatype.plugins.types.MutableCompositeMetaType; - -/** - * This class provides code that maps back and forth between a {@link PropertyList} of {@link PropertyMap}s and - * a {@link MapCompositeValueSupport} with the key being a JMS security role name and the value being a - * {@link CompositeValueSupport}s representing the role's read/write/create permissions. Here's what the - * PropertyList looks like: - * - * - * <c:list-property name="securityConfig" min="2" max="4" - * displayName="Security Configurations" - * description="This element specifies a XML fragment which describes the access control list to be - * used by the SecurityManager to authorize client operations against the destination. - * The content model is the same as for the SecurityManager SecurityConf attribute."> - * <c:map-property name="role" - * displayName="Security Configuration Attributes" - * description="These are the attributes that define the role name, and if the role is allowed to - * read, write or create Messages on this Queue."> - * <c:simple-property name="name" - * description="Name of the Security Role. e.g. Guest" - * summary="true" required="true"/> - * <c:simple-property name="read" - * description="Is this role allowed to read messages?" - * summary="true" required="false" type="boolean"/> - * <c:simple-property name="write" - * description="Is this role allowed to write messages?" - * summary="true" required="false" type="boolean"/> - * <c:simple-property name="create" - * description="Is this role allowed to create messages?" - * summary="true" required="false" type="boolean"/> - * </c:map-property> - * </c:list-property> - * - * - * @author Ian Springer - */ -public class JMSSecurityConfigAdapter extends AbstractPropertyListAdapter -{ - public MetaValue convertToMetaValue(PropertyList propertyList, PropertyDefinitionList propertyDefinitionList, - MetaType metaType) - { - MapCompositeMetaType securityConfigCompositeMetaType = (MapCompositeMetaType)metaType; - MapCompositeValueSupport securityConfigCompositeValue = - new MapCompositeValueSupport(securityConfigCompositeMetaType.getValueType()); - populateMetaValueFromProperty(propertyList, securityConfigCompositeValue, propertyDefinitionList); - return securityConfigCompositeValue; - } - - public void populateMetaValueFromProperty(PropertyList propertyList, MetaValue metaValue, - PropertyDefinitionList propertyDefinitionList) - { - MapCompositeValueSupport securityConfigCompositeValue = (MapCompositeValueSupport)metaValue; - PropertyDefinitionMap memberPropDefMap = (PropertyDefinitionMap)propertyDefinitionList.getMemberDefinition(); - for (Property memberProperty : propertyList.getList()) { - PropertyMap memberPropMap = (PropertyMap)memberProperty; - String roleName = memberPropMap.getSimple("name").getStringValue(); - CompositeValueSupport roleCompositeValue = (CompositeValueSupport)createCompositeValue(memberPropDefMap); - populateMetaValueFromProperty(memberPropMap, roleCompositeValue, memberPropDefMap); - securityConfigCompositeValue.put(roleName, roleCompositeValue); - } - } - - public void populatePropertyFromMetaValue(PropertyList propertyList, MetaValue metaValue, - PropertyDefinitionList propertyDefinitionList) - { - CompositeValue compositeValue = (CompositeValue)metaValue; - CompositeMetaType compositeMetaType = compositeValue.getMetaType(); - PropertyDefinitionMap memberPropertyDefinitionMap = (PropertyDefinitionMap)propertyDefinitionList.getMemberDefinition(); - PropertyMapToMapCompositeValueSupportAdapter mapToMapCompositeValueAdapter = new PropertyMapToMapCompositeValueSupportAdapter(); - for (String memberName : compositeMetaType.itemSet()) { - MetaValue memberMetaValue = compositeValue.get(memberName); - PropertyMap memberPropertyMap = mapToMapCompositeValueAdapter.convertToProperty(memberMetaValue, memberPropertyDefinitionMap); - memberPropertyMap.put(new PropertySimple("name", memberName)); // add a simple for the role name to the map - propertyList.add(memberPropertyMap); - } - } - - // NOTE: We can't just leverage PropertyMapToCompositeValueSupportAdapter, because we have to skip the "name" map member. - private CompositeValue createCompositeValue(PropertyDefinitionMap propDefMap) { - String name = (propDefMap != null) ? - propDefMap.getName() : "CompositeMetaType"; - String desc = (propDefMap != null && propDefMap.getDescription() != null) ? - propDefMap.getDescription() : "none"; - MutableCompositeMetaType compositeMetaType = new MutableCompositeMetaType(name, desc); - if (propDefMap != null) { - for (PropertyDefinition mapMemberPropDef : propDefMap.getPropertyDefinitions().values()) { - if (mapMemberPropDef.getName().equals("name")) - continue; - String mapMemberDesc = (propDefMap.getDescription() != null) ? propDefMap.getDescription() : "none"; - MetaType mapMemberMetaType = ConversionUtils.convertPropertyDefinitionToMetaType(mapMemberPropDef); - compositeMetaType.addItem(mapMemberPropDef.getName(), mapMemberDesc, mapMemberMetaType); - } - } - return new CompositeValueSupport(compositeMetaType); - } - - // NOTE: We can't just leverage PropertyMapToCompositeValueSupportAdapter, because we have to skip the "name" map member. - private void populateMetaValueFromProperty(PropertyMap propMap, MetaValue metaValue, PropertyDefinitionMap propDefMap) { - CompositeValueSupport compositeValue = (CompositeValueSupport)metaValue; - for (String mapMemberPropName : propMap.getMap().keySet()) { - if (mapMemberPropName.equals("name")) - continue; - Property mapMemberProp = propMap.get(mapMemberPropName); - PropertyDefinition mapMemberPropDef = propDefMap.get(mapMemberPropName); - MetaType mapMemberMetaType = compositeValue.getMetaType().getType(mapMemberPropName); - if (mapMemberMetaType == null) { - // this will occur when new map properties are added since they are not present - // in the original metaValue which we are using - mapMemberMetaType = SimpleMetaType.STRING; - } - PropertyAdapter adapter = PropertyAdapterFactory.getPropertyAdapter(mapMemberMetaType); - MetaValue mapMemberMetaValue = adapter.convertToMetaValue(mapMemberProp, mapMemberPropDef, mapMemberMetaType); - compositeValue.set(mapMemberPropName, mapMemberMetaValue); - } - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/measurement/SimpleMetaValueMeasurementAdapter.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/measurement/SimpleMetaValueMeasurementAdapter.java deleted file mode 100644 index 6a4ac814e8..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/measurement/SimpleMetaValueMeasurementAdapter.java +++ /dev/null @@ -1,67 +0,0 @@ -/* -* Jopr Management Platform -* Copyright (C) 2005-2009 Red Hat, Inc. -* All rights reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License, version 2, as -* published by the Free Software Foundation, and/or the GNU Lesser -* General Public License, version 2.1, also as published by the Free -* Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License and the GNU Lesser General Public License -* for more details. -* -* You should have received a copy of the GNU General Public License -* and the GNU Lesser General Public License along with this program; -* if not, write to the Free Software Foundation, Inc., -* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -package org.rhq.plugins.jbossas5.adapter.impl.measurement; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.jboss.metatype.api.values.MetaValue; -import org.jboss.metatype.api.values.SimpleValueSupport; - -import org.rhq.core.domain.measurement.DataType; -import org.rhq.core.domain.measurement.MeasurementDataNumeric; -import org.rhq.core.domain.measurement.MeasurementDataTrait; -import org.rhq.core.domain.measurement.MeasurementDefinition; -import org.rhq.core.domain.measurement.MeasurementReport; -import org.rhq.core.domain.measurement.MeasurementScheduleRequest; -import org.rhq.plugins.jbossas5.adapter.api.MeasurementAdapter; - -/** - * TODO - */ -public class SimpleMetaValueMeasurementAdapter implements MeasurementAdapter { - private final Log LOG = LogFactory.getLog(SimpleMetaValueMeasurementAdapter.class); - - public void setMeasurementData(MeasurementReport report, MetaValue metaValue, MeasurementScheduleRequest request, MeasurementDefinition measurementDefinition) { - SimpleValueSupport simpleValue = (SimpleValueSupport)metaValue; - DataType dataType = measurementDefinition.getDataType(); - switch (dataType) { - case MEASUREMENT: - try { - MeasurementDataNumeric dataNumeric = new MeasurementDataNumeric(request, new Double(simpleValue.getValue().toString())); - report.addData(dataNumeric); - } - catch (NumberFormatException e) { - LOG.warn("Measurement request: " + request.getName() + " did not return a numeric value from the Profile Service", e); - } - break; - case TRAIT: - MeasurementDataTrait dataTrait = new MeasurementDataTrait(request, String.valueOf(simpleValue.getValue())); - report.addData(dataTrait); - break; - default: - throw new IllegalStateException("Unsupported measurement data type: " + dataType); - - } - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/measurement/custom/JMSMessageCounterAdapter.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/measurement/custom/JMSMessageCounterAdapter.java deleted file mode 100644 index 4b2563d5fc..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/measurement/custom/JMSMessageCounterAdapter.java +++ /dev/null @@ -1,57 +0,0 @@ - /* - * Jopr Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - package org.rhq.plugins.jbossas5.adapter.impl.measurement.custom; - -import org.jboss.metatype.api.values.CompositeValueSupport; -import org.jboss.metatype.api.values.MetaValue; -import org.jboss.metatype.api.values.SimpleValueSupport; -import org.rhq.core.domain.measurement.DataType; -import org.rhq.core.domain.measurement.MeasurementDataNumeric; -import org.rhq.core.domain.measurement.MeasurementDataTrait; -import org.rhq.core.domain.measurement.MeasurementDefinition; -import org.rhq.core.domain.measurement.MeasurementReport; -import org.rhq.core.domain.measurement.MeasurementScheduleRequest; -import org.rhq.plugins.jbossas5.adapter.api.MeasurementAdapter; - -public class JMSMessageCounterAdapter implements MeasurementAdapter -{ - public void setMeasurementData(MeasurementReport report, MetaValue metaValue, MeasurementScheduleRequest request, MeasurementDefinition measurementDefinition) - { - // TODO: fix this - CompositeValueSupport compositeValue = (CompositeValueSupport) metaValue; - DataType dataType = measurementDefinition.getDataType(); - String metricName = request.getName(); - if (dataType.equals(DataType.MEASUREMENT)) - { - //@todo break out the getting the value out of the ValueSupport object - MeasurementDataNumeric dataNumeric = new MeasurementDataNumeric(request, (Double) ((SimpleValueSupport) (compositeValue.get(metricName))).getValue()); - report.addData(dataNumeric); - } - else if (dataType.equals(DataType.TRAIT)) - { - //@todo break out the getting the value out of the ValueSupport object - MeasurementDataTrait dataTrait = new MeasurementDataTrait(request, (String) ((SimpleValueSupport) (compositeValue.get(metricName))).getValue()); - report.addData(dataTrait); - } - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/measurement/custom/JMSMessageStatisticsAdapter.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/measurement/custom/JMSMessageStatisticsAdapter.java deleted file mode 100644 index b3cc172dd0..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/adapter/impl/measurement/custom/JMSMessageStatisticsAdapter.java +++ /dev/null @@ -1,37 +0,0 @@ - /* - * Jopr Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - package org.rhq.plugins.jbossas5.adapter.impl.measurement.custom; - -import org.rhq.plugins.jbossas5.adapter.api.MeasurementAdapter; -import org.rhq.core.domain.measurement.MeasurementReport; -import org.rhq.core.domain.measurement.MeasurementScheduleRequest; -import org.rhq.core.domain.measurement.MeasurementDefinition; -import org.jboss.metatype.api.values.MetaValue; - -public class JMSMessageStatisticsAdapter implements MeasurementAdapter -{ - public void setMeasurementData(MeasurementReport report, MetaValue metaValue, MeasurementScheduleRequest request, MeasurementDefinition measurementDefinition) - { - // TODO - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/factory/ProfileServiceFactory.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/factory/ProfileServiceFactory.java deleted file mode 100644 index f48210d568..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/factory/ProfileServiceFactory.java +++ /dev/null @@ -1,227 +0,0 @@ - /* - * Jopr Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.rhq.plugins.jbossas5.factory; - -import java.util.Set; - -import javax.naming.InitialContext; -import javax.naming.NamingException; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jetbrains.annotations.NotNull; - -import org.jboss.deployers.spi.management.ManagementView; -import org.jboss.deployers.spi.management.deploy.DeploymentManager; -import org.jboss.managed.api.ComponentType; -import org.jboss.managed.api.ManagedComponent; -import org.jboss.profileservice.spi.ProfileKey; -import org.jboss.profileservice.spi.ProfileService; - -/** - * Factory class to get the ProfileService and Profile Service related objects directly from the - * ProfileService object. - * - * @author Mark Spritzler - */ -public class ProfileServiceFactory -{ - private static final Log LOG = LogFactory.getLog(ProfileServiceFactory.class); - - private static final String PROFILE_SERVICE_JNDI_NAME = "ProfileService"; - - private static ProfileService profileService; - - private static ManagementView currentProfileView; - - private static final ProfileKey DEFAULT_PROFILE_KEY = new ProfileKey(ProfileKey.DEFAULT); - - /** - * Returns the profile service from the JBoss server through JNDI - * - * @return ProfileService - */ - @NotNull - public static ProfileService getProfileService() - { - if (profileService == null) - { - InitialContext initialContext; - try - { - initialContext = new InitialContext(); - } - catch (NamingException e) - { - throw new RuntimeException("Failed to create JNDI InitialContext.", e); - } - try - { - profileService = (ProfileService) initialContext.lookup(PROFILE_SERVICE_JNDI_NAME); - } - catch (NamingException e) - { - throw new RuntimeException("Failed to lookup JNDI name '" + PROFILE_SERVICE_JNDI_NAME - + "' from InitialContext.", e); - } - } - return profileService; - } - - /** - * Get the current profile's Management view. This will get the domains from the profile service - * and return the first one in the list. - * - * @return ManagementView the management view of the first domain - */ - public static ManagementView getCurrentProfileView() - { - if (currentProfileView == null) - { - currentProfileView = getProfileService().getViewManager(); - refreshCurrentProfileView(); - } - return currentProfileView; - } - - /** - * Refresh the current profile's ManagementView so it contains all the latest data. - * Use {@link #getCurrentProfileView()} to obtain the ManagementView. - */ - public static void refreshCurrentProfileView() - { - try - { - loadProfile(getCurrentProfileView()); - } - catch (Exception e) - { - LOG.error("Could not load default profile from current management view.", e); - } - } - - public static DeploymentManager getDeploymentManager() throws Exception { - DeploymentManager deploymentManager = getProfileService().getDeploymentManager(); - // Load and associate the given profile with the DeploymentManager for future operations. This is mandatory - // in order for us to be able to successfully invoke the various DeploymentManager methods. - loadProfile(deploymentManager); - return deploymentManager; - } - - private static void loadProfile(ManagementView managementView) - { - try - { - LOG.trace("Loading profile via ManagementView..."); - long startTime = System.currentTimeMillis(); - managementView.load(); - long elapsedTime = System.currentTimeMillis() - startTime; - LOG.trace("Loaded profile via Management View in " + elapsedTime + " ms."); - } - catch (Exception e) - { - LOG.error("Failed to load profile via Management View.", e); - } - } - - private static void loadProfile(DeploymentManager deploymentManager) - { - try - { - LOG.trace("Loading profile '" + DEFAULT_PROFILE_KEY + "' via Deployment Manager..."); - long startTime = System.currentTimeMillis(); - deploymentManager.loadProfile(DEFAULT_PROFILE_KEY); - long elapsedTime = System.currentTimeMillis() - startTime; - LOG.trace("Loaded profile '" + DEFAULT_PROFILE_KEY + "' via Deployment Manager in " + elapsedTime + " ms."); - } - catch (Exception e) - { - LOG.error("Failed to load profile '" + DEFAULT_PROFILE_KEY + "' via Deployment Manager.", e); - } - } - - /** - * Locate the given ComponentType with the given component name. - * - * @param type ComponentType of the component to get - * @param name String name of the component - * @return the matching ManagedComponent if found, null otherwise - * @throws Exception on error - */ - public static ManagedComponent getManagedComponent(ComponentType type, String name) - throws Exception - { - ManagementView managementView = getCurrentProfileView(); - return getManagedComponent(managementView, type, name); - } - - /** - * Locate the given ComponentType with the given component name. - * - * @param managementView - * @param type - * @param name - * @return the matching ManagedComponent if found, null otherwise - * @throws Exception on error - */ - public static ManagedComponent getManagedComponent(ManagementView managementView, - ComponentType type, String name) - throws Exception - { - Set managedComponents = managementView.getComponentsForType(type); - if (managedComponents != null) { - for (ManagedComponent managedComponent : managedComponents) { - if (managedComponent.getName().equals(name)) - return managedComponent; - } - } - return null; - } - - /** - * - * @param name - * @param componentType - * @return - */ - public static boolean isManagedComponent(String name, ComponentType componentType) - { - boolean isDeployed = false; - if (name != null) - { - try - { - ManagedComponent component = getManagedComponent(componentType, name); - if (component != null) - isDeployed = true; - } - catch (Exception e) - { - // Setting it to true to be safe than sorry, since there might be a component - // already deployed in the AS. TODO (ips): I don't think I like this. - isDeployed = true; - } - } - return isDeployed; - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/util/ConversionUtils.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/util/ConversionUtils.java deleted file mode 100644 index 8894d337bf..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/util/ConversionUtils.java +++ /dev/null @@ -1,431 +0,0 @@ - /* - * Jopr Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.rhq.plugins.jbossas5.util; - -import java.io.Serializable; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jboss.deployers.spi.management.KnownDeploymentTypes; -import org.jboss.managed.api.ComponentType; -import org.jboss.managed.api.ManagedOperation; -import org.jboss.managed.api.ManagedParameter; -import org.jboss.managed.api.ManagedProperty; -import org.jboss.managed.api.annotation.ViewUse; -import org.jboss.metatype.api.types.MapCompositeMetaType; -import org.jboss.metatype.api.types.MetaType; -import org.jboss.metatype.api.types.SimpleMetaType; -import org.jboss.metatype.api.values.EnumValue; -import org.jboss.metatype.api.values.MetaValue; -import org.jboss.metatype.api.values.SimpleValue; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.Property; -import org.rhq.core.domain.configuration.PropertySimple; -import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; -import org.rhq.core.domain.configuration.definition.ConfigurationTemplate; -import org.rhq.core.domain.configuration.definition.PropertyDefinition; -import org.rhq.core.domain.configuration.definition.PropertyDefinitionList; -import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap; -import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple; -import org.rhq.core.domain.configuration.definition.PropertySimpleType; -import org.rhq.core.domain.measurement.MeasurementDefinition; -import org.rhq.core.domain.measurement.MeasurementReport; -import org.rhq.core.domain.measurement.MeasurementScheduleRequest; -import org.rhq.core.domain.operation.OperationDefinition; -import org.rhq.core.domain.resource.ResourceType; -import org.rhq.plugins.jbossas5.adapter.api.MeasurementAdapter; -import org.rhq.plugins.jbossas5.adapter.api.MeasurementAdapterFactory; -import org.rhq.plugins.jbossas5.adapter.api.PropertyAdapter; -import org.rhq.plugins.jbossas5.adapter.api.PropertyAdapterFactory; -import org.rhq.plugins.mobicents.servlet.sip.jboss5.AbstractManagedDeploymentComponent; -import org.rhq.plugins.mobicents.servlet.sip.jboss5.ManagedComponentComponent; - - /** - * Utility class to convert some basic Profile Service objects to JON objects, and some basic - * manipulation and data gathering of Profile Service objects. - *

- * This should not include converting between Property objects and ManagedProperties. Those conversions - * should be in the corresponding Adapter classes. - * - * @author Ian Springer - * @author Mark Spritzler - */ -public class ConversionUtils -{ - private static final Log LOG = LogFactory.getLog(ConversionUtils.class); - - private static final Map COMPONENT_TYPE_CACHE = new HashMap(); - private static final Map DEPLOYMENT_TYPE_CACHE = new HashMap(); - private static final Map DEFAULT_PLUGIN_CONFIG_CACHE = new HashMap(); - - protected static final String PLUGIN = "ProfileService"; - - public static ComponentType getComponentType(@NotNull ResourceType resourceType) { - String resourceTypeName = resourceType.getName(); - if (COMPONENT_TYPE_CACHE.containsKey(resourceTypeName)) - return COMPONENT_TYPE_CACHE.get(resourceTypeName); - - Configuration defaultPluginConfig; - if (DEFAULT_PLUGIN_CONFIG_CACHE.containsKey(resourceTypeName)) - defaultPluginConfig = DEFAULT_PLUGIN_CONFIG_CACHE.get(resourceTypeName); - else { - defaultPluginConfig = getDefaultPluginConfiguration(resourceType); - DEFAULT_PLUGIN_CONFIG_CACHE.put(resourceTypeName, defaultPluginConfig); - } - - String type = defaultPluginConfig.getSimpleValue(ManagedComponentComponent.COMPONENT_TYPE_PROPERTY, null); - if (type == null || type.equals("")) - throw new IllegalStateException("Required plugin configuration property '" - + ManagedComponentComponent.COMPONENT_TYPE_PROPERTY + "' is not defined in default template."); - String subtype = defaultPluginConfig.getSimpleValue(ManagedComponentComponent.COMPONENT_SUBTYPE_PROPERTY, null); - if (subtype == null || subtype.equals("")) - throw new IllegalStateException("Required plugin configuration property '" - + ManagedComponentComponent.COMPONENT_SUBTYPE_PROPERTY + "' is not defined in default template."); - ComponentType componentType = new ComponentType(type, subtype); - COMPONENT_TYPE_CACHE.put(resourceTypeName, componentType); - return componentType; - } - - public static KnownDeploymentTypes getDeploymentType(@NotNull ResourceType resourceType) { - String resourceTypeName = resourceType.getName(); - if (DEPLOYMENT_TYPE_CACHE.containsKey(resourceTypeName)) - return DEPLOYMENT_TYPE_CACHE.get(resourceTypeName); - - Configuration defaultPluginConfig; - if (DEFAULT_PLUGIN_CONFIG_CACHE.containsKey(resourceTypeName)) - defaultPluginConfig = DEFAULT_PLUGIN_CONFIG_CACHE.get(resourceTypeName); - else { - defaultPluginConfig = getDefaultPluginConfiguration(resourceType); - DEFAULT_PLUGIN_CONFIG_CACHE.put(resourceTypeName, defaultPluginConfig); - } - - String typeName = defaultPluginConfig.getSimpleValue(AbstractManagedDeploymentComponent.DEPLOYMENT_TYPE_NAME_PROPERTY, null); - if (typeName == null || typeName.equals("")) - throw new IllegalStateException("Required plugin configuration property '" - + ManagedComponentComponent.COMPONENT_TYPE_PROPERTY + "' is not defined in default template."); - KnownDeploymentTypes deploymentType = KnownDeploymentTypes.valueOf(typeName); - DEPLOYMENT_TYPE_CACHE.put(resourceTypeName, deploymentType); - return deploymentType; - } - - private static Configuration getDefaultPluginConfiguration(ResourceType resourceType) { - ConfigurationDefinition definition = resourceType.getPluginConfigurationDefinition(); - if (definition != null) { - ConfigurationTemplate template = definition.getDefaultTemplate(); - if (template != null) { - return template.getConfiguration().deepCopy(); - } - } - return new Configuration(); // there is no default plugin config defined - return an empty one - } - - public static Configuration convertManagedObjectToConfiguration(Map managedProperties, - Map customProps, - ResourceType resourceType) - { - Configuration config = new Configuration(); - ConfigurationDefinition configDef = resourceType.getResourceConfigurationDefinition(); - Map propDefs = configDef.getPropertyDefinitions(); - Set propNames = managedProperties.keySet(); - for (String propName : propNames) - { - PropertyDefinition propertyDefinition = propDefs.get(propName); - ManagedProperty managedProperty = managedProperties.get(propName); - if (propertyDefinition == null) { - if (!managedProperty.hasViewUse(ViewUse.STATISTIC)) - LOG.debug(resourceType + " does not define a property corresponding to ManagedProperty '" + propName - + "'."); - continue; - } - if (managedProperty == null) { - // This should never happen, but don't let it blow us up. - LOG.error("ManagedProperty '" + propName + "' has a null value in the ManagedProperties Map."); - continue; - } - MetaValue metaValue = managedProperty.getValue(); - if (managedProperty.isRemoved() || metaValue == null) { - // Don't even add a Property to the Configuration if the ManagedProperty is flagged as removed or has a - // null value. - continue; - } - PropertySimple customProp = customProps.get(propName); - PropertyAdapter propertyAdapter = PropertyAdapterFactory.getCustomPropertyAdapter(customProp); - if (propertyAdapter == null) - propertyAdapter = PropertyAdapterFactory.getPropertyAdapter(metaValue); - if (propertyAdapter == null) - { - LOG.error("Unable to find a PropertyAdapter for ManagedProperty '" + propName + "' with MetaType [" - + metaValue.getMetaType() + "] for ResourceType '" + resourceType.getName() + "'."); - continue; - } - Property property = propertyAdapter.convertToProperty(metaValue, propertyDefinition); - config.put(property); - } - return config; - } - - public static void convertConfigurationToManagedProperties(Map managedProperties, - Configuration configuration, ResourceType resourceType, - Map customProps) - { - ConfigurationDefinition configDefinition = resourceType.getResourceConfigurationDefinition(); - Set missingManagedPropertyNames = new HashSet(); - for (Property property : configuration.getProperties()) - { - String propertyName = property.getName(); - ManagedProperty managedProperty = managedProperties.get(propertyName); - PropertyDefinition propertyDefinition = configDefinition.get(propertyName); - if (managedProperty == null) { - // NOTE: We expect the Profile Service to always return templates that contain *all* ManagedProperties - // that are defined for the ComponentType, so this is considered an error. We could build a - // ManagedProperty from scratch based on only a PropertyDefinition anyway, since a propDef could - // map to multiple different types of MetaValues (e.g. a PropertyList could potentially map to - // either an ArrayValue or a CollectionValue). - missingManagedPropertyNames.add(propertyName); - } - else { - populateManagedPropertyFromProperty(property, propertyDefinition, managedProperty, - customProps.get(propertyName)); - } - if (!missingManagedPropertyNames.isEmpty()) - throw new IllegalStateException("***** The following properties are defined in this plugin's " - + "descriptor but have no coresponding ManagedProperties: " + missingManagedPropertyNames); - } - return; - } - - private static void populateManagedPropertyFromProperty(Property property, PropertyDefinition propertyDefinition, - @NotNull ManagedProperty managedProperty, - @Nullable PropertySimple customProperty) - { - if (property == null || - (property instanceof PropertySimple && ((PropertySimple)property).getStringValue() == null)) { - // The property is unset, which translates to "removed" in Profile Service lingo. - // We will also set the ManagedProperty's MetaValue to a default value - this will be handled by the - // conversion performed below by the property's adapter. - managedProperty.setRemoved(true); - } - // If the ManagedProperty defines a default value, assume it's more definitive than any default value that may - // have been defined in the plugin descriptor, and update the PropertyDefinition to use that as its default - // value. - MetaValue defaultValue = managedProperty.getDefaultValue(); - if (defaultValue != null) - updateDefaultValueOnPropertyDefinition(propertyDefinition, defaultValue); - // See if there is a custom adapter defined for this property. - PropertyAdapter propertyAdapter = PropertyAdapterFactory.getCustomPropertyAdapter(customProperty); - MetaValue metaValue = managedProperty.getValue(); - if (metaValue != null) - { - LOG.trace("Populating existing MetaValue of type " + metaValue.getMetaType() - + " from RHQ property " + property + " with definition " + propertyDefinition + "..."); - if (propertyAdapter == null) - propertyAdapter = PropertyAdapterFactory.getPropertyAdapter(metaValue); - propertyAdapter.populateMetaValueFromProperty(property, metaValue, propertyDefinition); - } - else - { - MetaType metaType = managedProperty.getMetaType(); - if (propertyAdapter == null) - propertyAdapter = PropertyAdapterFactory.getPropertyAdapter(metaType); - LOG.trace("Converting property " + property + " with definition " + propertyDefinition - + " to MetaValue of type " + metaType + "..."); - metaValue = propertyAdapter.convertToMetaValue(property, propertyDefinition, metaType); - managedProperty.setValue(metaValue); - } - } - - private static void updateDefaultValueOnPropertyDefinition(PropertyDefinition propertyDefinition, - @NotNull MetaValue defaultValue) - { - if (!(propertyDefinition instanceof PropertyDefinitionSimple)) { - LOG.debug("Cannot update default value on non-simple property definition " + propertyDefinition - + "(default value is " + defaultValue + ")."); - return; - } - MetaType metaType = defaultValue.getMetaType(); - if (!metaType.isSimple() && !metaType.isEnum()) { - LOG.debug("Cannot update default value on " + propertyDefinition - + ", because default value's type (" + metaType + ") is not simple or enum."); - return; - } - PropertyDefinitionSimple propertyDefinitionSimple = (PropertyDefinitionSimple)propertyDefinition; - if (metaType.isSimple()) { - SimpleValue defaultSimpleValue = (SimpleValue)defaultValue; - Serializable value = defaultSimpleValue.getValue(); - propertyDefinitionSimple.setDefaultValue((value != null) ? value.toString() : null); - } else { // defaultValueMetaType.isEnum() - EnumValue defaultEnumValue = (EnumValue)defaultValue; - Serializable value = defaultEnumValue.getValue(); - propertyDefinitionSimple.setDefaultValue((value != null) ? value.toString() : null); - } - } - - public static MetaType convertPropertyDefinitionToMetaType(PropertyDefinition propDef) { - MetaType memberMetaType; - if (propDef instanceof PropertyDefinitionSimple) { - PropertySimpleType propSimpleType = ((PropertyDefinitionSimple)propDef).getType(); - memberMetaType = convertPropertySimpleTypeToSimpleMetaType(propSimpleType); - } else if (propDef instanceof PropertyDefinitionList) { - // TODO (very low priority, since lists of lists are not going to be at all common) - memberMetaType = null; - } else if (propDef instanceof PropertyDefinitionMap) { - Map memberPropDefs = ((PropertyDefinitionMap)propDef).getPropertyDefinitions(); - if (memberPropDefs.isEmpty()) - throw new IllegalStateException("PropertyDefinitionMap doesn't contain any member PropertyDefinitions."); - // NOTE: We assume member prop defs are all of the same type, since for MapCompositeMetaTypes, they have to be. - PropertyDefinition mapMemberPropDef = memberPropDefs.values().iterator().next(); - MetaType mapMemberMetaType = convertPropertyDefinitionToMetaType(mapMemberPropDef); - memberMetaType = new MapCompositeMetaType(mapMemberMetaType); - } else { - throw new IllegalStateException("List member PropertyDefinition has unknown type: " - + propDef.getClass().getName()); - } - return memberMetaType; - } - - private static MetaType convertPropertySimpleTypeToSimpleMetaType(PropertySimpleType memberSimpleType) { - MetaType memberMetaType; - Class memberClass; - switch (memberSimpleType) { - case BOOLEAN: memberClass = Boolean.class; break; - case INTEGER: memberClass = Integer.class; break; - case LONG: memberClass = Long.class; break; - case FLOAT: memberClass = Float.class; break; - case DOUBLE: memberClass = Double.class; break; - default: memberClass = String.class; break; - } - memberMetaType = SimpleMetaType.resolve(memberClass.getName()); - return memberMetaType; - } - - /** - * Takes the Configuration parameter object and converts it into a MetaValue array, which can them be passed - * in with the invoke method to the ProfileService to fire the operation of a resource. - * - * @param managedOperation Operation that will be fired and stores the parameter types for the operation - * @param parameters set of Parameter Values that the OperationFacet sent to the Component - * @param operationDefinition the RHQ operation definition - * @return MetaValue[] array of MetaValues representing the parameters; if there are no parameters, an empty array - * will be returned - */ - @NotNull - public static MetaValue[] convertOperationsParametersToMetaValues(@NotNull ManagedOperation managedOperation, - @NotNull Configuration parameters, - @NotNull OperationDefinition operationDefinition) - { - ConfigurationDefinition paramsConfigDef = operationDefinition.getParametersConfigurationDefinition(); - if (paramsConfigDef == null) - return new MetaValue[0]; - ManagedParameter[] managedParams = managedOperation.getParameters(); // this is guaranteed to be non-null - Map paramPropDefs = paramsConfigDef.getPropertyDefinitions(); - MetaValue[] paramMetaValues = new MetaValue[managedParams.length]; - for (int i = 0; i < managedParams.length; i++) - { - ManagedParameter managedParam = managedParams[i]; - String paramName = managedParam.getName(); - Property paramProp = parameters.get(paramName); - PropertyDefinition paramPropDef = paramPropDefs.get(paramName); - MetaType metaType = managedParam.getMetaType(); - PropertyAdapter propertyAdapter = PropertyAdapterFactory.getPropertyAdapter(metaType); - LOG.trace("Converting RHQ operation param property " + paramProp + " with definition " + paramPropDef - + " to MetaValue of type " + metaType + "..."); - MetaValue paramMetaValue = propertyAdapter.convertToMetaValue(paramProp, paramPropDef, metaType); - // NOTE: There's no need to set the value on the ManagedParameter, since the invoke() API takes an array of - // MetaValues. - paramMetaValues[i] = paramMetaValue; - } - return paramMetaValues; - } - - public static void convertManagedOperationResults(ManagedOperation operation, MetaValue resultMetaValue, - Configuration complexResults, - OperationDefinition operationDefinition) - { - ConfigurationDefinition resultConfigDef = operationDefinition.getResultsConfigurationDefinition(); - // Don't return any results if we have no definition with which to display them - if (resultConfigDef == null || resultConfigDef.getPropertyDefinitions().isEmpty()) { - if (resultMetaValue != null) { - LOG.error("Plugin error: Operation [" + operationDefinition.getName() - + "] is defined as returning no results, but it returned non-null results: " - + resultMetaValue.toString()); - } - return; - } else { - Map resultPropDefs = resultConfigDef.getPropertyDefinitions(); - // There should and must be only one property definition to map to the results from the Profile Service, - // otherwise there will be a huge mismatch. - if (resultPropDefs.size() > 1) - LOG.error("Operation [" + operationDefinition.getName() - + "] is defined with multiple result properties: " + resultPropDefs.values()); - - PropertyDefinition resultPropDef = resultPropDefs.values().iterator().next(); - - // Don't return any results, if the actual result object is null. - if (resultMetaValue == null) { - // Check if result is required or not, and if it is, log an error. - if (resultPropDef.isRequired()) { - LOG.error("Plugin error: Operation [" + operationDefinition.getName() - + "] is defined as returning a required result, but it returned null."); - } - return; - } - - MetaType resultMetaType = operation.getReturnType(); - if (!MetaTypeUtils.instanceOf(resultMetaValue, resultMetaType)) - LOG.debug("Profile Service Error: Result type (" + resultMetaType + ") of [" + operation.getName() - + "] ManagedOperation does not match the type of the value returned by invoke() (" - + resultMetaValue + ")."); - - PropertyAdapter propertyAdapter = PropertyAdapterFactory.getPropertyAdapter(resultMetaValue); - Property resultProp = propertyAdapter.convertToProperty(resultMetaValue, resultPropDef); - complexResults.put(resultProp); - } - } - - public static void convertMetricValuesToMeasurement(MeasurementReport report, ManagedProperty metricProperty, MeasurementScheduleRequest request, ResourceType resourceType, String deploymentName) - { - String metricName = metricProperty.getName(); - MetaType type = metricProperty.getMetaType(); - MetaValue value = metricProperty.getValue(); - if (value != null) - { - MeasurementAdapter measurementAdapter = MeasurementAdapterFactory.getMeasurementPropertyAdapter(type); - MeasurementDefinition measurementDefinition = ResourceTypeUtils.getMeasurementDefinition(resourceType, metricName); - if (measurementDefinition != null) - { - measurementAdapter.setMeasurementData(report, value, request, measurementDefinition); - } - } - else - { - LOG.debug("Unable to obtain metric data for resource: " + deploymentName + " metric: " + metricName); - } - } - -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/util/DebugUtils.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/util/DebugUtils.java deleted file mode 100644 index d54289d09b..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/util/DebugUtils.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -package org.rhq.plugins.jbossas5.util; - -import java.util.Map; -import java.util.ArrayList; -import java.util.List; -import java.util.Collections; -import java.util.Comparator; -import java.util.EnumSet; - -import org.jetbrains.annotations.Nullable; -import org.rhq.plugins.jbossas5.util.ManagedComponentUtils; - -import org.jboss.managed.api.ManagedComponent; -import org.jboss.managed.api.ManagedProperty; -import org.jboss.managed.api.DeploymentTemplateInfo; -import org.jboss.managed.api.annotation.ViewUse; -import org.jboss.metatype.api.values.MetaValue; -import org.jboss.metatype.api.values.CollectionValue; -import org.jboss.metatype.api.values.CompositeValue; - -/** - * Utility methods for converting various Profile Service objects into Strings for debugging purposes. - * - * @author Ian Springer - */ -public abstract class DebugUtils { - public static String convertPropertiesToString(ManagedComponent managedComponent) { - StringBuilder buf = new StringBuilder(); - String componentTypeName = managedComponent.getType().getSubtype() + " " + managedComponent.getType().getType(); - buf.append("Properties for [").append(componentTypeName).append("] ManagedComponent ["); - buf.append(managedComponent.getName()).append("]:\n"); - buf.append(convertPropertiesToString(managedComponent.getProperties())); - return buf.toString(); - } - - public static String convertPropertiesToString(DeploymentTemplateInfo template) { - StringBuilder buf = new StringBuilder(); - buf.append("Properties for DeploymentTemplateInfo [").append(template.getName()).append("]:\n"); - buf.append(convertPropertiesToString(template.getProperties())); - return buf.toString(); - } - - public static String convertMetaValueToString(MetaValue metaValue) { - StringBuilder buffer = new StringBuilder(); - convertMetaValueToString(metaValue, buffer, true, 1); - return buffer.toString(); - } - - public static String convertPropertiesToString(Map managedProps) { - StringBuilder buf = new StringBuilder(); - List props = new ArrayList(managedProps.values()); - Collections.sort(props, new ManagedPropertyComparator()); // sort by name - for (ManagedProperty managedProperty : props) { - if (managedProperty.isMandatory()) - buf.append("* "); - else - buf.append(" "); - buf.append("name=").append(managedProperty.getName()); - if (!managedProperty.getName().equals(managedProperty.getMappedName())) - buf.append(", mappedName=").append(managedProperty.getMappedName()); - EnumSet viewUses = ManagedComponentUtils.getViewUses(managedProperty); - buf.append(", viewUses=").append(viewUses); - buf.append(", readOnly=").append(managedProperty.isReadOnly()); - buf.append(", mandatory=").append(managedProperty.isMandatory()); - buf.append(", removed=").append(managedProperty.isRemoved()); - Object value = managedProperty.getValue(); - if (value != null && !(value instanceof MetaValue)) - throw new IllegalStateException("Value of ManagedProperty [" + managedProperty.getName() - + "] is not a MetaValue - it is a " + value.getClass().getName() + "."); - if (value == null) - buf.append(", type=").append(managedProperty.getMetaType()); - buf.append(", value=").append(convertMetaValueToString((MetaValue)value)); - } - return buf.toString(); - } - - private static void convertMetaValueToString(MetaValue metaValue, StringBuilder buffer, boolean indentFirstLine, - int indentLevel) { - if (indentFirstLine) - for (int i = 0; i < indentLevel; i++) buffer.append(" "); - if (metaValue == null) { - buffer.append("<<>>\n"); // make it stand out a bit - } else if (metaValue.getMetaType().isCollection()) { - CollectionValue collectionValue = (CollectionValue)metaValue; - buffer.append(collectionValue).append("\n"); - /*for (int i = 0; i < indentLevel; i++) buffer.append(" "); - buffer.append("Elements:\n"); - indentLevel++; - for (MetaValue elementMetaValue : collectionValue.getElements()) - convertMetaValueToString(elementMetaValue, buffer, true, indentLevel);*/ - } else if (metaValue.getMetaType().isComposite()) { - CompositeValue compositeValue = (CompositeValue)metaValue; - buffer.append(compositeValue).append("\n"); - /*for (int i = 0; i < indentLevel; i++) buffer.append(" "); - buffer.append("Items:\n"); - indentLevel++; - for (String key : compositeValue.getMetaType().keySet()) { - for (int i = 0; i < indentLevel; i++) buffer.append(" "); - buffer.append(key).append("="); - convertMetaValueToString(compositeValue.get(key), buffer, false, indentLevel); - }*/ - } else { - buffer.append(metaValue).append("\n"); - } - } - - private static class ManagedPropertyComparator implements Comparator { - /** - * Use viewUse as primary sort field and name as secondary sort field. - */ - public int compare(ManagedProperty prop1, ManagedProperty prop2) { - ViewUse prop1ViewUse = getPrimaryViewUse(prop1); - ViewUse prop2ViewUse = getPrimaryViewUse(prop2); - if (prop1ViewUse == null) - return (prop2ViewUse == null) ? 0 : -1; - if (prop2ViewUse == null) - return 1; - int result = prop1ViewUse.name().compareTo(prop2ViewUse.name()); - if (result == 0) - result = prop1.getName().compareTo(prop2.getName()); // break the tie - return result; - } - - @Nullable - private static ViewUse getPrimaryViewUse(ManagedProperty managedProperty) - { - ViewUse viewUse; - if (managedProperty.hasViewUse(ViewUse.CONFIGURATION)) - viewUse = ViewUse.CONFIGURATION; - else if (managedProperty.hasViewUse(ViewUse.RUNTIME)) - viewUse = ViewUse.RUNTIME; - else if (managedProperty.hasViewUse(ViewUse.STATISTIC)) - viewUse = ViewUse.STATISTIC; - else - viewUse = null; - return viewUse; - } - } - - private DebugUtils() { - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/util/ManagedComponentUtils.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/util/ManagedComponentUtils.java deleted file mode 100644 index a6cf15a1d6..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/util/ManagedComponentUtils.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -package org.rhq.plugins.jbossas5.util; - -import java.util.Set; -import java.util.EnumSet; -import java.io.Serializable; - -import org.rhq.plugins.jbossas5.factory.ProfileServiceFactory; -import org.jetbrains.annotations.NotNull; - -import org.jboss.deployers.spi.management.ManagementView; -import org.jboss.managed.api.ComponentType; -import org.jboss.managed.api.ManagedComponent; -import org.jboss.managed.api.ManagedProperty; -import org.jboss.managed.api.annotation.ViewUse; -import org.jboss.metatype.api.values.SimpleValue; -import org.jboss.metatype.api.values.EnumValue; -import org.jboss.metatype.api.types.MetaType; - -/** - * @author Ian Springer - */ -public class ManagedComponentUtils -{ - public static ManagedComponent getManagedComponent(ComponentType componentType, String componentName) - { - Set components = getManagedComponents(componentType); - for (ManagedComponent component : components) - { - if (component.getName().equals(componentName)) - return component; - } - return null; - } - - public static ManagedComponent getSingletonManagedComponent(ComponentType componentType) - { - Set components = getManagedComponents(componentType); - if (components.size() != 1) - throw new IllegalStateException("Found more than one component of type " + componentType + ": " - + components); - @SuppressWarnings({"UnnecessaryLocalVariable"}) - ManagedComponent component = components.iterator().next(); - return component; - } - - public static Serializable getSimplePropertyValue(ManagedComponent component, String propertyName) - { - ManagedProperty property = component.getProperty(propertyName); - MetaType metaType = property.getMetaType(); - Serializable value; - if (metaType.isSimple()) { - SimpleValue simpleValue = (SimpleValue)property.getValue(); - value = (simpleValue != null) ? simpleValue.getValue() : null; - } else if (metaType.isEnum()) { - EnumValue enumValue = (EnumValue)property.getValue(); - value = (enumValue != null) ? enumValue.getValue() : null; - } else { - throw new IllegalStateException("Type of [" + property + "] is not simple or enum."); - } - return value; - } - - @NotNull - public static EnumSet getViewUses(ManagedProperty managedProperty) - { - EnumSet viewUses = EnumSet.noneOf(ViewUse.class); - for (ViewUse viewUse : ViewUse.values()) { - if (managedProperty.hasViewUse(viewUse)) - viewUses.add(viewUse); - } - return viewUses; - } - - @NotNull - private static Set getManagedComponents(ComponentType componentType) - { - ManagementView managementView = ProfileServiceFactory.getCurrentProfileView(); - Set components; - try - { - components = managementView.getComponentsForType(componentType); - } - catch (Exception e) - { - throw new IllegalStateException(e); - } - return components; - } -} \ No newline at end of file diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/util/MetaTypeUtils.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/util/MetaTypeUtils.java deleted file mode 100644 index c381902116..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/util/MetaTypeUtils.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -package org.rhq.plugins.jbossas5.util; - -import org.jboss.metatype.api.values.MetaValue; -import org.jboss.metatype.api.types.MetaType; -import org.jboss.metatype.api.types.MapCompositeMetaType; -import org.jboss.metatype.api.types.CompositeMetaType; -import org.jboss.metatype.api.types.SimpleMetaType; - -/** - * @author Mark Spritzler - * @author Ian Springer - */ -public class MetaTypeUtils -{ - /** - * Checks if the specified MetaValue is an instance of the specified MetaType. - * - * @param metaValue a MetaValue - * @param metaType a MetaType - * - * @return true if the MetaValue is an instance of the MetaType, or false if not - */ - public static boolean instanceOf(MetaValue metaValue, MetaType metaType) { - MetaType valueType = metaValue.getMetaType(); - if (valueType.isSimple() && metaType.isSimple()) - return true; - else if (valueType.isEnum() && metaType.isEnum()) - return true; - else if (valueType.isCollection() && metaType.isCollection()) - return true; - else if (valueType.isArray() && metaType.isArray()) - return true; - else if (valueType.isComposite() && metaType.isComposite()) { - return (valueType instanceof MapCompositeMetaType && metaType instanceof MapCompositeMetaType) || - (!(valueType instanceof CompositeMetaType) && !(metaType instanceof CompositeMetaType)); - } else if (valueType.isGeneric() && metaType.isGeneric()) - return true; - else if (valueType.isTable() && metaType.isTable()) - return true; - else if (valueType.isProperties() && metaType.isProperties()) - return true; - else - return false; - } - - public static boolean isNumeric(SimpleMetaType simpleMetaType) { - return (simpleMetaType.equals(SimpleMetaType.BIGDECIMAL) || - simpleMetaType.equals(SimpleMetaType.BIGINTEGER) || - simpleMetaType.equals(SimpleMetaType.BYTE) || - simpleMetaType.equals(SimpleMetaType.BYTE_PRIMITIVE) || - simpleMetaType.equals(SimpleMetaType.DOUBLE) || - simpleMetaType.equals(SimpleMetaType.DOUBLE_PRIMITIVE) || - simpleMetaType.equals(SimpleMetaType.FLOAT) || - simpleMetaType.equals(SimpleMetaType.FLOAT_PRIMITIVE) || - simpleMetaType.equals(SimpleMetaType.INTEGER) || - simpleMetaType.equals(SimpleMetaType.INTEGER_PRIMITIVE) || - simpleMetaType.equals(SimpleMetaType.LONG) || - simpleMetaType.equals(SimpleMetaType.LONG_PRIMITIVE) || - simpleMetaType.equals(SimpleMetaType.SHORT) || - simpleMetaType.equals(SimpleMetaType.SHORT_PRIMITIVE)); - } - - private MetaTypeUtils() - { - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/util/MetadataConversionUtils.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/util/MetadataConversionUtils.java deleted file mode 100644 index 7c46eedcc6..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/util/MetadataConversionUtils.java +++ /dev/null @@ -1,465 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -package org.rhq.plugins.jbossas5.util; - -import java.io.Serializable; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; -import java.util.EnumSet; -import java.util.HashSet; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; -import org.rhq.core.domain.configuration.definition.PropertyDefinition; -import org.rhq.core.domain.configuration.definition.PropertyDefinitionList; -import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap; -import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple; -import org.rhq.core.domain.configuration.definition.PropertySimpleType; -import org.rhq.core.domain.configuration.definition.constraint.FloatRangeConstraint; -import org.rhq.core.domain.configuration.definition.constraint.IntegerRangeConstraint; -import org.rhq.core.domain.measurement.DataType; -import org.rhq.core.domain.measurement.DisplayType; -import org.rhq.core.domain.measurement.MeasurementCategory; -import org.rhq.core.domain.measurement.MeasurementDefinition; -import org.rhq.core.domain.measurement.MeasurementUnits; -import org.rhq.core.domain.operation.OperationDefinition; -import org.rhq.core.domain.resource.ResourceCategory; -import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.domain.util.StringUtils; - -import org.jboss.managed.api.ComponentType; -import org.jboss.managed.api.ManagedComponent; -import org.jboss.managed.api.ManagedDeployment; -import org.jboss.managed.api.ManagedObject; -import org.jboss.managed.api.ManagedOperation; -import org.jboss.managed.api.ManagedParameter; -import org.jboss.managed.api.ManagedProperty; -import org.jboss.managed.api.annotation.ViewUse; -import org.jboss.metatype.api.types.ArrayMetaType; -import org.jboss.metatype.api.types.CollectionMetaType; -import org.jboss.metatype.api.types.CompositeMetaType; -import org.jboss.metatype.api.types.MapCompositeMetaType; -import org.jboss.metatype.api.types.MetaType; -import org.jboss.metatype.api.types.PropertiesMetaType; -import org.jboss.metatype.api.types.TableMetaType; -import org.jboss.metatype.api.types.SimpleMetaType; -import org.jboss.metatype.api.values.ArrayValue; -import org.jboss.metatype.api.values.CollectionValue; -import org.jboss.metatype.api.values.GenericValue; -import org.jboss.metatype.api.values.MetaValue; - -/** - * Utility class for converting JBAS5 Profile Service {@link ManagedComponent}s and {@link ManagedDeployment}s to RHQ - * {@link ResourceType}s. - * - * @author Ian Springer - */ -public class MetadataConversionUtils { - private static final Log LOG = LogFactory.getLog(MetadataConversionUtils.class); - - private static final String PLUGIN_NAME = "ProfileService"; - - private static Map TYPE_MAP = new HashMap(); - static { - TYPE_MAP.put(boolean.class.getName(), PropertySimpleType.BOOLEAN); - TYPE_MAP.put(Boolean.class.getName(), PropertySimpleType.BOOLEAN); - TYPE_MAP.put(int.class.getName(), PropertySimpleType.INTEGER); - TYPE_MAP.put(Integer.class.getName(), PropertySimpleType.INTEGER); - TYPE_MAP.put(long.class.getName(), PropertySimpleType.LONG); - TYPE_MAP.put(Long.class.getName(), PropertySimpleType.LONG); - TYPE_MAP.put(float.class.getName(), PropertySimpleType.FLOAT); - TYPE_MAP.put(Float.class.getName(), PropertySimpleType.FLOAT); - TYPE_MAP.put(double.class.getName(), PropertySimpleType.DOUBLE); - TYPE_MAP.put(Double.class.getName(), PropertySimpleType.DOUBLE); - } - - public static ResourceType convertDeploymentToResourceType(String deploymentTypeName, ManagedDeployment deployment) { - LOG.debug("Creating ResourceType for ManagedDeployment type [" + deploymentTypeName + "]..."); - ResourceType resourceType = new ResourceType(deploymentTypeName, PLUGIN_NAME, ResourceCategory.SERVICE, null); - Set metricDefs = convertMetricPropertiesToMeasurementDefinitions(deployment); - resourceType.setMetricDefinitions(metricDefs); - ConfigurationDefinition resourceConfigDef = convertConfigurationPropertiesToConfigurationDefinition(deployment); - resourceType.setResourceConfigurationDefinition(resourceConfigDef); - return resourceType; - } - - public static ResourceType convertComponentToResourceType(ManagedComponent component) - { - LOG.debug("Creating ResourceType for ManagedComponent type [" + component.getType() + "]..."); - ComponentType componentType = component.getType(); - String name; - if (componentType.getSubtype().equals("*")) - name = component.getName() + " " + componentType.getType(); - else - name = componentType.getSubtype() + " " + componentType.getType(); - ResourceType resourceType = new ResourceType(name, PLUGIN_NAME, ResourceCategory.SERVICE, null); - Set opDefs = convertManagedOperationsToOperationDefinitions(component); - for (OperationDefinition opDef : opDefs) - resourceType.addOperationDefinition(opDef); - Set metricDefs = convertMetricPropertiesToMeasurementDefinitions(component); - resourceType.setMetricDefinitions(metricDefs); - ConfigurationDefinition resourceConfigDef = convertConfigurationPropertiesToConfigurationDefinition(component); - resourceType.setResourceConfigurationDefinition(resourceConfigDef); - return resourceType; - } - - private static Set convertManagedOperationsToOperationDefinitions(ManagedComponent component) { - Set opDefs = new TreeSet(new OperationDefinitionComparator()); - Map managedOperations = new HashMap(); - for (ManagedOperation operation : component.getOperations()) { - ManagedOperation operationWithSameName = managedOperations.get(operation.getName()); - if (operationWithSameName == null || - operationWithSameName.getParameters().length < operation.getParameters().length) { - if (operationWithSameName != null) - LOG.info("Found more than one ManagedOperation named '" + operation.getName() - + "' - converting only the one with the most parameters."); - managedOperations.put(operation.getName(), operation); - } - } - for (ManagedOperation operation : managedOperations.values()) { - OperationDefinition opDef = convertOperationToOperationDefinition(operation); - opDefs.add(opDef); - } - return opDefs; - } - - private static OperationDefinition convertOperationToOperationDefinition(ManagedOperation operation) { - String desc = (!operation.getName().equals(operation.getDescription())) ? operation.getDescription() : null; - OperationDefinition opDef = new OperationDefinition(operation.getName(), null, desc); - opDef.setDisplayName(StringUtils.deCamelCase(operation.getName())); - ConfigurationDefinition paramsConfigDef = convertParametersToConfigurationDefinition(operation); - opDef.setParametersConfigurationDefinition(paramsConfigDef); - ConfigurationDefinition resultsConfigDef = convertResultToConfigurationDefinition(operation); - opDef.setResultsConfigurationDefinition(resultsConfigDef); - return opDef; - } - - private static ConfigurationDefinition convertParametersToConfigurationDefinition(ManagedOperation operation) - { - if (operation.getParameters() == null || operation.getParameters().length == 0) - return null; - ConfigurationDefinition configDef = new ConfigurationDefinition(operation.getName(), null); - for (ManagedParameter parameter : operation.getParameters()) { - PropertyDefinition propDef = convertParameterToPropertyDefinition(parameter); - configDef.put(propDef); - } - return configDef; - } - - private static PropertyDefinition convertParameterToPropertyDefinition(ManagedParameter parameter) { - PropertyDefinition propDef = convertMetaTypeToPropertyDefinition(parameter.getMetaType(), parameter.getName(), - parameter.getValue()); - String desc = (!parameter.getName().equals(parameter.getDescription())) ? parameter.getDescription() : null; - propDef.setDescription(desc); - // TODO: Convert parameter.getLegalValues() to enum defs. - if (propDef instanceof PropertyDefinitionSimple) { - PropertyDefinitionSimple propDefSimple = (PropertyDefinitionSimple)propDef; - addConstraints(propDefSimple, parameter.getMinimumValue(), parameter.getMaximumValue()); - } - return propDef; - } - - private static PropertyDefinitionList convertMetaTypeToPropertyDefinitionList(MetaType metaType, String name, - MetaValue metaValue) { - MetaType elementType; - MetaValue elementValue = null; - if (metaType.isCollection()) { - CollectionMetaType collectionMetaType = (CollectionMetaType)metaType; - elementType = collectionMetaType.getElementType(); - if (metaValue != null) { - CollectionValue collectionValue = (CollectionValue)metaValue; - MetaValue[] elements = collectionValue.getElements(); - if (elements != null && elements.length != 0) - elementValue = elements[0]; - } - } else if (metaType.isArray()) { - ArrayMetaType arrayMetaType = (ArrayMetaType)metaType; - elementType = arrayMetaType.getElementType(); - if (metaValue != null) { - ArrayValue arrayValue = (ArrayValue)metaValue; - if (arrayValue.getLength() != 0 && arrayValue.getValue(0) instanceof MetaValue) - elementValue = (MetaValue)arrayValue.getValue(0); - } - } else { - throw new IllegalStateException("Unsupported MetaType: " + metaType); - } - PropertyDefinition elementPropDef = convertMetaTypeToPropertyDefinition(elementType, "element", elementValue); - @SuppressWarnings({"UnnecessaryLocalVariable"}) - PropertyDefinitionList propDefList = new PropertyDefinitionList(name, null, true, elementPropDef); - return propDefList; - } - - private static PropertyDefinitionMap convertMetaTypeToPropertyDefinitionMap(MetaType metaType, String name, - MetaValue metaValue) { - PropertyDefinitionMap propDefMap = new PropertyDefinitionMap(name, null, false); - if (metaType.isComposite()) { - if (!(metaType instanceof MapCompositeMetaType)) { - CompositeMetaType compositeMetaType = (CompositeMetaType)metaType; - for (String itemName : compositeMetaType.itemSet()) { - MetaType itemMetaType = compositeMetaType.getType(itemName); - if (itemMetaType.isComposite()) { - // Avoid StackOverflowErrors caused by recursive CompositeMetaType metadata. - if (itemMetaType == compositeMetaType) - LOG.error("CompositeMetaType " + compositeMetaType - + " contains an item whose type is a reference to the CompositeMetaType itself!"); - else - LOG.error("CompositeMetaType " + compositeMetaType - + " contains an item whose type is another CompositeMetaType: " + itemMetaType); - continue; - } - LOG.trace("Converting item with type [" + itemMetaType + "@" + System.identityHashCode(itemMetaType) - + "] and name [" + itemName + "]..."); - PropertyDefinition itemPropDef = convertMetaTypeToPropertyDefinition(itemMetaType, itemName, null); - propDefMap.put(itemPropDef); - String desc = (!itemName.equals(compositeMetaType.getDescription(itemName))) ? - compositeMetaType.getDescription(itemName) : null; - itemPropDef.setDescription(desc); - } - } - } else if (metaType.isGeneric()) { - if (metaValue != null) { - GenericValue genericValue = (GenericValue)metaValue; - Serializable value = genericValue.getValue(); - if (value != null && value instanceof ManagedObject) { - ManagedObject managedObject = (ManagedObject)value; - for (ManagedProperty managedProp : managedObject.getProperties().values()) { - PropertyDefinition itemPropDef = convertManagedPropertyToPropertyDefinition(managedProp); - propDefMap.put(itemPropDef); - } - } - } - } else if (metaType.isTable()) { - TableMetaType tableMetaType = (TableMetaType)metaType; - CompositeMetaType itemMetaType = tableMetaType.getRowType(); - for (String itemName : tableMetaType.getIndexNames()) { - PropertyDefinition itemPropDef = convertMetaTypeToPropertyDefinition(itemMetaType, itemName, null); - propDefMap.put(itemPropDef); - } - } else if (metaType instanceof PropertiesMetaType) { - @SuppressWarnings({"UnusedDeclaration"}) - PropertiesMetaType propertiesMetaType = (PropertiesMetaType)metaType; - } - return propDefMap; - } - - private static ConfigurationDefinition convertResultToConfigurationDefinition(ManagedOperation operation) - { - MetaType returnType = operation.getReturnType(); - if (returnType.getClassName().equals(Void.class.getName())) - return null; - PropertyDefinition propDef = convertMetaTypeToPropertyDefinition(returnType, "result", null); - ConfigurationDefinition configDef = new ConfigurationDefinition(operation.getName(), operation.getDescription()); - configDef.put(propDef); - return configDef; - } - - private static Set convertMetricPropertiesToMeasurementDefinitions(ManagedDeployment deployment) - { - return convertMetricPropertiesToMeasurementDefinitions(deployment.getProperties()); - } - - private static Set convertMetricPropertiesToMeasurementDefinitions(ManagedComponent component) - { - return convertMetricPropertiesToMeasurementDefinitions(component.getProperties()); - } - - private static Set convertMetricPropertiesToMeasurementDefinitions(Map props) { - Set measurementDefs = new TreeSet(new MeasurementDefinitionComparator()); - if (props == null) - return measurementDefs; - for(ManagedProperty prop : props.values()) { - if (prop.hasViewUse(ViewUse.RUNTIME) || prop.hasViewUse(ViewUse.STATISTIC)) { - MetaType metaType = prop.getMetaType(); - if (metaType.isSimple() || metaType.isEnum()) - { - MeasurementDefinition measurementDef = getMeasurementDefinitionForSimpleManagedProperty(prop); - measurementDefs.add(measurementDef); - } - else if (prop.getMetaType().isComposite()) - { - Set compositeMeasurementDefs = - getMeasurementDefinitionsForCompositeManagedProperty(prop); - measurementDefs.addAll(compositeMeasurementDefs); - } - else - { - LOG.warn("Skipping property [" + prop + "] with unsupported type [" + metaType + "]."); - } - } - } - return measurementDefs; - } - - private static MeasurementDefinition getMeasurementDefinitionForSimpleManagedProperty(ManagedProperty prop) - { - MetaType metaType = prop.getMetaType(); - DataType dataType; - if (metaType.isSimple()) { - SimpleMetaType simpleMetaType = (SimpleMetaType)metaType; - dataType = (prop.hasViewUse(ViewUse.STATISTIC) && MetaTypeUtils.isNumeric(simpleMetaType)) ? - DataType.MEASUREMENT : DataType.TRAIT; - } else { // metaType.isEnum() - // Enum values are always Strings. - dataType = DataType.TRAIT; - } - int defaultInterval = (dataType == DataType.MEASUREMENT) ? 60000 : 600000; - DisplayType displayType = (dataType == DataType.MEASUREMENT) ? DisplayType.DETAIL : DisplayType.SUMMARY; - MeasurementDefinition measurementDef = new MeasurementDefinition(prop.getName(), - MeasurementCategory.PERFORMANCE, MeasurementUnits.NONE, dataType, true, defaultInterval, displayType); - measurementDef.setDisplayName(StringUtils.deCamelCase(prop.getName())); - String desc = (!prop.getName().equals(prop.getDescription())) ? prop.getDescription() : null; - measurementDef.setDescription(desc); - return measurementDef; - } - - private static Set getMeasurementDefinitionsForCompositeManagedProperty(ManagedProperty property) { - Set measurementDefs = new HashSet(); - CompositeMetaType compositeMetaType = (CompositeMetaType)property.getMetaType(); - Set itemNames = compositeMetaType.keySet(); - for (String itemName : itemNames) { - MetaType itemType = compositeMetaType.getType(itemName); - if (itemType.isSimple() || itemType.isEnum()) { - String metricName = property.getName() + "." + itemName; - DataType dataType = (itemType.getClassName().equals(String.class.getName())) ? - DataType.TRAIT : DataType.MEASUREMENT; - MeasurementDefinition measurementDef = new MeasurementDefinition(metricName, - MeasurementCategory.PERFORMANCE, MeasurementUnits.NONE, dataType, true, 60000, - DisplayType.DETAIL); - measurementDefs.add(measurementDef); - measurementDef.setDisplayName(StringUtils.deCamelCase(itemName)); - } else { - LOG.warn("Composite stat property [" + property.getName() + "] contains non-simple item with type [" - + itemType + "] - skipping..." ); - } - } - return measurementDefs; - } - - private static ConfigurationDefinition convertConfigurationPropertiesToConfigurationDefinition(String configName, Map managedProps) - { - Set propDefs = new TreeSet(new PropertyDefinitionComparator()); - for(ManagedProperty prop : managedProps.values()) { - EnumSet viewUses = ManagedComponentUtils.getViewUses(prop); - // Assume a property with no view uses is a config prop. - if (viewUses.contains(ViewUse.CONFIGURATION) || viewUses.contains(ViewUse.RUNTIME) || viewUses.isEmpty()) { - PropertyDefinition propDef = convertManagedPropertyToPropertyDefinition(prop); - propDefs.add(propDef); - } - } - if (propDefs.isEmpty()) - return null; - ConfigurationDefinition configDef = new ConfigurationDefinition(configName, null); - for (PropertyDefinition propDef : propDefs) - configDef.getPropertyDefinitions().put(propDef.getName(), propDef); - return configDef; - } - - private static PropertyDefinition convertManagedPropertyToPropertyDefinition(ManagedProperty prop) { - PropertyDefinition propDef; - propDef = convertMetaTypeToPropertyDefinition(prop.getMetaType(), prop.getName(), prop.getValue()); - String desc = (!prop.getName().equals(prop.getDescription())) ? prop.getDescription() : null; - propDef.setDescription(desc); - propDef.setRequired(prop.isMandatory()); - propDef.setReadOnly(prop.isReadOnly()); - // TODO: Convert prop.getLegalValues() to enum defs. - if (propDef instanceof PropertyDefinitionSimple) { - PropertyDefinitionSimple propDefSimple = (PropertyDefinitionSimple)propDef; - addConstraints(propDefSimple, prop.getMinimumValue(), prop.getMaximumValue()); - } - return propDef; - } - - private static PropertyDefinition convertMetaTypeToPropertyDefinition(MetaType metaType, String propName, - MetaValue metaValue) { - PropertyDefinition propDef; - if (metaType.isSimple() || metaType.isEnum()) { - PropertySimpleType propType = convertClassToPropertySimpleType(metaType.getClassName()); - propDef = new PropertyDefinitionSimple(propName, null, false, propType); - } else if (metaType.isCollection() || metaType.isArray()) { - propDef = convertMetaTypeToPropertyDefinitionList(metaType, propName, metaValue); - } else if (metaType.isComposite() || metaType.isGeneric() || metaType.isTable() || - metaType instanceof PropertiesMetaType) { - LOG.trace("Converting map with type [" + metaType + "@" + System.identityHashCode(metaType) + "], name [" - + propName + "], and value [" + metaValue + "]..."); - propDef = convertMetaTypeToPropertyDefinitionMap(metaType, propName, metaValue); - } else { - throw new IllegalStateException("Unsupported MetaType: " + metaType); - } - propDef.setDisplayName(StringUtils.deCamelCase(propName)); - return propDef; - } - - private static ConfigurationDefinition convertConfigurationPropertiesToConfigurationDefinition(ManagedDeployment deployment) - { - return convertConfigurationPropertiesToConfigurationDefinition(deployment.getName() + " resource config", - deployment.getProperties()); - } - - private static ConfigurationDefinition convertConfigurationPropertiesToConfigurationDefinition(ManagedComponent component) - { - return convertConfigurationPropertiesToConfigurationDefinition(component.getName() + " resource config", - component.getProperties()); - } - - private static PropertySimpleType convertClassToPropertySimpleType(String className) { - PropertySimpleType simpleType = TYPE_MAP.get(className); - return (simpleType != null) ? simpleType : PropertySimpleType.STRING; - } - - private static void addConstraints(PropertyDefinitionSimple propDefSimple, Comparable minValue, - Comparable maxValue) { - if (minValue != null || maxValue != null) { - if (propDefSimple.getType() == PropertySimpleType.INTEGER || - propDefSimple.getType() == PropertySimpleType.LONG) { - Long min = (minValue != null) ? ((Number)minValue).longValue() : null; - Long max = (maxValue != null) ? ((Number)maxValue).longValue() : null; - IntegerRangeConstraint constraint = new IntegerRangeConstraint(min, max); - propDefSimple.addConstraints(constraint); - } else if (propDefSimple.getType() == PropertySimpleType.FLOAT || - propDefSimple.getType() == PropertySimpleType.DOUBLE) { - Double min = (minValue != null) ? ((Number)minValue).doubleValue() : null; - Double max = (maxValue != null) ? ((Number)maxValue).doubleValue() : null; - FloatRangeConstraint constraint = new FloatRangeConstraint(min, max); - propDefSimple.addConstraints(constraint); - } - } - } - - private static class OperationDefinitionComparator implements Comparator { - public int compare(OperationDefinition opDef1, OperationDefinition opDef2) { - return opDef1.getName().compareTo(opDef2.getName()); - } - } - - private static class MeasurementDefinitionComparator implements Comparator { - public int compare(MeasurementDefinition metricDef1, MeasurementDefinition metricDef2) { - return metricDef1.getName().compareTo(metricDef2.getName()); - } - } - - private static class PropertyDefinitionComparator implements Comparator { - public int compare(PropertyDefinition propDef1, PropertyDefinition propDef2) { - return propDef1.getName().compareTo(propDef2.getName()); - } - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/util/PluginDescriptorGenerator.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/util/PluginDescriptorGenerator.java deleted file mode 100644 index 37d058e36c..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/util/PluginDescriptorGenerator.java +++ /dev/null @@ -1,355 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -package org.rhq.plugins.jbossas5.util; - -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.OutputStream; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; -import java.util.Map; -import java.util.HashMap; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.Marshaller; -import javax.xml.bind.JAXBElement; -import javax.xml.namespace.QName; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.jboss.deployers.spi.management.KnownComponentTypes; -import org.jboss.deployers.spi.management.KnownDeploymentTypes; -import org.jboss.deployers.spi.management.ManagementView; -import org.jboss.managed.api.ComponentType; -import org.jboss.managed.api.ManagedComponent; -import org.jboss.managed.api.ManagedDeployment; -import org.jboss.profileservice.spi.NoSuchDeploymentException; - -import org.rhq.core.clientapi.descriptor.DescriptorPackages; -import org.rhq.core.clientapi.descriptor.configuration.ConfigurationDescriptor; -import org.rhq.core.clientapi.descriptor.configuration.SimpleProperty; -import org.rhq.core.clientapi.descriptor.configuration.PropertyType; -import org.rhq.core.clientapi.descriptor.configuration.ConfigurationProperty; -import org.rhq.core.clientapi.descriptor.configuration.ListProperty; -import org.rhq.core.clientapi.descriptor.configuration.MapProperty; -import org.rhq.core.clientapi.descriptor.plugin.MetricDescriptor; -import org.rhq.core.clientapi.descriptor.plugin.OperationDescriptor; -import org.rhq.core.clientapi.descriptor.plugin.PluginDescriptor; -import org.rhq.core.clientapi.descriptor.plugin.ResourceDescriptor; -import org.rhq.core.clientapi.descriptor.plugin.ServiceDescriptor; -import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; -import org.rhq.core.domain.configuration.definition.PropertyDefinition; -import org.rhq.core.domain.configuration.definition.PropertySimpleType; -import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple; -import org.rhq.core.domain.configuration.definition.PropertyDefinitionList; -import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap; -import org.rhq.core.domain.measurement.MeasurementDefinition; -import org.rhq.core.domain.operation.OperationDefinition; -import org.rhq.core.domain.resource.ResourceType; - -/** - * Generates an RHQ plugin descriptor based on the ManagedComponent types represented in a Profile Service - * ManagementView. - * - * @author Ian Springer - */ -public class PluginDescriptorGenerator { - private static final Log LOG = LogFactory.getLog(PluginDescriptorGenerator.class); - - private static final QName SIMPLE_PROPERTY_QNAME = new QName(RhqNamespacePrefixMapper.CONFIGURATION_NAMESPACE, "simple-property"); - private static final QName LIST_PROPERTY_QNAME = new QName(RhqNamespacePrefixMapper.CONFIGURATION_NAMESPACE, "list-property"); - private static final QName MAP_PROPERTY_QNAME = new QName(RhqNamespacePrefixMapper.CONFIGURATION_NAMESPACE, "map-property"); - - private static Map TYPE_MAP = new HashMap(); - static { - TYPE_MAP.put(PropertySimpleType.BOOLEAN, PropertyType.BOOLEAN); - TYPE_MAP.put(PropertySimpleType.DIRECTORY, PropertyType.DIRECTORY); - TYPE_MAP.put(PropertySimpleType.DOUBLE, PropertyType.DOUBLE); - TYPE_MAP.put(PropertySimpleType.FILE, PropertyType.FILE); - TYPE_MAP.put(PropertySimpleType.FLOAT, PropertyType.FLOAT); - TYPE_MAP.put(PropertySimpleType.INTEGER, PropertyType.INTEGER); - TYPE_MAP.put(PropertySimpleType.LONG, PropertyType.LONG); - TYPE_MAP.put(PropertySimpleType.LONG_STRING, PropertyType.LONG_STRING); - TYPE_MAP.put(PropertySimpleType.PASSWORD, PropertyType.PASSWORD); - TYPE_MAP.put(PropertySimpleType.STRING, PropertyType.STRING); - } - - public static void generatePluginDescriptor(ManagementView managementView, File tempDir) throws Exception { - PluginDescriptor pluginDescriptor = new PluginDescriptor(); - addComponentsToDescriptor(managementView, pluginDescriptor); - addDeploymentsToDescriptor(managementView, pluginDescriptor); - File tempFile = File.createTempFile("rhq-plugin", ".xml", tempDir); - writeToFile(pluginDescriptor, tempFile); - } - - private static void addDeploymentsToDescriptor(ManagementView managementView, PluginDescriptor pluginDescriptor) throws Exception { - Set knownDeploymentTypeNames = getKnownDeploymentTypeNames(); - for (String deploymentTypeName : knownDeploymentTypeNames) { - Set deploymentNames = managementView.getDeploymentNamesForType(deploymentTypeName); - if (deploymentNames == null || deploymentNames.isEmpty()) { - LOG.warn("No deployments of type [" + deploymentTypeName + "] found."); - continue; - } - ManagedDeployment deployment = null; - for (String deploymentName : deploymentNames) { - try { - // Use the first one we successfully retrieve as a representative sample of the type. - deployment = managementView.getDeployment(deploymentName); - break; - } - catch (NoSuchDeploymentException e) { - LOG.warn(e); - } - } - if (deployment == null) { - LOG.warn("Unable to successfully retrieve a Deployment of type [" + deploymentTypeName - + "] due to https://jira.jboss.org/jira/browse/JBAS-5640."); - continue; - } - // First convert ManagedDeployment to ResourceType... - ResourceType resourceType = MetadataConversionUtils.convertDeploymentToResourceType(deploymentTypeName, - deployment); - // Then convert ResourceType to JAXB ServiceDescriptor object. - convertAndMergeResourceType(pluginDescriptor, resourceType); - } - } - - private static void addComponentsToDescriptor(ManagementView managementView, PluginDescriptor pluginDescriptor) throws Exception { - Set knownComponentTypes = getKnownComponentTypes(); - for (ComponentType componentType : knownComponentTypes) { - Set components = managementView.getComponentsForType(componentType); - if (components == null || components.isEmpty()) { - LOG.warn("No components of type [" + componentType + "] found."); - continue; - } - if (componentType.getSubtype().equals("*")) { - for (ManagedComponent component : components) - addComponentToDescriptor(pluginDescriptor, component); - } else { - // Use the first one as a representative sample of the type. - ManagedComponent component = components.iterator().next(); - addComponentToDescriptor(pluginDescriptor, component); - } - } - } - - private static void addComponentToDescriptor(PluginDescriptor pluginDescriptor, ManagedComponent component) - { - // First convert ManagedComponent to ResourceType... - ResourceType resourceType = MetadataConversionUtils.convertComponentToResourceType(component); - // Then convert ResourceType to JAXB ServiceDescriptor object. - convertAndMergeResourceType(pluginDescriptor, resourceType); - } - - private static void convertAndMergeResourceType(PluginDescriptor pluginDescriptor, ResourceType resourceType) { - List services = pluginDescriptor.getServices(); - ServiceDescriptor serviceDescriptor = new ServiceDescriptor(); - serviceDescriptor.setName(resourceType.getName()); - if (resourceType.isSingleton()) - serviceDescriptor.setSingleton(resourceType.isSingleton()); - // TODO: Handle remaining fields. - convertAndMergeOperationDefinitions(resourceType, serviceDescriptor); - convertAndMergeMetricDefinitions(resourceType, serviceDescriptor); - convertAndMergeResourceConfiguration(resourceType, serviceDescriptor); - services.add(serviceDescriptor); - } - - private static void convertAndMergeResourceConfiguration(ResourceType resourceType, ServiceDescriptor serviceDescriptor) { - ConfigurationDefinition resourceConfigDef = resourceType.getResourceConfigurationDefinition(); - ConfigurationDescriptor resourceConfigDescriptor = convertConfigurationDefinitionToConfigurationDescriptor( - resourceConfigDef); - serviceDescriptor.setResourceConfiguration(resourceConfigDescriptor); - } - - private static void convertAndMergeMetricDefinitions(ResourceType resourceType, ServiceDescriptor serviceDescriptor) { - List metricDescriptors = serviceDescriptor.getMetric(); - for (MeasurementDefinition metricDef : resourceType.getMetricDefinitions()) { - MetricDescriptor metricDescriptor = new MetricDescriptor(); - metricDescriptors.add(metricDescriptor); - if (metricDef.getCategory() != null) - metricDescriptor.setCategory(metricDef.getCategory().name().toLowerCase()); - metricDescriptor.setDataType(metricDef.getDataType().name().toLowerCase()); - metricDescriptor.setDefaultInterval((int)metricDef.getDefaultInterval()); - metricDescriptor.setDefaultOn(metricDef.isDefaultOn()); - metricDescriptor.setDescription(metricDef.getDescription()); - metricDescriptor.setDestinationType(metricDef.getDestinationType()); - metricDescriptor.setDisplayName(metricDef.getDisplayName()); - if (metricDef.getDisplayType() != null) - metricDescriptor.setDisplayType(metricDef.getDisplayType().name().toLowerCase()); - if (metricDef.getNumericType() != null) - metricDescriptor.setMeasurementType(metricDef.getNumericType().name().toLowerCase()); - metricDescriptor.setProperty(metricDef.getName()); - //metricDescriptor.setUnits(metricDef.getUnits()); // TODO - } - } - - private static void convertAndMergeOperationDefinitions(ResourceType resourceType, ResourceDescriptor resourceDescriptor) { - List operationDescriptors = resourceDescriptor.getOperation(); - for (OperationDefinition opDef : resourceType.getOperationDefinitions()) { - OperationDescriptor operationDescriptor = new OperationDescriptor(); - operationDescriptors.add(operationDescriptor); - operationDescriptor.setDescription(opDef.getDescription()); - operationDescriptor.setDisplayName(opDef.getDisplayName()); - operationDescriptor.setName(opDef.getName()); - ConfigurationDefinition paramsConfigDef = opDef.getParametersConfigurationDefinition(); - ConfigurationDescriptor paramsConfigDescriptor = convertConfigurationDefinitionToConfigurationDescriptor(paramsConfigDef); - operationDescriptor.setParameters(paramsConfigDescriptor); - ConfigurationDefinition resultsConfigDef = opDef.getResultsConfigurationDefinition(); - ConfigurationDescriptor resultsConfigDescriptor = convertConfigurationDefinitionToConfigurationDescriptor(resultsConfigDef); - operationDescriptor.setResults(resultsConfigDescriptor); - operationDescriptor.setTimeout(opDef.getTimeout()); - } - } - - private static ConfigurationDescriptor convertConfigurationDefinitionToConfigurationDescriptor( - ConfigurationDefinition configDef) { - if (configDef == null) - return null; - ConfigurationDescriptor configDescriptor = new ConfigurationDescriptor(); - configDescriptor.setNotes(configDef.getDescription()); - for (PropertyDefinition propDef : configDef.getPropertyDefinitions().values()) { - ConfigurationProperty configProp = convertPropertyDefinitionToConfigurationProperty(propDef); - JAXBElement propElement = getJAXBElement(configProp); - configDescriptor.getConfigurationProperty().add(propElement); - } - return configDescriptor; - } - - private static ConfigurationProperty convertPropertyDefinitionToConfigurationProperty(PropertyDefinition propDef) { - ConfigurationProperty configProp; - if (propDef instanceof PropertyDefinitionSimple) { - PropertyDefinitionSimple propDefSimple = (PropertyDefinitionSimple)propDef; - SimpleProperty simpleProp = new SimpleProperty(); - simpleProp.setDefaultValue(propDefSimple.getDefaultValue()); - simpleProp.setDefaultValueDescription(propDefSimple.getDefaultValue()); - simpleProp.setInitialValue(propDefSimple.getDefaultValue()); - if (propDefSimple.getType() != PropertySimpleType.STRING) - simpleProp.setType(TYPE_MAP.get(propDefSimple.getType())); - configProp = simpleProp; - } else if (propDef instanceof PropertyDefinitionList) { - PropertyDefinitionList propDefList = (PropertyDefinitionList)propDef; - ListProperty listProp = new ListProperty(); - //listProp.setMin(BigInteger.valueOf(propDefList.getMin())); - //listProp.setMax(String.valueOf(propDefList.getMax())); - ConfigurationProperty memberConfigProp = convertPropertyDefinitionToConfigurationProperty( - propDefList.getMemberDefinition()); - JAXBElement propElement = getJAXBElement(memberConfigProp); - listProp.setConfigurationProperty(propElement); - configProp = listProp; - } else if (propDef instanceof PropertyDefinitionMap) { - PropertyDefinitionMap propDefMap = (PropertyDefinitionMap)propDef; - MapProperty mapProp = new MapProperty(); - for (PropertyDefinition itemPropDef : propDefMap.getPropertyDefinitions().values()) { - ConfigurationProperty itemConfigProp = convertPropertyDefinitionToConfigurationProperty(itemPropDef); - JAXBElement propElement = getJAXBElement(itemConfigProp); - mapProp.getConfigurationProperty().add(propElement); - } - configProp = mapProp; - } else { - throw new IllegalStateException("Invalid property definition type: " + propDef.getClass().getName()); - } - configProp.setDescription(propDef.getDescription()); - //simpleProp.setActivationPolicy(propDefSimple.getActivationPolicy()); // TODO - configProp.setName(propDef.getName()); - //simpleProp.setPropertyOptions(); // TODO - if (propDef.isReadOnly()) - configProp.setReadOnly(propDef.isReadOnly()); - if (!propDef.isRequired()) - configProp.setRequired(propDef.isRequired()); - if (propDef.isSummary()) - configProp.setSummary(propDef.isSummary()); - //simpleProp.setUnits(propDefSimple.getUnits()); // TODO - return configProp; - } - - private static JAXBElement getJAXBElement(ConfigurationProperty configProp) { - JAXBElement propElement; - QName qname; - if (configProp instanceof SimpleProperty) - qname = SIMPLE_PROPERTY_QNAME; - else if (configProp instanceof ListProperty) - qname = LIST_PROPERTY_QNAME; - else if (configProp instanceof MapProperty) - qname = MAP_PROPERTY_QNAME; - else - throw new IllegalStateException(); - propElement = new JAXBElement(qname, configProp.getClass(), configProp); - return propElement; - } - - private static Set getKnownDeploymentTypeNames() { - Set knownDeploymentTypeNames = new LinkedHashSet(); - for (KnownDeploymentTypes type : KnownDeploymentTypes.values()) { - knownDeploymentTypeNames.add(type.getType()); - } - return knownDeploymentTypeNames; - } - - private static Set getKnownComponentTypes() { - Set knownComponentTypes = new LinkedHashSet(); - for (KnownComponentTypes.DataSourceTypes componentType : KnownComponentTypes.DataSourceTypes.values()) { - knownComponentTypes.add(componentType.getType()); - } - for (KnownComponentTypes.ConnectionFactoryTypes componentType : KnownComponentTypes.ConnectionFactoryTypes.values()) { - knownComponentTypes.add(componentType.getType()); - } - // TODO: Remove the below line once we upgrade to profileservice-spi 5.1.0.CR2. - knownComponentTypes.add(new ComponentType("ConnectionFactory", "Tx")); - for (KnownComponentTypes.JMSDestination componentType : KnownComponentTypes.JMSDestination.values()) { - knownComponentTypes.add(componentType.getType()); - } - for (KnownComponentTypes.EJB componentType : KnownComponentTypes.EJB.values()) { - knownComponentTypes.add(componentType.getType()); - } - for (KnownComponentTypes.MBean componentType : KnownComponentTypes.MBean.values()) { - knownComponentTypes.add(componentType.getType()); - } - knownComponentTypes.add(new ComponentType("MBean", "Platform")); - knownComponentTypes.add(new ComponentType("MBean", "Web")); - for (KnownComponentTypes.MCBean componentType : KnownComponentTypes.MCBean.values()) { - knownComponentTypes.add(componentType.getType()); - } - knownComponentTypes.add(new ComponentType("MCBean", "JTA")); - knownComponentTypes.add(new ComponentType("MCBean", "MCServer")); - knownComponentTypes.add(new ComponentType("MCBean", "Security")); - knownComponentTypes.add(new ComponentType("MCBean", "ServerConfig")); - knownComponentTypes.add(new ComponentType("MCBean", "ServerInfo")); - knownComponentTypes.add(new ComponentType("MCBean", "ServicebindingManager")); - knownComponentTypes.add(new ComponentType("MCBean", "ServiceBindingSet")); - knownComponentTypes.add(new ComponentType("MCBean", "ServicebindingStore")); - return knownComponentTypes; - } - - private static void writeToFile(PluginDescriptor pluginDescriptor, - File file) - throws Exception { - LOG.info("Writing plugin descriptor to [" + file + "]..."); - OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(file)); - JAXBContext jaxbContext = JAXBContext.newInstance(DescriptorPackages.PC_PLUGIN); - Marshaller marshaller = jaxbContext.createMarshaller(); - marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); - marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); - marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", new RhqNamespacePrefixMapper()); - marshaller.marshal(pluginDescriptor, outputStream); - outputStream.close(); - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/util/ResourceComponentUtils.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/util/ResourceComponentUtils.java deleted file mode 100644 index 3dd9889793..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/util/ResourceComponentUtils.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -package org.rhq.plugins.jbossas5.util; - -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.Property; -import org.rhq.core.domain.configuration.PropertyMap; -import org.rhq.core.domain.configuration.PropertySimple; - -/** - * @author Ian Springer - */ -public class ResourceComponentUtils { - private static final String CUSTOM_PROPERTIES_PROPERTY = "customProperties"; - - private static final Log LOG = LogFactory.getLog(ResourceComponentUtils.class); - - public static Map getCustomProperties(Configuration pluginConfig) { - Map customProperties = new LinkedHashMap(); - if (pluginConfig == null) - return customProperties; - PropertyMap customPropsMap = pluginConfig.getMap(CUSTOM_PROPERTIES_PROPERTY); - if (customPropsMap != null) { - Collection customProps = customPropsMap.getMap().values(); - for (Property customProp : customProps) { - if (!(customProp instanceof PropertySimple)) { - LOG.error("Custom property definitions in plugin configuration must be simple properties - property " - + customProp + " is not - ignoring..."); - continue; - } - customProperties.put(customProp.getName(), (PropertySimple)customProp); - } - } - return customProperties; - } - -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/util/ResourceTypeUtils.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/util/ResourceTypeUtils.java deleted file mode 100644 index 1b55bd8784..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/util/ResourceTypeUtils.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -package org.rhq.plugins.jbossas5.util; - -import java.util.Set; - -import org.rhq.core.domain.measurement.MeasurementDefinition; -import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.domain.operation.OperationDefinition; -import org.jetbrains.annotations.Nullable; - -/** - * @author Ian Springer - */ -public class ResourceTypeUtils -{ - /** - * TODO - * @param resourceType - * @param metricName - * @return - */ - @Nullable - public static MeasurementDefinition getMeasurementDefinition(ResourceType resourceType, String metricName) { - Set metricDefinitions = resourceType.getMetricDefinitions(); - for (MeasurementDefinition metricDefinition : metricDefinitions) - { - if (metricDefinition.getName().equals(metricName)) - return metricDefinition; - } - return null; - } - - /** - * TODO - * @param resourceType - * @param operationName - * @return - */ - @Nullable - public static OperationDefinition getOperationDefinition(ResourceType resourceType, String operationName) { - Set operationDefinitions = resourceType.getOperationDefinitions(); - for (OperationDefinition operationDefinition : operationDefinitions) - { - if (operationDefinition.getName().equals(operationName)) - return operationDefinition; - } - return null; - } - - private ResourceTypeUtils() - { - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/util/RhqNamespacePrefixMapper.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/util/RhqNamespacePrefixMapper.java deleted file mode 100644 index 360527db3b..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/jbossas5/util/RhqNamespacePrefixMapper.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -package org.rhq.plugins.jbossas5.util; - -import com.sun.xml.bind.marshaller.NamespacePrefixMapper; - -/** - * @author Ian Springer - */ -public class RhqNamespacePrefixMapper extends NamespacePrefixMapper { - public static final String PLUGIN_NAMESPACE = "urn:xmlns:rhq-plugin"; - public static final String CONFIGURATION_NAMESPACE = "urn:xmlns:rhq-configuration"; - - public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) { - if (namespaceUri.equals(PLUGIN_NAMESPACE)) { - return ""; - } else if (namespaceUri.equals(CONFIGURATION_NAMESPACE)) { - return "c"; - } else { - return null; - } - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/SipApplicationDispatcherComponent.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/SipApplicationDispatcherComponent.java deleted file mode 100644 index 6985b96f61..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/SipApplicationDispatcherComponent.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2008, Red Hat Middleware LLC, and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ -package org.rhq.plugins.mobicents.servlet.sip; - -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; -import java.util.SortedSet; -import java.util.concurrent.atomic.AtomicLong; - -import org.mc4j.ems.connection.bean.attribute.EmsAttribute; -import org.mc4j.ems.connection.bean.operation.EmsOperation; -import org.rhq.core.domain.measurement.MeasurementDataNumeric; -import org.rhq.core.domain.measurement.MeasurementReport; -import org.rhq.core.domain.measurement.MeasurementScheduleRequest; -import org.rhq.core.pluginapi.measurement.MeasurementFacet; -import org.rhq.plugins.jmx.MBeanResourceComponent; - -/** - * @author jean.deruelle@gmail.com - * - */ -public class SipApplicationDispatcherComponent extends MBeanResourceComponent implements MeasurementFacet{ - private static final String NB_RESPONSES_PROCESSED_BY_SC_ATTRIBUTE_NAME = "responsesProcessedByStatusCode"; - private static final String NB_REQUESTS_PROCESSED_BY_METHOD_ATTRIBUTE_NAME = "requestsProcessedByMethod"; - private static final CharSequence REQUEST_METHOD = "numberOfRequests"; - private static final CharSequence RESPONSE_SC = "numberOfResponses"; - - @Override - public void getValues(MeasurementReport report, Set requests) { - super.getValues(report, requests); -// dumpEmsInformation(); - Map requestsProcessedByMethod = null; - Map responsesProcessedBySc = null; - try { - EmsAttribute requestAttribute = getEmsBean().getAttribute(NB_REQUESTS_PROCESSED_BY_METHOD_ATTRIBUTE_NAME); - requestsProcessedByMethod = requestsProcessedByMethod = (Map) requestAttribute.refresh(); - } catch (Throwable e) { - log.error("An unexpected exception occured while trying to access the Sip Balancer requestsProcessedByMethod", e); - } - try { - EmsAttribute responseAttribute = getEmsBean().getAttribute(NB_RESPONSES_PROCESSED_BY_SC_ATTRIBUTE_NAME); - responsesProcessedBySc = (Map) responseAttribute.refresh(); - } catch (Throwable e) { - log.error("An unexpected exception occured while trying to access the Sip Balancer responsesProcessedByStatusCode", e); - } - Set remainingSchedules = new LinkedHashSet(); - for (MeasurementScheduleRequest schedule : (Set)requests) { - String metricName = schedule.getName(); - log.debug("trying to retrieve value for metric " + metricName); - if (metricName.contains(REQUEST_METHOD)) { - try { - if(requestsProcessedByMethod != null) { - String method = metricName.substring(REQUEST_METHOD.length()); - log.debug("method is " + method); - AtomicLong requestsProcessed = requestsProcessedByMethod.get(method); - Double value = Double.valueOf((double) requestsProcessed.get()); - log.debug("value for metric " + metricName + " is " + value); - MeasurementDataNumeric metric = new MeasurementDataNumeric(schedule, value); - report.addData(metric); - } else { - log.error(NB_REQUESTS_PROCESSED_BY_METHOD_ATTRIBUTE_NAME + " attribute is not available on the mbean"); - } - } catch (Throwable e) { - log.error("An unexpected exception occured while trying to access the metric " + metricName + " from the requestProcessedByMethod", e); - } - } else if (metricName.contains(RESPONSE_SC)) { - try { - if(responsesProcessedBySc != null) { - String statusCode = metricName.substring(RESPONSE_SC.length()); - log.debug("statusCode is " + statusCode); - AtomicLong responsesProcessed = responsesProcessedBySc.get(statusCode); - Double value = Double.valueOf((double) responsesProcessed.get()); - log.debug("value for metric " + metricName + " is " + value); - MeasurementDataNumeric metric = new MeasurementDataNumeric(schedule, value); - report.addData(metric); - } else { - log.error(NB_RESPONSES_PROCESSED_BY_SC_ATTRIBUTE_NAME + " attribute is not available on the mbean"); - } - } catch (Throwable e) { - log.error("An unexpected exception occured while trying to access the metric " + metricName + " from the responsesProcessedByStatusCode", e); - } - } else { - remainingSchedules.add(schedule); - } - } - } - - public void dumpEmsInformation() { - log.debug("Ems Attributes"); - SortedSet attributes = getEmsBean().getAttributes(); - for (EmsAttribute emsAttribute : attributes) { - log.debug("Ems Attribute: " + emsAttribute.getName() + " type = " + emsAttribute.getType()); - } - log.debug("Ems Operations"); - SortedSet operations = getEmsBean().getOperations(); - for (EmsOperation emsOperation : operations) { - log.debug("Ems Operation: " + emsOperation.getName() + " type = " + emsOperation.getParameters()); - } - } - -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/AbstractManagedComponent.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/AbstractManagedComponent.java deleted file mode 100644 index 9cdbbd4caf..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/AbstractManagedComponent.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -package org.rhq.plugins.mobicents.servlet.sip.jboss5; - -import java.util.Map; - -import org.apache.commons.logging.Log; - -import org.jboss.managed.api.ManagedProperty; - -import org.rhq.core.pluginapi.inventory.ResourceContext; -import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; -import org.rhq.core.pluginapi.configuration.ConfigurationFacet; -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.PropertySimple; -import org.rhq.core.domain.configuration.ConfigurationUpdateStatus; -import org.rhq.core.util.exception.ThrowableUtil; -import org.rhq.plugins.jbossas5.util.ConversionUtils; -import org.rhq.plugins.jbossas5.util.DebugUtils; -import org.rhq.plugins.jbossas5.util.ResourceComponentUtils; - -/** - * @author Ian Springer - */ -public abstract class AbstractManagedComponent implements ConfigurationFacet { - private ResourceContext resourceContext; - private String resourceDescription; - - public void start(ResourceContext resourceContext) throws Exception { - this.resourceContext = resourceContext; - this.resourceDescription = this.resourceContext.getResourceType() - + " Resource with key [" + this.resourceContext.getResourceKey() + "]"; - } - - public void stop() { - return; - } - - // ConfigurationComponent Implementation -------------------------------------------- - - public Configuration loadResourceConfiguration() { - Configuration resourceConfig; - try - { - Map managedProperties = getManagedProperties(); - Map customProps = - ResourceComponentUtils.getCustomProperties(this.resourceContext.getPluginConfiguration()); - if (getLog().isDebugEnabled()) getLog().debug("*** AFTER LOAD:\n" - + DebugUtils.convertPropertiesToString(managedProperties)); - resourceConfig = ConversionUtils.convertManagedObjectToConfiguration(managedProperties, - customProps, this.resourceContext.getResourceType()); - } - catch (Exception e) - { - getLog().error("Failed to load configuration for " + this.resourceDescription + ".", e); - throw new RuntimeException(ThrowableUtil.getAllMessages(e)); - } - return resourceConfig; - } - - public void updateResourceConfiguration(ConfigurationUpdateReport configurationUpdateReport) - { - Configuration resourceConfig = configurationUpdateReport.getConfiguration(); - Configuration pluginConfig = this.resourceContext.getPluginConfiguration(); - try - { - Map managedProperties = getManagedProperties(); - Map customProps = ResourceComponentUtils.getCustomProperties(pluginConfig); - if (getLog().isDebugEnabled()) getLog().debug("*** BEFORE UPDATE:\n" - + DebugUtils.convertPropertiesToString(managedProperties)); - ConversionUtils.convertConfigurationToManagedProperties(managedProperties, resourceConfig, - this.resourceContext.getResourceType(), customProps); - if (getLog().isDebugEnabled()) getLog().debug("*** AFTER UPDATE:\n" - + DebugUtils.convertPropertiesToString(managedProperties)); - updateComponent(); - configurationUpdateReport.setStatus(ConfigurationUpdateStatus.SUCCESS); - } - catch (Exception e) - { - getLog().error("Failed to update configuration for " + this.resourceDescription + ".", e); - configurationUpdateReport.setStatus(ConfigurationUpdateStatus.FAILURE); - configurationUpdateReport.setErrorMessage(ThrowableUtil.getAllMessages(e)); - } - } - - protected abstract Map getManagedProperties() throws Exception; - - protected abstract void updateComponent() throws Exception; - - protected abstract Log getLog(); - - protected ResourceContext getResourceContext() { - return resourceContext; - } - - public String getResourceDescription() { - return resourceDescription; - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/AbstractManagedDeploymentComponent.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/AbstractManagedDeploymentComponent.java deleted file mode 100644 index 7f845be3c7..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/AbstractManagedDeploymentComponent.java +++ /dev/null @@ -1,173 +0,0 @@ -/* -* Jopr Management Platform -* Copyright (C) 2005-2009 Red Hat, Inc. -* All rights reserved. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License, version 2, as -* published by the Free Software Foundation, and/or the GNU Lesser -* General Public License, version 2.1, also as published by the Free -* Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License and the GNU Lesser General Public License -* for more details. -* -* You should have received a copy of the GNU General Public License -* and the GNU Lesser General Public License along with this program; -* if not, write to the Free Software Foundation, Inc., -* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -package org.rhq.plugins.mobicents.servlet.sip.jboss5; - -import java.io.File; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jboss.deployers.spi.management.KnownDeploymentTypes; -import org.jboss.deployers.spi.management.ManagementView; -import org.jboss.deployers.spi.management.deploy.DeploymentManager; -import org.jboss.deployers.spi.management.deploy.DeploymentProgress; -import org.jboss.deployers.spi.management.deploy.DeploymentStatus; -import org.jboss.deployers.spi.management.deploy.ProgressEvent; -import org.jboss.deployers.spi.management.deploy.ProgressListener; -import org.jboss.managed.api.DeploymentState; -import org.jboss.managed.api.ManagedDeployment; -import org.jboss.managed.api.ManagedProperty; -import org.jboss.profileservice.spi.NoSuchDeploymentException; -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.measurement.AvailabilityType; -import org.rhq.core.pluginapi.inventory.ResourceComponent; -import org.rhq.core.pluginapi.inventory.ResourceContext; -import org.rhq.core.pluginapi.operation.OperationFacet; -import org.rhq.core.pluginapi.operation.OperationResult; -import org.rhq.plugins.jbossas5.factory.ProfileServiceFactory; -import org.rhq.plugins.mobicents.servlet.sip.jboss5.util.DeploymentUtils; - -/** - * ResourceComponent for managing ManagedDeployments (EARs, WARs, SARs, etc.). - * - * @author Mark Spritzler - * @author Ian Springer - */ -public abstract class AbstractManagedDeploymentComponent - extends AbstractManagedComponent - implements ResourceComponent, OperationFacet, ProgressListener { - public static final String DEPLOYMENT_NAME_PROPERTY = "deploymentName"; - public static final String DEPLOYMENT_TYPE_NAME_PROPERTY = "deploymentTypeName"; - - private static final boolean IS_WINDOWS = (File.separatorChar == '\\'); - - private final Log log = LogFactory.getLog(this.getClass()); - - /** - * The name of the ManagedDeloyment (e.g.: vfszip:/C:/opt/jboss-5.0.0.GA/server/default/deploy/foo.war). - */ - protected String deploymentName; - - /** - * The type of the ManagedDeloyment. - */ - protected KnownDeploymentTypes deploymentType; - - /** - * The absolute path of the deployment file (e.g.: C:/opt/jboss-5.0.0.GA/server/default/deploy/foo.war). - */ - protected File deploymentFile; - - // ----------- ResourceComponent Implementation ------------ - - public void start(ResourceContext resourceContext) throws Exception { - super.start(resourceContext); - Configuration pluginConfig = getResourceContext().getPluginConfiguration(); - this.deploymentName = pluginConfig.getSimple(DEPLOYMENT_NAME_PROPERTY).getStringValue(); - this.deploymentFile = getDeploymentFile(); - String deploymentTypeName = pluginConfig.getSimple(DEPLOYMENT_TYPE_NAME_PROPERTY).getStringValue(); - this.deploymentType = KnownDeploymentTypes.valueOf(deploymentTypeName); - log.trace("Started ResourceComponent for " + getResourceDescription() + ", managing " + this.deploymentType - + " deployment '" + this.deploymentName + "' with path '" + this.deploymentFile + "'."); - } - - public AvailabilityType getAvailability() { - try { - return (getManagedDeployment().getDeploymentState() == DeploymentState.STARTED) ? AvailabilityType.UP : - AvailabilityType.DOWN; - } - catch (NoSuchDeploymentException e) { - log.warn(this.deploymentType + " deployment '" + this.deploymentName + "' not found. Cause: " - + e.getLocalizedMessage()); - return AvailabilityType.DOWN; - } - } - - // ------------ OperationFacet Implementation ------------ - - public OperationResult invokeOperation(String name, Configuration parameters) throws InterruptedException, Exception - { - DeploymentManager deploymentManager = ProfileServiceFactory.getDeploymentManager(); - DeploymentProgress progress; - if (name.equals("start")) { - progress = deploymentManager.start(this.deploymentName); - } else if (name.equals("stop")) { - progress = deploymentManager.stop(this.deploymentName); - } else if (name.equals("restart")) { - progress = deploymentManager.stop(this.deploymentName); - DeploymentUtils.run(progress); - progress = deploymentManager.start(this.deploymentName); - } else { - throw new UnsupportedOperationException(name); - } - DeploymentStatus status = DeploymentUtils.run(progress); - log.debug("Operation '" + name + "' on " + getResourceDescription() + " completed with status [" + status - + "]."); - return new OperationResult(); - } - - // ------------ ProgressListener implementation ------------- - - public void progressEvent(ProgressEvent event) { - log.debug(event); - } - - // ------------ AbstractManagedComponent implementation ------------- - - protected Map getManagedProperties() throws Exception { - return getManagedDeployment().getProperties(); - } - - protected Log getLog() { - return this.log; - } - - protected void updateComponent() throws Exception { - ManagementView managementView = ProfileServiceFactory.getCurrentProfileView(); - managementView.process(); - } - - // ------------------------------------------------------------- - - protected ManagedDeployment getManagedDeployment() throws NoSuchDeploymentException - { - ProfileServiceFactory.refreshCurrentProfileView(); - ManagementView managementView = ProfileServiceFactory.getCurrentProfileView(); - String resourceKey = getResourceContext().getResourceKey(); - return managementView.getDeployment(resourceKey); - } - - private File getDeploymentFile() throws MalformedURLException { - URL vfsURL = new URL(this.deploymentName); - String path = vfsURL.getPath(); - // Under Windows, the deployment name URL will look like: - // vfszip:/C:/opt/jboss-5.1.0.CR1/server/default/deploy/eardeployment.ear/ - // so we need to trim the leading slash off the path portion. Java considers the version with the leading slash - // to be a valid and equivalent path, but the leading slash is unnecessary and ugly, so we shall axe it. - if (IS_WINDOWS && path.charAt(0) == '/') - path = path.substring(1); - return new File(path); - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/ApplicationServerComponent.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/ApplicationServerComponent.java deleted file mode 100644 index 72a6458ac0..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/ApplicationServerComponent.java +++ /dev/null @@ -1,611 +0,0 @@ - /* - * Jopr Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.rhq.plugins.mobicents.servlet.sip.jboss5; - -import java.io.File; -import java.io.Serializable; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jboss.deployers.spi.management.KnownDeploymentTypes; -import org.jboss.deployers.spi.management.ManagementView; -import org.jboss.deployers.spi.management.deploy.DeploymentStatus; -import org.jboss.deployers.spi.management.deploy.ProgressEvent; -import org.jboss.deployers.spi.management.deploy.ProgressListener; -import org.jboss.managed.api.ComponentType; -import org.jboss.managed.api.DeploymentTemplateInfo; -import org.jboss.managed.api.ManagedComponent; -import org.jboss.managed.api.ManagedDeployment; -import org.jboss.managed.api.ManagedProperty; -import org.jboss.profileservice.spi.NoSuchDeploymentException; -import org.mc4j.ems.connection.ConnectionFactory; -import org.mc4j.ems.connection.EmsConnection; -import org.mc4j.ems.connection.bean.EmsBean; -import org.mc4j.ems.connection.settings.ConnectionSettings; -import org.mc4j.ems.connection.support.ConnectionProvider; -import org.mc4j.ems.connection.support.metadata.ConnectionTypeDescriptor; -import org.mc4j.ems.connection.support.metadata.InternalVMTypeDescriptor; -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.Property; -import org.rhq.core.domain.configuration.PropertySimple; -import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; -import org.rhq.core.domain.configuration.definition.ConfigurationTemplate; -import org.rhq.core.domain.configuration.definition.PropertyDefinition; -import org.rhq.core.domain.content.PackageDetailsKey; -import org.rhq.core.domain.content.transfer.ResourcePackageDetails; -import org.rhq.core.domain.measurement.AvailabilityType; -import org.rhq.core.domain.measurement.DataType; -import org.rhq.core.domain.measurement.MeasurementDataNumeric; -import org.rhq.core.domain.measurement.MeasurementDataTrait; -import org.rhq.core.domain.measurement.MeasurementReport; -import org.rhq.core.domain.measurement.MeasurementScheduleRequest; -import org.rhq.core.domain.resource.CreateResourceStatus; -import org.rhq.core.domain.resource.ResourceCreationDataType; -import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.pluginapi.configuration.ConfigurationFacet; -import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; -import org.rhq.core.pluginapi.inventory.CreateChildResourceFacet; -import org.rhq.core.pluginapi.inventory.CreateResourceReport; -import org.rhq.core.pluginapi.inventory.ResourceComponent; -import org.rhq.core.pluginapi.inventory.ResourceContext; -import org.rhq.core.pluginapi.measurement.MeasurementFacet; -import org.rhq.plugins.jbossas5.adapter.api.PropertyAdapter; -import org.rhq.plugins.jbossas5.adapter.api.PropertyAdapterFactory; -import org.rhq.plugins.jbossas5.factory.ProfileServiceFactory; -import org.rhq.plugins.jbossas5.util.ConversionUtils; -import org.rhq.plugins.jbossas5.util.DebugUtils; -import org.rhq.plugins.jbossas5.util.ManagedComponentUtils; -import org.rhq.plugins.jbossas5.util.ResourceComponentUtils; -import org.rhq.plugins.jmx.JMXDiscoveryComponent; -import org.rhq.plugins.jmx.JMXServerComponent; -import org.rhq.plugins.jmx.ObjectNameQueryUtility; -import org.rhq.plugins.mobicents.servlet.sip.jboss5.util.DeploymentUtils; -import org.rhq.plugins.mobicents.servlet.sip.jboss5.util.MainDeployer; - - /** - * ResourceComponent for a JBoss AS, 5.1.0.CR1 or later, Server. - * - * @author Jason Dobies - * @author Mark Spritzler - * @author Ian Springer - */ -public class ApplicationServerComponent - extends JMXServerComponent - implements ResourceComponent, CreateChildResourceFacet, MeasurementFacet, ConfigurationFacet, ProgressListener -{ - static final String TEMPLATE_NAME_PROPERTY = "templateName"; - static final String RESOURCE_NAME_PROPERTY = "resourceName"; - static final String SERVER_NAME_PROPERTY = "serverName"; - public static final String JBOSS_HOME_DIR_CONFIG_PROP = "jbossHomeDir"; - public static final String NAMING_URL_CONFIG_PROP = "namingURL"; - private static final String JNP_DISABLE_DISCOVERY_JNP_INIT_PROP = "jnp.disableDiscovery"; - /** - * This is the timeout for the initial connection to the MBeanServer that is made by {@link #start(ResourceContext)}. - */ - private static final int JNP_TIMEOUT = 30 * 1000; // 30 seconds - /** - * This is the timeout for MBean attribute gets/sets and operations invoked on the remote MBeanServer. - * NOTE: This timeout comes into play if the JBossAS instance has gone down since the original JNP connection was made. - */ - private static final int JNP_SO_TIMEOUT = 15 * 1000; // 15 seconds - - private static final String MANAGED_PROPERTY_GROUP = "managedPropertyGroup"; - - private static final Pattern METRIC_NAME_PATTERN = Pattern.compile("(.*)\\|(.*)\\|(.*)\\|(.*)"); - - private final Log log = LogFactory.getLog(this.getClass()); - - private ResourceContext resourceContext; - private File deployDirectory; - private EmsConnection connection; - - /** - * Controls the dampening of connection error stack traces in an attempt to control spam to the log - * file. Each time a connection error is encountered, this will be incremented. When the connection - * is finally established, this will be reset to zero. - */ - private int consecutiveConnectionErrors; - private MainDeployer mainDeployer; - - - public AvailabilityType getAvailability() - { - // TODO: Always returning UP is fine for Embedded, but we'll need to actually check avail for Enterprise. - return AvailabilityType.UP; - } - - public void start(ResourceContext resourceContext) - { - this.resourceContext = resourceContext; - } - - public void stop() - { - return; - } - - // ------------ MeasurementFacet Implementation ------------ - - public void getValues(MeasurementReport report, Set requests) - { - for (MeasurementScheduleRequest request : requests) { - String metricName = request.getName(); - try - { - // Metric names are expected to have the following syntax: - // "|||" - Matcher matcher = METRIC_NAME_PATTERN.matcher(metricName); - if (!matcher.matches()) { - log.error("Metric name '" + metricName + "' does not match pattern '" + METRIC_NAME_PATTERN + "'."); - continue; - } - String componentCategory = matcher.group(1); - String componentSubType = matcher.group(2); - String componentName = matcher.group(3); - String propertyName = matcher.group(4); - ComponentType componentType = new ComponentType(componentCategory, componentSubType); - ManagedComponent component; - if (componentName.equals("*")) { - component = ManagedComponentUtils.getSingletonManagedComponent(componentType); - } else { - component = ManagedComponentUtils.getManagedComponent(componentType, componentName); - } - Serializable value = ManagedComponentUtils.getSimplePropertyValue(component, propertyName); - if (value == null) { - log.debug("Null value returned for metric '" + metricName + "'."); - continue; - } - if (request.getDataType() == DataType.MEASUREMENT) { - Number number = (Number)value; - report.addData(new MeasurementDataNumeric(request, number.doubleValue())); - } else if (request.getDataType() == DataType.TRAIT) { - report.addData(new MeasurementDataTrait(request, value.toString())); - } - } - catch (RuntimeException e) - { - log.error("Failed to obtain metric '" + metricName + "'.", e); - } - } - } - - // ------------ ConfigurationFacet Implementation ------------ - - public Configuration loadResourceConfiguration() - { - /* Need to determine what we consider server configuration to return. Also need to understand - what ComponentType the profile service would use to retrieve "server" level configuration. - */ - - return null; - } - - public void updateResourceConfiguration(ConfigurationUpdateReport configurationUpdateReport) - { - // See above comment on server configuration. - } - - // CreateChildResourceFacet -------------------------------------------- - - public CreateResourceReport createResource(CreateResourceReport createResourceReport) - { - //ProfileServiceFactory.refreshCurrentProfileView(); - ResourceType resourceType = createResourceReport.getResourceType(); - if (resourceType.getCreationDataType() == ResourceCreationDataType.CONTENT) - createContentBasedResource(createResourceReport, resourceType); - else - createConfigurationBasedResource(createResourceReport, resourceType); - return createResourceReport; - } - - public File getDeployDirectory() - { - if (this.deployDirectory == null) - this.deployDirectory = computeDeployDirectory(); - return this.deployDirectory; - } - - // ProgressListener -------------------------------------------- - - public void progressEvent(ProgressEvent eventInfo) { - log.debug(eventInfo); - } - - private void handleMiscManagedProperties(Collection managedPropertyGroup, - Map managedProperties, - Configuration pluginConfiguration) - { - for (PropertyDefinition propertyDefinition : managedPropertyGroup) - { - String propertyKey = propertyDefinition.getName(); - Property property = pluginConfiguration.get(propertyKey); - ManagedProperty managedProperty = managedProperties.get(propertyKey); - if (managedProperty != null && property != null) - { - PropertyAdapter propertyAdapter = PropertyAdapterFactory.getPropertyAdapter(managedProperty.getMetaType()); - propertyAdapter.populateMetaValueFromProperty(property, managedProperty.getValue(), propertyDefinition); - } - } - } - - private static String getResourceName(Configuration pluginConfig, Configuration resourceConfig) - { - PropertySimple resourceNameProp = pluginConfig.getSimple(RESOURCE_NAME_PROPERTY); - if (resourceNameProp == null || resourceNameProp.getStringValue() == null) - throw new IllegalStateException("Property [" + RESOURCE_NAME_PROPERTY - + "] is not defined in the default plugin configuration."); - String resourceNamePropName = resourceNameProp.getStringValue(); - PropertySimple propToUseAsResourceName = resourceConfig.getSimple(resourceNamePropName); - if (propToUseAsResourceName == null) - throw new IllegalStateException("Property [" + resourceNamePropName - + "] is not defined in initial Resource configuration."); - return propToUseAsResourceName.getStringValue(); - } - - private String getResourceKey(ResourceType resourceType, String resourceName) - { - ComponentType componentType = ConversionUtils.getComponentType(resourceType); - if (componentType == null) - throw new IllegalStateException("Unable to map " + resourceType + " to a ComponentType."); - // TODO (ips): I think the key can just be the resource name. - return componentType.getType() + ":" + componentType.getSubtype() + ":" + resourceName; - } - - private void createConfigurationBasedResource(CreateResourceReport createResourceReport, ResourceType resourceType) - { - Configuration defaultPluginConfig = getDefaultPluginConfiguration(resourceType); - Configuration resourceConfig = createResourceReport.getResourceConfiguration(); - String resourceName = getResourceName(defaultPluginConfig, resourceConfig); - ComponentType componentType = ConversionUtils.getComponentType(resourceType); - if (ProfileServiceFactory.isManagedComponent(resourceName, componentType)) { - createResourceReport.setStatus(CreateResourceStatus.FAILURE); - createResourceReport.setErrorMessage("A " + resourceType.getName() + " named '" + resourceName - + "' already exists."); - return; - } - - createResourceReport.setResourceName(resourceName); - String resourceKey = getResourceKey(resourceType, resourceName); - createResourceReport.setResourceKey(resourceKey); - - PropertySimple templateNameProperty = defaultPluginConfig.getSimple(TEMPLATE_NAME_PROPERTY); - String templateName = templateNameProperty.getStringValue(); - - ManagementView managementView = ProfileServiceFactory.getCurrentProfileView(); - DeploymentTemplateInfo template; - try - { - template = managementView.getTemplate(templateName); - Map managedProperties = template.getProperties(); - Map customProps = ResourceComponentUtils.getCustomProperties(defaultPluginConfig); - - if (log.isDebugEnabled()) log.debug("BEFORE CREATE:\n" + DebugUtils.convertPropertiesToString(template)); - ConversionUtils.convertConfigurationToManagedProperties(managedProperties, resourceConfig, resourceType, customProps); - if (log.isDebugEnabled()) log.debug("AFTER CREATE:\n" + DebugUtils.convertPropertiesToString(template)); - - ConfigurationDefinition pluginConfigDef = resourceType.getPluginConfigurationDefinition(); - Collection managedPropertyGroup = pluginConfigDef.getPropertiesInGroup(MANAGED_PROPERTY_GROUP); - handleMiscManagedProperties(managedPropertyGroup, managedProperties, defaultPluginConfig); - log.debug("Applying template [" + templateName + "] to create ManagedComponent of type [" + componentType - + "]..."); - try - { - managementView.applyTemplate(resourceName, template); - managementView.process(); - createResourceReport.setStatus(CreateResourceStatus.SUCCESS); - } - catch (Exception e) - { - log.error("Unable to apply template [" + templateName + "] to create ManagedComponent of type " - + componentType + ".", e); - createResourceReport.setStatus(CreateResourceStatus.FAILURE); - createResourceReport.setException(e); - } - } - catch (NoSuchDeploymentException e) - { - log.error("Unable to find template [" + templateName + "].", e); - createResourceReport.setStatus(CreateResourceStatus.FAILURE); - createResourceReport.setException(e); - } - catch (Exception e) - { - log.error("Unable to process create request", e); - createResourceReport.setStatus(CreateResourceStatus.FAILURE); - createResourceReport.setException(e); - } - } - - private void createContentBasedResource(CreateResourceReport createResourceReport, ResourceType resourceType) - { - ResourcePackageDetails details = createResourceReport.getPackageDetails(); - PackageDetailsKey key = details.getKey(); - // This is the full path to a temporary file which was written by the UI layer. - String archivePath = key.getName(); - - try { - File archiveFile = new File(archivePath); - - if (!DeploymentUtils.hasCorrectExtension(archiveFile, resourceType)) { - createResourceReport.setStatus(CreateResourceStatus.FAILURE); - createResourceReport.setErrorMessage("Incorrect extension specified on filename [" + archivePath + "]"); - return; - } - - abortIfApplicationAlreadyDeployed(resourceType, archiveFile); - - Configuration deployTimeConfig = details.getDeploymentTimeConfiguration(); - @SuppressWarnings({"ConstantConditions"}) - boolean deployExploded = deployTimeConfig.getSimple("deployExploded").getBooleanValue(); - - DeploymentStatus status = DeploymentUtils.deployArchive(archiveFile, getDeployDirectory(), deployExploded); - - if (status.getState() == DeploymentStatus.StateType.COMPLETED) { - createResourceReport.setResourceName(archivePath); - createResourceReport.setResourceKey(archivePath); - createResourceReport.setStatus(CreateResourceStatus.SUCCESS); - } else { - createResourceReport.setStatus(CreateResourceStatus.FAILURE); - createResourceReport.setErrorMessage(status.getMessage()); - //noinspection ThrowableResultOfMethodCallIgnored - createResourceReport.setException(status.getFailure()); - } - } catch (Throwable t) { - log.error("Error deploying application for report: " + createResourceReport, t); - createResourceReport.setStatus(CreateResourceStatus.FAILURE); - createResourceReport.setException(t); - } - } - - private static Configuration getDefaultPluginConfiguration(ResourceType resourceType) { - ConfigurationTemplate pluginConfigDefaultTemplate = - resourceType.getPluginConfigurationDefinition().getDefaultTemplate(); - return (pluginConfigDefaultTemplate != null) ? - pluginConfigDefaultTemplate.createConfiguration() : new Configuration(); - } - - private void abortIfApplicationAlreadyDeployed(ResourceType resourceType, File archiveFile) - throws Exception - { - String archiveFileName = archiveFile.getName(); - KnownDeploymentTypes deploymentType = ConversionUtils.getDeploymentType(resourceType); - String deploymentTypeString = deploymentType.getType(); - ProfileServiceFactory.refreshCurrentProfileView(); - ManagementView managementView = ProfileServiceFactory.getCurrentProfileView(); - Set managedDeployments = managementView.getDeploymentsForType(deploymentTypeString); - for (ManagedDeployment managedDeployment : managedDeployments) - { - if (managedDeployment.getSimpleName().equals(archiveFileName)) - throw new IllegalArgumentException("An application named '" + archiveFileName + "' is already deployed."); - } - } - - private File computeDeployDirectory() - { - ManagementView managementView = ProfileServiceFactory.getCurrentProfileView(); - Set warDeployments; - try - { - warDeployments = managementView.getDeploymentsForType( - KnownDeploymentTypes.JavaEEWebApplication.getType()); - } - catch (Exception e) - { - throw new IllegalStateException(e); - } - ManagedDeployment standaloneWarDeployment = null; - for (ManagedDeployment warDeployment : warDeployments) - { - if (warDeployment.getParent() == null) { - standaloneWarDeployment = warDeployment; - break; - } - } - if (standaloneWarDeployment == null) - // This could happen if no standalone WARs, including the admin console WAR, have been fully deployed yet. - return null; - log.debug("Standalone WAR deployment: " + standaloneWarDeployment.getName()); - URL warUrl; - try - { - warUrl = new URL(standaloneWarDeployment.getName()); - } - catch (MalformedURLException e) - { - throw new IllegalStateException(e); - } - File warFile = new File(warUrl.getPath()); - File deployDir = warFile.getParentFile(); - log.debug(">>>>> Deploy directory: " + deployDir); - return deployDir; - } - @Override - public EmsConnection getEmsConnection() { - EmsConnection emsConnection = null; - - try { - emsConnection = loadConnection(); - } catch (Exception e) { - log.error("Component attempting to access a connection that could not be loaded"); - } - - return emsConnection; - } - - private boolean runningEmbedded() { - Configuration pluginConfiguration = this.resourceContext.getPluginConfiguration(); - String namingUrl = pluginConfiguration.getSimpleValue(NAMING_URL_CONFIG_PROP, null); - return namingUrl == null; - } - - /** - * This is the preferred way to use a connection from within this class; methods should not access the connection - * property directly as it may not have been instantiated if the connection could not be made. - * - *

If the connection has already been established, return the object reference to it. If not, attempt to make - * a live connection to the JMX server.

- * - *

If the connection could not be made in the {@link #start(org.rhq.core.pluginapi.inventory.ResourceContext)} - * method, this method will effectively try to load the connection on each attempt to use it. As such, multiple - * threads may attempt to access the connection through this means at a time. Therefore, the method has been - * made synchronized on instances of the class.

- * - *

If any errors are encountered, this method will log the error, taking into account logic to prevent spamming - * the log file. Calling methods should take care to not redundantly log the exception thrown by this method.

- * - * @return live connection to the JMX server; this will not be null - * - * @throws Exception if there are any issues at all connecting to the server - */ - private synchronized EmsConnection loadConnection() throws Exception { - if (this.connection == null) { - try { - Configuration pluginConfig = resourceContext.getPluginConfiguration(); - String jbossHomeDir = pluginConfig.getSimpleValue(JBOSS_HOME_DIR_CONFIG_PROP, null); - - ConnectionSettings connectionSettings = new ConnectionSettings(); - - String connectionTypeDescriptorClass = pluginConfig.getSimple(JMXDiscoveryComponent.CONNECTION_TYPE) - .getStringValue(); - connectionSettings.initializeConnectionType((ConnectionTypeDescriptor) Class.forName( - connectionTypeDescriptorClass).newInstance()); - boolean runningEmbedded = runningEmbedded(); - if (runningEmbedded) { - connectionSettings.setServerUrl(System.getProperty("jboss.bind.address", "127.0.0.1")); - } else { - connectionSettings.setServerUrl(pluginConfig.getSimpleValue(NAMING_URL_CONFIG_PROP, null)); - } - - connectionSettings.setPrincipal(pluginConfig.getSimpleValue(PRINCIPAL_CONFIG_PROP, null)); - connectionSettings.setCredentials(pluginConfig.getSimpleValue(CREDENTIALS_CONFIG_PROP, null)); - connectionSettings.setLibraryURI(jbossHomeDir); - - ConnectionFactory connectionFactory = new ConnectionFactory(); - connectionFactory.discoverServerClasses(connectionSettings); - - if (connectionSettings.getAdvancedProperties() == null) { - connectionSettings.setAdvancedProperties(new Properties()); - } - - connectionSettings.getAdvancedProperties().setProperty(JNP_DISABLE_DISCOVERY_JNP_INIT_PROP, "true"); - - // Make sure the timeout always happens, even if the JBoss server is hung. - connectionSettings.getAdvancedProperties().setProperty("jnp.timeout", String.valueOf(JNP_TIMEOUT)); - connectionSettings.getAdvancedProperties().setProperty("jnp.sotimeout", String.valueOf(JNP_SO_TIMEOUT)); - - // Tell EMS to make copies of jar files so that the ems classloader doesn't lock - // application files (making us unable to update them) Bug: JBNADM-670 - // TODO GH: turn this off in the embedded case - connectionSettings.getControlProperties().setProperty(ConnectionFactory.COPY_JARS_TO_TEMP, - String.valueOf(Boolean.TRUE)); - - // But tell it to put them in a place that we clean up when shutting down the agent - connectionSettings.getControlProperties().setProperty(ConnectionFactory.JAR_TEMP_DIR, - resourceContext.getTemporaryDirectory().getAbsolutePath()); - - connectionSettings.getAdvancedProperties().setProperty(InternalVMTypeDescriptor.DEFAULT_DOMAIN_SEARCH, - "jboss"); - - log.info("Loading JBoss connection [" + connectionSettings.getServerUrl() + "] with install path [" - + connectionSettings.getLibraryURI() + "]..."); - - ConnectionProvider connectionProvider = connectionFactory.getConnectionProvider(connectionSettings); - this.connection = connectionProvider.connect(); - - this.connection.loadSynchronous(false); // this loads all the MBeans - - this.consecutiveConnectionErrors = 0; - - try { - this.mainDeployer = new MainDeployer(this.connection); - } catch (Exception e) { - log.error("Unable to access MainDeployer MBean required for creation and deletion of managed " - + "resources - this should never happen. Cause: " + e); - } - - if (log.isDebugEnabled()) - log.debug("Successfully made connection to the AS instance for resource [" - + this.resourceContext.getResourceKey() + "]"); - } catch (Exception e) { - - // The connection will be established even in the case that the principal cannot be authenticated, - // but the connection will not work. That failure seems to come from the call to loadSynchronous after - // the connection is established. If we get to this point that an exception was thrown, close any - // connection that was made and null it out so we can try to establish it again. - if (connection != null) { - if (log.isDebugEnabled()) - log.debug("Connection created but an exception was thrown. Closing the connection.", e); - connection.close(); - connection = null; - } - - // Since the connection is attempted each time it's used, failure to connect could result in log - // file spamming. Log it once for every 10 consecutive times it's encountered. - if (consecutiveConnectionErrors % 10 == 0) { - log.warn("Could not establish connection to the JBoss AS instance [" - + (consecutiveConnectionErrors + 1) + "] times for resource [" - + resourceContext.getResourceKey() + "]", e); - } - - if (log.isDebugEnabled()) - log.debug("Could not connect to the JBoss AS instance for resource [" - + resourceContext.getResourceKey() + "]", e); - - consecutiveConnectionErrors++; - - throw e; - } - } - - return connection; - } - - public List getWebApplicationEmsBeans(String applicationName) { - - String pattern = "jboss.web:host=%host%,path=" + getContextPath(applicationName) + ",type=Manager"; - ObjectNameQueryUtility queryUtil = new ObjectNameQueryUtility(pattern); - return getEmsConnection().queryBeans(queryUtil.getTranslatedQuery()); - } - - public List getConvergedSipApplicationEmsBeans(String applicationName) { - - String pattern = "jboss.web:host=%host%,path=" + getContextPath(applicationName) + ",type=SipManager"; - ObjectNameQueryUtility queryUtil = new ObjectNameQueryUtility(pattern); - return getEmsConnection().queryBeans(queryUtil.getTranslatedQuery()); - } - - public static String getContextPath(String contextRoot) { - return contextRoot.equals("/") - ? "/" : "/" + contextRoot; - } -} - diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/ApplicationServerDiscoveryComponent.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/ApplicationServerDiscoveryComponent.java deleted file mode 100644 index f9ce598958..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/ApplicationServerDiscoveryComponent.java +++ /dev/null @@ -1,148 +0,0 @@ - /* - * Jopr Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.rhq.plugins.mobicents.servlet.sip.jboss5; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails; -import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent; -import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext; -import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.PropertySimple; -import org.rhq.plugins.jbossas5.factory.ProfileServiceFactory; -import org.rhq.plugins.jbossas5.util.PluginDescriptorGenerator; -import org.rhq.plugins.jbossas5.util.ManagedComponentUtils; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; -import java.io.File; - -import org.jboss.deployers.spi.management.ManagementView; -import org.jboss.profileservice.spi.ProfileKey; -import org.jboss.profileservice.spi.ProfileService; -import org.jboss.managed.api.ComponentType; -import org.jboss.managed.api.ManagedComponent; - - /** - * Discovery component for JBoss AS, 5.1.0.CR1 or later, Servers. - * - * @author Ian Springer - * @author Mark Spritzler - */ -public class ApplicationServerDiscoveryComponent - implements ResourceDiscoveryComponent -{ - private static final String DEFAULT_RESOURCE_DESCRIPTION = "JBoss Application Server"; - private static final String JBMANCON_DEBUG_SYSPROP = "jbmancon.debug"; - - private final Log log = LogFactory.getLog(this.getClass()); - - public Set discoverResources(ResourceDiscoveryContext resourceDiscoveryContext) - { - log.trace("Discovering " + resourceDiscoveryContext.getResourceType().getName() + " Resources..." ); - - Set servers = new HashSet(); - - ProfileService profileService = ProfileServiceFactory.getProfileService(); - Collection profileKeys = profileService.getActiveProfileKeys(); - if (profileKeys.isEmpty()) - throw new IllegalStateException("No active profiles found."); - log.trace("Found the following active profiles: " + profileKeys); - ProfileServiceFactory.refreshCurrentProfileView(); - - ManagedComponent serverConfigComponent = ManagedComponentUtils.getSingletonManagedComponent( - new ComponentType("MCBean", "ServerConfig")); - String serverName = (String)ManagedComponentUtils.getSimplePropertyValue(serverConfigComponent, "serverName"); - - // TODO: Figure out if the instance is AS or EAP, and reflect that in the Resource name. - String resourceName = "JBoss AS 5 (" + serverName + ")"; - - String resourceKey = (String)ManagedComponentUtils.getSimplePropertyValue(serverConfigComponent, "serverHomeDir"); - - String version = (String)ManagedComponentUtils.getSimplePropertyValue(serverConfigComponent, "specificationVersion"); - - Configuration pluginConfig = resourceDiscoveryContext.getDefaultPluginConfiguration(); - pluginConfig.put(new PropertySimple(ApplicationServerComponent.SERVER_NAME_PROPERTY, serverName)); - - DiscoveredResourceDetails server = - new DiscoveredResourceDetails( - resourceDiscoveryContext.getResourceType(), - resourceKey, - resourceName, - version, - DEFAULT_RESOURCE_DESCRIPTION, - pluginConfig, - null); - servers.add(server); -/* - } catch (NoSuchProfileException e) - { - LOG.error("No Active Profile found", e); - } -*/ - - // Implementation to find all profiles - /* - Collection profileKeys = profileService.getProfileKeys(); - - for (ProfileKey key: profileKeys) - { - - String resourceKey = "Jboss AS 5:" + key.getName(); - // @TODO when the Profile Service gives more AS info, replace hardcoded strings - DiscoveredResourceDetails server = - new DiscoveredResourceDetails( - context.getResourceType(), - resourceKey, - resourceKey, - "5.0", - "JBoss App Server"); - servers.add( server ); - } - */ - ResourceType resourceType = resourceDiscoveryContext.getResourceType(); - log.trace("Discovered " + servers.size() + " " + resourceType.getName() + " Resources." ); - - boolean debug = Boolean.getBoolean(JBMANCON_DEBUG_SYSPROP); - if (debug) { - //new UnitTestRunner().runUnitTests(); - generatePluginDescriptor(resourceDiscoveryContext); - } - - return servers; - } - - private void generatePluginDescriptor(ResourceDiscoveryContext resourceDiscoveryContext) { - log.info("Generating RHQ plugin descriptor..."); - try { - ManagementView managementView = ProfileServiceFactory.getCurrentProfileView(); - File tempDir = resourceDiscoveryContext.getParentResourceContext().getTemporaryDirectory(); - PluginDescriptorGenerator.generatePluginDescriptor(managementView, tempDir); - } - catch (Exception e) { - log.error("Failed to generate RHQ plugin descriptor.", e); - } - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/ConvergedSipEmbeddedComponent.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/ConvergedSipEmbeddedComponent.java deleted file mode 100644 index 45f21987dc..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/ConvergedSipEmbeddedComponent.java +++ /dev/null @@ -1,264 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -package org.rhq.plugins.mobicents.servlet.sip.jboss5; - -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jboss.profileservice.spi.NoSuchDeploymentException; -import org.mc4j.ems.connection.EmsConnection; -import org.mc4j.ems.connection.bean.EmsBean; -import org.mc4j.ems.connection.bean.attribute.EmsAttribute; -import org.rhq.core.domain.measurement.MeasurementDataNumeric; -import org.rhq.core.domain.measurement.MeasurementDataTrait; -import org.rhq.core.domain.measurement.MeasurementReport; -import org.rhq.core.domain.measurement.MeasurementScheduleRequest; -import org.rhq.core.pluginapi.inventory.ResourceContext; -import org.rhq.plugins.jmx.ObjectNameQueryUtility; - -/** - * - * @author jean.deruelle@gmail.com - * - */ -public class ConvergedSipEmbeddedComponent extends EmbeddedManagedDeploymentComponent -{ - private final Log log = LogFactory.getLog(this.getClass()); - - private static final String SERVLET_PREFIX = "Servlet."; - private static final String SIP_SERVLET_PREFIX = "SipServlet."; - public static final String CONTEXT_ROOT_CONFIG_PROP = "contextRoot"; - public static final String NAME_CONFIG_PROP = "name"; - public static final String FILE_NAME = "filename"; - public static final String JBOSS_WEB_NAME = "jbossWebName"; - public static final String RESPONSE_TIME_LOG_FILE_CONFIG_PROP = "responseTimeLogFile"; - public static final String RESPONSE_TIME_URL_EXCLUDES_CONFIG_PROP = "responseTimeUrlExcludes"; - public static final String RESPONSE_TIME_URL_TRANSFORMS_CONFIG_PROP = "responseTimeUrlTransforms"; - - private static final String RESPONSE_TIME_METRIC = "ResponseTime"; - private static final String CONTEXT_ROOT_METRIC = "ContextRoot"; - - private static final String MAX_SERVLET_TIME = "Servlet.MaxResponseTime"; - private static final String MIN_SERVLET_TIME = "Servlet.MinResponseTime"; - private static final String AVG_SERVLET_TIME = "Servlet.AvgResponseTime"; - private static final String NUM_SERVLET_REQUESTS = "Servlet.NumRequests"; - private static final String NUM_SERVLET_ERRORS = "Servlet.NumErrors"; - private static final String TOTAL_TIME = "Servlet.TotalTime"; - private static final String SERVLET_NAME_BASE_TEMPLATE = "jboss.web:J2EEApplication=none,J2EEServer=none,j2eeType=Servlet,name=%name%"; - private static final String SIP_SERVLET_NAME_BASE_TEMPLATE = "jboss.web:J2EEApplication=none,J2EEServer=none,j2eeType=SipServlet,name=%name%"; - - private static final String SESSION_PREFIX = "Session."; - private static final String SIP_SESSION_NAME_BASE_TEMPLATE = "jboss.web:host=%HOST%,type=SipManager,path=%PATH%"; - private static final String SIP_SESSION_PREFIX = "SipSession."; - - private static final String VHOST_PREFIX = "Vhost"; - public static final String VHOST_CONFIG_PROP = "vHost"; - - public static final String ROOT_WEBAPP_CONTEXT_ROOT = "/"; - -// private EmsBean jbossWebMBean; -// private ResponseTimeLogParser logParser; -// String vhost; - private String contextRoot; - - ApplicationServerComponent applicationServerComponent; - - @Override - public void start(ResourceContext resourceContext) throws Exception { - super.start(resourceContext); - applicationServerComponent = (ApplicationServerComponent)resourceContext.getParentResourceComponent(); - // -4 is for the extension .war to be removed - this.contextRoot = deploymentName.substring(0, deploymentName.length() - 5); - this.contextRoot = contextRoot.substring(contextRoot.lastIndexOf("/") + 1); - - } - - // ------------ MeasurementFacet Implementation ------------ - - public void getValues(MeasurementReport report, Set requests) throws NoSuchDeploymentException { - for (MeasurementScheduleRequest request : requests) { - String metricName = request.getName(); - if (metricName.equals(CUSTOM_PARENT_TRAIT)) { - this.contextRoot = deploymentName.substring(0, deploymentName.length() - 5); - this.contextRoot = contextRoot.substring(contextRoot.lastIndexOf("/") + 1); - List mBeans = applicationServerComponent.getConvergedSipApplicationEmsBeans(contextRoot); - String parentDeploymentName = getManagedDeployment().getParent().getName(); - if(mBeans.size() < 1) { - // -4 is for the extension .war to be removed - this.contextRoot = parentDeploymentName.substring(0, parentDeploymentName.length() - 5); - this.contextRoot = contextRoot.substring(contextRoot.lastIndexOf("/") + 1); - } - MeasurementDataTrait trait = new MeasurementDataTrait(request, parentDeploymentName); - report.addData(trait); - } - } - Set remainingSchedules = new LinkedHashSet(); - for (MeasurementScheduleRequest schedule : requests) { - String metricName = schedule.getName(); - if (metricName.equals(RESPONSE_TIME_METRIC)) { -// if (this.logParser != null) { -// try { -// CallTimeData callTimeData = new CallTimeData(schedule); -// this.logParser.parseLog(callTimeData); -// report.addData(callTimeData); -// } catch (Exception e) { -// log.error("Failed to retrieve HTTP call-time data.", e); -// } -// } else { -// log.error("The '" + RESPONSE_TIME_METRIC + "' metric is enabled for WAR resource '" -// + getApplicationName() + "', but no value is defined for the '" -// + RESPONSE_TIME_LOG_FILE_CONFIG_PROP + "' connection property."); -// // TODO: Communicate this error back to the server for display in the GUI. -// } - } else if (metricName.equals(CONTEXT_ROOT_METRIC)) { - MeasurementDataTrait trait = new MeasurementDataTrait(schedule, contextRoot); - report.addData(trait); - } else if (metricName.startsWith(SERVLET_PREFIX) || metricName.startsWith(SIP_SERVLET_PREFIX)) { - Double value = getServletMetric(metricName); - MeasurementDataNumeric metric = new MeasurementDataNumeric(schedule, value); - report.addData(metric); - } else if (metricName.startsWith(SESSION_PREFIX) || metricName.startsWith(SIP_SESSION_PREFIX)) { - Double value = getSessionMetric(metricName); - MeasurementDataNumeric metric = new MeasurementDataNumeric(schedule, value); - report.addData(metric); - } else if (metricName.startsWith(VHOST_PREFIX)) { -// if (metricName.equals("Vhost.name")) { -// List beans = getVHosts(contextRoot); -// String value = ""; -// Iterator iter = beans.iterator(); -// while (iter.hasNext()) { -// EmsBean eBean = iter.next(); -// value += eBean.getBeanName().getKeyProperty("host"); -// if (iter.hasNext()) -// value += ","; -// } -// MeasurementDataTrait trait = new MeasurementDataTrait(schedule, value); -// report.addData(trait); -// } - } else { - remainingSchedules.add(schedule); - } - } - } - - private Double getServletMetric(String metricName) { - - EmsConnection jmxConnection = applicationServerComponent.getEmsConnection(); - - String servletNameBaseTemplate = SERVLET_NAME_BASE_TEMPLATE; - if(metricName.startsWith(SIP_SERVLET_PREFIX)) { - servletNameBaseTemplate = SIP_SERVLET_NAME_BASE_TEMPLATE; - } - //FIXME : replace localhost with the real vhost - String servletMBeanNames = servletNameBaseTemplate + ",WebModule=//localhost" - + applicationServerComponent.getContextPath(this.contextRoot); - ObjectNameQueryUtility queryUtility = new ObjectNameQueryUtility(servletMBeanNames); - List mBeans = jmxConnection.queryBeans(queryUtility.getTranslatedQuery()); - - long min = Long.MAX_VALUE; - long max = 0; - long processingTime = 0; - int requestCount = 0; - int errorCount = 0; - Double result; - - for (EmsBean mBean : mBeans) { - mBean.refreshAttributes(); - if (metricName.equals(MIN_SERVLET_TIME)) { - EmsAttribute att = mBean.getAttribute("minTime"); - Long l = (Long) att.getValue(); - if (l < min) - min = l; - } else if (metricName.equals(MAX_SERVLET_TIME)) { - EmsAttribute att = mBean.getAttribute("maxTime"); - Long l = (Long) att.getValue(); - if (l > max) - max = l; - } else if (metricName.equals(AVG_SERVLET_TIME)) { - EmsAttribute att = mBean.getAttribute("processingTime"); - Long l = (Long) att.getValue(); - processingTime += l; - att = mBean.getAttribute("requestCount"); - Integer i = (Integer) att.getValue(); - requestCount += i; - } else if (metricName.equals(NUM_SERVLET_REQUESTS)) { - EmsAttribute att = mBean.getAttribute("requestCount"); - Integer i = (Integer) att.getValue(); - requestCount += i; - } else if (metricName.equals(NUM_SERVLET_ERRORS)) { - EmsAttribute att = mBean.getAttribute("errorCount"); - Integer i = (Integer) att.getValue(); - errorCount += i; - } else if (metricName.equals(TOTAL_TIME)) { - EmsAttribute att = mBean.getAttribute("processingTime"); - Long l = (Long) att.getValue(); - processingTime += l; - } - } - if (metricName.equals(AVG_SERVLET_TIME)) { - result = (requestCount > 0) ? ((double) processingTime / (double) requestCount) : Double.NaN; - } else if (metricName.equals(MIN_SERVLET_TIME)) { - result = (min != Long.MAX_VALUE) ? (double) min : Double.NaN; - } else if (metricName.equals(MAX_SERVLET_TIME)) { - result = (max != 0) ? (double) max : Double.NaN; - } else if (metricName.equals(NUM_SERVLET_ERRORS)) { - result = (double) errorCount; - } else if (metricName.equals(NUM_SERVLET_REQUESTS)) { - result = (double) requestCount; - } else if (metricName.equals(TOTAL_TIME)) { - result = (double) processingTime; - } else { - // fallback - result = Double.NaN; - } - - return result; - } - - private Double getSessionMetric(String metricName) { - EmsConnection jmxConnection = applicationServerComponent.getEmsConnection(); - - String servletMBeanNames = SIP_SESSION_NAME_BASE_TEMPLATE.replace("%PATH%", - applicationServerComponent.getContextPath(this.contextRoot)); - //FIXME : replace localhost with the real vhost - servletMBeanNames = servletMBeanNames.replace("%HOST%", "localhost"); - ObjectNameQueryUtility queryUtility = new ObjectNameQueryUtility(servletMBeanNames); - List mBeans = jmxConnection.queryBeans(queryUtility.getTranslatedQuery()); - - String property = metricName.substring(SIP_SESSION_PREFIX.length()); - - Double ret = Double.NaN; - - if (mBeans.size() > 0) { // TODO flag error if != 1 ? - EmsBean eBean = mBeans.get(0); - eBean.refreshAttributes(); - EmsAttribute att = eBean.getAttribute(property); - if (att != null) { - Integer i = (Integer) att.getValue(); - ret = new Double(i); - } - - } - return ret; - } - -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/ConvergedSipEmbeddedDiscoveryComponent.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/ConvergedSipEmbeddedDiscoveryComponent.java deleted file mode 100644 index 40e021359c..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/ConvergedSipEmbeddedDiscoveryComponent.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.rhq.plugins.mobicents.servlet.sip.jboss5; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jboss.managed.api.ManagedDeployment; -import org.mc4j.ems.connection.bean.EmsBean; -import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext; - -public class ConvergedSipEmbeddedDiscoveryComponent extends EmbeddedManagedDeploymentDiscoveryComponent { - private final Log log = LogFactory.getLog(this.getClass()); - - @Override - protected boolean accept( - ManagedDeployment managedDeployment, - ResourceDiscoveryContext resourceDiscoveryContext) { - boolean isEmbedded = super.accept(managedDeployment, resourceDiscoveryContext); - if(!isEmbedded) { - return false; - } - String applicationName = managedDeployment.getSimpleName().substring(0,managedDeployment.getSimpleName().indexOf(".war")); - List mBeans = resourceDiscoveryContext.getParentResourceComponent().getConvergedSipApplicationEmsBeans(applicationName); - - List parentMBeans = new ArrayList(); - if(managedDeployment.getParent().getSimpleName().indexOf(".ear") != -1) { - String parentApplicationName = managedDeployment.getParent().getSimpleName().substring(0,managedDeployment.getParent().getSimpleName().indexOf(".ear")); - parentMBeans = resourceDiscoveryContext.getParentResourceComponent().getConvergedSipApplicationEmsBeans(parentApplicationName); - } - - List allBeans = new ArrayList(); - allBeans.addAll(mBeans); - allBeans.addAll(parentMBeans); - - if(allBeans.size() > 0) { - return true; - } else { - return false; - } - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/ConvergedSipStandaloneComponent.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/ConvergedSipStandaloneComponent.java deleted file mode 100644 index a860cea5ed..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/ConvergedSipStandaloneComponent.java +++ /dev/null @@ -1,252 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -package org.rhq.plugins.mobicents.servlet.sip.jboss5; - -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.mc4j.ems.connection.EmsConnection; -import org.mc4j.ems.connection.bean.EmsBean; -import org.mc4j.ems.connection.bean.attribute.EmsAttribute; -import org.rhq.core.domain.measurement.MeasurementDataNumeric; -import org.rhq.core.domain.measurement.MeasurementDataTrait; -import org.rhq.core.domain.measurement.MeasurementReport; -import org.rhq.core.domain.measurement.MeasurementScheduleRequest; -import org.rhq.core.pluginapi.inventory.ResourceContext; -import org.rhq.plugins.jmx.ObjectNameQueryUtility; - -/** - * - * @author jean.deruelle@gmail.com - * - */ -public class ConvergedSipStandaloneComponent extends StandaloneManagedDeploymentComponent -{ - private final Log log = LogFactory.getLog(this.getClass()); - - private static final String SERVLET_PREFIX = "Servlet."; - private static final String SIP_SERVLET_PREFIX = "SipServlet."; - public static final String CONTEXT_ROOT_CONFIG_PROP = "contextRoot"; - public static final String NAME_CONFIG_PROP = "name"; - public static final String FILE_NAME = "filename"; - public static final String JBOSS_WEB_NAME = "jbossWebName"; - public static final String RESPONSE_TIME_LOG_FILE_CONFIG_PROP = "responseTimeLogFile"; - public static final String RESPONSE_TIME_URL_EXCLUDES_CONFIG_PROP = "responseTimeUrlExcludes"; - public static final String RESPONSE_TIME_URL_TRANSFORMS_CONFIG_PROP = "responseTimeUrlTransforms"; - - private static final String RESPONSE_TIME_METRIC = "ResponseTime"; - private static final String CONTEXT_ROOT_METRIC = "ContextRoot"; - - private static final String MAX_SERVLET_TIME = "Servlet.MaxResponseTime"; - private static final String MIN_SERVLET_TIME = "Servlet.MinResponseTime"; - private static final String AVG_SERVLET_TIME = "Servlet.AvgResponseTime"; - private static final String NUM_SERVLET_REQUESTS = "Servlet.NumRequests"; - private static final String NUM_SERVLET_ERRORS = "Servlet.NumErrors"; - private static final String TOTAL_TIME = "Servlet.TotalTime"; - private static final String SERVLET_NAME_BASE_TEMPLATE = "jboss.web:J2EEApplication=none,J2EEServer=none,j2eeType=Servlet,name=%name%"; - private static final String SIP_SERVLET_NAME_BASE_TEMPLATE = "jboss.web:J2EEApplication=none,J2EEServer=none,j2eeType=SipServlet,name=%name%"; - - private static final String SESSION_PREFIX = "Session."; - private static final String SIP_SESSION_NAME_BASE_TEMPLATE = "jboss.web:host=%HOST%,type=SipManager,path=%PATH%"; - private static final String SIP_SESSION_PREFIX = "SipSession."; - - private static final String VHOST_PREFIX = "Vhost"; - public static final String VHOST_CONFIG_PROP = "vHost"; - - public static final String ROOT_WEBAPP_CONTEXT_ROOT = "/"; - -// private EmsBean jbossWebMBean; -// private ResponseTimeLogParser logParser; -// String vhost; - private String contextRoot; - - ApplicationServerComponent applicationServerComponent; - - @Override - public void start(ResourceContext resourceContext) throws Exception { - super.start(resourceContext); - applicationServerComponent = (ApplicationServerComponent)resourceContext.getParentResourceComponent(); - // -4 is for the extension .war to be removed - this.contextRoot = deploymentName.substring(0, deploymentName.length() - 5); - this.contextRoot = contextRoot.substring(contextRoot.lastIndexOf("/") + 1); - - } - - // ------------ MeasurementFacet Implementation ------------ - - public void getValues(MeasurementReport report, Set requests) { - super.getValues(report, requests); - Set remainingSchedules = new LinkedHashSet(); - for (MeasurementScheduleRequest schedule : requests) { - String metricName = schedule.getName(); - if (metricName.equals(RESPONSE_TIME_METRIC)) { -// if (this.logParser != null) { -// try { -// CallTimeData callTimeData = new CallTimeData(schedule); -// this.logParser.parseLog(callTimeData); -// report.addData(callTimeData); -// } catch (Exception e) { -// log.error("Failed to retrieve HTTP call-time data.", e); -// } -// } else { -// log.error("The '" + RESPONSE_TIME_METRIC + "' metric is enabled for WAR resource '" -// + getApplicationName() + "', but no value is defined for the '" -// + RESPONSE_TIME_LOG_FILE_CONFIG_PROP + "' connection property."); -// // TODO: Communicate this error back to the server for display in the GUI. -// } - } else if (metricName.equals(CONTEXT_ROOT_METRIC)) { - MeasurementDataTrait trait = new MeasurementDataTrait(schedule, contextRoot); - report.addData(trait); - } else if (metricName.startsWith(SERVLET_PREFIX) || metricName.startsWith(SIP_SERVLET_PREFIX)) { - Double value = getServletMetric(metricName); - MeasurementDataNumeric metric = new MeasurementDataNumeric(schedule, value); - report.addData(metric); - } else if (metricName.startsWith(SESSION_PREFIX) || metricName.startsWith(SIP_SESSION_PREFIX)) { - Double value = getSessionMetric(metricName); - MeasurementDataNumeric metric = new MeasurementDataNumeric(schedule, value); - report.addData(metric); - } else if (metricName.startsWith(VHOST_PREFIX)) { -// if (metricName.equals("Vhost.name")) { -// List beans = getVHosts(contextRoot); -// String value = ""; -// Iterator iter = beans.iterator(); -// while (iter.hasNext()) { -// EmsBean eBean = iter.next(); -// value += eBean.getBeanName().getKeyProperty("host"); -// if (iter.hasNext()) -// value += ","; -// } -// MeasurementDataTrait trait = new MeasurementDataTrait(schedule, value); -// report.addData(trait); -// } - } else { - remainingSchedules.add(schedule); - } - } - } - - private Double getServletMetric(String metricName) { - - EmsConnection jmxConnection = applicationServerComponent.getEmsConnection(); - - String servletNameBaseTemplate = SERVLET_NAME_BASE_TEMPLATE; - if(metricName.startsWith(SIP_SERVLET_PREFIX)) { - servletNameBaseTemplate = SIP_SERVLET_NAME_BASE_TEMPLATE; - } - //FIXME : replace localhost with the real vhost - String servletMBeanNames = servletNameBaseTemplate + ",WebModule=//localhost" - + applicationServerComponent.getContextPath(this.contextRoot); - ObjectNameQueryUtility queryUtility = new ObjectNameQueryUtility(servletMBeanNames); - List mBeans = jmxConnection.queryBeans(queryUtility.getTranslatedQuery()); - - long min = Long.MAX_VALUE; - long max = 0; - long processingTime = 0; - int requestCount = 0; - int errorCount = 0; - Double result; - - for (EmsBean mBean : mBeans) { - mBean.refreshAttributes(); - if (metricName.equals(MIN_SERVLET_TIME)) { - EmsAttribute att = mBean.getAttribute("minTime"); - Long l = (Long) att.getValue(); - if (l < min) - min = l; - } else if (metricName.equals(MAX_SERVLET_TIME)) { - EmsAttribute att = mBean.getAttribute("maxTime"); - Long l = (Long) att.getValue(); - if (l > max) - max = l; - } else if (metricName.equals(AVG_SERVLET_TIME)) { - EmsAttribute att = mBean.getAttribute("processingTime"); - Long l = (Long) att.getValue(); - processingTime += l; - att = mBean.getAttribute("requestCount"); - Integer i = (Integer) att.getValue(); - requestCount += i; - } else if (metricName.equals(NUM_SERVLET_REQUESTS)) { - EmsAttribute att = mBean.getAttribute("requestCount"); - Integer i = (Integer) att.getValue(); - requestCount += i; - } else if (metricName.equals(NUM_SERVLET_ERRORS)) { - EmsAttribute att = mBean.getAttribute("errorCount"); - Integer i = (Integer) att.getValue(); - errorCount += i; - } else if (metricName.equals(TOTAL_TIME)) { - EmsAttribute att = mBean.getAttribute("processingTime"); - Long l = (Long) att.getValue(); - processingTime += l; - } - } - if (metricName.equals(AVG_SERVLET_TIME)) { - result = (requestCount > 0) ? ((double) processingTime / (double) requestCount) : Double.NaN; - } else if (metricName.equals(MIN_SERVLET_TIME)) { - result = (min != Long.MAX_VALUE) ? (double) min : Double.NaN; - } else if (metricName.equals(MAX_SERVLET_TIME)) { - result = (max != 0) ? (double) max : Double.NaN; - } else if (metricName.equals(NUM_SERVLET_ERRORS)) { - result = (double) errorCount; - } else if (metricName.equals(NUM_SERVLET_REQUESTS)) { - result = (double) requestCount; - } else if (metricName.equals(TOTAL_TIME)) { - result = (double) processingTime; - } else { - // fallback - result = Double.NaN; - } - - return result; - } - - private Double getSessionMetric(String metricName) { - EmsConnection jmxConnection = applicationServerComponent.getEmsConnection(); - - String servletMBeanNames = SIP_SESSION_NAME_BASE_TEMPLATE.replace("%PATH%", - applicationServerComponent.getContextPath(this.contextRoot)); - //FIXME : replace localhost with the real vhost - servletMBeanNames = servletMBeanNames.replace("%HOST%", "localhost"); - ObjectNameQueryUtility queryUtility = new ObjectNameQueryUtility(servletMBeanNames); - List mBeans = jmxConnection.queryBeans(queryUtility.getTranslatedQuery()); - - String property = metricName.substring(SIP_SESSION_PREFIX.length()); - - Double ret = Double.NaN; - - if (mBeans.size() > 0) { // TODO flag error if != 1 ? - EmsBean eBean = mBeans.get(0); - eBean.refreshAttributes(); - EmsAttribute att = eBean.getAttribute(property); - if (att != null) { - if(att.getValue() instanceof Double) { - ret = (Double) att.getValue(); - } else { - Integer i = (Integer) att.getValue(); - ret = new Double(i); - } - } - - } - return ret; - } - -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/ConvergedSipStandaloneDiscoveryComponent.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/ConvergedSipStandaloneDiscoveryComponent.java deleted file mode 100644 index 3db73491cd..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/ConvergedSipStandaloneDiscoveryComponent.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.rhq.plugins.mobicents.servlet.sip.jboss5; - -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jboss.managed.api.ManagedDeployment; -import org.mc4j.ems.connection.bean.EmsBean; -import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext; - -public class ConvergedSipStandaloneDiscoveryComponent extends StandaloneManagedDeploymentDiscoveryComponent { - private final Log log = LogFactory.getLog(this.getClass()); - - @Override - protected boolean accept( - ManagedDeployment managedDeployment, - ResourceDiscoveryContext resourceDiscoveryContext) { - boolean isEmbedded = !super.accept(managedDeployment, resourceDiscoveryContext); - if(isEmbedded) { - return false; - } - String applicationName = managedDeployment.getSimpleName().substring(0,managedDeployment.getSimpleName().indexOf(".war")); - List mBeans = resourceDiscoveryContext.getParentResourceComponent().getConvergedSipApplicationEmsBeans(applicationName); - if(mBeans.size() > 0) { - return true; - } else { - return false; - } - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/EmbeddedManagedDeploymentComponent.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/EmbeddedManagedDeploymentComponent.java deleted file mode 100644 index 3cf0796a19..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/EmbeddedManagedDeploymentComponent.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -package org.rhq.plugins.mobicents.servlet.sip.jboss5; - -import java.util.Set; - -import org.rhq.core.pluginapi.measurement.MeasurementFacet; -import org.rhq.core.domain.measurement.MeasurementReport; -import org.rhq.core.domain.measurement.MeasurementScheduleRequest; -import org.rhq.core.domain.measurement.MeasurementDataTrait; - -import org.jboss.profileservice.spi.NoSuchDeploymentException; - -/** - * @author Ian Springer - */ -public class EmbeddedManagedDeploymentComponent extends AbstractManagedDeploymentComponent - implements MeasurementFacet -{ - public static final String CUSTOM_PARENT_TRAIT = "custom.parent"; - - // ------------ MeasurementFacet Implementation ------------ - - public void getValues(MeasurementReport report, Set requests) - throws NoSuchDeploymentException - { - for (MeasurementScheduleRequest request : requests) { - String metricName = request.getName(); - if (metricName.equals(CUSTOM_PARENT_TRAIT)) { - String parentDeploymentName = getManagedDeployment().getParent().getName(); - MeasurementDataTrait trait = new MeasurementDataTrait(request, parentDeploymentName); - report.addData(trait); - } - } - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/EmbeddedManagedDeploymentDiscoveryComponent.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/EmbeddedManagedDeploymentDiscoveryComponent.java deleted file mode 100644 index 08dc380b70..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/EmbeddedManagedDeploymentDiscoveryComponent.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -package org.rhq.plugins.mobicents.servlet.sip.jboss5; - -import org.jboss.managed.api.ManagedDeployment; -import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext; - -/** - * @author Ian Springer - */ -public class EmbeddedManagedDeploymentDiscoveryComponent extends ManagedDeploymentDiscoveryComponent -{ - protected boolean accept(ManagedDeployment managedDeployment, ResourceDiscoveryContext resourceDiscoveryContext) - { - return (managedDeployment.getParent() != null); - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/JmsDestinationComponent.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/JmsDestinationComponent.java deleted file mode 100644 index 29f848529d..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/JmsDestinationComponent.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -package org.rhq.plugins.mobicents.servlet.sip.jboss5; - -import java.util.ArrayList; -import java.util.List; - -import javax.management.ObjectName; -import javax.management.MalformedObjectNameException; - -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.PropertySimple; -import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; - -/** - * A Resource component for JBoss AS 5 JBoss Messaging JMS topic and queues. - * - * @author Ian Springer - */ -public class JmsDestinationComponent extends ManagedComponentComponent -{ - private static final String[] OBJECT_NAME_PROPERTY_NAMES = new String[] {"DLQ", "expiryQueue", "serverPeer"}; - - @Override - public void updateResourceConfiguration(ConfigurationUpdateReport configurationUpdateReport) - { - Configuration resourceConfig = configurationUpdateReport.getConfiguration(); - List invalidObjectNamePropertyNames = new ArrayList(); - for (String objectNamePropertyName : OBJECT_NAME_PROPERTY_NAMES) - { - PropertySimple propertySimple = resourceConfig.getSimple(objectNamePropertyName); - try - { - validateObjectNameProperty(propertySimple); - } - catch (MalformedObjectNameException e) - { - propertySimple.setErrorMessage("Invalid ObjectName: " + e.getLocalizedMessage()); - invalidObjectNamePropertyNames.add(propertySimple.getName()); - } - } - if (!invalidObjectNamePropertyNames.isEmpty()) - configurationUpdateReport.setErrorMessage("The following ObjectName properties have invalid values: " - + invalidObjectNamePropertyNames); - else - super.updateResourceConfiguration(configurationUpdateReport); - } - - private static void validateObjectNameProperty(PropertySimple propertySimple) throws MalformedObjectNameException - { - if (propertySimple != null) { - String value = propertySimple.getStringValue(); - if (value != null) { - ObjectName objectName = new ObjectName(value); - if (objectName.isPattern()) - throw new MalformedObjectNameException("Patterns are not allowed."); - } - } - } -} \ No newline at end of file diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/ManagedComponentComponent.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/ManagedComponentComponent.java deleted file mode 100644 index 2515d9354a..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/ManagedComponentComponent.java +++ /dev/null @@ -1,276 +0,0 @@ - /* - * Jopr Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.rhq.plugins.mobicents.servlet.sip.jboss5; - - import java.util.Map; - import java.util.Set; - - import org.apache.commons.logging.Log; - import org.apache.commons.logging.LogFactory; - - import org.jboss.deployers.spi.management.ManagementView; - import org.jboss.managed.api.ComponentType; - import org.jboss.managed.api.ManagedComponent; - import org.jboss.managed.api.ManagedOperation; - import org.jboss.managed.api.ManagedProperty; - import org.jboss.managed.api.RunState; - import org.jboss.metatype.api.values.CompositeValue; - import org.jboss.metatype.api.values.MetaValue; - import org.jboss.metatype.api.values.SimpleValue; - - import org.rhq.core.domain.configuration.Configuration; - import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; - import org.rhq.core.domain.measurement.AvailabilityType; - import org.rhq.core.domain.measurement.DataType; - import org.rhq.core.domain.measurement.MeasurementDataNumeric; - import org.rhq.core.domain.measurement.MeasurementDataTrait; - import org.rhq.core.domain.measurement.MeasurementReport; - import org.rhq.core.domain.measurement.MeasurementScheduleRequest; - import org.rhq.core.domain.operation.OperationDefinition; - import org.rhq.core.domain.resource.ResourceType; - import org.rhq.core.pluginapi.configuration.ConfigurationFacet; - import org.rhq.core.pluginapi.inventory.DeleteResourceFacet; - import org.rhq.core.pluginapi.inventory.ResourceComponent; - import org.rhq.core.pluginapi.inventory.ResourceContext; - import org.rhq.core.pluginapi.measurement.MeasurementFacet; - import org.rhq.core.pluginapi.operation.OperationFacet; - import org.rhq.core.pluginapi.operation.OperationResult; - import org.rhq.plugins.jbossas5.factory.ProfileServiceFactory; - import org.rhq.plugins.jbossas5.util.ConversionUtils; - import org.rhq.plugins.jbossas5.util.ResourceTypeUtils; - import org.jetbrains.annotations.NotNull; - - /** - * Service ResourceComponent for all {@link ManagedComponent}s in a Profile. - * - * @author Ian Springer - * @author Jason Dobies - * @author Mark Spritzler - */ -public class ManagedComponentComponent extends AbstractManagedComponent - implements ResourceComponent, ConfigurationFacet, DeleteResourceFacet, OperationFacet, MeasurementFacet -{ - public static final String COMPONENT_TYPE_PROPERTY = "componentType"; - public static final String COMPONENT_SUBTYPE_PROPERTY = "componentSubtype"; - public static final String COMPONENT_NAME_PROPERTY = "componentName"; - - private final Log log = LogFactory.getLog(this.getClass()); - - private String componentName; - private ComponentType componentType; - - // ResourceComponent Implementation -------------------------------------------- - - public AvailabilityType getAvailability() - { - RunState runState = getManagedComponent().getRunState(); - return (runState == RunState.RUNNING) ? AvailabilityType.UP : - AvailabilityType.DOWN; - } - - public void start(ResourceContext resourceContext) throws Exception { - super.start(resourceContext); - this.componentType = ConversionUtils.getComponentType(getResourceContext().getResourceType()); - Configuration pluginConfig = resourceContext.getPluginConfiguration(); - this.componentName = pluginConfig.getSimple(COMPONENT_NAME_PROPERTY).getStringValue(); - log.trace("Started ResourceComponent for " + getResourceDescription() + ", managing " + this.componentType - + " component '" + this.componentName + "'."); - } - - public void stop() - { - return; - } - - // DeleteResourceFacet Implementation -------------------------------------------- - - public void deleteResource() throws Exception - { - throw new UnsupportedOperationException("Deletion of " + getResourceContext().getResourceType().getName() - + " Resources is not currently supported."); - /* - ManagedComponent managedComponent = getManagedComponent(); - log.debug("Removing " + getResourceDescription() + " with component " + toString(managedComponent) + "..."); - ManagementView managementView = ProfileServiceFactory.getCurrentProfileView(); - managementView.removeComponent(managedComponent); - managementView.reload(); - */ - } - - // OperationFacet Implementation -------------------------------------------- - - public OperationResult invokeOperation(String name, Configuration parameters) throws Exception - { - OperationDefinition operationDefinition = getOperationDefinition(name); - ManagedOperation managedOperation = getManagedOperation(operationDefinition); - // Convert parameters into MetaValue array. - MetaValue[] parameterMetaValues = ConversionUtils.convertOperationsParametersToMetaValues(managedOperation, - parameters, operationDefinition); - // invoke() takes a varargs, so we need to pass an empty array, rather than null. - MetaValue resultMetaValue = managedOperation.invoke(parameterMetaValues); - OperationResult result = new OperationResult(); - // Convert result MetaValue to corresponding Property type. - ConversionUtils.convertManagedOperationResults(managedOperation, resultMetaValue, result.getComplexResults(), - operationDefinition); - return result; - } - - // MeasurementFacet Implementation -------------------------------------------- - - public void getValues(MeasurementReport report, Set metrics) throws Exception - { - ManagedComponent managedComponent = getManagedComponent(); - for (MeasurementScheduleRequest request : metrics) - { - try { - if (request.getName().equals("runState")) { - String runState = managedComponent.getRunState().name(); - report.addData(new MeasurementDataTrait(request, runState)); - } else { - SimpleValue simpleValue = getSimpleValue(managedComponent, request); - if (simpleValue != null) - addSimpleValueToMeasurementReport(report, request, simpleValue); - } - } catch (Exception e) { - log.error("Failed to collect metric for " + request, e); - } - } - } - - // ------------ AbstractManagedComponent implementation ------------- - - protected Map getManagedProperties() { - return getManagedComponent().getProperties(); - } - - protected Log getLog() { - return this.log; - } - - protected void updateComponent() throws Exception { - ManagedComponent managedComponent = getManagedComponent(); - log.trace("Updating " + getResourceDescription() + " with component " + toString(managedComponent) + "..."); - ManagementView managementView = ProfileServiceFactory.getCurrentProfileView(); - managementView.updateComponent(managedComponent); - managementView.reload(); - } - - // ------------------------------------------------------------------------------ - - private SimpleValue getSimpleValue(ManagedComponent managedComponent, MeasurementScheduleRequest request) { - String metricName = request.getName(); - int dotIndex = metricName.indexOf('.'); - String metricPropName = (dotIndex == -1) ? metricName : metricName.substring(0, dotIndex); - ManagedProperty metricProp = managedComponent.getProperty(metricPropName); - SimpleValue simpleValue; - if (dotIndex == -1) - simpleValue = (SimpleValue)metricProp.getValue(); - else { - CompositeValue compositeValue = (CompositeValue)metricProp.getValue(); - String key = metricName.substring(dotIndex + 1); - simpleValue = (SimpleValue)compositeValue.get(key); - } - if (simpleValue == null) - log.debug("Profile service returned null value for metric [" + request.getName() + "]."); - return simpleValue; - } - - private void addSimpleValueToMeasurementReport(MeasurementReport report, MeasurementScheduleRequest request, SimpleValue simpleValue) { - DataType dataType = request.getDataType(); - switch (dataType) { - case MEASUREMENT: - try { - MeasurementDataNumeric dataNumeric = new MeasurementDataNumeric(request, - Double.valueOf(simpleValue.getValue().toString())); - report.addData(dataNumeric); - } - catch (NumberFormatException e) { - log.error("Profile service did not return a numeric value as expected for metric [" - + request.getName() + "] - value returned was " + simpleValue + ".", e); - } - break; - case TRAIT: - MeasurementDataTrait dataTrait = new MeasurementDataTrait(request, - String.valueOf(simpleValue.getValue())); - report.addData(dataTrait); - break; - default: - throw new IllegalStateException("Unsupported measurement data type: " + dataType); - } - } - - private ManagedComponent getManagedComponent() - { - ManagedComponent managedComponent; - try { - //ProfileServiceFactory.refreshCurrentProfileView(); - ManagementView managementView = ProfileServiceFactory.getCurrentProfileView(); - managedComponent = ProfileServiceFactory.getManagedComponent(managementView, this.componentType, - this.componentName); - } - catch (Exception e) { - throw new RuntimeException("Failed to load [" + this.componentType + "] ManagedComponent [" - + this.componentName + "].", e); - } - if (managedComponent == null) - throw new IllegalStateException("Failed to find [" + this.componentType + "] ManagedComponent named [" - + this.componentName + "]."); - log.trace("Retrieved " + toString(managedComponent) + "."); - return managedComponent; - } - - @NotNull - private OperationDefinition getOperationDefinition(String operationName) { - ResourceType resourceType = getResourceContext().getResourceType(); - OperationDefinition operationDefinition = ResourceTypeUtils.getOperationDefinition(resourceType, operationName); - if (operationDefinition == null) - throw new IllegalStateException("Operation named '" + operationName + "' is not defined for Resource type '" - + resourceType.getName() + "' in the '" + resourceType.getPlugin() + "' plugin's descriptor."); - return operationDefinition; - } - - @NotNull - private ManagedOperation getManagedOperation(OperationDefinition operationDefinition) - { - ManagedComponent managedComponent = getManagedComponent(); - Set operations = managedComponent.getOperations(); - for (ManagedOperation operation : operations) - { - ConfigurationDefinition paramsConfigDef = operationDefinition.getParametersConfigurationDefinition(); - int paramCount = (paramsConfigDef != null) ? paramsConfigDef.getPropertyDefinitions().size() : 0; - if (operation.getName().equals(operationDefinition.getName()) && - (operation.getParameters().length == paramCount)) - return operation; - } - throw new IllegalStateException("ManagedOperation named '" + operationDefinition.getName() - + "' not found on ManagedComponent [" + getManagedComponent() + "]."); - } - - private static String toString(ManagedComponent managedComponent) { - Map properties = managedComponent.getProperties(); - return managedComponent.getClass().getSimpleName() + "@" + System.identityHashCode(managedComponent) + "[" - + "type=" + managedComponent.getType() + ", name=" + managedComponent.getName() - + ", properties=" + properties.getClass().getSimpleName() + "@" + System.identityHashCode(properties) - + "]"; - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/ManagedComponentDiscoveryComponent.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/ManagedComponentDiscoveryComponent.java deleted file mode 100644 index e1dab39ebc..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/ManagedComponentDiscoveryComponent.java +++ /dev/null @@ -1,106 +0,0 @@ - /* - * Jopr Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.rhq.plugins.mobicents.servlet.sip.jboss5; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jboss.deployers.spi.management.ManagementView; -import org.jboss.managed.api.ComponentType; -import org.jboss.managed.api.ManagedComponent; -import org.rhq.core.domain.configuration.PropertySimple; -import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails; -import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent; -import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext; -import org.rhq.plugins.jbossas5.factory.ProfileServiceFactory; -import org.rhq.plugins.jbossas5.util.ConversionUtils; - -import java.util.HashSet; -import java.util.Set; - -/** - * Discovery component for all ManagedComponents exposed by the JBoss AS 5.x Profile Service. - * - * @author Jason Dobies - * @author Mark Spritzer - */ -public class ManagedComponentDiscoveryComponent - implements ResourceDiscoveryComponent -{ - private final Log log = LogFactory.getLog(this.getClass()); - - public Set discoverResources( - ResourceDiscoveryContext discoveryContext) - { - ResourceType resourceType = discoveryContext.getResourceType(); - log.trace("Discovering " + resourceType.getName() + " Resources..." ); - - // TODO (ips): Only refresh the ManagementView *once* per runtime discovery scan, rather than every time this - // method is called. Do this by providing a runtime scan id in the ResourceDiscoveryContext. - ProfileServiceFactory.refreshCurrentProfileView(); - - ManagementView managementView = ProfileServiceFactory.getCurrentProfileView(); - - ComponentType componentType = ConversionUtils.getComponentType(resourceType); - Set components; - try - { - components = managementView.getComponentsForType(componentType); - } - catch (Exception e) - { - throw new IllegalStateException("Failed to get component types for " + resourceType + ".", e); - } - - Set discoveredResources = new HashSet(components.size()); - /* Create a resource for each managed component found. We know all managed components will be of a - type we're interested in, so we can just add them all. There may be need for multiple iterations - over lists retrieved from different component types, but that is possible through the current API. - */ - for (ManagedComponent component : components) - { - String resourceName = component.getName(); - - String resourceKey = componentType.getType() + ":" + - componentType.getSubtype() + ":" + resourceName; - - String version = "?"; // TODO - DiscoveredResourceDetails resource = - new DiscoveredResourceDetails(resourceType, - resourceKey, - resourceName, - version, - resourceType.getDescription(), - discoveryContext.getDefaultPluginConfiguration(), - null); - - resource.getPluginConfiguration().put(new PropertySimple(ManagedComponentComponent.COMPONENT_NAME_PROPERTY, - component.getName())); - - discoveredResources.add(resource); - } - - log.trace("Discovered " + discoveredResources.size() + " " + resourceType.getName() + " Resources." ); - return discoveredResources; - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/ManagedDeploymentDiscoveryComponent.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/ManagedDeploymentDiscoveryComponent.java deleted file mode 100644 index 010d1b1df8..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/ManagedDeploymentDiscoveryComponent.java +++ /dev/null @@ -1,133 +0,0 @@ - /* - * Jopr Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.rhq.plugins.mobicents.servlet.sip.jboss5; - -import java.util.HashSet; -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jboss.deployers.spi.management.ManagementView; -import org.jboss.deployers.spi.management.KnownDeploymentTypes; -import org.jboss.managed.api.ManagedDeployment; -import org.jboss.profileservice.spi.NoSuchDeploymentException; -import org.rhq.core.domain.configuration.PropertySimple; -import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails; -import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent; -import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext; -import org.rhq.plugins.jbossas5.factory.ProfileServiceFactory; -import org.rhq.plugins.jbossas5.util.ConversionUtils; - -/** - * Discovery class for discovering deployable resources like ear/war/jar/sar - * - * @author Mark Spritzler - * @author Ian Springer - */ -public abstract class ManagedDeploymentDiscoveryComponent implements ResourceDiscoveryComponent { - private final Log log = LogFactory.getLog(this.getClass()); - - public Set discoverResources(ResourceDiscoveryContext resourceDiscoveryContext) - { - Set discoveredResources = new HashSet(); - ResourceType resourceType = resourceDiscoveryContext.getResourceType(); - log.trace("Discovering " + resourceType.getName() + " Resources..." ); - KnownDeploymentTypes deploymentType = ConversionUtils.getDeploymentType(resourceType); - String deploymentTypeString = deploymentType.getType(); - - // TODO (ips): Only refresh the ManagementView *once* per runtime discovery scan, rather than every time this - // method is called. Do this by providing a runtime scan id in the ResourceDiscoveryContext. - ProfileServiceFactory.refreshCurrentProfileView(); - - ManagementView managementView = ProfileServiceFactory.getCurrentProfileView(); - - Set deploymentNames = null; - try - { - deploymentNames = managementView.getDeploymentNamesForType(deploymentTypeString); - } - catch (Exception e) - { - log.error("Unable to get deployment for type " + deploymentTypeString, e); - } - - if (deploymentNames != null) - { - discoveredResources = new HashSet(deploymentNames.size()); - /* Create a resource for each managed component found. We know all managed components will be of a - type we're interested in, so we can just add them all. There may be need for multiple iterations - over lists retrieved from different component types, but that is possible through the current API. - */ - for (String deploymentName : deploymentNames) - { - try - { - ManagedDeployment managedDeployment = managementView.getDeployment(deploymentName); - if (!accept(managedDeployment, resourceDiscoveryContext)) - continue; - String resourceName = managedDeployment.getSimpleName(); - // @TODO remove this when AS5 actually implements this for sars, and some other DeploymentTypes that haven't implemented getSimpleName() - if (resourceName.equals("%Generated%")) - { - resourceName = getResourceName(deploymentName); - } - String version = null; // TODO - DiscoveredResourceDetails resource = - new DiscoveredResourceDetails(resourceType, - deploymentName, - resourceName, - version, - resourceType.getDescription(), - resourceDiscoveryContext.getDefaultPluginConfiguration(), - null); - // example of a deployment name: vfszip:/C:/opt/jboss-5.1.0.CR1/server/default/deploy/foo.war - resource.getPluginConfiguration().put( - new PropertySimple(AbstractManagedDeploymentComponent.DEPLOYMENT_NAME_PROPERTY, deploymentName)); - discoveredResources.add(resource); - } - catch (NoSuchDeploymentException e) - { - // This is a bug in the profile service that occurs often, so don't log the stack trace. - log.error("ManagementView.getDeploymentNamesForType() returned [" + deploymentName - + "] as a deployment name, but calling getDeployment() with that name failed."); - } - catch (Exception e) - { - log.error("An error occurred while discovering " + resourceType + " Resources.", e); - } - } - } - - log.trace("Discovered " + discoveredResources.size() + " " + resourceType.getName() + " Resources." ); - return discoveredResources; - } - - protected abstract boolean accept(ManagedDeployment managedDeployment, ResourceDiscoveryContext resourceDiscoveryContext); - - private static String getResourceName(String fullPath) - { - int lastSlashIndex = fullPath.lastIndexOf("/"); - return fullPath.substring(lastSlashIndex + 1); - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/StandaloneManagedDeploymentComponent.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/StandaloneManagedDeploymentComponent.java deleted file mode 100644 index 32446b7fbe..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/StandaloneManagedDeploymentComponent.java +++ /dev/null @@ -1,392 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -package org.rhq.plugins.mobicents.servlet.sip.jboss5; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.apache.commons.io.FileUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jboss.deployers.spi.management.deploy.DeploymentManager; -import org.jboss.deployers.spi.management.deploy.DeploymentProgress; -import org.rhq.core.domain.content.PackageDetailsKey; -import org.rhq.core.domain.content.PackageType; -import org.rhq.core.domain.content.transfer.ContentResponseResult; -import org.rhq.core.domain.content.transfer.DeployIndividualPackageResponse; -import org.rhq.core.domain.content.transfer.DeployPackageStep; -import org.rhq.core.domain.content.transfer.DeployPackagesResponse; -import org.rhq.core.domain.content.transfer.RemovePackagesResponse; -import org.rhq.core.domain.content.transfer.ResourcePackageDetails; -import org.rhq.core.domain.measurement.MeasurementDataTrait; -import org.rhq.core.domain.measurement.MeasurementReport; -import org.rhq.core.domain.measurement.MeasurementScheduleRequest; -import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.pluginapi.content.ContentFacet; -import org.rhq.core.pluginapi.content.ContentServices; -import org.rhq.core.pluginapi.content.version.PackageVersions; -import org.rhq.core.pluginapi.inventory.DeleteResourceFacet; -import org.rhq.core.pluginapi.measurement.MeasurementFacet; -import org.rhq.core.util.ZipUtil; -import org.rhq.core.util.exception.ThrowableUtil; -import org.rhq.plugins.jbossas5.factory.ProfileServiceFactory; -import org.rhq.plugins.mobicents.servlet.sip.jboss5.util.DeploymentUtils; - -/** - * @author Ian Springer - */ -public class StandaloneManagedDeploymentComponent extends AbstractManagedDeploymentComponent - implements MeasurementFacet, ContentFacet, DeleteResourceFacet -{ - public static final String RESOURCE_TYPE_EAR = "Enterprise Application (EAR)"; - public static final String RESOURCE_TYPE_WAR = "Web Application (WAR)"; - public static final String RESOURCE_TYPE_CONVERGED_WAR = "Converged SIP/Web Application (WAR)"; - public static final String RESOURCE_TYPE_RAR = "Resource Adaptor (RAR)"; - - private static final String CUSTOM_PATH_TRAIT = "custom.path"; - private static final String CUSTOM_EXPLODED_TRAIT = "custom.exploded"; - - /** - * Name of the backing package type that will be used when discovering packages. This corresponds to the name - * of the package type defined in the plugin descriptor. For simplicity, the package type for both EARs and - * WARs is simply called "file". This is still unique within the context of the parent resource type and lets - * this class use the same package type name in both cases. - */ - private static final String PKG_TYPE_FILE = "file"; - - /** - * Architecture string used in describing discovered packages. - */ - private static final String ARCHITECTURE = "noarch"; - - private static final String BACKUP_FILE_EXTENSION = ".rej"; - - private final Log log = LogFactory.getLog(this.getClass()); - - private PackageVersions versions; - - // ------------ MeasurementFacet Implementation ------------ - - public void getValues(MeasurementReport report, Set requests) { - for (MeasurementScheduleRequest request : requests) { - String metricName = request.getName(); - if (metricName.equals(CUSTOM_PATH_TRAIT)) { - MeasurementDataTrait trait = new MeasurementDataTrait(request, this.deploymentFile.getPath()); - report.addData(trait); - } - else if (metricName.equals(CUSTOM_EXPLODED_TRAIT)) { - boolean exploded = this.deploymentFile.isDirectory(); - MeasurementDataTrait trait = new MeasurementDataTrait(request, (exploded) ? "yes" : "no"); - report.addData(trait); - } - } - } - - // ------------ ContentFacet implementation ------------- - - public InputStream retrievePackageBits(ResourcePackageDetails packageDetails) { - File packageFile = new File(packageDetails.getName()); - File fileToSend; - try { - if (packageFile.isDirectory()) { - fileToSend = File.createTempFile("rhq", ".zip"); - ZipUtil.zipFileOrDirectory(packageFile, fileToSend); - } - else - fileToSend = packageFile; - return new BufferedInputStream(new FileInputStream(fileToSend)); - } - catch (IOException e) { - throw new RuntimeException("Failed to retrieve package bits for " + packageDetails, e); - } - } - - public Set discoverDeployedPackages(PackageType packageType) { - if (!this.deploymentFile.exists()) - throw new IllegalStateException("Deployment file '" + this.deploymentFile + "' for " + - getResourceDescription() + " does not exist."); - - String fileName = this.deploymentFile.getName(); - PackageVersions packageVersions = loadPackageVersions(); - String version = packageVersions.getVersion(fileName); - if (version == null) { - // This is either the first time we've discovered this EAR/WAR, or someone purged the PC's data dir. - version = "1.0"; - packageVersions.putVersion(fileName, version); - packageVersions.saveToDisk(); - } - - // Package name is the deployment's file name (e.g. foo.ear). - PackageDetailsKey key = new PackageDetailsKey(fileName, version, PKG_TYPE_FILE, ARCHITECTURE); - ResourcePackageDetails packageDetails = new ResourcePackageDetails(key); - packageDetails.setFileName(fileName); - packageDetails.setLocation(this.deploymentFile.getPath()); - if (!this.deploymentFile.isDirectory()) - packageDetails.setFileSize(this.deploymentFile.length()); - packageDetails.setFileCreatedDate(null); // TODO: get created date via SIGAR - Set packages = new HashSet(); - packages.add(packageDetails); - - return packages; - } - - public RemovePackagesResponse removePackages(Set packages) { - throw new UnsupportedOperationException("Cannot remove the package backing an EAR/WAR resource."); - } - - public List generateInstallationSteps(ResourcePackageDetails packageDetails) { - // Intentional - there are no steps involved in installing an EAR or WAR. - return null; - } - - public DeployPackagesResponse deployPackages(Set packages, ContentServices contentServices) { - // You can only update the one application file referenced by this resource, so punch out if multiple are - // specified. - if (packages.size() != 1) { - log.warn("Request to update an EAR/WAR file contained multiple packages: " + packages); - DeployPackagesResponse response = new DeployPackagesResponse(ContentResponseResult.FAILURE); - response.setOverallRequestErrorMessage("When updating an EAR/WAR, only one EAR/WAR can be updated at a time."); - return response; - } - - ResourcePackageDetails packageDetails = packages.iterator().next(); - - log.debug("Updating EAR/WAR file '" + this.deploymentFile + "' using [" + packageDetails + "]..."); - // Find location of existing application. - if (!this.deploymentFile.exists()) { - return failApplicationDeployment("Could not find application to update at location: " + this.deploymentFile, - packageDetails); - } - - log.debug("Writing new EAR/WAR bits to temporary file..."); - File tempFile; - try { - tempFile = writeNewAppBitsToTempFile(contentServices, packageDetails); - } - catch (Exception e) { - return failApplicationDeployment("Error writing new application bits to temporary file - cause: " + e, - packageDetails); - } - log.debug("Wrote new EAR/WAR bits to temporary file '" + tempFile + "'."); - - boolean deployExploded = this.deploymentFile.isDirectory(); - - // Backup the original app file/dir to .rej. - File backupOfOriginalFile = new File(this.deploymentFile.getPath() + BACKUP_FILE_EXTENSION); - log.debug("Backing up existing EAR/WAR '" + this.deploymentFile + "' to '" + backupOfOriginalFile + "'..."); - try - { - if (backupOfOriginalFile.exists()) - FileUtils.forceDelete(backupOfOriginalFile); - if (this.deploymentFile.isDirectory()) - FileUtils.copyDirectory(this.deploymentFile, backupOfOriginalFile, true); - else - FileUtils.copyFile(this.deploymentFile, backupOfOriginalFile, true); - } - catch (Exception e) - { - throw new RuntimeException("Failed to backup existing EAR/WAR '" + this.deploymentFile + "' to '" - + backupOfOriginalFile + "'."); - } - - // Now stop the original app. - try - { - DeploymentManager deploymentManager = ProfileServiceFactory.getDeploymentManager(); - DeploymentProgress progress = deploymentManager.stop(this.deploymentName); - DeploymentUtils.run(progress); - } - catch (Exception e) - { - throw new RuntimeException("Failed to stop deployment [" + this.deploymentName + "].", e); - } - - // And then remove it (this will delete the physical file/dir from the deploy dir). - try - { - DeploymentManager deploymentManager = ProfileServiceFactory.getDeploymentManager(); - DeploymentProgress progress = deploymentManager.remove(this.deploymentName); - DeploymentUtils.run(progress); - } - catch (Exception e) - { - throw new RuntimeException("Failed to remove deployment [" + this.deploymentName + "].", e); - } - - // Deploy away! - log.debug("Deploying '" + tempFile + "'..."); - File deployDir = this.deploymentFile.getParentFile(); - try { - DeploymentUtils.deployArchive(tempFile, deployDir, deployExploded); - } - catch (Exception e) { - // Deploy failed - rollback to the original app file... - log.debug("Redeploy failed - rolling back to original archive...", e); - String errorMessage = ThrowableUtil.getAllMessages(e); - try { - // Delete the new app, which failed to deploy. - FileUtils.forceDelete(this.deploymentFile); - // Need to redeploy the original file - this generally should succeed. - DeploymentUtils.deployArchive(backupOfOriginalFile, deployDir, deployExploded); - errorMessage += " ***** ROLLED BACK TO ORIGINAL APPLICATION FILE. *****"; - } - catch (Exception e1) { - log.debug("Rollback failed!", e1); - errorMessage += " ***** FAILED TO ROLLBACK TO ORIGINAL APPLICATION FILE. *****: " - + ThrowableUtil.getAllMessages(e1); - } - log.info("Failed to update EAR/WAR file '" + this.deploymentFile + "' using [" + packageDetails + "]." ); - return failApplicationDeployment(errorMessage, packageDetails); - } - - // Deploy was successful! - - deleteBackupOfOriginalFile(backupOfOriginalFile); - persistApplicationVersion(packageDetails, this.deploymentFile); - - DeployPackagesResponse response = new DeployPackagesResponse(ContentResponseResult.SUCCESS); - DeployIndividualPackageResponse packageResponse = - new DeployIndividualPackageResponse(packageDetails.getKey(), ContentResponseResult.SUCCESS); - response.addPackageResponse(packageResponse); - - log.debug("Updated EAR/WAR file '" + this.deploymentFile + "' successfully - returning response [" + response - + "]..."); - - return response; - } - - // ------------ DeleteResourceFacet implementation ------------- - - public void deleteResource() throws Exception { - DeploymentManager deploymentManager = ProfileServiceFactory.getDeploymentManager(); - log.debug("Stopping deployment [" + this.deploymentName + "]..."); - DeploymentProgress progress = deploymentManager.stop(deploymentName); - DeploymentUtils.run(progress); - log.debug("Removing deployment [" + this.deploymentName + "]..."); - progress = deploymentManager.remove(deploymentName); - DeploymentUtils.run(progress); - } - - // ------------ AbstractManagedComponent implementation ------------- - - @Override - protected Log getLog() - { - return this.log; - } - - /** - * Creates the necessary transfer objects to report a failed application deployment (update). - * - * @param errorMessage reason the deploy failed - * @param packageDetails describes the update being made - * - * @return response populated to reflect a failure - */ - private DeployPackagesResponse failApplicationDeployment(String errorMessage, ResourcePackageDetails packageDetails) { - DeployPackagesResponse response = new DeployPackagesResponse(ContentResponseResult.FAILURE); - - DeployIndividualPackageResponse packageResponse = - new DeployIndividualPackageResponse(packageDetails.getKey(), ContentResponseResult.FAILURE); - packageResponse.setErrorMessage(errorMessage); - - response.addPackageResponse(packageResponse); - - return response; - } - - private void persistApplicationVersion(ResourcePackageDetails packageDetails, File appFile) { - String packageName = appFile.getName(); - log.debug("Persisting application version '" + packageDetails.getVersion() + "' for package '" + packageName - + "'"); - PackageVersions versions = loadPackageVersions(); - versions.putVersion(packageName, packageDetails.getVersion()); - } - - private void deleteBackupOfOriginalFile(File backupOfOriginalFile) { - log.debug("Deleting backup of original file '" + backupOfOriginalFile + "'..."); - try { - FileUtils.forceDelete(backupOfOriginalFile); - } - catch (Exception e) { - // not critical. - log.warn("Failed to delete backup of original file: " + backupOfOriginalFile); - } - } - - private File writeNewAppBitsToTempFile(ContentServices contentServices, ResourcePackageDetails packageDetails - ) throws Exception { - File tempDir = getResourceContext().getTemporaryDirectory(); - File tempFile = new File(tempDir, this.deploymentFile.getName()); - - OutputStream tempOutputStream = null; - try { - tempOutputStream = new BufferedOutputStream(new FileOutputStream(tempFile)); - long bytesWritten = contentServices.downloadPackageBits(getResourceContext().getContentContext(), packageDetails.getKey(), - tempOutputStream, true); - log.debug("Wrote " + bytesWritten + " bytes to '" + tempFile + "'."); - } catch (IOException e) { - log.error("Error writing updated application bits to temporary location: " + tempFile, e); - throw e; - } finally { - if (tempOutputStream != null) { - try { - tempOutputStream.close(); - } catch (IOException e) { - log.error("Error closing temporary output stream", e); - } - } - } - if (!tempFile.exists()) { - log.error("Temporary file for application update not written to: " + tempFile); - throw new Exception(); - } - return tempFile; - } - - /** - * Returns an instantiated and loaded versions store access point. - * - * @return will not be null - */ - private PackageVersions loadPackageVersions() { - if (this.versions == null) { - ResourceType resourceType = getResourceContext().getResourceType(); - String pluginName = resourceType.getPlugin(); - File dataDirectoryFile = getResourceContext().getDataDirectory(); - dataDirectoryFile.mkdirs(); - String dataDirectory = dataDirectoryFile.getAbsolutePath(); - log.trace("Creating application versions store with plugin name [" + pluginName + - "] and data directory [" + dataDirectory + "]"); - this.versions = new PackageVersions(pluginName, dataDirectory); - this.versions.loadFromDisk(); - } - - return this.versions; - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/StandaloneManagedDeploymentDiscoveryComponent.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/StandaloneManagedDeploymentDiscoveryComponent.java deleted file mode 100644 index 8a60a42e73..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/StandaloneManagedDeploymentDiscoveryComponent.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -package org.rhq.plugins.mobicents.servlet.sip.jboss5; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jboss.managed.api.ManagedDeployment; -import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext; - -/** - * @author Ian Springer - */ -public class StandaloneManagedDeploymentDiscoveryComponent extends ManagedDeploymentDiscoveryComponent -{ - private final Log log = LogFactory.getLog(this.getClass()); - - protected boolean accept(ManagedDeployment managedDeployment, ResourceDiscoveryContext resourceDiscoveryContext) - { - return (managedDeployment.getParent() == null); - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/TxConnectionFactoryComponent.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/TxConnectionFactoryComponent.java deleted file mode 100644 index 42ac9177b6..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/TxConnectionFactoryComponent.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -package org.rhq.plugins.mobicents.servlet.sip.jboss5; - -import java.util.Set; -import java.util.HashSet; - -import org.rhq.core.domain.measurement.MeasurementReport; -import org.rhq.core.domain.measurement.MeasurementScheduleRequest; -import org.rhq.core.domain.measurement.MeasurementDataTrait; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.jboss.metatype.api.values.SimpleValue; -import org.jboss.managed.api.ManagedProperty; - -/** - * A Resource component for JBoss AS 5 Tx Connection Factories. - * - * @author Ian Springer - */ -public class TxConnectionFactoryComponent extends ManagedComponentComponent -{ - private final Log log = LogFactory.getLog(this.getClass()); - - @Override - public void getValues(MeasurementReport report, Set metrics) throws Exception - { - Set uncollectedMetrics = new HashSet(); - for (MeasurementScheduleRequest request : metrics) - { - try { - if (request.getName().equals("custom.transactionType")) { - ManagedProperty xaTransactionProp = getManagedProperties().get("xa-transaction"); - SimpleValue xaTransactionMetaValue = (SimpleValue)xaTransactionProp.getValue(); - Boolean xaTransactionValue = (xaTransactionMetaValue != null) - ? (Boolean)xaTransactionMetaValue.getValue() : null; - boolean isXa = (xaTransactionValue != null && xaTransactionValue); - String transactionType = (isXa) ? "XA" : "Local"; - report.addData(new MeasurementDataTrait(request, transactionType)); - } else { - uncollectedMetrics.add(request); - } - } catch (Exception e) { - log.error("Failed to collect metric for " + request, e); - } - } - super.getValues(report, uncollectedMetrics); - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/WarEmbeddedComponent.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/WarEmbeddedComponent.java deleted file mode 100644 index 5ef6e3ba39..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/WarEmbeddedComponent.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -package org.rhq.plugins.mobicents.servlet.sip.jboss5; - -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jboss.profileservice.spi.NoSuchDeploymentException; -import org.mc4j.ems.connection.EmsConnection; -import org.mc4j.ems.connection.bean.EmsBean; -import org.mc4j.ems.connection.bean.attribute.EmsAttribute; -import org.rhq.core.domain.measurement.MeasurementDataNumeric; -import org.rhq.core.domain.measurement.MeasurementDataTrait; -import org.rhq.core.domain.measurement.MeasurementReport; -import org.rhq.core.domain.measurement.MeasurementScheduleRequest; -import org.rhq.core.pluginapi.inventory.ResourceContext; -import org.rhq.plugins.jmx.ObjectNameQueryUtility; - -/** - * - * @author jean.deruelle@gmail.com - * - */ -public class WarEmbeddedComponent extends EmbeddedManagedDeploymentComponent -{ - private final Log log = LogFactory.getLog(this.getClass()); - - private static final String SERVLET_PREFIX = "Servlet."; - public static final String CONTEXT_ROOT_CONFIG_PROP = "contextRoot"; - public static final String NAME_CONFIG_PROP = "name"; - public static final String FILE_NAME = "filename"; - public static final String JBOSS_WEB_NAME = "jbossWebName"; - public static final String RESPONSE_TIME_LOG_FILE_CONFIG_PROP = "responseTimeLogFile"; - public static final String RESPONSE_TIME_URL_EXCLUDES_CONFIG_PROP = "responseTimeUrlExcludes"; - public static final String RESPONSE_TIME_URL_TRANSFORMS_CONFIG_PROP = "responseTimeUrlTransforms"; - - private static final String RESPONSE_TIME_METRIC = "ResponseTime"; - private static final String CONTEXT_ROOT_METRIC = "ContextRoot"; - - private static final String MAX_SERVLET_TIME = "Servlet.MaxResponseTime"; - private static final String MIN_SERVLET_TIME = "Servlet.MinResponseTime"; - private static final String AVG_SERVLET_TIME = "Servlet.AvgResponseTime"; - private static final String NUM_SERVLET_REQUESTS = "Servlet.NumRequests"; - private static final String NUM_SERVLET_ERRORS = "Servlet.NumErrors"; - private static final String TOTAL_TIME = "Servlet.TotalTime"; - private static final String SERVLET_NAME_BASE_TEMPLATE = "jboss.web:J2EEApplication=none,J2EEServer=none,j2eeType=Servlet,name=%name%"; - - private static final String SESSION_PREFIX = "Session."; - private static final String SESSION_NAME_BASE_TEMPLATE = "jboss.web:host=%HOST%,type=Manager,path=%PATH%"; - - private static final String VHOST_PREFIX = "Vhost"; - public static final String VHOST_CONFIG_PROP = "vHost"; - - public static final String ROOT_WEBAPP_CONTEXT_ROOT = "/"; - -// private EmsBean jbossWebMBean; -// private ResponseTimeLogParser logParser; -// String vhost; - private String contextRoot; - - ApplicationServerComponent applicationServerComponent; - - @Override - public void start(ResourceContext resourceContext) throws Exception { - super.start(resourceContext); - applicationServerComponent = (ApplicationServerComponent)resourceContext.getParentResourceComponent(); - } - - // ------------ MeasurementFacet Implementation ------------ - - public void getValues(MeasurementReport report, Set requests) throws NoSuchDeploymentException { - for (MeasurementScheduleRequest request : requests) { - String metricName = request.getName(); - if (metricName.equals(CUSTOM_PARENT_TRAIT)) { - this.contextRoot = deploymentName.substring(0, deploymentName.length() - 5); - this.contextRoot = contextRoot.substring(contextRoot.lastIndexOf("/") + 1); - List mBeans = applicationServerComponent.getWebApplicationEmsBeans(contextRoot); - String parentDeploymentName = getManagedDeployment().getParent().getName(); - if(mBeans.size() < 1) { - // -4 is for the extension .war to be removed - this.contextRoot = parentDeploymentName.substring(0, parentDeploymentName.length() - 5); - this.contextRoot = contextRoot.substring(contextRoot.lastIndexOf("/") + 1); - } - MeasurementDataTrait trait = new MeasurementDataTrait(request, parentDeploymentName); - report.addData(trait); - } - } - Set remainingSchedules = new LinkedHashSet(); - for (MeasurementScheduleRequest schedule : requests) { - String metricName = schedule.getName(); - if (metricName.equals(RESPONSE_TIME_METRIC)) { -// if (this.logParser != null) { -// try { -// CallTimeData callTimeData = new CallTimeData(schedule); -// this.logParser.parseLog(callTimeData); -// report.addData(callTimeData); -// } catch (Exception e) { -// log.error("Failed to retrieve HTTP call-time data.", e); -// } -// } else { -// log.error("The '" + RESPONSE_TIME_METRIC + "' metric is enabled for WAR resource '" -// + getApplicationName() + "', but no value is defined for the '" -// + RESPONSE_TIME_LOG_FILE_CONFIG_PROP + "' connection property."); -// // TODO: Communicate this error back to the server for display in the GUI. -// } - } else if (metricName.equals(CONTEXT_ROOT_METRIC)) { - MeasurementDataTrait trait = new MeasurementDataTrait(schedule, contextRoot); - report.addData(trait); - } else if (metricName.startsWith(SERVLET_PREFIX)) { - Double value = getServletMetric(metricName); - MeasurementDataNumeric metric = new MeasurementDataNumeric(schedule, value); - report.addData(metric); - } else if (metricName.startsWith(SESSION_PREFIX)) { - Double value = getSessionMetric(metricName); - MeasurementDataNumeric metric = new MeasurementDataNumeric(schedule, value); - report.addData(metric); - } else if (metricName.startsWith(VHOST_PREFIX)) { -// if (metricName.equals("Vhost.name")) { -// List beans = getVHosts(contextRoot); -// String value = ""; -// Iterator iter = beans.iterator(); -// while (iter.hasNext()) { -// EmsBean eBean = iter.next(); -// value += eBean.getBeanName().getKeyProperty("host"); -// if (iter.hasNext()) -// value += ","; -// } -// MeasurementDataTrait trait = new MeasurementDataTrait(schedule, value); -// report.addData(trait); -// } - } else { - remainingSchedules.add(schedule); - } - } - } - - private Double getServletMetric(String metricName) { - - EmsConnection jmxConnection = applicationServerComponent.getEmsConnection(); - - //FIXME : replace localhost with the real vhost - String servletMBeanNames = SERVLET_NAME_BASE_TEMPLATE + ",WebModule=//localhost" - + applicationServerComponent.getContextPath(this.contextRoot); - ObjectNameQueryUtility queryUtility = new ObjectNameQueryUtility(servletMBeanNames); - List mBeans = jmxConnection.queryBeans(queryUtility.getTranslatedQuery()); - - long min = Long.MAX_VALUE; - long max = 0; - long processingTime = 0; - int requestCount = 0; - int errorCount = 0; - Double result; - - for (EmsBean mBean : mBeans) { - mBean.refreshAttributes(); - if (metricName.equals(MIN_SERVLET_TIME)) { - EmsAttribute att = mBean.getAttribute("minTime"); - Long l = (Long) att.getValue(); - if (l < min) - min = l; - } else if (metricName.equals(MAX_SERVLET_TIME)) { - EmsAttribute att = mBean.getAttribute("maxTime"); - Long l = (Long) att.getValue(); - if (l > max) - max = l; - } else if (metricName.equals(AVG_SERVLET_TIME)) { - EmsAttribute att = mBean.getAttribute("processingTime"); - Long l = (Long) att.getValue(); - processingTime += l; - att = mBean.getAttribute("requestCount"); - Integer i = (Integer) att.getValue(); - requestCount += i; - } else if (metricName.equals(NUM_SERVLET_REQUESTS)) { - EmsAttribute att = mBean.getAttribute("requestCount"); - Integer i = (Integer) att.getValue(); - requestCount += i; - } else if (metricName.equals(NUM_SERVLET_ERRORS)) { - EmsAttribute att = mBean.getAttribute("errorCount"); - Integer i = (Integer) att.getValue(); - errorCount += i; - } else if (metricName.equals(TOTAL_TIME)) { - EmsAttribute att = mBean.getAttribute("processingTime"); - Long l = (Long) att.getValue(); - processingTime += l; - } - } - if (metricName.equals(AVG_SERVLET_TIME)) { - result = (requestCount > 0) ? ((double) processingTime / (double) requestCount) : Double.NaN; - } else if (metricName.equals(MIN_SERVLET_TIME)) { - result = (min != Long.MAX_VALUE) ? (double) min : Double.NaN; - } else if (metricName.equals(MAX_SERVLET_TIME)) { - result = (max != 0) ? (double) max : Double.NaN; - } else if (metricName.equals(NUM_SERVLET_ERRORS)) { - result = (double) errorCount; - } else if (metricName.equals(NUM_SERVLET_REQUESTS)) { - result = (double) requestCount; - } else if (metricName.equals(TOTAL_TIME)) { - result = (double) processingTime; - } else { - // fallback - result = Double.NaN; - } - - return result; - } - - private Double getSessionMetric(String metricName) { - EmsConnection jmxConnection = applicationServerComponent.getEmsConnection(); - - String servletMBeanNames = SESSION_NAME_BASE_TEMPLATE.replace("%PATH%", - applicationServerComponent.getContextPath(this.contextRoot)); - //FIXME : replace localhost with the real vhost - servletMBeanNames = servletMBeanNames.replace("%HOST%", "localhost"); - ObjectNameQueryUtility queryUtility = new ObjectNameQueryUtility(servletMBeanNames); - List mBeans = jmxConnection.queryBeans(queryUtility.getTranslatedQuery()); - - String property = metricName.substring(SESSION_PREFIX.length()); - - Double ret = Double.NaN; - - if (mBeans.size() > 0) { // TODO flag error if != 1 ? - EmsBean eBean = mBeans.get(0); - eBean.refreshAttributes(); - EmsAttribute att = eBean.getAttribute(property); - if (att != null) { - Integer i = (Integer) att.getValue(); - ret = new Double(i); - } - - } - return ret; - } - -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/WarEmbeddedDiscoveryComponent.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/WarEmbeddedDiscoveryComponent.java deleted file mode 100644 index 1d2367ccfc..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/WarEmbeddedDiscoveryComponent.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.rhq.plugins.mobicents.servlet.sip.jboss5; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jboss.managed.api.ManagedDeployment; -import org.mc4j.ems.connection.bean.EmsBean; -import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext; - -public class WarEmbeddedDiscoveryComponent extends EmbeddedManagedDeploymentDiscoveryComponent { - private final Log log = LogFactory.getLog(this.getClass()); - - @Override - protected boolean accept( - ManagedDeployment managedDeployment, - ResourceDiscoveryContext resourceDiscoveryContext) { - boolean isEmbedded = super.accept(managedDeployment, resourceDiscoveryContext); - if(!isEmbedded) { - return false; - } - String applicationName = managedDeployment.getSimpleName().substring(0,managedDeployment.getSimpleName().indexOf(".war")); - List mBeans = resourceDiscoveryContext.getParentResourceComponent().getWebApplicationEmsBeans(applicationName); - - List parentMBeans = new ArrayList(); - if(managedDeployment.getParent().getSimpleName().indexOf(".ear") != -1) { - String parentApplicationName = managedDeployment.getParent().getSimpleName().substring(0,managedDeployment.getParent().getSimpleName().indexOf(".ear")); - parentMBeans = resourceDiscoveryContext.getParentResourceComponent().getWebApplicationEmsBeans(parentApplicationName); - } - - List allBeans = new ArrayList(); - allBeans.addAll(mBeans); - allBeans.addAll(parentMBeans); - - if(allBeans.size() > 0) { - return true; - } else { - return false; - } -// log.warn(managedDeployment.getName()); -// log.warn(managedDeployment.getSimpleName()); -// log.warn("Children"); -// for(ManagedDeployment managedDeploymenttemp : managedDeployment.getChildren()){ -// log.warn("Child : " + managedDeploymenttemp.getName()); -// } -// log.warn("Components"); -// for(Entry component : managedDeployment.getComponents().entrySet()){ -// log.warn("ManagedComponent : key=" + component.getKey() +" ,value=" + component.getValue().getName()); -// } -// log.warn("ManagedObjectNames"); -// for(String managedObjectName : managedDeployment.getManagedObjectNames()){ -// log.warn("ManagedObjectName : " + managedObjectName ); -// } -// log.warn("Properties"); -// for(Entry property : managedDeployment.getProperties().entrySet()){ -// log.warn("ManagedProperty : key=" + property.getKey() +" ,value=" + property.getValue().getName()); -// } - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/WarStandaloneComponent.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/WarStandaloneComponent.java deleted file mode 100644 index 9c79866c79..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/WarStandaloneComponent.java +++ /dev/null @@ -1,244 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -package org.rhq.plugins.mobicents.servlet.sip.jboss5; - -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jboss.profileservice.spi.NoSuchDeploymentException; -import org.mc4j.ems.connection.EmsConnection; -import org.mc4j.ems.connection.bean.EmsBean; -import org.mc4j.ems.connection.bean.attribute.EmsAttribute; -import org.rhq.core.domain.measurement.MeasurementDataNumeric; -import org.rhq.core.domain.measurement.MeasurementDataTrait; -import org.rhq.core.domain.measurement.MeasurementReport; -import org.rhq.core.domain.measurement.MeasurementScheduleRequest; -import org.rhq.core.pluginapi.inventory.ResourceContext; -import org.rhq.plugins.jmx.ObjectNameQueryUtility; - -/** - * - * @author jean.deruelle@gmail.com - * - */ -public class WarStandaloneComponent extends StandaloneManagedDeploymentComponent -{ - private final Log log = LogFactory.getLog(this.getClass()); - - private static final String SERVLET_PREFIX = "Servlet."; - public static final String CONTEXT_ROOT_CONFIG_PROP = "contextRoot"; - public static final String NAME_CONFIG_PROP = "name"; - public static final String FILE_NAME = "filename"; - public static final String JBOSS_WEB_NAME = "jbossWebName"; - public static final String RESPONSE_TIME_LOG_FILE_CONFIG_PROP = "responseTimeLogFile"; - public static final String RESPONSE_TIME_URL_EXCLUDES_CONFIG_PROP = "responseTimeUrlExcludes"; - public static final String RESPONSE_TIME_URL_TRANSFORMS_CONFIG_PROP = "responseTimeUrlTransforms"; - - private static final String RESPONSE_TIME_METRIC = "ResponseTime"; - private static final String CONTEXT_ROOT_METRIC = "ContextRoot"; - - private static final String MAX_SERVLET_TIME = "Servlet.MaxResponseTime"; - private static final String MIN_SERVLET_TIME = "Servlet.MinResponseTime"; - private static final String AVG_SERVLET_TIME = "Servlet.AvgResponseTime"; - private static final String NUM_SERVLET_REQUESTS = "Servlet.NumRequests"; - private static final String NUM_SERVLET_ERRORS = "Servlet.NumErrors"; - private static final String TOTAL_TIME = "Servlet.TotalTime"; - private static final String SERVLET_NAME_BASE_TEMPLATE = "jboss.web:J2EEApplication=none,J2EEServer=none,j2eeType=Servlet,name=%name%"; - - private static final String SESSION_PREFIX = "Session."; - private static final String SESSION_NAME_BASE_TEMPLATE = "jboss.web:host=%HOST%,type=Manager,path=%PATH%"; - - private static final String VHOST_PREFIX = "Vhost"; - public static final String VHOST_CONFIG_PROP = "vHost"; - - public static final String ROOT_WEBAPP_CONTEXT_ROOT = "/"; - -// private EmsBean jbossWebMBean; -// private ResponseTimeLogParser logParser; -// String vhost; - private String contextRoot; - - ApplicationServerComponent applicationServerComponent; - - @Override - public void start(ResourceContext resourceContext) throws Exception { - super.start(resourceContext); - applicationServerComponent = (ApplicationServerComponent)resourceContext.getParentResourceComponent(); - // -4 is for the extension .war to be removed - this.contextRoot = deploymentName.substring(0, deploymentName.length() - 5); - this.contextRoot = contextRoot.substring(contextRoot.lastIndexOf("/") + 1); - - } - - // ------------ MeasurementFacet Implementation ------------ - - public void getValues(MeasurementReport report, Set requests) { - super.getValues(report, requests); - Set remainingSchedules = new LinkedHashSet(); - for (MeasurementScheduleRequest schedule : requests) { - String metricName = schedule.getName(); - if (metricName.equals(RESPONSE_TIME_METRIC)) { -// if (this.logParser != null) { -// try { -// CallTimeData callTimeData = new CallTimeData(schedule); -// this.logParser.parseLog(callTimeData); -// report.addData(callTimeData); -// } catch (Exception e) { -// log.error("Failed to retrieve HTTP call-time data.", e); -// } -// } else { -// log.error("The '" + RESPONSE_TIME_METRIC + "' metric is enabled for WAR resource '" -// + getApplicationName() + "', but no value is defined for the '" -// + RESPONSE_TIME_LOG_FILE_CONFIG_PROP + "' connection property."); -// // TODO: Communicate this error back to the server for display in the GUI. -// } - } else if (metricName.equals(CONTEXT_ROOT_METRIC)) { - MeasurementDataTrait trait = new MeasurementDataTrait(schedule, contextRoot); - report.addData(trait); - } else if (metricName.startsWith(SERVLET_PREFIX)) { - Double value = getServletMetric(metricName); - MeasurementDataNumeric metric = new MeasurementDataNumeric(schedule, value); - report.addData(metric); - } else if (metricName.startsWith(SESSION_PREFIX)) { - Double value = getSessionMetric(metricName); - MeasurementDataNumeric metric = new MeasurementDataNumeric(schedule, value); - report.addData(metric); - } else if (metricName.startsWith(VHOST_PREFIX)) { -// if (metricName.equals("Vhost.name")) { -// List beans = getVHosts(contextRoot); -// String value = ""; -// Iterator iter = beans.iterator(); -// while (iter.hasNext()) { -// EmsBean eBean = iter.next(); -// value += eBean.getBeanName().getKeyProperty("host"); -// if (iter.hasNext()) -// value += ","; -// } -// MeasurementDataTrait trait = new MeasurementDataTrait(schedule, value); -// report.addData(trait); -// } - } else { - remainingSchedules.add(schedule); - } - } - } - - private Double getServletMetric(String metricName) { - - EmsConnection jmxConnection = applicationServerComponent.getEmsConnection(); - - String servletNameBaseTemplate = SERVLET_NAME_BASE_TEMPLATE; - - //FIXME : replace localhost with the real vhost - String servletMBeanNames = servletNameBaseTemplate + ",WebModule=//localhost" - + applicationServerComponent.getContextPath(this.contextRoot); - ObjectNameQueryUtility queryUtility = new ObjectNameQueryUtility(servletMBeanNames); - List mBeans = jmxConnection.queryBeans(queryUtility.getTranslatedQuery()); - - long min = Long.MAX_VALUE; - long max = 0; - long processingTime = 0; - int requestCount = 0; - int errorCount = 0; - Double result; - - for (EmsBean mBean : mBeans) { - mBean.refreshAttributes(); - if (metricName.equals(MIN_SERVLET_TIME)) { - EmsAttribute att = mBean.getAttribute("minTime"); - Long l = (Long) att.getValue(); - if (l < min) - min = l; - } else if (metricName.equals(MAX_SERVLET_TIME)) { - EmsAttribute att = mBean.getAttribute("maxTime"); - Long l = (Long) att.getValue(); - if (l > max) - max = l; - } else if (metricName.equals(AVG_SERVLET_TIME)) { - EmsAttribute att = mBean.getAttribute("processingTime"); - Long l = (Long) att.getValue(); - processingTime += l; - att = mBean.getAttribute("requestCount"); - Integer i = (Integer) att.getValue(); - requestCount += i; - } else if (metricName.equals(NUM_SERVLET_REQUESTS)) { - EmsAttribute att = mBean.getAttribute("requestCount"); - Integer i = (Integer) att.getValue(); - requestCount += i; - } else if (metricName.equals(NUM_SERVLET_ERRORS)) { - EmsAttribute att = mBean.getAttribute("errorCount"); - Integer i = (Integer) att.getValue(); - errorCount += i; - } else if (metricName.equals(TOTAL_TIME)) { - EmsAttribute att = mBean.getAttribute("processingTime"); - Long l = (Long) att.getValue(); - processingTime += l; - } - } - if (metricName.equals(AVG_SERVLET_TIME)) { - result = (requestCount > 0) ? ((double) processingTime / (double) requestCount) : Double.NaN; - } else if (metricName.equals(MIN_SERVLET_TIME)) { - result = (min != Long.MAX_VALUE) ? (double) min : Double.NaN; - } else if (metricName.equals(MAX_SERVLET_TIME)) { - result = (max != 0) ? (double) max : Double.NaN; - } else if (metricName.equals(NUM_SERVLET_ERRORS)) { - result = (double) errorCount; - } else if (metricName.equals(NUM_SERVLET_REQUESTS)) { - result = (double) requestCount; - } else if (metricName.equals(TOTAL_TIME)) { - result = (double) processingTime; - } else { - // fallback - result = Double.NaN; - } - - return result; - } - - private Double getSessionMetric(String metricName) { - EmsConnection jmxConnection = applicationServerComponent.getEmsConnection(); - - String servletMBeanNames = SESSION_NAME_BASE_TEMPLATE.replace("%PATH%", - applicationServerComponent.getContextPath(this.contextRoot)); - //FIXME : replace localhost with the real vhost - servletMBeanNames = servletMBeanNames.replace("%HOST%", "localhost"); - ObjectNameQueryUtility queryUtility = new ObjectNameQueryUtility(servletMBeanNames); - List mBeans = jmxConnection.queryBeans(queryUtility.getTranslatedQuery()); - - String property = metricName.substring(SESSION_PREFIX.length()); - - Double ret = Double.NaN; - - if (mBeans.size() > 0) { // TODO flag error if != 1 ? - EmsBean eBean = mBeans.get(0); - eBean.refreshAttributes(); - EmsAttribute att = eBean.getAttribute(property); - if (att != null) { - Integer i = (Integer) att.getValue(); - ret = new Double(i); - } - - } - return ret; - } - -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/WarStandaloneDiscoveryComponent.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/WarStandaloneDiscoveryComponent.java deleted file mode 100644 index 09721c9f0b..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/WarStandaloneDiscoveryComponent.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.rhq.plugins.mobicents.servlet.sip.jboss5; - -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jboss.managed.api.ManagedDeployment; -import org.mc4j.ems.connection.bean.EmsBean; -import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext; - -public class WarStandaloneDiscoveryComponent extends StandaloneManagedDeploymentDiscoveryComponent { - private final Log log = LogFactory.getLog(this.getClass()); - - @Override - protected boolean accept( - ManagedDeployment managedDeployment, - ResourceDiscoveryContext resourceDiscoveryContext) { - boolean isEmbedded = !super.accept(managedDeployment, resourceDiscoveryContext); - if(isEmbedded) { - return false; - } - String applicationName = managedDeployment.getSimpleName().substring(0,managedDeployment.getSimpleName().indexOf(".war")); - List mBeans = resourceDiscoveryContext.getParentResourceComponent().getWebApplicationEmsBeans(applicationName); - if(mBeans.size() > 0) { - return true; - } else { - return false; - } -// log.warn(managedDeployment.getName()); -// log.warn(managedDeployment.getSimpleName()); -// log.warn("Children"); -// for(ManagedDeployment managedDeploymenttemp : managedDeployment.getChildren()){ -// log.warn("Child : " + managedDeploymenttemp.getName()); -// } -// log.warn("Components"); -// for(Entry component : managedDeployment.getComponents().entrySet()){ -// log.warn("ManagedComponent : key=" + component.getKey() +" ,value=" + component.getValue().getName()); -// } -// log.warn("ManagedObjectNames"); -// for(String managedObjectName : managedDeployment.getManagedObjectNames()){ -// log.warn("ManagedObjectName : " + managedObjectName ); -// } -// log.warn("Properties"); -// for(Entry property : managedDeployment.getProperties().entrySet()){ -// log.warn("ManagedProperty : key=" + property.getKey() +" ,value=" + property.getValue().getName()); -// } - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/util/DeploymentUtils.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/util/DeploymentUtils.java deleted file mode 100644 index 647ec2d505..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/util/DeploymentUtils.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2008 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -package org.rhq.plugins.mobicents.servlet.sip.jboss5.util; - -import java.io.File; -import java.io.IOException; -import java.net.URL; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jboss.deployers.spi.management.deploy.DeploymentManager; -import org.jboss.deployers.spi.management.deploy.DeploymentProgress; -import org.jboss.deployers.spi.management.deploy.DeploymentStatus; -import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.util.ZipUtil; -import org.rhq.plugins.jbossas5.factory.ProfileServiceFactory; -import org.rhq.plugins.mobicents.servlet.sip.jboss5.StandaloneManagedDeploymentComponent; - -/** - * @author Ian Springer - */ -public abstract class DeploymentUtils { - private static final Log LOG = LogFactory.getLog(DeploymentUtils.class); - - public static boolean hasCorrectExtension(File archiveFile, ResourceType resourceType) - { - String resourceTypeName = resourceType.getName(); - String expectedExtension; - if (resourceTypeName.equals(StandaloneManagedDeploymentComponent.RESOURCE_TYPE_EAR)) { - expectedExtension = "ear"; - } else if (resourceTypeName.equals(StandaloneManagedDeploymentComponent.RESOURCE_TYPE_WAR)){ - expectedExtension = "war"; - } else if (resourceTypeName.equals(StandaloneManagedDeploymentComponent.RESOURCE_TYPE_CONVERGED_WAR)){ - expectedExtension = "war"; - } else if (resourceTypeName.equals(StandaloneManagedDeploymentComponent.RESOURCE_TYPE_RAR)){ - expectedExtension = "rar"; - } else { - expectedExtension = "jar"; - } - String archiveName = archiveFile.getName(); - int lastPeriod = archiveName.lastIndexOf("."); - String extension = archiveName.substring(lastPeriod + 1); - // TODO: String compare should be case-insensitive if on Windows. - return (lastPeriod != -1 && expectedExtension.equals(extension)); - } - - public static DeploymentStatus deployArchive(File archiveFile, File deployDirectory, boolean deployExploded) - throws Exception - { - if (deployDirectory == null) - throw new IllegalArgumentException("Deploy directory is null."); - DeploymentManager deploymentManager = ProfileServiceFactory.getDeploymentManager(); - String archiveFileName = archiveFile.getName(); - DeploymentProgress progress; - if (deployExploded) { - LOG.debug("Deploying '" + archiveFileName + "' in exploded form..."); - File tempDir = new File(deployDirectory, archiveFile.getName() + ".rej"); - ZipUtil.unzipFile(archiveFile, tempDir); - File archiveDir = new File(deployDirectory, archiveFileName); - URL contentURL = archiveDir.toURI().toURL(); - if (!tempDir.renameTo(archiveDir)) - throw new IOException("Failed to rename '" + tempDir + "' to '" + archiveDir + "'."); - progress = deploymentManager.distribute(archiveFileName, contentURL, false); - } else { - LOG.debug("Deploying '" + archiveFileName + "' in non-exploded form..."); - URL contentURL = archiveFile.toURI().toURL(); - File deployLocation = new File(deployDirectory, archiveFileName); - boolean copyContent = !deployLocation.equals(archiveFile); - progress = deploymentManager.distribute(archiveFileName, contentURL, copyContent); - } - run(progress); - - // Now that we've distributed the deployment, we need to start it! - String[] repositoryNames = progress.getDeploymentID().getRepositoryNames(); - progress = deploymentManager.start(repositoryNames); - return run(progress); - } - - public static DeploymentStatus run(DeploymentProgress progress) - throws Exception - { - progress.run(); - DeploymentStatus status = progress.getDeploymentStatus(); - if (status.isFailed()) - //noinspection ThrowableResultOfMethodCallIgnored - throw new Exception(status.getMessage(), status.getFailure()); - return status; - } - - private DeploymentUtils() - { - } -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/util/EmsUtility.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/util/EmsUtility.java deleted file mode 100644 index 9ad0d424e8..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/util/EmsUtility.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Jopr Management Platform - * Copyright (C) 2005-2008 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.rhq.plugins.mobicents.servlet.sip.jboss5.util; - -import java.util.Arrays; -import java.util.List; -import java.util.SortedSet; - -import org.mc4j.ems.connection.bean.EmsBean; -import org.mc4j.ems.connection.bean.operation.EmsOperation; -import org.mc4j.ems.connection.bean.parameter.EmsParameter; - -/** - * @author Ian Springer - */ -public class EmsUtility { - /** - * Retrieves an MBean operation from an EMS MBean proxy which matches the specified name and parameter types. - * The method is modeled after {@link java.lang.Class#getMethod(String, Class[])}. - * - * @param mbean an EMS MBean proxy - * @param name the name of the operation - * @param parameterTypes the list of parameter types - * - * @return the EmsOperation object that matches the specified - * name and parameterTypes - * - * @throws NoSuchMethodException if a matching operation is not found - */ - public static EmsOperation getOperation(EmsBean mbean, String name, Class... parameterTypes) throws NoSuchMethodException { - if (mbean == null || name == null || parameterTypes == null) - throw new IllegalArgumentException("All parameters must be non-null."); - - String[] parameterTypeNames = new String[parameterTypes.length]; - int i = 0; - for (Class paramType : parameterTypes) { - parameterTypeNames[i] = paramType.getName(); - } - - return getOperation(mbean, name, parameterTypeNames); - } - - public static EmsOperation getOperation(EmsBean mbean, String name, String... parameterTypeNames) throws NoSuchMethodException { - if (mbean == null || name == null || parameterTypeNames == null) - throw new IllegalArgumentException("All parameters must be non-null."); - SortedSet operations = mbean.getOperations(); - - operationsLoop: for (EmsOperation operation : operations) { - List operationParameters = operation.getParameters(); - - if (operationParameters.size() != parameterTypeNames.length || !operation.getName().equals(name)) - // Different name or number of params than what we are looking for - move on... - continue; - // At this point, name and number of params match. Now compare the parameter types... - for (int i = 0; i < operationParameters.size(); i++) { - EmsParameter operationParameter = operationParameters.get(i); - if (!operationParameter.getType().equals(parameterTypeNames[i])) - // One of the params doesn't match - move on... - continue operationsLoop; - } - // If we made it here, we have a match. - return operation; - } - // If we made it here, we failed to find a match. - throw new NoSuchMethodException("Operation named [" + name + "] with parameters [" + Arrays.asList(parameterTypeNames) + "] not found on MBean [" + mbean.getBeanName() + "]."); - } - -} diff --git a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/util/MainDeployer.java b/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/util/MainDeployer.java deleted file mode 100644 index 53994915de..0000000000 --- a/management/jopr-plugin-as-5/src/main/java/org/rhq/plugins/mobicents/servlet/sip/jboss5/util/MainDeployer.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2008, Red Hat Middleware LLC, and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ -package org.rhq.plugins.mobicents.servlet.sip.jboss5.util; - -import java.io.File; -import java.net.MalformedURLException; -import java.net.URL; - -import org.mc4j.ems.connection.EmsConnection; -import org.mc4j.ems.connection.bean.EmsBean; -import org.mc4j.ems.connection.bean.operation.EmsOperation; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * @author jean.deruelle@gmail.com - * - */ -public class MainDeployer { - private final Log log = LogFactory.getLog(this.getClass()); - public static final String MAIN_DEPLOYER = "jboss.system:service=MainDeployer"; - - private EmsOperation deployOperation; - private EmsOperation redeployOperation; - private EmsOperation undeployOperation; - - public MainDeployer(EmsConnection connection) throws NoSuchMethodException { - EmsBean mainDeployer = connection.getBean(MAIN_DEPLOYER); - if (mainDeployer == null) { - throw new IllegalStateException("MBean named [" + MAIN_DEPLOYER + "] does not exist."); - } - this.deployOperation = EmsUtility.getOperation(mainDeployer, "deploy", URL.class); - this.redeployOperation = EmsUtility.getOperation(mainDeployer, "redeploy", URL.class); - this.undeployOperation = EmsUtility.getOperation(mainDeployer, "undeploy", URL.class); - } - - public void deploy(File file) throws DeployerException { - log.debug("Deploying " + file + "..."); - try { - URL url = toURL(file); - this.deployOperation.invoke(new Object[]{url}); - } - catch (RuntimeException e) { - throw new DeployerException("Failed to deploy " + file, e); - } - } - - public void redeploy(File file) throws DeployerException { - log.debug("Redeploying " + file + "..."); - try { - URL url = toURL(file); - this.redeployOperation.invoke(new Object[]{url}); - } - catch (RuntimeException e) { - throw new DeployerException("Failed to redeploy " + file, e); - } - } - - public void undeploy(File file) throws DeployerException { - log.debug("Undeploying " + file + "..."); - try { - URL url = toURL(file); - this.undeployOperation.invoke(new Object[]{url}); - } - catch (RuntimeException e) { - throw new DeployerException("Failed to undeploy " + file, e); - } - } - - private static URL toURL(File file) { - URL url; - try { - url = file.toURI().toURL(); - } - catch (MalformedURLException e) { - throw new IllegalStateException(e); - } - return url; - } - - public class DeployerException extends Exception - { - DeployerException(String message) { - super(message); - } - - DeployerException(String message, Throwable cause) { - super(message, cause); - } - } - -} diff --git a/management/jopr-plugin-as-5/src/main/resources/META-INF/rhq-plugin.xml b/management/jopr-plugin-as-5/src/main/resources/META-INF/rhq-plugin.xml deleted file mode 100644 index 208afa9540..0000000000 --- a/management/jopr-plugin-as-5/src/main/resources/META-INF/rhq-plugin.xml +++ /dev/null @@ -1,2860 +0,0 @@ - - - -'> - - - - - - - - The fully qualified name of the Java class to use to format the the sub pool statistics. The default - is "org.jboss.resource.statistic.pool.JBossDefaultSubPoolStatisticFormatter". - - - - - - - A formatted sub pool statistics report. - - - - - - - - - - -'> - - - - - - - - - - - -'> - - - - - - The minimum number of connections the pool should hold. The default is 0. - - - - - - - - - The maximum number of connections the pool should hold. The default is 10. - - - - - -'> - - - - - - -'> - - - - The number of times that allocating a connection should be tried before throwing an exception. The default - is 0. - - - - - - The time in milliseconds to wait between retrying to allocate a connection. The default is 5000 (5 seconds). - - - - - - Specify if connections should be validated on a background thread versus being validated - prior to use. Background validation is meant to reduce the overall load on the RDBMS system when validating - a connection. The default is No. - - - - - - The interval, in milliseconds, at which the ConnectionValidator will run. Set to 0 to disable background - validation. The default is 0. - - - - - - Indicates the maximum time in milliseconds to block while waiting for a connection before throwing - an exception. Note that this blocks only while waiting for a permit for a connection, and will never - throw an exception if creating a new connection takes an inordinately long time. The default is 30000 - (30 seconds). - - - - - - - - - The maximum time, in minutes, a connection may be idle before being closed. The default is 30. - - - - - - - - - If set, unconditionally sets the boolean return value of javax.transaction.xa.XAResource.isSameRM(XAResource). - - - - - - The ObjectName of the JMX Invoker MBean associated with this datasource. - - - - - - - The name of the corresponding type-mapping in conf/standardjbosscmp-jdbc.xml. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Whether or not to use separate pools. The default is Yes. - - - - - - - - - Whether to attempt to prefill the connection pool to the minimum number of connections. NOTE: Only - supporting pools (OnePool) support this feature. A warning can be found in the logs if the pool does not - support this. The default is No. - - - - - - Security settings for connections in the pool. - - - - - Indicates whether Subject (from security domain), application-supplied parameters - (such as from getConnection(user, pw)), both Subject and app-supplied parameters, - or neither Subject nor app-supplied parameters are used to distinguish connections - in the pool. The default is "NONE". - - - - - - - - - - - - The name of the JAAS security manager that will handle authentication (only required if security - deployment type is DOMAIN or DOMAIN_AND_APPLICATION). This name correlates to the JAAS login-config.xml - descriptor application-policy/name attribute. - - - - - - - The fully qualified class name of the class to use for formatting managed connection pool statistics for - this datasource. The class must implement the org.jboss.resource.statistic.formatter.StatisticsFormatter. - interface. The default is "org.jboss.resource.statistic.pool.JBossDefaultSubPoolStatisticFormatter". - - - - - - The name of the corresponding type-mapping in conf/standardjbosscmp-jdbc.xml. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Indicates whether the JNDI name should be bound under the "java" context, - which causes the DataSource to only be accessible from within the JBossAS VM. - The default is Yes. - - - - - - Whether idle connections below the min-pool-size should be closed. The default is No. - - - - - - The validate-on-match element indicates whether or not connection level validation should be done when a - connection factory attempts to match a managed connection for a given set. This is typically exclusive to - the use of background validation. The default is Yes. - - -'> - - - The SQL statement to use to check the validity of a pool connection. - - - - - The connection definition inside the RAR deployment uniquely identified by the connection factory interface, - e.g. "javax.sql.DataSource". - - - - - - The fully qualified name of a Java class to use to check if an exception should be broadcast. - - - - - - An SQL statement to execute whenever a new connection is added to the pool; this can be used to set the - connection schema, etc. - - - - - - The number of prepared statements per connection to be kept open and reused in subsequent requests. They are - stored in an LRU cache. Set to 0 to disable the cache. The default is 0. - - - - - - - - - Any configured query timeout in seconds. A value of 0 means no timeout. The default is 0. - - - - - - The RAR deployment to associate with the connection manager MBean. e.g. jms-ra.rar or - myapplication.ear#my.rar for nested rars. - - - - - - Whether to set the query timeout based on the time remaining until transaction timeout; - any configured query timeout will be used if there is no transaction. The default is No. - - - - - - Should prepared statements be shared? The default is No. - - - - - - Fully qualified name of the Java class used to check if a connection has become stale. - - - - - - Whether to check for unclosed Statements and ResultSets when connections are returned to the pool. The - default is "yes-no-warnings". - - - - - - - - - - - - - - - - - - - - - Specifies the delimiter for URLs in connection-url for HA datasources. - - - - - - The fully qualified class name of a class that implements the - org.jboss.resource.adapter.jdbc.URLSelectorStrategy interface. - - - - - - Any configured timeout, in milliseconds, for internal locks on the resource adapter objects. A value of 0 - means no timeout. The default is 0. - - - - - - Fully qualified name of the Java class used to validate if a connection is valid. - - -'> - - - - - - -'> - - - - - - - - - - - -'> - - - - - - - - The name of the RAR file that contains the definition for the resource we want to provide. For nested RAR - files, the name would look like myapplication.ear#my.rar. - - - - - - The connection factory interface class. It should match the connectionfactory-interface in the ra.xml file. - - - -'> - - - - - Properties to supply to the ManagedConnectionFactory (MCF) MBean service configuration. - - -'> - - - - - - - - - - - - - - - - - - - - -'> - - - - - - - -'> - - - - - - - - - - - - - - - - - - -'> - - - - - - - - -'> - -]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - This holds the property in the configuration to use - to define the filename that the profile service should use in the creation of a file - - - - - Profile Services managed property call datasource type - which is used for datasources to have the correct main tag in a xxx-ds.xml file" - - - - - - - - - - &datasourceAndConnectionFactoryOperations; - - &managedObjectMetrics; - &datasourceMetrics; - - - - - - - &datasourceConnectionResourceConfigProps; - &datasourceAndConnectionFactoryConnectionResourceConfigProps; - &nonXaDatasourceConnectionResourceConfigProps; - - - - &datasourceAndConnectionFactoryAdvancedResourceConfigProps; - &datasourceAdvancedResourceConfigProps; - - - Whether the connection should be locked into the transaction. - - - - - &nonXaDatasourceOracleTemplateProps; - - - - - - - - - - - - - - - This holds the property in the configuration to use - to define the filename that the profile service should use in the creation of a file - - - - - Profile Services managed property call datasource type - which is used for datasources to have the correct main tag in a xxx-ds.xml file - - - - - - - - - - &datasourceAndConnectionFactoryOperations; - - &managedObjectMetrics; - &datasourceMetrics; - - - - - - - - - - - - - - &datasourceConnectionResourceConfigProps; - &datasourceAndConnectionFactoryConnectionResourceConfigProps; - &nonXaDatasourceConnectionResourceConfigProps; - - - - &datasourceAndConnectionFactoryAdvancedResourceConfigProps; - &datasourceAdvancedResourceConfigProps; - - - Whether the connection should be locked into the transaction. - - - - - - &nonXaDatasourceOracleTemplateProps; - - - - - - - - - - - - - - - - This holds the property in the configuration to use - to define the filename that the profile service should use in the creation of a file - - - - - Profile Services managed property call datasource type - which is used for datasources to have the correct main tag in a xxx-ds.xml file - - - - - - - - - - &datasourceAndConnectionFactoryOperations; - - &managedObjectMetrics; - &datasourceMetrics; - - - - - - - - - - - - - - &datasourceConnectionResourceConfigProps; - &datasourceAndConnectionFactoryConnectionResourceConfigProps; - - - - - - Specify properties to assign to the XADataSource implementation class. - Each property is mapped - onto the XADataSource implementation by looking for a JavaBeans style - getter method for the property name. If found, the value of the property is - set using the JavaBeans setter with the element text translated to the true - property type using the java.beans.PropertyEditor for the type. - - - - - - XA transaction timeout, in seconds (passed to XAResource.setTransactionTimeout()) - - default is zero which does not invoke the setter. - - - - - - - - &datasourceAndConnectionFactoryAdvancedResourceConfigProps; - &datasourceAdvancedResourceConfigProps; - - - Whether the connection should be locked into the transaction. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - This holds the property in the configuration to use - to define the filename that the profile service should use in the creation of a file - - - - - - - - - - - &managedObjectMetrics; - &connectionFactoryMetrics; - - - - - - &connectionFactoryConnectionResourceConfigProps; - &datasourceAndConnectionFactoryConnectionResourceConfigProps; - - - - - - &datasourceAndConnectionFactoryAdvancedResourceConfigProps; - &connectionFactoryAdvancedResourceConfigProps; - - - Whether the connection should be locked into the transaction. - - - - - - - - - - - - - - - - - The name of the resource-configuration property to use to define the ManagedComponent name that - the profile service should use when creating a new ManagedComponent. - - - - - - - - - - - &datasourceAndConnectionFactoryOperations; - - - - &managedObjectMetrics; - &connectionFactoryMetrics; - - - - - - &connectionFactoryConnectionResourceConfigProps; - &datasourceAndConnectionFactoryConnectionResourceConfigProps; - - - - Whether on not to use XA transactions. The default is No. - - - - - - - - &datasourceAndConnectionFactoryAdvancedResourceConfigProps; - &connectionFactoryAdvancedResourceConfigProps; - - - - Whether the connection should be locked into the transaction. The default is Yes. - - - - - - The maximum time, in minutes, an XA Resource can be idle before it is removed. 0 means no - timeout. The default is 0. - - - - - - - - - - - - - - - - - - - - - - - - - - - - This holds the property in the configuration to use - to define the filename that the profile service should use in the creation of a file - - - - - - - - - - - - - &destinationOperations; - - - - - - - List all messages with selector - - - - - - - - - - - - - - - - List all durable mesages using a selector - - - - - - - - - - - - - - - - List all non durable mesages using a selector - - - - - - - - - - - - - Get the message counter as HTML - - - - - - - Get the message counter history as HTML - - - - - - - - - &managedObjectMetrics; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Is this queue clustered? For an existing queue, this property is read-only. If not specified - when creating a new queue, the default value is false. - - - - - - When paging messages to storage from a subscription, they first go into a "Down Cache" before - being written to storage. This enables the write to occur as a single operation, thus aiding - performance. This setting determines the maximum number of messages that the Down Cache will hold - before they are flushed to storage. - Updates to this property will not go into effect until the queue has been restarted. - The default value is 2000. - - - - - - - - - The maximum number of messages for the queue held in memory at any one time. - The actual queue can hold many more messages than this, but these are paged to and from - storage as necessary, as messages are added or consumed. - Updates to this property will not go into effect until the queue has been restarted. - The default value is 200000. - - - - - - - - - The number of delivery attempts before a message to a subscriber of this queue is moved to the - DLQ. The default value is 10. A value of -1 indicates the default value should be used. - - - - - - - - - The maximum number of messages this queue can hold before they are dropped. - A value of -1 means there is no maximum. The default value is -1. - - - - - - - - - When loading messages from a subscription, this is the maximum number of messages to - pre-load in one operation. Must be less than Full Size and greater than or equal to Down Cache Size. - Updates to this property will not go into effect until the queue has been restarted. - The default value is 2000. - - - - - - - - - The delay in milliseconds before a rolled back or recovered message is redelivered. - Set to 0 to disable redelivery. The default value is 0. A value of -1 indicates the default value should be used. - - - - - - - - - The JMX ObjectName of the dead letter queue (DLQ) for this queue (e.g. - "jboss.messaging.destination:service=Queue,name=PrivateDLQ") - overrides the default DLQ on the - server peer. - - - - - - - - - The JMX ObjectName of the expiry queue for this queue (e.g. - "jboss.messaging.destination:service=Queue,name=PrivateExpiryQueue") - overrides the default - expiry queue on the server peer. - - - - - - - - - The JMX ObjectName of the server peer this queue was deployed on (e.g. - "jboss.messaging:service=ServerPeer"). Updates to this property will not go into effect until - the queue has been restarted. - - - - - - - - - - - - - - - - - - - - - - - - - - - - This holds the property in the configuration to use - to define the filename that the profile service should use in the creation of a file - - - - - - - - - - - - - &destinationOperations; - - - - - - - - List all messages for the specified subscription with the specified selector - - - - - - - - - - - - - - - - - List all durable messages for the specified subscription with the specified selector - - - - - - - - - - - - - - - - - List all non durable messages for the specified subscription with the specified selector - - - - - - - - - - - - - Return all subscriptions for the topic - - - - - - - - - Return all subscriptions for the topic in HTML - - - - - - - Return all durable subscriptions for the topic - - - - - - - - - Return all durable subscriptions for the topic in HTML - - - - - - - Return all non durable subscriptions for the topic - - - - - - - - - Return all non durable subscriptions for the topic in HTML - - - - - &managedObjectMetrics; - - - - - - - - - - - - - - - - - - - - - - - - - - - - Is this topic clustered? For an existing topic, this property is read-only. If not specified - when creating a new topic, the default value is false. - - - - - - When paging messages to storage from a subscription, they first go into a "Down Cache" before - being written to storage. This enables the write to occur as a single operation, thus aiding - performance. This setting determines the maximum number of messages that the Down Cache will hold - before they are flushed to storage. - Updates to this property will not go into effect until the topic has been restarted. - The default value is 2000. - - - - - - - - - The maximum number of messages held by the topic subscriptions in memory at any one time. - The actual subscription can hold many more messages than this, but these are paged to and from - storage as necessary, as messages are added or consumed. - Updates to this property will not go into effect until the topic has been restarted. - The default value is 200000. - - - - - - - - - The number of delivery attempts before a message to a subscriber of this topic is moved to the - DLQ. The default value is 10. A value of -1 indicates the default value should be used. - - - - - - - - - The maximum number of messages this topic can hold before they are dropped. - A value of -1 means there is no maximum. The default value is -1. - - - - - - - - - When loading messages from a subscription, this is the maximum number of messages to - pre-load in one operation. Must be less than Full Size and greater than or equal to Down Cache Size. - Updates to this property will not go into effect until the topic has been restarted. - The default value is 2000. - - - - - - - - - The delay in milliseconds before a rolled back or recovered message is redelivered. - Set to 0 to disable redelivery. The default value is 0. A value of -1 indicates the default value should be used. - - - - - - - - - The JMX ObjectName of the dead letter queue (DLQ) for this topic (e.g. - "jboss.messaging.destination:service=Queue,name=PrivateDLQ") - overrides the default DLQ on the - server peer. - - - - - - - - - The JMX ObjectName of the expiry queue for this topic (e.g. - "jboss.messaging.destination:service=Queue,name=PrivateExpiryQueue") - overrides the default - expiry queue on the server peer. - - - - - - - - - The JMX ObjectName of the server peer this topic was deployed on (e.g. - "jboss.messaging:service=ServerPeer"). Updates to this property will not go into effect until - the topic has been restarted. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - The name of the item from the org.jboss.deployers.spi.management.KnownDeploymentTypes enum - corresponding to this deployment's type. - - - - - - - - - - - - - - - - - &deploymentContentConfigProps; - - - - - - - - - - - - - - - - - - - - The name of the item from the org.jboss.deployers.spi.management.KnownDeploymentTypes enum - corresponding to this deployment's type. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - &deploymentContentConfigProps; - - - - - - - - - - - - - - - - - - - The name of the item from the org.jboss.deployers.spi.management.KnownDeploymentTypes enum - corresponding to this deployment's type. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - The name of the item from the org.jboss.deployers.spi.management.KnownDeploymentTypes enum - corresponding to this deployment's type. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - The name of the item from the org.jboss.deployers.spi.management.KnownDeploymentTypes enum - corresponding to this deployment's type. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - &deploymentContentConfigProps; - - - - - - - - - - - - - - - - - - - The name of the item from the org.jboss.deployers.spi.management.KnownDeploymentTypes enum - corresponding to this deployment's type. - - - - - - - - - - - - - - - - - &deploymentContentConfigProps; - - - - - - - - - - - - - - - - - - - The name of the item from the org.jboss.deployers.spi.management.KnownDeploymentTypes enum - corresponding to this deployment's type. - - - - - - - - - - - - - - - - - - - - - - - - The name of the item from the org.jboss.deployers.spi.management.KnownDeploymentTypes enum - corresponding to this deployment's type. - - - - - - - - - - - - - - - - - &deploymentContentConfigProps; - - - - - - - - - - - - - - - - - - - The name of the item from the org.jboss.deployers.spi.management.KnownDeploymentTypes enum - corresponding to this deployment's type. - - - - - - - - - - - - - - - - - - - - - - - - The name of the item from the org.jboss.deployers.spi.management.KnownDeploymentTypes enum - corresponding to this deployment's type. - - - - - - - - - - - - - - - - - &deploymentContentConfigProps; - - - - - - - - - - - - - - - - - - - The name of the item from the org.jboss.deployers.spi.management.KnownDeploymentTypes enum - corresponding to this deployment's type. - - - - - - - - - - - - - - \ No newline at end of file diff --git a/management/jopr-plugin/.ant-targets-build-binary.xml b/management/jopr-plugin/.ant-targets-build-binary.xml deleted file mode 100644 index ddb8ac95f0..0000000000 --- a/management/jopr-plugin/.ant-targets-build-binary.xml +++ /dev/null @@ -1,4 +0,0 @@ -build-mobicents-jopr-plugin -extract-embjopr -get-embjopr -init diff --git a/management/jopr-plugin/.classpath b/management/jopr-plugin/.classpath deleted file mode 100644 index c3ac8d3504..0000000000 --- a/management/jopr-plugin/.classpath +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/management/jopr-plugin/.project b/management/jopr-plugin/.project deleted file mode 100644 index 6e0d274ae7..0000000000 --- a/management/jopr-plugin/.project +++ /dev/null @@ -1,13 +0,0 @@ - - jopr-mobicents-sip-servlets-plugin - A plugin for managing Mobicents Sip Servlets servers - - - - org.eclipse.jdt.core.javabuilder - - - - org.eclipse.jdt.core.javanature - - \ No newline at end of file diff --git a/management/jopr-plugin/.settings/org.eclipse.jdt.core.prefs b/management/jopr-plugin/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 61f01432f8..0000000000 --- a/management/jopr-plugin/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,5 +0,0 @@ -#Thu May 07 08:17:51 CEST 2009 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.source=1.5 -org.eclipse.jdt.core.compiler.compliance=1.5 diff --git a/management/jopr-plugin/build-binary.xml b/management/jopr-plugin/build-binary.xml deleted file mode 100644 index 73fbc02728..0000000000 --- a/management/jopr-plugin/build-binary.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Downloading Embedded Jopr - - - - - - - - - - - - Building Mobicents Jopr Plugin - - - - - - - - - - - - - - diff --git a/management/jopr-plugin/pom.xml b/management/jopr-plugin/pom.xml deleted file mode 100644 index 5236170a16..0000000000 --- a/management/jopr-plugin/pom.xml +++ /dev/null @@ -1,187 +0,0 @@ - - - - 4.0.0 - - - mobicents - org.mobicents - 1.19 - - org.mobicents.servlet.sip.management - jopr-mobicents-sip-servlets-plugin - 1.4-SNAPSHOT - jar - - Jopr Mobicents Sip Servlets Plugin - A plugin for managing Mobicents Sip Servlets servers - - - jboss-public-repository-group - JBoss Public Maven Repository Group - https://repository.jboss.org/nexus/content/groups/public - default - - true - never - - - true - never - - - - - - - scm:svn:http://mobicents.googlecode.com/svn/trunk/servers/sip-servlets - scm:svn:https://mobicents.googlecode.com/svn/trunk/servers/sip-servlets - http://code.google.com/p/mobicents/source/browse/trunk/servers/sip-servlets - - - - jboss-releases-repository - JBoss Releases Repository - https://repository.jboss.org/nexus/service/local/staging/deploy/maven2/ - - - jboss-snapshots-repository - JBoss Snapshots Repository - https://repository.jboss.org/nexus/content/repositories/snapshots/ - - - - 2.2.0.GA - 1.2.0.GA - - - - - - org.rhq - rhq-core-parent - ${rhq.version} - pom - - - - log4j - log4j - 1.2.14 - provided - - - - - commons-logging - commons-logging - 1.0.4 - provided - - - - mc4j - org-mc4j-ems - 1.2.5 - - - - org.jboss.on - jopr-jboss-as-plugin - ${jopr-version} - - - - org.jboss.on - jopr-tomcat-plugin - ${jopr-version} - - - - org.jetbrains - annotations - 7.0.2 - - - - org.rhq - rhq-core-native-system - ${rhq.version} - provided - - - - org.rhq - rhq-core-util - ${rhq.version} - provided - - - - org.rhq - rhq-plugins-parent - ${rhq.version} - pom - provided - - - - org.rhq - rhq-jmx-plugin - ${rhq.version} - provided - - - - org.rhq - rhq-core-domain - ${rhq.version} - provided - - - - org.rhq - rhq-core-plugin-api - ${rhq.version} - provided - - - - javax.persistence - persistence-api - 1.0 - - - - javax.persistence - persistence-api - 1.0 - - - - org.hibernate - hibernate-annotations - 3.3.0.ga - - - org.hibernate - hibernate-commons-annotations - 3.3.0.ga - - - - - - - maven-compiler-plugin - - - - - 1.5 - 1.5 - - - - - diff --git a/management/jopr-plugin/src/main/java/org/rhq/plugins/mobicents/servlet/sip/ConvergedDeploymentUtility.java b/management/jopr-plugin/src/main/java/org/rhq/plugins/mobicents/servlet/sip/ConvergedDeploymentUtility.java deleted file mode 100644 index 408d141af8..0000000000 --- a/management/jopr-plugin/src/main/java/org/rhq/plugins/mobicents/servlet/sip/ConvergedDeploymentUtility.java +++ /dev/null @@ -1,263 +0,0 @@ -/** - * - */ -package org.rhq.plugins.mobicents.servlet.sip; - -import java.io.File; -import java.lang.reflect.Field; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.management.ObjectName; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.mc4j.ems.connection.EmsConnection; -import org.mc4j.ems.connection.bean.EmsBean; -import org.mc4j.ems.connection.bean.operation.EmsOperation; -import org.rhq.plugins.jbossas.util.WarDeploymentInformation; -import org.rhq.plugins.jmx.ObjectNameQueryUtility; - -/** - * Accesses the MainDeployer mbean to find the deployment files behind services. - * - * Original file copied over from jopr jboss as plugin trunk rev 26. - * getVHosts method has been modified to fetch SipManager instead of Manager - * - * @author Greg Hinkle - * @author Jean Deruelle - */ -public class ConvergedDeploymentUtility { - private static Log log = LogFactory.getLog(ConvergedDeploymentUtility.class); - /** - * The object name of the JBoss main deployer MBean. - */ - protected static final String MAIN_DEPLOYER = "jboss.system:service=MainDeployer"; - - /** - * The name of the main deployer operation that is to be used to get the list of the modules are deployed - this is - * the Main Deployer operation name for JBossAS 4.x. - */ - private static final String LIST_DEPLOYED_MODULES_OP_NAME = "listDeployedModules"; - - /** - * The name of the main deployer operation that is to be used to get the list of the modules are deployed - this is - * the Main Deployer operation name for JBossAS 3.x. - */ - private static final String LIST_DEPLOYED_OP_NAME = "listDeployed"; - - /** - * Retrieves all the discovery information for a War resources. We are retrieving all the information - * so that there is only ever one call to the MBeanServer to get the deployed mbeans, therefore saving - * some performance if it did this for each and every war resource one at a time. - * - * @param connection EmsConnection to get the mbean information - * @param objectNames Name of the main jboss.management mbeans for a collection of wars. - * @return map holds all the war deployment information for the objects passed in the objectNames collection - */ - public static Map> getConvergedWarDeploymentInformation(EmsConnection connection, - List objectNames) { - // We need a list of informations, as one jsr77 deployment can end up in multiple web apps in different vhosts - HashMap> retDeploymentInformationMap = new HashMap>(); - - // will contain information on all deployments - Collection deployed; - try { - deployed = getDeploymentInformations(connection); - } - catch (Exception e) { - return null; - } - - String separator = System.getProperty("file.separator"); - boolean isOnWin = separator.equals("\\"); - - // Loop through the deployments, get the name information and compare it to the collection - // of strings passed into this method - // Interpreter i = new Interpreter(); - for (Object sdi : deployed) { - try { - ObjectName jbossWebObjectName = getFieldValue(sdi, "deployedObject", javax.management.ObjectName.class); - if (jbossWebObjectName != null) { - String shortName = getFieldValue(sdi, "shortName", String.class); - - for (String objectNameString : objectNames) { - String nameFromObject = getMBeanNameAttribute(objectNameString); - - if (shortName.equals(nameFromObject)) { - - String jbossWebmBeanName = jbossWebObjectName.getCanonicalName(); - String contextRoot = getMBeanNameAttribute(jbossWebmBeanName); - int lastSlashIndex = contextRoot.lastIndexOf("/"); - if (lastSlashIndex > 0) { - int lastIndex = contextRoot.length() - 1; - // If it ends in a slash, it's the root context (context root -> "/"). Otherwise, the - // context root will be everything after the last slash (e.g. "jmx-console"). - contextRoot = (lastSlashIndex == lastIndex) ? "/" : contextRoot.substring(lastSlashIndex + 1); - } - - String file = getFieldValue(sdi, "url", URL.class).toString(); - if (file.startsWith("file:/")) { - if (isOnWin) { - file = file.substring(6); - // listDeployed() always delivers / as path separator, so we need to correct this. - File tmp = new File(file); - file = tmp.getCanonicalPath(); - } - else - file = file.substring(5); - } - - /* - * We now have a valid deployment. Go back to the MBeanServer and get *all* - * applicable virtual hosts for this web app. Return deployment info for all - * of them. - * Most of the time this will only be one virtual host called 'localhost', as - * this is the default if no vhost is set. - */ - List vhosts = getVHosts(contextRoot, connection); - List infos = new ArrayList(vhosts - .size()); - - for (EmsBean vhost : vhosts) { - WarDeploymentInformation deploymentInformation = new WarDeploymentInformation(); - String vhostname = vhost.getBeanName().getKeyProperty("host"); - deploymentInformation.setVHost(vhostname); - deploymentInformation.setFileName(file); - deploymentInformation.setContextRoot(contextRoot); - // jboss.web:J2EEApplication=none,J2EEServer=none,j2eeType=WebModule,name=//bsd.de/test - // TODO to we have a better tool to exchange a value of a key-value pair in an ObjectName ? - int index = jbossWebmBeanName.indexOf("name="); - jbossWebmBeanName = jbossWebmBeanName.substring(0, index + 5); - jbossWebmBeanName += "//" + vhostname +ConvergedWarDiscoveryHelper.getContextPath(contextRoot); - - deploymentInformation.setJbossWebModuleMBeanObjectName(jbossWebmBeanName); - infos.add(deploymentInformation); - } - retDeploymentInformationMap.put(objectNameString, infos); - } - } - } - } catch (Exception evalError) { - log.warn("Failed to determine if a deployment contains our mbean", evalError); - } - } - return retDeploymentInformationMap; - } - - - /** - * Retrieves the virtual host MBeans for the webapp with the specified context root. - * VHost MBeans have the pattern "jboss.web:host=*,path=/,type=Manager". - * - * @param contextRoot the context root - * - * @return the list of VHost MBeans for this webapp - */ - public static List getVHosts(String contextRoot, EmsConnection emsConnection) { - String pattern = "jboss.web:host=%host%,path=" + ConvergedWarDiscoveryHelper.getContextPath(contextRoot) - + ",type=SipManager"; - ObjectNameQueryUtility queryUtil = new ObjectNameQueryUtility(pattern); - String translatedQuery = queryUtil.getTranslatedQuery(); - List mBeans = emsConnection.queryBeans(translatedQuery); - - pattern = "jboss.web:host=%host%,path=" + ConvergedWarDiscoveryHelper.getContextPath(contextRoot) - + ",type=ClusterSipManager"; - queryUtil = new ObjectNameQueryUtility(pattern); - translatedQuery = queryUtil.getTranslatedQuery(); - List haMBeans = emsConnection.queryBeans(translatedQuery); - - List allBeans = new ArrayList(mBeans); - allBeans.addAll(haMBeans); - - return allBeans; - } - - private static Collection getDeploymentInformations(EmsConnection connection) throws Exception { - Collection deploymentInfos = null; - EmsOperation operation = null; - try { - operation = getListDeployedOperation(connection); - if (operation == null) { - throw new UnsupportedOperationException( - "This JBossAS instance is unsupported; its MainDeployer MBean doesn't have a listDeployedModules or listDeployed operation."); - } - deploymentInfos = (Collection) operation.invoke(new Object[0]); - } catch (RuntimeException re) { - // Make a last ditch effort in case the call to listDeployedModules() failed due to - // https://jira.jboss.org/jira/browse/JBAS-5983. - if (operation != null && operation.getName().equals(LIST_DEPLOYED_MODULES_OP_NAME)) { - EmsBean mainDeployerMBean = connection.getBean(MAIN_DEPLOYER); - operation = mainDeployerMBean.getOperation(LIST_DEPLOYED_OP_NAME); - try { - deploymentInfos = (Collection) operation.invoke(new Object[0]); - } - catch (RuntimeException re2) { - deploymentInfos = null; - } - } - if (deploymentInfos == null) { - log.warn("Cannot determine deployed modules - cause: " + re); - throw new Exception(re); - } - } - return deploymentInfos; - } - - private static String getMBeanNameAttribute(String objectBeanName) { - Object[] splitName = objectBeanName.split("name="); - String retNameAttribute = ""; - if (splitName.length > 1) { - String afterName = (String) splitName[1]; - String[] removeAnythingAfter = afterName.split(","); - if (removeAnythingAfter.length > 0) { - retNameAttribute = removeAnythingAfter[0]; - } else { - retNameAttribute = afterName; - } - } - return retNameAttribute; - } - - private static T getFieldValue(Object target, String name, Class T) { - - if (target == null) - return null; - - Field field; - T ret; - try { - field = target.getClass().getField(name); - ret = (T) field.get(target); - if (T == ObjectName.class && ret != null) { - ret = (T) new ObjectName(ret.toString()); - } - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - return null; - } - - return ret; - } - - protected static EmsOperation getListDeployedOperation(EmsConnection connection) { - EmsOperation retOperation; - EmsBean bean = connection.getBean(MAIN_DEPLOYER); - - // first try the new operation name, used by JBossAS 3.2.8 and 4.x. - retOperation = bean.getOperation(LIST_DEPLOYED_MODULES_OP_NAME); - - // if that doesn't exist, we are probably connected to a JBossAS 3.2.7 or earlier version - if (retOperation == null) { - retOperation = bean.getOperation(LIST_DEPLOYED_OP_NAME); - } - - // if we still did not manage to find the operation name, let the caller handle this error condition - return retOperation; - } -} diff --git a/management/jopr-plugin/src/main/java/org/rhq/plugins/mobicents/servlet/sip/ConvergedWarComponent.java b/management/jopr-plugin/src/main/java/org/rhq/plugins/mobicents/servlet/sip/ConvergedWarComponent.java deleted file mode 100644 index 270d53cc14..0000000000 --- a/management/jopr-plugin/src/main/java/org/rhq/plugins/mobicents/servlet/sip/ConvergedWarComponent.java +++ /dev/null @@ -1,449 +0,0 @@ - /* - * Jopr Management Platform - * Copyright (C) 2005-2008 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.rhq.plugins.mobicents.servlet.sip; - -import java.io.File; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jetbrains.annotations.Nullable; -import org.mc4j.ems.connection.EmsConnection; -import org.mc4j.ems.connection.bean.EmsBean; -import org.mc4j.ems.connection.bean.attribute.EmsAttribute; -import org.mc4j.ems.connection.bean.operation.EmsOperation; -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.measurement.AvailabilityType; -import org.rhq.core.domain.measurement.MeasurementDataNumeric; -import org.rhq.core.domain.measurement.MeasurementDataTrait; -import org.rhq.core.domain.measurement.MeasurementReport; -import org.rhq.core.domain.measurement.MeasurementScheduleRequest; -import org.rhq.core.domain.measurement.calltime.CallTimeData; -import org.rhq.core.pluginapi.inventory.ResourceContext; -import org.rhq.core.pluginapi.operation.OperationFacet; -import org.rhq.core.pluginapi.operation.OperationResult; -import org.rhq.core.pluginapi.util.ResponseTimeConfiguration; -import org.rhq.core.pluginapi.util.ResponseTimeLogParser; -import org.rhq.plugins.jbossas.ApplicationComponent; -import org.rhq.plugins.jbossas.util.WarDeploymentInformation; -import org.rhq.plugins.jmx.ObjectNameQueryUtility; - -/** - * A JON plugin resource component for managing a webapp deployed to a JBossAS server. - * - * Original file copied over from jopr jboss as plugin trunk rev 26. - * - * Sip Session and Sip Application Session metrics specific to sip application are collected - * Manager has been changed to SipManager in the object name JMX fecthing - * - * @author Ian Springer - * @author Heiko W. Rupp - * @author Jean Deruelle - */ -public class ConvergedWarComponent extends ApplicationComponent implements OperationFacet { - private static final String SERVLET_PREFIX = "Servlet."; - private static final String SIP_SERVLET_PREFIX = "SipServlet."; - public static final String CONTEXT_ROOT_CONFIG_PROP = "contextRoot"; - public static final String NAME_CONFIG_PROP = "name"; - public static final String FILE_NAME = "filename"; - public static final String JBOSS_WEB_NAME = "jbossWebName"; - public static final String RESPONSE_TIME_LOG_FILE_CONFIG_PROP = "responseTimeLogFile"; - public static final String RESPONSE_TIME_URL_EXCLUDES_CONFIG_PROP = "responseTimeUrlExcludes"; - public static final String RESPONSE_TIME_URL_TRANSFORMS_CONFIG_PROP = "responseTimeUrlTransforms"; - - private static final String RESPONSE_TIME_METRIC = "ResponseTime"; - private static final String CONTEXT_ROOT_METRIC = "ContextRoot"; - - private static final String MAX_SERVLET_TIME = "Servlet.MaxResponseTime"; - private static final String MIN_SERVLET_TIME = "Servlet.MinResponseTime"; - private static final String AVG_SERVLET_TIME = "Servlet.AvgResponseTime"; - private static final String NUM_SERVLET_REQUESTS = "Servlet.NumRequests"; - private static final String NUM_SERVLET_ERRORS = "Servlet.NumErrors"; - private static final String TOTAL_TIME = "Servlet.TotalTime"; - private static final String SERVLET_NAME_BASE_TEMPLATE = "jboss.web:J2EEApplication=none,J2EEServer=none,j2eeType=Servlet,name=%name%"; - private static final String SIP_SERVLET_NAME_BASE_TEMPLATE = "jboss.web:J2EEApplication=none,J2EEServer=none,j2eeType=SipServlet,name=%name%"; - - private static final String SESSION_PREFIX = "Session."; - private static final String SIP_SESSION_NAME_BASE_TEMPLATE = "jboss.web:host=%HOST%,type=SipManager,path=%PATH%"; - private static final String HA_SIP_SESSION_NAME_BASE_TEMPLATE = "jboss.web:host=%HOST%,type=ClusterSipManager,path=%PATH%"; - private static final String SIP_SESSION_PREFIX = "SipSession."; - - private static final String VHOST_PREFIX = "Vhost"; - public static final String VHOST_CONFIG_PROP = "vHost"; - - public static final String ROOT_WEBAPP_CONTEXT_ROOT = "/"; - - private final Log log = LogFactory.getLog(this.getClass()); - - private EmsBean jbossWebMBean; - private ResponseTimeLogParser logParser; - String vhost; - private String contextRoot; - - @Override - public AvailabilityType getAvailability() { - AvailabilityType availability; - if (this.jbossWebMBean != null) { - int state = (Integer) this.jbossWebMBean.getAttribute("state").refresh(); - availability = (state == JBossWebMBeanState.STARTED) ? AvailabilityType.UP : AvailabilityType.DOWN; - } else { - // The WAR has no jboss.web MBean associated with it - this means it - // has no associated context root (i.e. it's not exposed via HTTP), - // so consider it down. - // @TODO In Embedded Console, we might want to call getJBossWebMBean() again to make sure. (See todo in that method for why) - - // Try to get the JBossWebMBean again - // If you can't then set this to down. - this.jbossWebMBean = getJBossWebMBean(); - if (this.jbossWebMBean == null) { - availability = AvailabilityType.DOWN; - } else { - availability = getAvailability(); - } - } - - return availability; - } - - @Override - public void start(ResourceContext resourceContext) { - super.start(resourceContext); - Configuration pluginConfig = getResourceContext().getPluginConfiguration(); - this.jbossWebMBean = getJBossWebMBean(); - this.vhost = pluginConfig.getSimple(VHOST_CONFIG_PROP).getStringValue(); - this.contextRoot = pluginConfig.getSimple(CONTEXT_ROOT_CONFIG_PROP).getStringValue(); - ResponseTimeConfiguration responseTimeConfig = new ResponseTimeConfiguration(pluginConfig); - File logFile = responseTimeConfig.getLogFile(); - if (logFile != null) { - this.logParser = new ResponseTimeLogParser(logFile); - this.logParser.setExcludes(responseTimeConfig.getExcludes()); - this.logParser.setTransforms(responseTimeConfig.getTransforms()); - } - } - - @Override - public void getValues(MeasurementReport report, Set schedules) { - Set remainingSchedules = new LinkedHashSet(); - for (MeasurementScheduleRequest schedule : schedules) { - String metricName = schedule.getName(); - if (metricName.equals(RESPONSE_TIME_METRIC)) { - if (this.logParser != null) { - try { - CallTimeData callTimeData = new CallTimeData(schedule); - this.logParser.parseLog(callTimeData); - report.addData(callTimeData); - } catch (Exception e) { - log.error("Failed to retrieve HTTP call-time data.", e); - } - } else { - log.error("The '" + RESPONSE_TIME_METRIC + "' metric is enabled for WAR resource '" - + getApplicationName() + "', but no value is defined for the '" - + RESPONSE_TIME_LOG_FILE_CONFIG_PROP + "' connection property."); - // TODO: Communicate this error back to the server for display in the GUI. - } - } else if (metricName.equals(CONTEXT_ROOT_METRIC)) { - MeasurementDataTrait trait = new MeasurementDataTrait(schedule, contextRoot); - report.addData(trait); - } else if (metricName.startsWith(SERVLET_PREFIX) || metricName.startsWith(SIP_SERVLET_PREFIX)) { - Double value = getServletMetric(metricName); - MeasurementDataNumeric metric = new MeasurementDataNumeric(schedule, value); - report.addData(metric); - } else if (metricName.startsWith(SESSION_PREFIX) || metricName.startsWith(SIP_SESSION_PREFIX)) { - Double value = getSessionMetric(metricName); - MeasurementDataNumeric metric = new MeasurementDataNumeric(schedule, value); - report.addData(metric); - } else if (metricName.startsWith(VHOST_PREFIX)) { - if (metricName.equals("Vhost.name")) { - List beans = getVHosts(contextRoot); - String value = ""; - Iterator iter = beans.iterator(); - while (iter.hasNext()) { - EmsBean eBean = iter.next(); - value += eBean.getBeanName().getKeyProperty("host"); - if (iter.hasNext()) - value += ","; - } - MeasurementDataTrait trait = new MeasurementDataTrait(schedule, value); - report.addData(trait); - } - } else { - remainingSchedules.add(schedule); - } - } - // TODO: What's the deal here - should the below be uncommented or can we get rid of it? (ips, 08/28/08) - //super.getValues(report, remainingSchedules); - } - - private Double getSessionMetric(String metricName) { - EmsConnection jmxConnection = getEmsConnection(); - - List mBeans = null; - String servletMBeanNames = SIP_SESSION_NAME_BASE_TEMPLATE.replace("%PATH%", - ConvergedWarDiscoveryHelper.getContextPath(this.contextRoot)); - if( servletMBeanNames != null) { - servletMBeanNames = servletMBeanNames.replace("%HOST%", vhost); - if( servletMBeanNames != null) { - ObjectNameQueryUtility queryUtility = new ObjectNameQueryUtility(servletMBeanNames); - mBeans = jmxConnection.queryBeans(queryUtility.getTranslatedQuery()); - } - } - - if(mBeans == null || mBeans.size() < 1) { - servletMBeanNames = HA_SIP_SESSION_NAME_BASE_TEMPLATE.replace("%PATH%", - ConvergedWarDiscoveryHelper.getContextPath(this.contextRoot)); - if( servletMBeanNames != null) { - servletMBeanNames = servletMBeanNames.replace("%HOST%", vhost); - if( servletMBeanNames != null) { - ObjectNameQueryUtility queryUtility = new ObjectNameQueryUtility(servletMBeanNames); - mBeans = jmxConnection.queryBeans(queryUtility.getTranslatedQuery()); - } - } - } - - String property = metricName.substring(SIP_SESSION_PREFIX.length()); - - Double ret = Double.NaN; - - if (mBeans.size() > 0) { // TODO flag error if != 1 ? - EmsBean eBean = mBeans.get(0); - eBean.refreshAttributes(); - EmsAttribute att = eBean.getAttribute(property); - if (att != null) { - Integer i = (Integer) att.getValue(); - ret = new Double(i); - } - - } - return ret; - } - - private Double getServletMetric(String metricName) { - - EmsConnection jmxConnection = getEmsConnection(); - - String servletNameBaseTemplate = SERVLET_NAME_BASE_TEMPLATE; - if(metricName.startsWith(SIP_SERVLET_PREFIX)) { - servletNameBaseTemplate = SIP_SERVLET_NAME_BASE_TEMPLATE; - } - - String servletMBeanNames = servletNameBaseTemplate + ",WebModule=//" + this.vhost - + ConvergedWarDiscoveryHelper.getContextPath(this.contextRoot); - ObjectNameQueryUtility queryUtility = new ObjectNameQueryUtility(servletMBeanNames); - List mBeans = jmxConnection.queryBeans(queryUtility.getTranslatedQuery()); - - long min = Long.MAX_VALUE; - long max = 0; - long processingTime = 0; - int requestCount = 0; - int errorCount = 0; - Double result; - - for (EmsBean mBean : mBeans) { - mBean.refreshAttributes(); - if (metricName.equals(MIN_SERVLET_TIME)) { - EmsAttribute att = mBean.getAttribute("minTime"); - Long l = (Long) att.getValue(); - if (l < min) - min = l; - } else if (metricName.equals(MAX_SERVLET_TIME)) { - EmsAttribute att = mBean.getAttribute("maxTime"); - Long l = (Long) att.getValue(); - if (l > max) - max = l; - } else if (metricName.equals(AVG_SERVLET_TIME)) { - EmsAttribute att = mBean.getAttribute("processingTime"); - Long l = (Long) att.getValue(); - processingTime += l; - att = mBean.getAttribute("requestCount"); - Integer i = (Integer) att.getValue(); - requestCount += i; - } else if (metricName.equals(NUM_SERVLET_REQUESTS)) { - EmsAttribute att = mBean.getAttribute("requestCount"); - Integer i = (Integer) att.getValue(); - requestCount += i; - } else if (metricName.equals(NUM_SERVLET_ERRORS)) { - EmsAttribute att = mBean.getAttribute("errorCount"); - Integer i = (Integer) att.getValue(); - errorCount += i; - } else if (metricName.equals(TOTAL_TIME)) { - EmsAttribute att = mBean.getAttribute("processingTime"); - Long l = (Long) att.getValue(); - processingTime += l; - } - } - if (metricName.equals(AVG_SERVLET_TIME)) { - result = (requestCount > 0) ? ((double) processingTime / (double) requestCount) : Double.NaN; - } else if (metricName.equals(MIN_SERVLET_TIME)) { - result = (min != Long.MAX_VALUE) ? (double) min : Double.NaN; - } else if (metricName.equals(MAX_SERVLET_TIME)) { - result = (max != 0) ? (double) max : Double.NaN; - } else if (metricName.equals(NUM_SERVLET_ERRORS)) { - result = (double) errorCount; - } else if (metricName.equals(NUM_SERVLET_REQUESTS)) { - result = (double) requestCount; - } else if (metricName.equals(TOTAL_TIME)) { - result = (double) processingTime; - } else { - // fallback - result = Double.NaN; - } - - return result; - } - - @Override - public OperationResult invokeOperation(String name, Configuration params) throws Exception { - WarOperation operation = getOperation(name); - if (this.jbossWebMBean == null) { - throw new IllegalStateException("Could not find jboss.web MBean for WAR '" + getApplicationName() + "'."); - } - - EmsOperation mbeanOperation = this.jbossWebMBean.getOperation(name); - if (mbeanOperation == null) { - throw new IllegalStateException("Operation [" + name + "] not found on bean [" - + this.jbossWebMBean.getBeanName() + "]"); - } - - // NOTE: None of the supported operations have any parameters or return values, which makes our job easier. - Object[] paramValues = new Object[0]; - mbeanOperation.invoke(paramValues); - int state = (Integer) this.jbossWebMBean.getAttribute("state").refresh(); - int expectedState = getExpectedPostExecutionState(operation); - if (state != expectedState) { - throw new Exception("Failed to " + name + " webapp (value of the 'state' attribute of MBean '" - + this.jbossWebMBean.getBeanName() + "' is " + state + ", not " + expectedState + ")."); - } - - return new OperationResult(); - } - - private static int getExpectedPostExecutionState(WarOperation operation) { - int expectedState; - switch (operation) { - case START: - case RELOAD: { - expectedState = JBossWebMBeanState.STARTED; - break; - } - - case STOP: { - expectedState = JBossWebMBeanState.STOPPED; - break; - } - - default: { - throw new IllegalStateException("Unsupported operation: " + operation); // will never happen - } - } - - return expectedState; - } - - private WarOperation getOperation(String name) { - try { - return WarOperation.valueOf(name.toUpperCase()); - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException("Invalid operation name: " + name); - } - } - - /** - * Returns the the jboss.web MBean associated with this WAR (e.g. - * jboss.web:J2EEApplication=none,J2EEServer=none,j2eeType=WebModule,name=//localhost/jmx-console), or null if the - * WAR has no corresponding jboss.web MBean. - * - *

This will return null only in the rare case that a deployed WAR has no context root associated with it. An - * example of this is ROOT.war in the RHQ Server. rhq.ear maps rhq-portal.war to "/" and overrides ROOT.war's - * association with "/". - * - * @return the jboss.web MBean associated with this WAR (e.g. - * jboss.web:J2EEApplication=none,J2EEServer=none,j2eeType=WebModule,name=//localhost/jmx-console), or null - * if the WAR has no corresponding jboss.web MBean - */ - @Nullable - private EmsBean getJBossWebMBean() { - String jbossWebMBeanName = getJBossWebMBeanName(); - if (jbossWebMBeanName != null) { - ObjectNameQueryUtility queryUtility = new ObjectNameQueryUtility(jbossWebMBeanName); - List mBeans = getEmsConnection().queryBeans(queryUtility.getTranslatedQuery()); - // There should only be one mBean for this match. - if (mBeans.size() == 1) { - return mBeans.get(0); - } - } else { - // This might be in Embedded in which during discovery it doesn't discover because they aren't deployed yet. - // Might re-get, or let it get picked up the next time a discovery occurs. - } - return null; - } - - @Nullable - private String getJBossWebMBeanName() { - Configuration pluginConfig = getResourceContext().getPluginConfiguration(); - String jbossWebMBeanName = pluginConfig.getSimpleValue(ConvergedWarComponent.JBOSS_WEB_NAME, null); - if (jbossWebMBeanName == null) { - WarDeploymentInformation deploymentInformation = getDeploymentInformation(); - if (deploymentInformation != null) { - jbossWebMBeanName = deploymentInformation.getJbossWebModuleMBeanObjectName(); - ConvergedWarDiscoveryHelper.setDeploymentInformation(pluginConfig, deploymentInformation); - } - } - return jbossWebMBeanName; - } - - /** - * Virtual hosts for this app have the patten 'jboss.web:host=*,path=,type=Manager' - * @param contextRoot - * @return - */ - private List getVHosts(String contextRoot) { - - return ConvergedDeploymentUtility.getVHosts(contextRoot, getEmsConnection()); - } - - private WarDeploymentInformation getDeploymentInformation() { - WarDeploymentInformation deploymentInformation = null; - EmsBean mBean = this.getEmsBean(); - if (mBean != null && mBean.getBeanName() != null) { - String beanName = this.getEmsBean().getBeanName().getCanonicalName(); - List beanNameList = new ArrayList(); - beanNameList.add(beanName); - // deploymentInformation = DeploymentUtility.getWarDeploymentInformation(getEmsConnection(), beanNameList) - // .get(beanName); TODO fix this - } - return deploymentInformation; - } - - private enum WarOperation { - START, STOP, RELOAD - } - - private interface JBossWebMBeanState { - int STOPPED = 0; - int STARTED = 1; - } -} \ No newline at end of file diff --git a/management/jopr-plugin/src/main/java/org/rhq/plugins/mobicents/servlet/sip/ConvergedWarDiscoveryComponent.java b/management/jopr-plugin/src/main/java/org/rhq/plugins/mobicents/servlet/sip/ConvergedWarDiscoveryComponent.java deleted file mode 100644 index 7cea6a71f7..0000000000 --- a/management/jopr-plugin/src/main/java/org/rhq/plugins/mobicents/servlet/sip/ConvergedWarDiscoveryComponent.java +++ /dev/null @@ -1,56 +0,0 @@ - /* - * Jopr Management Platform - * Copyright (C) 2005-2008 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.rhq.plugins.mobicents.servlet.sip; - -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails; -import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext; -import org.rhq.plugins.jbossas.ApplicationDiscoveryComponent; -import org.rhq.plugins.jbossas.JBossASServerComponent; -import org.rhq.plugins.jmx.JMXComponent; - -/** - * A JON plugin discovery component for discovering standalone webapps deployed to a JBossAS server. - * - * Original file copied over from jopr jboss as plugin trunk rev 26 - * It has been copied because it uses ConvergedWarDiscoveryHelper and - * since methods in this class are static they couldn't be extended by inheritance - * - * @author Ian Springer - * @author Jean Deruelle - */ -public class ConvergedWarDiscoveryComponent extends ApplicationDiscoveryComponent { - private static final Log log = LogFactory.getLog(ConvergedWarDiscoveryComponent.class); - @Override - public Set discoverResources(ResourceDiscoveryContext discoveryContext) { - Set resources = super.discoverResources(discoveryContext); - JBossASServerComponent parentJBossASComponent = (JBossASServerComponent) discoveryContext - .getParentResourceComponent(); - resources = ConvergedWarDiscoveryHelper.initPluginConfigurations(parentJBossASComponent, resources); - log.debug("resources size" + resources.size()); - return resources; - } -} \ No newline at end of file diff --git a/management/jopr-plugin/src/main/java/org/rhq/plugins/mobicents/servlet/sip/ConvergedWarDiscoveryHelper.java b/management/jopr-plugin/src/main/java/org/rhq/plugins/mobicents/servlet/sip/ConvergedWarDiscoveryHelper.java deleted file mode 100644 index 079938e903..0000000000 --- a/management/jopr-plugin/src/main/java/org/rhq/plugins/mobicents/servlet/sip/ConvergedWarDiscoveryHelper.java +++ /dev/null @@ -1,207 +0,0 @@ - /* - * Jopr Management Platform - * Copyright (C) 2005-2008 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.rhq.plugins.mobicents.servlet.sip; - -import java.io.File; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.regex.Pattern; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.mc4j.ems.connection.EmsConnection; -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.PropertySimple; -import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails; -import org.rhq.plugins.jbossas.EmbeddedWarDiscoveryComponent; -import org.rhq.plugins.jbossas.JBossASServerComponent; -import org.rhq.plugins.jbossas.util.WarDeploymentInformation; -import org.rhq.plugins.jmx.MBeanResourceComponent; - -/** - * Provides helper methods that are used by both {@link WarDiscoveryComponent} and {@link EmbeddedWarDiscoveryComponent} - * - * Original file copied over from jopr jboss as plugin trunk rev 26 - * It has been copied because it uses ConvergedDeploymentUtility and - * since methods in this class are static they couldn't be extended by inheritance - * - * @author Ian Springer - * @author Heiko W. Rupp - * @author Jean Deruelle - */ -public class ConvergedWarDiscoveryHelper { - private static final Log LOG = LogFactory.getLog(ConvergedWarDiscoveryHelper.class); - - public static final String JBOSS_WEB_MBEAN_NAME_TEMPLATE = "jboss.web:J2EEApplication=none,J2EEServer=none,j2eeType=WebModule,name=%name%"; - private static final String ROOT_WEBAPP_RT_LOG_FILE_NAME_BASE = "ROOT"; - private static final String RT_LOG_FILE_NAME_SUFFIX = "_rt.log"; - - // regex for web-services container-generated war filenames, - // e.g. rhq.ear-on-enterprise-server-ejb.ejb346088.war - private static final String WEB_SERVICES_EJB_WAR_FILE_NAME_REGEX = "\\.(ejb|jar)\\d+\\.war$"; - - // precompile the pattern for optimal performance - private static final Pattern WEB_SERVICES_EJB_WAR_FILE_NAME_PATTERN = Pattern - .compile(WEB_SERVICES_EJB_WAR_FILE_NAME_REGEX); - private static final String ROOT_WEBAPP_RESOURCE_NAME = "ROOT.war"; - - private ConvergedWarDiscoveryHelper() { - } - - public static Set initPluginConfigurations( - JBossASServerComponent parentJBossASComponent, Set warResources) { - - EmsConnection jmxConnection = parentJBossASComponent.getEmsConnection(); - File configPath = parentJBossASComponent.getConfigurationPath(); - File logDir = new File(configPath, "log"); - File rtLogDir = new File(logDir, "rt"); - - List objectNames = new ArrayList(); - - // Create a List of objectNames that will be passed to DeploymentUtility. - for (DiscoveredResourceDetails resourceDetails : warResources) { - Configuration warConfig = resourceDetails.getPluginConfiguration(); - PropertySimple objectNameProperty = warConfig.getSimple(MBeanResourceComponent.OBJECT_NAME_PROP); - objectNames.add(objectNameProperty.getStringValue()); - } - - Map> deploymentInformations = ConvergedDeploymentUtility - .getConvergedWarDeploymentInformation(jmxConnection, objectNames); - - Set resultingResources = new HashSet(); - - for (Iterator warResourcesIterator = warResources.iterator(); warResourcesIterator - .hasNext();) { - DiscoveredResourceDetails discoResDetail = warResourcesIterator.next(); - Configuration warConfig = discoResDetail.getPluginConfiguration(); - PropertySimple objectNameProperty = warConfig.getSimple(MBeanResourceComponent.OBJECT_NAME_PROP); - List deploymentInfoList = null; - - if (deploymentInformations != null) { - deploymentInfoList = deploymentInformations.get(objectNameProperty.getStringValue()); - } - - if (deploymentInfoList != null) { - /* - * Loop over the list elements and create new resources for all the vhosts - * that are not localhost. This is needed so that the majority of installed - * webapps will just be found with their existing key in case of an update. - */ - for (WarDeploymentInformation info : deploymentInfoList) { - String vhost = info.getVHost(); - LOG.debug("vHost " + vhost); - if ("localhost".equals(vhost)) { - initPluginConfiguration(info, rtLogDir, warResourcesIterator, discoResDetail); - resultingResources.add(discoResDetail); - } else { - DiscoveredResourceDetails myDetail; - String key = discoResDetail.getResourceKey(); - key += ",vhost=" + vhost; - - Configuration configClone; - try { - configClone = discoResDetail.getPluginConfiguration().clone(); - } catch (CloneNotSupportedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - configClone = new Configuration(); - } - - myDetail = new DiscoveredResourceDetails(discoResDetail.getResourceType(), key, discoResDetail - .getResourceName(), discoResDetail.getResourceVersion(), discoResDetail - .getResourceDescription() - + " on (" + vhost + ")", configClone, discoResDetail.getProcessInfo()); - - initPluginConfiguration(info, rtLogDir, warResourcesIterator, myDetail); - resultingResources.add(myDetail); // the cloned one - } - } - } else { - // WAR has no associated context root, so remove it from the list of discovered resources... - // @todo Might not want to call remove, because, as an example, in EC, the EC war file would end up being removed because this happens before it is completely deployed - warResourcesIterator.remove(); - - if (!discoResDetail.getResourceName().equals(ROOT_WEBAPP_RESOURCE_NAME)) { - LOG - .debug("The deployed WAR '" - + discoResDetail.getResourceName() - + "' does not have a jboss.web MBean (i.e. context root) associated with it; it will not be added to inventory."); - } - } - } - return resultingResources; - } - - public static void setDeploymentInformation(Configuration pluginConfig, - WarDeploymentInformation deploymentInformation) { - // JBNADM-3420 - These are being set incorrectly. Specifically, the incorrect file name is causing invalid - // file names on windows and thus breaking WAR updates. - pluginConfig.put(new PropertySimple(ConvergedWarComponent.FILE_NAME, deploymentInformation.getFileName())); - pluginConfig.put(new PropertySimple(ConvergedWarComponent.JBOSS_WEB_NAME, deploymentInformation - .getJbossWebModuleMBeanObjectName())); - pluginConfig.put(new PropertySimple(ConvergedWarComponent.CONTEXT_ROOT_CONFIG_PROP, deploymentInformation - .getContextRoot())); - pluginConfig.put(new PropertySimple(ConvergedWarComponent.VHOST_CONFIG_PROP, deploymentInformation.getVHost())); - } - - public static String getContextPath(String contextRoot) { - return ((contextRoot.equals(ConvergedWarComponent.ROOT_WEBAPP_CONTEXT_ROOT)) - ? "/" : "/" + contextRoot); - } - - private static void initPluginConfiguration(WarDeploymentInformation deploymentInformation, File rtLogDir, - Iterator warResourcesIterator, DiscoveredResourceDetails resource) { - Configuration pluginConfig = resource.getPluginConfiguration(); - String warFileName = resource.getResourceName(); - String contextRoot = deploymentInformation.getContextRoot(); - int length = contextRoot.length(); - if (length > 0 && (contextRoot.charAt(length - 1) == '.') // e.g. "//localhost/rhq-rhq-enterprise-server-ejb." - && WEB_SERVICES_EJB_WAR_FILE_NAME_PATTERN.matcher(warFileName).find()) { - // It's a web-services container-generated war - we don't want to auto-discover - // these, since they're not explicitly deployed by the user and their names change - // on every redeploy of the parent ear (see http://jira.jboss.com/jira/browse/JBNADM-2728). - // So remove it from the list of discovered resources and move on... - warResourcesIterator.remove(); - return; - } - - ConvergedWarDiscoveryHelper.setDeploymentInformation(pluginConfig, deploymentInformation); - - // Set the default value for the 'responseTimeLogFile' plugin config prop. - // We do it here because the filename is derived from the context root. - String rtLogFileNameBase = (contextRoot.equals(ConvergedWarComponent.ROOT_WEBAPP_CONTEXT_ROOT)) - ? ROOT_WEBAPP_RT_LOG_FILE_NAME_BASE : contextRoot; - String vHost = deploymentInformation.getVHost(); - if ("localhost".equals(vHost)) - vHost = ""; - else - vHost = vHost + "_"; - String rtLogFileName = vHost + rtLogFileNameBase + RT_LOG_FILE_NAME_SUFFIX; - File rtLogFile = new File(rtLogDir, rtLogFileName); - pluginConfig.put(new PropertySimple(ConvergedWarComponent.RESPONSE_TIME_LOG_FILE_CONFIG_PROP, rtLogFile)); - } -} \ No newline at end of file diff --git a/management/jopr-plugin/src/main/java/org/rhq/plugins/mobicents/servlet/sip/EmbeddedConvergedWarDiscoveryComponent.java b/management/jopr-plugin/src/main/java/org/rhq/plugins/mobicents/servlet/sip/EmbeddedConvergedWarDiscoveryComponent.java deleted file mode 100644 index b031f48f09..0000000000 --- a/management/jopr-plugin/src/main/java/org/rhq/plugins/mobicents/servlet/sip/EmbeddedConvergedWarDiscoveryComponent.java +++ /dev/null @@ -1,94 +0,0 @@ - /* - * Jopr Management Platform - * Copyright (C) 2005-2008 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation, and/or the GNU Lesser - * General Public License, version 2.1, also as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License and the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * and the GNU Lesser General Public License along with this program; - * if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.rhq.plugins.mobicents.servlet.sip; - -import java.util.HashSet; -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.PropertySimple; -import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails; -import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext; -import org.rhq.plugins.jbossas.JBossASServerComponent; -import org.rhq.plugins.jmx.MBeanResourceDiscoveryComponent; - -/** - * JON plugin discovery component for finding SAR/WARs that are nested inside of an EAR. - * - * Original file *NOT* copied over from jopr jboss as plugin trunk rev 26 because it was failing with a classcastexception - * - * - * @author Jean Deruelle - */ -public class EmbeddedConvergedWarDiscoveryComponent extends MBeanResourceDiscoveryComponent { - // ResourceDiscoveryComponent Implementation -------------------------------------------- - private static final Log log = LogFactory.getLog(EmbeddedConvergedWarDiscoveryComponent.class); - - @Override - public Set discoverResources(ResourceDiscoveryContext context) { - //discovering ear kind of app - Set resources = super.discoverResources(context); - - Set resourceDetails = new HashSet(); - log.debug("resources " + resources.size()); - //For each EAR app, try to discover if it contains a sip application (Manager will be of type SipManager) - for (DiscoveredResourceDetails discoveredResourceDetails : resources) { - // Generate object name based on the parent EAR with the following format. - // jboss.management.local:J2EEApplication=rhq.ear,J2EEServer=Local,j2eeType=WebModule,name=on-portal.war - JBossASServerComponent parentJBossASComponent = (JBossASServerComponent) context.getParentResourceComponent(); - -// ApplicationResourceComponent parentEarComponent = (ApplicationResourceComponent) context -// .getParentResourceComponent(); - String parentEar = discoveredResourceDetails.getResourceName(); - - String objectName = "jboss.management.local:J2EEApplication=" + parentEar - + ",J2EEServer=Local,j2eeType=WebModule,name=%name%"; - - log.debug("discoveredResourceDetails Object name to dicsover the converged sar/war embedded resource " + - objectName); - // Stuff the object name into the default plugin configuration to look like any other JMX discovery - // where the objectName is read from the default plugin configuration - Configuration defaultPluginConfiguration = context.getDefaultPluginConfiguration(); - defaultPluginConfiguration.put(new PropertySimple(MBeanResourceDiscoveryComponent.PROPERTY_OBJECT_NAME, - objectName)); - - // Call the base MBean discovery method to perform the actual discovery - resourceDetails = super.performDiscovery(defaultPluginConfiguration, - parentJBossASComponent, context.getResourceType()); - log.debug("resourceDetails size" + resourceDetails.size()); - resourceDetails = ConvergedWarDiscoveryHelper.initPluginConfigurations(parentJBossASComponent, resourceDetails); - log.debug("resourceDetails final size" + resourceDetails.size()); - // 2) Then the stuff specific to embedded WARs... -// String parentEarFullFileName = parentEarComponent.getFileName() + File.separator; -// for (DiscoveredResourceDetails resource : resourceDetails) { -// Configuration pluginConfiguration = resource.getPluginConfiguration(); -// pluginConfiguration.put(new PropertySimple(ConvergedWarComponent.FILE_NAME, parentEarFullFileName -// + resource.getResourceName())); -// } - } - - return resourceDetails; - } -} \ No newline at end of file diff --git a/management/jopr-plugin/src/main/resources/META-INF/rhq-plugin.xml b/management/jopr-plugin/src/main/resources/META-INF/rhq-plugin.xml deleted file mode 100644 index 01cb079ab8..0000000000 --- a/management/jopr-plugin/src/main/resources/META-INF/rhq-plugin.xml +++ /dev/null @@ -1,406 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pom.xml b/pom.xml index fed44b8648..775b6ee4f4 100644 --- a/pom.xml +++ b/pom.xml @@ -89,13 +89,15 @@ 1.0.0.FINAL - 1.2.287 - 1.15.26 - 2.0.41 - 1.5.31 - 1.3.23 - 1.0.134 + [1.3,1.4) + [1.15, 1.16) + [2.0, 2.1) + [1.5, 1.6) + [1.4, 1.5) + [2.0, 2.1) 7.0.64 + 3.1.0 + 1.5.5 UTF-8 @@ -410,7 +412,7 @@ containers/sip-servlets-as7-drop-in/jboss-as-mobicents containers/sip-servlets-as7-drop-in/build-restcomm-modules - + 1.0.0.Final 1.2.16 diff --git a/sip-servlets-application-router/.classpath b/sip-servlets-application-router/.classpath index f78b8f925d..b624c6ffea 100644 --- a/sip-servlets-application-router/.classpath +++ b/sip-servlets-application-router/.classpath @@ -1,5 +1,6 @@ + diff --git a/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/CongestionControlEvent.java b/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/CongestionControlEvent.java index ed47883722..1785f54955 100644 --- a/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/CongestionControlEvent.java +++ b/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/CongestionControlEvent.java @@ -22,39 +22,47 @@ package org.mobicents.javax.servlet; /** - * Defines a Congestion Control Event when the congestion control is triggered by the Container - * - * It allows to get the Reason whether the memory usage or CPU usage or any other condition in the future has triggered the callback - * + * Defines a Congestion Control Event when the congestion control is triggered + * by the Container + * + * It allows to get the Reason whether the memory usage or CPU usage or any + * other condition in the future has triggered the callback + * * @author jean.deruelle@gmail.com * */ -public class CongestionControlEvent { - public enum Reason { - Memory, Queue //, TODO add CPU Usage congestion control - } +public class CongestionControlEvent extends ContainerEvent { + + public enum Reason { + Memory, Queue //, TODO add CPU Usage congestion control + } + + Reason reason; + String message; + + public CongestionControlEvent(ContainerEventType eventType, Reason reason, String message) { + super(eventType); + this.reason = reason; + this.message = message; + } + + /** + * Gives the reason on whether the memory usage or CPU usage or any other + * condition in the future has triggered the callback + * + * @return the reason on whether the memory usage or CPU usage or any other + * condition in the future has triggered the callback + */ + public Reason getReason() { + return reason; + } - Reason reason; - String message; - - public CongestionControlEvent(Reason reason, String message) { - this.reason = reason; - this.message = message; - } - - /** - * Gives the reason on whether the memory usage or CPU usage or any other condition in the future has triggered the callback - * @return the reason on whether the memory usage or CPU usage or any other condition in the future has triggered the callback - */ - public Reason getReason() { - return reason; - } - - /** - * Gives the reason message on what exactly triggered the callback - * @return the reason message on what exactly triggered the callback - */ - public String getMessage() { - return message; - } + /** + * Gives the reason message on what exactly triggered the callback + * + * @return the reason message on what exactly triggered the callback + */ + public String getMessage() { + return message; + } } diff --git a/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/CongestionControlPolicy.java b/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/CongestionControlPolicy.java index d9dacd1588..3895b272b4 100644 --- a/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/CongestionControlPolicy.java +++ b/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/CongestionControlPolicy.java @@ -19,22 +19,24 @@ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ - package org.mobicents.javax.servlet; /** * Congestion Control Policy for the Mobicents Sip Servlets Server.
- * - * The congestion control policy defines how an incoming message is handled when the server is overloaded. The following parameters are configurable : - * + * + * The congestion control policy defines how an incoming message is handled when + * the server is overloaded. The following parameters are configurable : + * *

    *
  • DropMessage - drop any incoming message
  • - *
  • ErrorResponse - send a 503 - Service Unavailable response to any incoming request (Default).
  • + *
  • ErrorResponse - send a 503 - Service Unavailable response to any incoming + * request (Default).
  • *
+ * * @author jean.deruelle@gmail.com * */ public enum CongestionControlPolicy { - ErrorResponse, - DropMessage + ErrorResponse, + DropMessage } diff --git a/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/CongestionStartedEvent.java b/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/CongestionStartedEvent.java new file mode 100644 index 0000000000..30f422c60b --- /dev/null +++ b/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/CongestionStartedEvent.java @@ -0,0 +1,37 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat Middleware LLC, and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.javax.servlet; + +/** + * As soon as congestion starts in the underlying source, it notifies this event. + * + * Notification is only one-time till the congestion abates + * in which case CongestionStoppedEvent is notified + * + */ +public class CongestionStartedEvent extends CongestionControlEvent { + + public CongestionStartedEvent(Reason reason, String message) { + super(ContainerEventType.CONGESTION_STARTED, reason, message); + } + +} diff --git a/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/CongestionStoppedEvent.java b/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/CongestionStoppedEvent.java new file mode 100644 index 0000000000..5b0138822b --- /dev/null +++ b/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/CongestionStoppedEvent.java @@ -0,0 +1,37 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat Middleware LLC, and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.javax.servlet; + +/** + * As soon as congestion abates in the underlying source, it notifies this event. + * + * Notification is only one-time till the congestion starts + * again in which case CongestionStartedEvent is notified. + * + */ +public class CongestionStoppedEvent extends CongestionControlEvent { + + public CongestionStoppedEvent(Reason reason, String message) { + super(ContainerEventType.CONGESTION_STOPPED, reason, message); + } + +} diff --git a/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/ContainerEvent.java b/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/ContainerEvent.java new file mode 100644 index 0000000000..0a23d0a636 --- /dev/null +++ b/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/ContainerEvent.java @@ -0,0 +1,49 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat Middleware LLC, and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.javax.servlet; + +/** + * Defines base class of all ContainerListener Event classes + * + * + * @author jean.deruelle@gmail.com + * + */ +public class ContainerEvent { + + private final ContainerEventType eventType; + + public ContainerEvent(ContainerEventType eventType) { + this.eventType = eventType; + } + + /** + * returns the event type to allow event handlers to apply specific logic to + * each event type based in a type-safe enumeration. + * + * @return + */ + public ContainerEventType getEventType() { + return eventType; + } + +} diff --git a/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/ContainerEventType.java b/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/ContainerEventType.java new file mode 100644 index 0000000000..73cb79ac3d --- /dev/null +++ b/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/ContainerEventType.java @@ -0,0 +1,35 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat Middleware LLC, and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.javax.servlet; + +/** + * + * @author jean.deruelle@gmail.com + * + */ +public enum ContainerEventType { + CONGESTION_STARTED, + CONGESTION_STOPPED, + REQUEST_THROTTLED, + GRACEFUL_SHUTDOWN_STARTED, + GRACEFUL_SHUTDOWN_CHECK +} diff --git a/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/ContainerListener.java b/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/ContainerListener.java index 70e005d5d1..b8b3ff1b66 100644 --- a/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/ContainerListener.java +++ b/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/ContainerListener.java @@ -19,46 +19,20 @@ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ - package org.mobicents.javax.servlet; -import javax.servlet.sip.SipServletRequest; -import javax.servlet.sip.SipServletResponse; +import javax.servlet.ServletContext; /** - * Causes applications to be notified of various events occuring the Container. + * Causes applications to be notified of various events ocurring in the Container. */ -public interface ContainerListener extends java.util.EventListener{ - - /** - * As soon as congestion starts in the underlying source, it calls this - * method to notify about it. Notification is only one-time till the - * congestion abates in which case - * {@link CongestionListener#onCongestionControlStopped(CongestionEvent)} is called - * - * @param source - * The underlying source which is facing congestion - */ - public void onCongestionControlStarted(CongestionControlEvent event); +public interface ContainerListener extends java.util.EventListener { /** - * As soon as congestion abates in the underlying source, it calls this - * method to notify about it. Notification is only one-time till the - * congestion starts again in which case - * {@link CongestionListener#onCongestionStart(String)} is called - * - * @param source - * The underlying source - */ - public void onCongestionControlStopped(CongestionControlEvent event); - - /** - * When a request that comes in is not passed up to the application because of congestion control. * - * @param request the request that wasn't passed up to the application because of congestion control - * @param event giving details on what triggered the throttling - * @return a SipServletResponse that should be sent back to the originator of the request. If null, then - * the container will generate the response automatically + * @param event the event fired. + * @param ctx the ServletContext for this service allowing to check or modify the + * existing context. */ - public SipServletResponse onRequestThrottled(SipServletRequest request, CongestionControlEvent event); + public void sendEvent(ContainerEvent event, ServletContext ctx); } diff --git a/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/GracefulShutdownCheckEvent.java b/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/GracefulShutdownCheckEvent.java new file mode 100644 index 0000000000..5ac2acb608 --- /dev/null +++ b/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/GracefulShutdownCheckEvent.java @@ -0,0 +1,39 @@ +package org.mobicents.javax.servlet; + +/** + * During graceful shutdown period, the container will periodically query the + * service logic if a premature shutdown is possible. + * + * The service logic may implement specific service criteria to coordinate with + * container. The event will be only notified when the container identifies no + * more active sessions are handled for the particular application. + * + * + * The logic may indicate premature shutdown is not allowed by inserting an + * attribute in the ServletContext "org.mobicents.servlet.sip.PREVENT_PREMATURE_SHUTDOWN". + * If no attribute is put, then the container will shutdown the container right after + * the event notification. + * + * The frequency at which the container will notify the service logic maybe + * configured from server configuration. Check documentation on how to configure + * "graceful-interval". By default this frequency is 30000 milliseconds. + */ +public class GracefulShutdownCheckEvent extends GracefulShutdownEvent { + + private final long elapsedTime; + + public GracefulShutdownCheckEvent(long elapsedTime, long timeToWait) { + super(ContainerEventType.GRACEFUL_SHUTDOWN_CHECK, timeToWait); + this.elapsedTime = elapsedTime; + } + + /** + * + * @return elapsed time in milliseconds from the original time when graceful + * shutdown procedure was invoked. + */ + public long getElapsedTime() { + return elapsedTime; + } + +} diff --git a/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/GracefulShutdownEvent.java b/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/GracefulShutdownEvent.java new file mode 100644 index 0000000000..fd4dfdbc58 --- /dev/null +++ b/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/GracefulShutdownEvent.java @@ -0,0 +1,26 @@ +package org.mobicents.javax.servlet; + +/** + * Base class for GracefulShutodwn events. + * + * @author jaime + */ +public class GracefulShutdownEvent extends ContainerEvent { + + private final long timeToWait; + + public GracefulShutdownEvent(ContainerEventType eventType, long timeToWait) { + super(eventType); + this.timeToWait = timeToWait; + } + + /** + * + * @return the original TimeToWait used to invoke the graceful shutdown + * procedure in milliseconds. + */ + public long getTimeToWait() { + return timeToWait; + } + +} diff --git a/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/GracefulShutdownStartedEvent.java b/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/GracefulShutdownStartedEvent.java new file mode 100644 index 0000000000..b94d2dc780 --- /dev/null +++ b/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/GracefulShutdownStartedEvent.java @@ -0,0 +1,20 @@ +package org.mobicents.javax.servlet; + + +/** + * During graceful shutdown period, the container will notify the service logic + * the procedure has been started. + * + * + * Notification is only one-time till the different conditions are met to finally + * stop the container. + * + * + */ +public class GracefulShutdownStartedEvent extends GracefulShutdownEvent { + + public GracefulShutdownStartedEvent(long timeToWait) { + super(ContainerEventType.GRACEFUL_SHUTDOWN_STARTED, timeToWait); + } + +} diff --git a/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/RequestThrottledEvent.java b/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/RequestThrottledEvent.java new file mode 100644 index 0000000000..39ab11ec4d --- /dev/null +++ b/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/RequestThrottledEvent.java @@ -0,0 +1,66 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat Middleware LLC, and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.javax.servlet; + +import javax.servlet.sip.SipServletRequest; +import javax.servlet.sip.SipServletResponse; + +/** + * When a request that comes in is not passed up to the application because of + * congestion control. + * + * The event gives details on what triggered the throttling. + * + * The service logic may introduce a SipServletResponse that should be sent back to the originator of + * the request in the ServletContext as attribute. + * + * The attribute name should be "org.mobicents.servlet.sip.THROTTLED_RESPONSE". + * If null, then the container will generate the response + * automatically. + */ +public class RequestThrottledEvent extends CongestionControlEvent { + + private final SipServletRequest request; + private SipServletResponse response = null; + + public RequestThrottledEvent(SipServletRequest request, Reason reason, String message) { + super(ContainerEventType.REQUEST_THROTTLED, reason, message); + this.request = request; + } + + public SipServletResponse getResponse() { + return response; + } + + public void setResponse(SipServletResponse response) { + this.response = response; + } + + /** + * @return the request that wasn't passed up to the application because + * of congestion control + */ + public SipServletRequest getRequest() { + return request; + } + +} diff --git a/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/sip/SipFactoryExt.java b/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/sip/SipFactoryExt.java index 3341d7a8e2..e99ccef192 100644 --- a/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/sip/SipFactoryExt.java +++ b/sip-servlets-client/src/main/java/org/mobicents/javax/servlet/sip/SipFactoryExt.java @@ -19,8 +19,12 @@ package org.mobicents.javax.servlet.sip; +import javax.servlet.sip.Address; +import javax.servlet.sip.ServletParseException; import javax.servlet.sip.SipApplicationSession; import javax.servlet.sip.SipFactory; +import javax.servlet.sip.SipServletRequest; +import javax.servlet.sip.URI; /** * Interface Extension that adds extra features to the JSR 289 SipFactory interface to allow proxying of orphaned requests.
@@ -87,4 +91,53 @@ public interface SipFactoryExt extends SipFactory { * @since 7.0.2 */ SipApplicationSession createApplicationSessionByKey(java.lang.String sipApplicationKey, boolean isContainerManaged); + + + /** + * Extension variant to the spec allowing to specify CallID. + * + * This method requires org.restcomm.servlets.sip.OVERRIDE_SYSTEM_HEADER_MODIFICATION + * param to be set at web/sip.xml descriptor. Value "Modifiable" + * + * @param appSession + * @param method + * @param from + * @param to + * @param callID If null, the container will autogenerate the callId as usual + * @return + */ + public SipServletRequest createRequestWithCallID(SipApplicationSession appSession, + String method, Address from, Address to, String callID); + + /** + * Extension variant to the spec allowing to specify CallID + * + * This method requires org.restcomm.servlets.sip.OVERRIDE_SYSTEM_HEADER_MODIFICATION + * param to be set at web/sip.xml descriptor. Value "Modifiable" + * + * @param appSession + * @param method + * @param from + * @param to + * @param callID If null, the container will autogenerate the callId as usual + * @return + */ + public SipServletRequest createRequestWithCallID(SipApplicationSession appSession, + String method, String from, String to, String callID) throws ServletParseException; + + /** + * Extension variant to the spec allowing to specify CallID + * + * This method requires org.restcomm.servlets.sip.OVERRIDE_SYSTEM_HEADER_MODIFICATION + * param to be set at web/sip.xml descriptor. Value "Modifiable" + * + * @param appSession + * @param method + * @param from + * @param to + * @param callID If null, the container will autogenerate the callId as usual + * @return + */ + public SipServletRequest createRequestWithCallID(SipApplicationSession appSession, + String method, URI from, URI to, String callID); } diff --git a/sip-servlets-client/src/main/java/org/mobicents/servlet/sip/SipConnector.java b/sip-servlets-client/src/main/java/org/mobicents/servlet/sip/SipConnector.java index 326f639be1..8a459e9e41 100644 --- a/sip-servlets-client/src/main/java/org/mobicents/servlet/sip/SipConnector.java +++ b/sip-servlets-client/src/main/java/org/mobicents/servlet/sip/SipConnector.java @@ -1,28 +1,26 @@ /* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, Telestax Inc and individual contributors + * by the @authors tag. * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * - * This software is distributed in the hope that it will be useful, + * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see */ package org.mobicents.servlet.sip; import java.io.Serializable; +import java.util.Properties; import java.util.Set; import javax.management.MBeanServer; @@ -32,7 +30,7 @@ import org.apache.log4j.Logger; /** - * Represents a Mobicents Sip Servlets SIP connector and its various attributes + * Represents a Restcomm Sip Servlets SIP connector and its various attributes * * @author jean.deruelle@gmail.com * @@ -87,6 +85,12 @@ public class SipConnector implements Serializable { private String loadBalancerAddress; private int loadBalancerRmiPort; private int loadBalancerSipPort; + // https://github.com/RestComm/sip-servlets/issues/172 + private Properties loadBalancerCustomInformation; + + public SipConnector() { + loadBalancerCustomInformation = new Properties(); + } /** * @return the Transport @@ -432,4 +436,19 @@ public int getLoadBalancerSipPort() { public void setLoadBalancerSipPort(int loadBalancerSipPort) { this.loadBalancerSipPort = loadBalancerSipPort; } + + /** + * @return the loadBalancerCustomInformation + */ + public Properties getLoadBalancerCustomInformation() { + return loadBalancerCustomInformation; + } + + /** + * @param loadBalancerCustomInformation the loadBalancerCustomInformation to set + */ + public void setLoadBalancerCustomInformation( + Properties loadBalancerCustomInformation) { + this.loadBalancerCustomInformation = loadBalancerCustomInformation; + } } diff --git a/sip-servlets-core-api/.classpath b/sip-servlets-core-api/.classpath index f27b8516ac..9da1a633d7 100644 --- a/sip-servlets-core-api/.classpath +++ b/sip-servlets-core-api/.classpath @@ -3,15 +3,20 @@ - - + + - - + + + + + + + - \ No newline at end of file + diff --git a/sip-servlets-core-api/src/main/java/org/mobicents/servlet/sip/core/SipApplicationDispatcher.java b/sip-servlets-core-api/src/main/java/org/mobicents/servlet/sip/core/SipApplicationDispatcher.java index 796d076010..350f6d7682 100644 --- a/sip-servlets-core-api/src/main/java/org/mobicents/servlet/sip/core/SipApplicationDispatcher.java +++ b/sip-servlets-core-api/src/main/java/org/mobicents/servlet/sip/core/SipApplicationDispatcher.java @@ -1,277 +1,286 @@ -/* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2014, Telestax Inc and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - */ - -package org.mobicents.servlet.sip.core; - -import gov.nist.javax.sip.SipListenerExt; - -import java.io.Serializable; -import java.text.ParseException; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.atomic.AtomicLong; - -import javax.servlet.sip.SipURI; -import javax.servlet.sip.ar.SipApplicationRouter; -import javax.servlet.sip.ar.SipApplicationRouterInfo; -import javax.sip.SipStack; -import javax.sip.header.CallIdHeader; -import javax.sip.header.RouteHeader; -import javax.sip.header.ViaHeader; -import javax.sip.message.Request; -import javax.sip.message.Response; - -import org.mobicents.ext.javax.sip.dns.DNSServerLocator; -import org.mobicents.javax.servlet.CongestionControlPolicy; -import org.mobicents.javax.servlet.sip.dns.DNSResolver; -import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; -import org.mobicents.servlet.sip.core.message.MobicentsSipServletRequest; - -/** - * - * Classes implementing this interface can be used in the SipService Class to - * be the central point getting the sip messages from the different stacks and - * dispatching them to sip applications. - */ -public interface SipApplicationDispatcher extends SipListenerExt { - /** - * Initialize the sip application dispatcher.
- * It will look for the first implementation of an application routerand - * packaged in accordance with the rules specified by the Java SE Service Provider framework.
- * It will first look for the javax.servlet.sip.ar.spi.SipApplicationRouterProvider system property - * since it can be used to override loading behavior. - * See JSR 289 Section 15.4.2 Application Router Packaging and Deployment for more information - * - * @throws LifecycleException The Sip Application Router cannot be initialized correctly - */ - void init(); - - /** - * Start the sip application dispatcher - */ - void start(); - - /** - * Stop the sip application dispatcher - */ - void stop(); - - /** - * Stop the Server GraceFully, ie the server will stop only when all applications - * will have no outstanding SIP or HTTP Sessions - * @param timeToWait - the container will wait for the time specified in this parameter before forcefully killing - * the remaining sessions (HTTP and SIP) for each application deployed, if a negative value is provided the container - * will wait until there is no remaining Session before shutting down - */ - public void stopGracefully(long timeToWait); - - /** - * Add a new sip application to which sip messages can be routed - * @param sipApplicationName the sip application logical name - * @param sipApplication the sip context representing the application - */ - void addSipApplication(String sipApplicationName, SipContext sipApplication); - /** - * Remove a sip application to which sip messages can be routed - * @param sipApplicationName the sip application logical name of the application to remove - */ - SipContext removeSipApplication(String sipApplicationName); - - /** - * Find the sip applications to which sip messages can currently be routed - * @return the sip applications to which sip messages can currently be routed - */ - Iterator findSipApplications(); - - /** - * Find the sip application to which sip messages can currently be routed by its name - * @param applicationName the name of the application - * @return the sip application to which sip messages can currently be routed by its name - * if it has been find, null otherwise - */ - SipContext findSipApplication(String applicationName); - - /** - * Retrieve the manager for the sip network interfaces for this application dispatcher - * @return the manager for the sip network interfaces for this application dispatcher - */ - SipNetworkInterfaceManager getSipNetworkInterfaceManager(); - - /** - * retrieve the sip factory - * @return the sip factory - */ - MobicentsSipFactory getSipFactory(); - /** - * Returns An immutable instance of the java.util.List interface containing - * the SipURI representation of IP addresses which are used by the container to send out the messages. - * @return immutable List containing the SipURI representation of IP addresses - */ - List getOutboundInterfaces(); - /** - * Add a new hostname to the application dispatcher. - * This information is used for the routing algorithm of an incoming Request. - * @param hostName the host name - */ - void addHostName(String hostName); - /** - * Remove the hostname from the application dispatcher. - * This information is used for the routing algorithm of an incoming Request. - * @param hostName the host name - */ - void removeHostName(String hostName); - /** - * Returns An immutable instance of the java.util.List interface containing - * the sip application dispatcher registered host names - * @return An immutable instance of the java.util.List interface containing - * the sip application dispatcher registered host names - */ - Set findHostNames(); - - /** - * - * @param sipServletRequestImpl - * @return - */ - SipApplicationRouterInfo getNextInterestedApplication(MobicentsSipServletRequest sipServletRequestImpl); - - String getDomain(); - - void setDomain(String domain); - - boolean isRouteExternal(RouteHeader routeHeader); - - boolean isViaHeaderExternal(ViaHeader viaHeader); - - boolean isExternal(String host, int port, String transport); - - SipApplicationRouter getSipApplicationRouter(); - - // should be in a seperate HA interface, but this may become deprecated in the future - void sendSwitchoverInstruction(String fromJvmRoute, String toJvmRoute); - // tell the application Disptacher to shutdown gracefully - void setGracefulShutdown(boolean shuttingDownGracefully); - - String getApplicationNameFromHash(String hash); - String getHashFromApplicationName(String appName); - - ConcurrencyControlMode getConcurrencyControlMode(); - String getConcurrencyControlModeByName(); - void setConcurrencyControlMode(ConcurrencyControlMode concurrencyControlMode); - void setConcurrencyControlModeByName(String concurrencyControlMode); - - int getQueueSize(); - void setQueueSize(int queueSize); - - void setMemoryThreshold(int memoryThreshold); - int getMemoryThreshold(); - - void setCongestionControlCheckingInterval(long interval); - long getCongestionControlCheckingInterval(); - - CongestionControlPolicy getCongestionControlPolicy(); - void setCongestionControlPolicy(CongestionControlPolicy congestionControlPolicy); - String getCongestionControlPolicyByName(); - void setCongestionControlPolicyByName(String congestionControlPolicy); - - int getNumberOfMessagesInQueue(); - double getPercentageOfMemoryUsed(); - - void setBypassRequestExecutor(boolean bypassRequestExecutor); - boolean isBypassRequestExecutor(); - - void setBypassResponseExecutor(boolean bypassResponseExecutor); - boolean isBypassResponseExecutor(); - - void setBaseTimerInterval(int baseTimerInterval); - int getBaseTimerInterval(); - void setT2Interval(int t2Interval); - int getT2Interval(); - void setT4Interval(int t4Interval); - int getT4Interval(); - void setTimerDInterval(int timerDInterval); - int getTimerDInterval(); - - String[] getExtensionsSupported(); - String[] getRfcSupported(); - - public Map getRequestsProcessedByMethod(); - public Map getResponsesProcessedByStatusCode(); - long getRequestsProcessedByMethod(String method); - long getResponsesProcessedByStatusCode(String statusCode); - // https://github.com/Mobicents/sip-servlets/issues/65 - public Map getRequestsSentByMethod(); - public Map getResponsesSentByStatusCode(); - long getRequestsSentByMethod(String method); - long getResponsesSentByStatusCode(String statusCode); - - /** - * reset all stats counter to initial value. - */ - void resetStatsCounters(); - - void setGatherStatistics(boolean gatherStatistics); - boolean isGatherStatistics(); - - void updateResponseStatistics(final Response response, final boolean processed); - void updateRequestsStatistics(final Request request, final boolean processed); - - void setBackToNormalMemoryThreshold( - int backToNormalMemoryThreshold); - int getBackToNormalMemoryThreshold(); - - void setBackToNormalQueueSize(int backToNormalQueueSize); - int getBackToNormalQueueSize(); - - ExecutorService getAsynchronousExecutor(); - ScheduledExecutorService getAsynchronousScheduledExecutor(); - - void setSipStack(SipStack sipStack); - SipStack getSipStack(); - - void setDNSServerLocator(DNSServerLocator dnsServerLocator); - DNSServerLocator getDNSServerLocator(); - void setDNSTimeout(int dnsTiemout); - int getDNSTimeout(); - - DNSResolver getDNSResolver(); - - String getVersion(); - - public Map> getApplicationRouterConfiguration(); - public Object retrieveApplicationRouterConfiguration(); - public void updateApplicationRouterConfiguration(Object configuration); - public Serializable retrieveApplicationRouterConfigurationString(); - public void updateApplicationRouterConfiguration(Serializable configuration); - - public String[] findInstalledSipApplications(); - - public SipService getSipService(); - public void setSipService(SipService sipService); - - String getApplicationServerId(); - String getApplicationServerIdHash(); - - int getTagHashMaxLength(); - CallIdHeader getCallId(MobicentsExtendedListeningPoint extendedListeningPoint, String callId) throws ParseException; -} +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2014, Telestax Inc and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + */ + +package org.mobicents.servlet.sip.core; + +import gov.nist.javax.sip.SipListenerExt; + +import java.io.Serializable; +import java.text.ParseException; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.atomic.AtomicLong; + +import javax.servlet.sip.SipURI; +import javax.servlet.sip.ar.SipApplicationRouter; +import javax.servlet.sip.ar.SipApplicationRouterInfo; +import javax.sip.SipStack; +import javax.sip.header.CallIdHeader; +import javax.sip.header.RouteHeader; +import javax.sip.header.ViaHeader; +import javax.sip.message.Request; +import javax.sip.message.Response; + +import org.mobicents.ext.javax.sip.dns.DNSServerLocator; +import org.mobicents.javax.servlet.CongestionControlPolicy; +import org.mobicents.javax.servlet.sip.dns.DNSResolver; +import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; +import org.mobicents.servlet.sip.core.message.MobicentsSipServletRequest; + +/** + * + * Classes implementing this interface can be used in the SipService Class to + * be the central point getting the sip messages from the different stacks and + * dispatching them to sip applications. + */ +public interface SipApplicationDispatcher extends SipListenerExt { + /** + * Initialize the sip application dispatcher.
+ * It will look for the first implementation of an application routerand + * packaged in accordance with the rules specified by the Java SE Service Provider framework.
+ * It will first look for the javax.servlet.sip.ar.spi.SipApplicationRouterProvider system property + * since it can be used to override loading behavior. + * See JSR 289 Section 15.4.2 Application Router Packaging and Deployment for more information + * + * @throws LifecycleException The Sip Application Router cannot be initialized correctly + */ + void init(); + + /** + * once in service apps will be notified of servletInitialized + */ + public void putInService() throws IllegalArgumentException; + + /** + * Start the sip application dispatcher + */ + void start(); + + /** + * Stop the sip application dispatcher + */ + void stop(); + + /** + * Stop the Server GraceFully, ie the server will stop only when all applications + * will have no outstanding SIP or HTTP Sessions + * @param timeToWait - the container will wait for the time specified in this parameter before forcefully killing + * the remaining sessions (HTTP and SIP) for each application deployed, if a negative value is provided the container + * will wait until there is no remaining Session before shutting down + */ + public void stopGracefully(long timeToWait); + + /** + * Add a new sip application to which sip messages can be routed + * @param sipApplicationName the sip application logical name + * @param sipApplication the sip context representing the application + */ + void addSipApplication(String sipApplicationName, SipContext sipApplication); + /** + * Remove a sip application to which sip messages can be routed + * @param sipApplicationName the sip application logical name of the application to remove + */ + SipContext removeSipApplication(String sipApplicationName); + + /** + * Find the sip applications to which sip messages can currently be routed + * @return the sip applications to which sip messages can currently be routed + */ + Iterator findSipApplications(); + + /** + * Find the sip application to which sip messages can currently be routed by its name + * @param applicationName the name of the application + * @return the sip application to which sip messages can currently be routed by its name + * if it has been find, null otherwise + */ + SipContext findSipApplication(String applicationName); + + /** + * Retrieve the manager for the sip network interfaces for this application dispatcher + * @return the manager for the sip network interfaces for this application dispatcher + */ + SipNetworkInterfaceManager getSipNetworkInterfaceManager(); + + /** + * retrieve the sip factory + * @return the sip factory + */ + MobicentsSipFactory getSipFactory(); + /** + * Returns An immutable instance of the java.util.List interface containing + * the SipURI representation of IP addresses which are used by the container to send out the messages. + * @return immutable List containing the SipURI representation of IP addresses + */ + List getOutboundInterfaces(); + /** + * Add a new hostname to the application dispatcher. + * This information is used for the routing algorithm of an incoming Request. + * @param hostName the host name + */ + void addHostName(String hostName); + /** + * Remove the hostname from the application dispatcher. + * This information is used for the routing algorithm of an incoming Request. + * @param hostName the host name + */ + void removeHostName(String hostName); + /** + * Returns An immutable instance of the java.util.List interface containing + * the sip application dispatcher registered host names + * @return An immutable instance of the java.util.List interface containing + * the sip application dispatcher registered host names + */ + Set findHostNames(); + + /** + * + * @param sipServletRequestImpl + * @return + */ + SipApplicationRouterInfo getNextInterestedApplication(MobicentsSipServletRequest sipServletRequestImpl); + + String getDomain(); + + void setDomain(String domain); + + boolean isRouteExternal(RouteHeader routeHeader); + + boolean isViaHeaderExternal(ViaHeader viaHeader); + + boolean isExternal(String host, int port, String transport); + + SipApplicationRouter getSipApplicationRouter(); + + // should be in a seperate HA interface, but this may become deprecated in the future + void sendSwitchoverInstruction(String fromJvmRoute, String toJvmRoute); + // tell the application Disptacher to shutdown gracefully + void setGracefulShutdown(boolean shuttingDownGracefully); + + String getApplicationNameFromHash(String hash); + String getHashFromApplicationName(String appName); + + ConcurrencyControlMode getConcurrencyControlMode(); + String getConcurrencyControlModeByName(); + void setConcurrencyControlMode(ConcurrencyControlMode concurrencyControlMode); + void setConcurrencyControlModeByName(String concurrencyControlMode); + + int getQueueSize(); + void setQueueSize(int queueSize); + + void setMemoryThreshold(int memoryThreshold); + int getMemoryThreshold(); + + void setCongestionControlCheckingInterval(long interval); + long getCongestionControlCheckingInterval(); + + CongestionControlPolicy getCongestionControlPolicy(); + void setCongestionControlPolicy(CongestionControlPolicy congestionControlPolicy); + String getCongestionControlPolicyByName(); + void setCongestionControlPolicyByName(String congestionControlPolicy); + + int getNumberOfMessagesInQueue(); + double getPercentageOfMemoryUsed(); + + void setBypassRequestExecutor(boolean bypassRequestExecutor); + boolean isBypassRequestExecutor(); + + void setBypassResponseExecutor(boolean bypassResponseExecutor); + boolean isBypassResponseExecutor(); + + void setBaseTimerInterval(int baseTimerInterval); + int getBaseTimerInterval(); + void setT2Interval(int t2Interval); + int getT2Interval(); + void setT4Interval(int t4Interval); + int getT4Interval(); + void setTimerDInterval(int timerDInterval); + int getTimerDInterval(); + + String[] getExtensionsSupported(); + String[] getRfcSupported(); + + public Map getRequestsProcessedByMethod(); + public Map getResponsesProcessedByStatusCode(); + long getRequestsProcessedByMethod(String method); + long getResponsesProcessedByStatusCode(String statusCode); + // https://telestax.atlassian.net/browse/MSS-74 + public Map getRequestsSentByMethod(); + public Map getResponsesSentByStatusCode(); + long getRequestsSentByMethod(String method); + long getResponsesSentByStatusCode(String statusCode); + + /** + * reset all stats counter to initial value. + */ + void resetStatsCounters(); + + void setGatherStatistics(boolean gatherStatistics); + boolean isGatherStatistics(); + + void updateResponseStatistics(final Response response, final boolean processed); + void updateRequestsStatistics(final Request request, final boolean processed); + + void incCalls(); + void incMessages(); + void incSeconds(long seconds); + + void setBackToNormalMemoryThreshold( + int backToNormalMemoryThreshold); + int getBackToNormalMemoryThreshold(); + + void setBackToNormalQueueSize(int backToNormalQueueSize); + int getBackToNormalQueueSize(); + + ExecutorService getAsynchronousExecutor(); + ScheduledExecutorService getAsynchronousScheduledExecutor(); + + void setSipStack(SipStack sipStack); + SipStack getSipStack(); + + void setDNSServerLocator(DNSServerLocator dnsServerLocator); + DNSServerLocator getDNSServerLocator(); + void setDNSTimeout(int dnsTiemout); + int getDNSTimeout(); + + DNSResolver getDNSResolver(); + + String getVersion(); + + public Map> getApplicationRouterConfiguration(); + public Object retrieveApplicationRouterConfiguration(); + public void updateApplicationRouterConfiguration(Object configuration); + public Serializable retrieveApplicationRouterConfigurationString(); + public void updateApplicationRouterConfiguration(Serializable configuration); + + public String[] findInstalledSipApplications(); + + public SipService getSipService(); + public void setSipService(SipService sipService); + + String getApplicationServerId(); + String getApplicationServerIdHash(); + + int getTagHashMaxLength(); + CallIdHeader getCallId(MobicentsExtendedListeningPoint extendedListeningPoint, String callId) throws ParseException; +} diff --git a/sip-servlets-core-api/src/main/java/org/mobicents/servlet/sip/core/SipContext.java b/sip-servlets-core-api/src/main/java/org/mobicents/servlet/sip/core/SipContext.java index 2e184b8881..0e9652f2fb 100644 --- a/sip-servlets-core-api/src/main/java/org/mobicents/servlet/sip/core/SipContext.java +++ b/sip-servlets-core-api/src/main/java/org/mobicents/servlet/sip/core/SipContext.java @@ -1,189 +1,197 @@ -/* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2014, Telestax Inc and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - */ - -package org.mobicents.servlet.sip.core; - -import java.lang.reflect.Method; -import java.util.List; -import java.util.Map; - -import javax.servlet.ServletContext; -import javax.servlet.sip.SipFactory; -import javax.servlet.sip.SipServletRequest; -import javax.servlet.sip.TimerService; - -import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; -import org.mobicents.servlet.sip.core.descriptor.MobicentsSipServletMapping; -import org.mobicents.servlet.sip.core.message.MobicentsSipServletRequest; -import org.mobicents.servlet.sip.core.message.MobicentsSipServletResponse; -import org.mobicents.servlet.sip.core.security.MobicentsSipLoginConfig; -import org.mobicents.servlet.sip.core.security.SipDigestAuthenticator; -import org.mobicents.servlet.sip.core.session.MobicentsSipApplicationSession; -import org.mobicents.servlet.sip.core.session.MobicentsSipSession; -import org.mobicents.servlet.sip.core.session.MobicentsSipSessionsUtil; -import org.mobicents.servlet.sip.core.timers.ProxyTimerService; -import org.mobicents.servlet.sip.core.timers.SipApplicationSessionTimerService; -import org.mobicents.servlet.sip.ruby.SipRubyController; - -/** - * A SipContext is a Container that represents a sip/converged servlet context, and - * therefore an individual sip/converged application, in the Catalina servlet engine. - * - *

- * This is used to by example extends Tomcat Context interface to allow sip capabilities to be used on Tomcat deployed applications. - *

- * - * @author Jean Deruelle - */ -public interface SipContext { - - public static final String APPLICATION_SIP_XML = "WEB-INF/sip.xml"; - - public static final String LOAD_BALANCER = "org.mobicents.servlet.sip.LoadBalancer"; - - String getApplicationName(); - String getApplicationNameHashed(); - - boolean hasDistributableManager(); - - void setApplicationName(String applicationName); - - String getDescription(); - - void setDescription(String description); - - String getLargeIcon(); - - void setLargeIcon(String largeIcon); - - SipListeners getListeners(); - - void setListeners(SipListeners listeners); - - boolean isMainServlet(); - - String getMainServlet(); - - void setMainServlet(String mainServlet); - - void setServletHandler(String servletHandler); - String getServletHandler(); - - int getProxyTimeout(); - - void setProxyTimeout(int proxyTimeout); - - int getSipApplicationSessionTimeout(); - - void setSipApplicationSessionTimeout(int proxyTimeout); - - String getSmallIcon(); - - void setSmallIcon(String smallIcon); - - void addSipApplicationListener(String listener); - - void removeSipApplicationListener(String listener); - - String[] findSipApplicationListeners(); - - Method getSipApplicationKeyMethod(); - - void setSipApplicationKeyMethod(Method sipApplicationKeyMethod); - - void setSipLoginConfig(MobicentsSipLoginConfig config); - - MobicentsSipLoginConfig getSipLoginConfig(); - - void addSipServletMapping(MobicentsSipServletMapping sipServletMapping); - - void removeSipServletMapping(MobicentsSipServletMapping sipServletMapping); - - List findSipServletMappings(); - - MobicentsSipServletMapping findSipServletMappings(SipServletRequest sipServletRequest); - - SipManager getSipManager(); - - SipApplicationDispatcher getSipApplicationDispatcher(); - - String getEngineName(); - - boolean notifySipContextListeners(SipContextEvent event); - - /** - * notify the application that we are going to access it with the sipapplicationsession and sip session in parameter and tells whether or not to check - * if we are in a managed thread to check if we should lock the session or not - * @param sipApplicationSession the sip application session that is accessing the application, it can be null - * @param sipSession the sip session that is accessing the application, it can be null - * @param checkIsManagedThread need to check if the access is done within a managed Thread or not to lock or not the session depending on the concurrency control - */ - void enterSipApp(MobicentsSipApplicationSession sipApplicationSession, MobicentsSipSession sipSession, boolean checkIsManagedThread, boolean isContainerManaged); - /** - * notify the application that we are going to exit it with the sipapplicationsession and sip session in parameter - * @param sipApplicationSession the sip application session that is exiting the application, it can be null - * @param sipSession the sip session that is exiting the application, it can be null - * - */ - void exitSipApp(MobicentsSipApplicationSession sipApplicationSession, MobicentsSipSession sipSession); - - //Issue http://code.google.com/p/mobicents/issues/detail?id=2452 - // Returning boolean vlaue and new parameter batchStarted to decide whether or not to end the batch - boolean enterSipAppHa(boolean startCacheActivity); - void exitSipAppHa(MobicentsSipServletRequest request, MobicentsSipServletResponse response, boolean batchStarted); - - SipFactory getSipFactoryFacade(); - - MobicentsSipSessionsUtil getSipSessionsUtil(); - - TimerService getTimerService(); - ProxyTimerService getProxyTimerService(); - SipApplicationSessionTimerService getSipApplicationSessionTimerService(); - - void setConcurrencyControlMode(ConcurrencyControlMode mode); - ConcurrencyControlMode getConcurrencyControlMode(); - - void setSipRubyController(SipRubyController rubyController); - SipRubyController getSipRubyController(); - - ServletContext getServletContext(); - String getPath(); - MobicentsSipServlet findSipServletByClassName(String canonicalName); - MobicentsSipServlet findSipServletByName(String name); - - ClassLoader getSipContextClassLoader(); - Map getChildrenMap(); - - boolean isPackageProtectionEnabled(); - - boolean authorize(MobicentsSipServletRequest request); - SipDigestAuthenticator getDigestAuthenticator(); - - // http://code.google.com/p/sipservlets/issues/detail?id=135 - void enterSipContext(); - void exitSipContext(ClassLoader oldClassLoader); - /** - * Stop the Context GraceFully, ie the context will stop only when there is no outstanding SIP or HTTP Sessions - * @param timeToWait - the context will wait for the time specified in this parameter before forcefully killing - * the remaining sessions (HTTP and SIP) for each application deployed, if a negative value is provided the context - * will wait until there is no remaining Session before shutting down - */ - void stopGracefully(long timeToWait); - boolean isStoppingGracefully(); -} +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2014, Telestax Inc and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + */ + +package org.mobicents.servlet.sip.core; + +import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; + +import javax.servlet.ServletContext; +import javax.servlet.sip.SipFactory; +import javax.servlet.sip.SipServletRequest; +import javax.servlet.sip.TimerService; + +import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; +import org.mobicents.servlet.sip.core.descriptor.MobicentsSipServletMapping; +import org.mobicents.servlet.sip.core.message.MobicentsSipServletRequest; +import org.mobicents.servlet.sip.core.message.MobicentsSipServletResponse; +import org.mobicents.servlet.sip.core.security.MobicentsSipLoginConfig; +import org.mobicents.servlet.sip.core.security.SipDigestAuthenticator; +import org.mobicents.servlet.sip.core.session.MobicentsSipApplicationSession; +import org.mobicents.servlet.sip.core.session.MobicentsSipSession; +import org.mobicents.servlet.sip.core.session.MobicentsSipSessionsUtil; +import org.mobicents.servlet.sip.core.timers.ProxyTimerService; +import org.mobicents.servlet.sip.core.timers.SipApplicationSessionTimerService; +import org.mobicents.servlet.sip.ruby.SipRubyController; + +/** + * A SipContext is a Container that represents a sip/converged servlet context, and + * therefore an individual sip/converged application, in the Catalina servlet engine. + * + *

+ * This is used to by example extends Tomcat Context interface to allow sip capabilities to be used on Tomcat deployed applications. + *

+ * + * @author Jean Deruelle + */ +public interface SipContext { + + public static final String APPLICATION_SIP_XML = "WEB-INF/sip.xml"; + + public static final String LOAD_BALANCER = "org.mobicents.servlet.sip.LoadBalancer"; + + /** + * This prefix will be used to name internal session attributes, or context + * params that are specially managed by the container. + */ + public static final String INTERNAL_ATT_PREFIX = "org.restcomm.servlets.sip"; + + String getApplicationName(); + String getApplicationNameHashed(); + + boolean hasDistributableManager(); + + void setApplicationName(String applicationName); + + String getDescription(); + + void setDescription(String description); + + String getLargeIcon(); + + void setLargeIcon(String largeIcon); + + SipListeners getListeners(); + + void setListeners(SipListeners listeners); + + boolean isMainServlet(); + + String getMainServlet(); + + void setMainServlet(String mainServlet); + + void setServletHandler(String servletHandler); + String getServletHandler(); + + int getProxyTimeout(); + + void setProxyTimeout(int proxyTimeout); + + int getSipApplicationSessionTimeout(); + + void setSipApplicationSessionTimeout(int proxyTimeout); + + String getSmallIcon(); + + void setSmallIcon(String smallIcon); + + void addSipApplicationListener(String listener); + + void removeSipApplicationListener(String listener); + + String[] findSipApplicationListeners(); + + Method getSipApplicationKeyMethod(); + + void setSipApplicationKeyMethod(Method sipApplicationKeyMethod); + + void setSipLoginConfig(MobicentsSipLoginConfig config); + + MobicentsSipLoginConfig getSipLoginConfig(); + + void addSipServletMapping(MobicentsSipServletMapping sipServletMapping); + + void removeSipServletMapping(MobicentsSipServletMapping sipServletMapping); + + List findSipServletMappings(); + + MobicentsSipServletMapping findSipServletMappings(SipServletRequest sipServletRequest); + + SipManager getSipManager(); + + SipApplicationDispatcher getSipApplicationDispatcher(); + + String getEngineName(); + + boolean notifySipContextListeners(SipContextEvent event); + + /** + * notify the application that we are going to access it with the sipapplicationsession and sip session in parameter and tells whether or not to check + * if we are in a managed thread to check if we should lock the session or not + * @param sipApplicationSession the sip application session that is accessing the application, it can be null + * @param sipSession the sip session that is accessing the application, it can be null + * @param checkIsManagedThread need to check if the access is done within a managed Thread or not to lock or not the session depending on the concurrency control + */ + void enterSipApp(MobicentsSipApplicationSession sipApplicationSession, MobicentsSipSession sipSession, boolean checkIsManagedThread, boolean isContainerManaged); + /** + * notify the application that we are going to exit it with the sipapplicationsession and sip session in parameter + * @param sipApplicationSession the sip application session that is exiting the application, it can be null + * @param sipSession the sip session that is exiting the application, it can be null + * + */ + void exitSipApp(MobicentsSipApplicationSession sipApplicationSession, MobicentsSipSession sipSession); + + //Issue http://code.google.com/p/mobicents/issues/detail?id=2452 + // Returning boolean vlaue and new parameter batchStarted to decide whether or not to end the batch + boolean enterSipAppHa(boolean startCacheActivity); + void exitSipAppHa(MobicentsSipServletRequest request, MobicentsSipServletResponse response, boolean batchStarted); + + SipFactory getSipFactoryFacade(); + + MobicentsSipSessionsUtil getSipSessionsUtil(); + + TimerService getTimerService(); + ProxyTimerService getProxyTimerService(); + SipApplicationSessionTimerService getSipApplicationSessionTimerService(); + + void setConcurrencyControlMode(ConcurrencyControlMode mode); + ConcurrencyControlMode getConcurrencyControlMode(); + + void setSipRubyController(SipRubyController rubyController); + SipRubyController getSipRubyController(); + + ServletContext getServletContext(); + String getPath(); + MobicentsSipServlet findSipServletByClassName(String canonicalName); + MobicentsSipServlet findSipServletByName(String name); + + ClassLoader getSipContextClassLoader(); + Map getChildrenMap(); + + boolean isPackageProtectionEnabled(); + + boolean authorize(MobicentsSipServletRequest request); + SipDigestAuthenticator getDigestAuthenticator(); + + // http://code.google.com/p/sipservlets/issues/detail?id=135 + void enterSipContext(); + void exitSipContext(ClassLoader oldClassLoader); + /** + * Stop the Context GraceFully, ie the context will stop only when there is no outstanding SIP or HTTP Sessions + * @param timeToWait - the context will wait for the time specified in this parameter before forcefully killing + * the remaining sessions (HTTP and SIP) for each application deployed, if a negative value is provided the context + * will wait until there is no remaining Session before shutting down + */ + void stopGracefully(long timeToWait); + boolean isStoppingGracefully(); + + void setGracefulInterval(long gracefulInterval); +} diff --git a/sip-servlets-core-api/src/main/java/org/mobicents/servlet/sip/core/SipListeners.java b/sip-servlets-core-api/src/main/java/org/mobicents/servlet/sip/core/SipListeners.java index 4dc72ba909..0d6f2e2e8d 100644 --- a/sip-servlets-core-api/src/main/java/org/mobicents/servlet/sip/core/SipListeners.java +++ b/sip-servlets-core-api/src/main/java/org/mobicents/servlet/sip/core/SipListeners.java @@ -32,6 +32,7 @@ import javax.servlet.sip.SipSessionAttributeListener; import javax.servlet.sip.SipSessionListener; import javax.servlet.sip.TimerListener; +import org.mobicents.javax.servlet.ContainerEvent; import org.mobicents.javax.servlet.ContainerListener; import org.mobicents.javax.servlet.sip.ProxyBranchListener; @@ -60,5 +61,7 @@ boolean loadListeners(String[] findSipApplicationListeners, List getSipServletsListeners(); List getSipConnectorListeners(); ContainerListener getContainerListener(); + + public void callbackContainerListener(ContainerEvent event); } diff --git a/sip-servlets-core-api/src/main/java/org/mobicents/servlet/sip/core/b2bua/MobicentsB2BUAHelper.java b/sip-servlets-core-api/src/main/java/org/mobicents/servlet/sip/core/b2bua/MobicentsB2BUAHelper.java index 0caa7bf14c..64a2610503 100644 --- a/sip-servlets-core-api/src/main/java/org/mobicents/servlet/sip/core/b2bua/MobicentsB2BUAHelper.java +++ b/sip-servlets-core-api/src/main/java/org/mobicents/servlet/sip/core/b2bua/MobicentsB2BUAHelper.java @@ -30,11 +30,10 @@ import org.mobicents.servlet.sip.core.MobicentsSipFactory; import org.mobicents.servlet.sip.core.SipManager; import org.mobicents.servlet.sip.core.message.MobicentsSipServletRequest; -import org.mobicents.servlet.sip.core.session.MobicentsSipSessionKey; /** * Extenstion from the B2BUAHelpr from Sip Servlets spec giving access to internals - * + * * @author jean.deruelle@gmail.com * */ @@ -42,9 +41,11 @@ public interface MobicentsB2BUAHelper extends B2buaHelper { void setMobicentsSipFactory(MobicentsSipFactory sipFactoryImpl); void setSipManager(SipManager sipManager); - void unlinkOriginalRequestInternal(MobicentsSipServletRequest sipServletMessage, + void setOriginalRequest(SipSession sipSession, MobicentsSipServletRequest sipServletMessage); + MobicentsSipServletRequest getOriginalRequest(SipSession sipSession); + void unlinkRequestInternal(MobicentsSipServletRequest sipServletMessage, boolean b); void unlinkSipSessionsInternal(SipSession sipSession, boolean b); - Map getSessionMap(); + Map getSessionMap(); } diff --git a/sip-servlets-core-api/src/main/java/org/mobicents/servlet/sip/core/session/MobicentsSipSession.java b/sip-servlets-core-api/src/main/java/org/mobicents/servlet/sip/core/session/MobicentsSipSession.java index 13fc8259a6..026abc24f7 100644 --- a/sip-servlets-core-api/src/main/java/org/mobicents/servlet/sip/core/session/MobicentsSipSession.java +++ b/sip-servlets-core-api/src/main/java/org/mobicents/servlet/sip/core/session/MobicentsSipSession.java @@ -1,5 +1,5 @@ /* - * TeleStax, Open Source Cloud Communications Copyright 2012. + * TeleStax, Open Source Cloud Communications Copyright 2012. * and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. @@ -45,7 +45,7 @@ /** * Extension to the SipSession interface from JSR 289 - * + * * @author Jean Deruelle * */ @@ -58,8 +58,8 @@ public interface MobicentsSipSession extends SipSession, SipSessionExt { MobicentsSipSessionKey getKey(); /** - * Add the derived sip session it will be identified by the To tag from its key - * @param derivedSession the derived session to add + * Add the derived sip session it will be identified by the To tag from its key + * @param derivedSession the derived session to add */ void addDerivedSipSessions(MobicentsSipSession derivedSession); /** @@ -67,7 +67,7 @@ public interface MobicentsSipSession extends SipSession, SipSessionExt { * @param key the key identifying the sip session to remove * @return the removed derived sip session */ - public MobicentsSipSession removeDerivedSipSession(String key); + public MobicentsSipSession removeDerivedSipSession(String key); /** * Find the derived sip session identified by its to tag * @param toTag the to Tag identifying the sip session to remove @@ -75,29 +75,29 @@ public interface MobicentsSipSession extends SipSession, SipSessionExt { */ public MobicentsSipSession findDerivedSipSession(String toTag); - + MobicentsSipApplicationSession getSipApplicationSession(); String getHandler(); Dialog getSessionCreatingDialog(); void setSessionCreatingDialog(Dialog dialog); - + MobicentsSipServletMessage getSessionCreatingTransactionRequest(); void setSessionCreatingTransactionRequest(MobicentsSipServletMessage message); Set getOngoingTransactions(); void removeOngoingTransaction(Transaction transaction); void addOngoingTransaction(Transaction transaction); - + void cleanDialogInformation(boolean terminate); Serializable getStateInfo(); void setStateInfo(Serializable stateInfo); - + SipPrincipal getUserPrincipal(); void setUserPrincipal(SipPrincipal principal); - + void setRoutingRegion(SipApplicationRoutingRegion routingRegion); /** @@ -106,9 +106,9 @@ public interface MobicentsSipSession extends SipSession, SipSessionExt { */ MobicentsProxy getProxy(); void setProxy(MobicentsProxy proxy); - + public void setB2buaHelper(MobicentsB2BUAHelper helperImpl); - public MobicentsB2BUAHelper getB2buaHelper(); + public MobicentsB2BUAHelper getB2buaHelper(); void access(); @@ -121,21 +121,21 @@ void updateStateOnSubsequentRequest( void onTerminatedState(); void onReadyToInvalidate(); - + String getOutboundInterface(); Iterator getDerivedSipSessions(); - void setState(State state); + void setState(State state); void setSipSubscriberURI(String subscriberURI); String getSipSubscriberURI(); - + MobicentsSipSession getParentSession(); void setParentSession(MobicentsSipSession mobicentsSipSession); - Map getSipSessionAttributeMap(); + Map getSipSessionAttributeMap(); void setSipSessionAttributeMap(Map sipSessionAttributeMap); @@ -144,44 +144,44 @@ void updateStateOnSubsequentRequest( void setRemoteParty(Address addressImpl); SipApplicationRoutingRegion getRegionInternal(); - + void acquire(); void release(); - + //RFC 3265 void addSubscription(MobicentsSipServletMessage sipServletMessage) throws SipException; void removeSubscription(MobicentsSipServletMessage sipServletMessage); - + MobicentsSipSession getFacade(); void setNextSipApplicationRouterInfo(SipApplicationRouterInfo routerInfo); - SipApplicationRouterInfo getNextSipApplicationRouterInfo(); + SipApplicationRouterInfo getNextSipApplicationRouterInfo(); public boolean isValidInternal(); // https://code.google.com/p/sipservlets/issues/detail?id=279 public boolean isReadyToInvalidateInternal(); - + public long getCseq(); public void setCseq(long cseq); boolean validateCSeq(MobicentsSipServletRequest sipServletRequestImpl); - + String getTransport(); void setTransport(String transport); - + int getRequestsPending(); void setRequestsPending(int requests); void setAckReceived(long cSeq, boolean ackReceived); void notifySipSessionListeners(SipSessionEventType creation); - + void setSipSessionSecurity(MobicentsSipSessionSecurity sipSessionSecurity); MobicentsSipSessionSecurity getSipSessionSecurity(); - + /** * Associate a particular flow (see RFC5626) with this * session. - * + * * @param flow */ public void setFlow(final javax.sip.address.SipURI flow); @@ -191,11 +191,13 @@ void updateStateOnSubsequentRequest( public void setOrphan(boolean orphan); public boolean isOrphan(); - + // https://code.google.com/p/sipservlets/issues/detail?id=279 /** * Invalidate with an option to bypass the check if the session was already invalidated * @param bypassCheck whether or not to by pass the checks to throw Exception if the session was already invalidated or is in the process of it */ public void invalidate(boolean bypassCheck); + + public boolean isB2BUAOrphan(); } diff --git a/sip-servlets-examples/websocket-b2bua/src/main/sipapp/Room/resources/js/WebRTComm.js b/sip-servlets-examples/websocket-b2bua/src/main/sipapp/Room/resources/js/WebRTComm.js index 759c7438b9..77fa294f7d 100644 --- a/sip-servlets-examples/websocket-b2bua/src/main/sipapp/Room/resources/js/WebRTComm.js +++ b/sip-servlets-examples/websocket-b2bua/src/main/sipapp/Room/resources/js/WebRTComm.js @@ -4861,7 +4861,7 @@ WebRTCommMessage.prototype.getFrom= function() { }; /** - * Get message recever identity + * Get message receiver identity * @public * @returns {String} to */ diff --git a/sip-servlets-impl/.classpath b/sip-servlets-impl/.classpath index 51e96f86d5..0b7141370c 100644 --- a/sip-servlets-impl/.classpath +++ b/sip-servlets-impl/.classpath @@ -1,25 +1,34 @@ + - - + - + - - - - + + + + + + + + + + + + + diff --git a/sip-servlets-impl/pom.xml b/sip-servlets-impl/pom.xml index 4599a3ee2b..15d64ddca1 100644 --- a/sip-servlets-impl/pom.xml +++ b/sip-servlets-impl/pom.xml @@ -14,7 +14,8 @@ Restcomm yyyyMMddHHmm - ${maven.build.timestamp} + ${maven.build.timestamp} + https://statistics.restcomm.com/rest/ @@ -99,6 +100,30 @@ 1.0.MOBICENTS provided + + + org.restcomm.commons + restcomm-statistics + ${restcomm.commons.version} + + + + io.dropwizard.metrics + metrics-core + ${metrics.version} + + + + org.slf4j + slf4j-api + ${slf4j.version} + + + + org.slf4j + slf4j-simple + ${slf4j.version} + @@ -213,7 +238,7 @@ copy-dependencies - jain-sip-api,jain-sip-ri,log4j,commons-logging,dnsjava,stun4j,activation,mail,restcomm-jain-sip-ha-core,restcomm-jain-sip-ext,commons-codec + jain-sip-api,jain-sip-ri,concurrent,log4j,commons-logging,dnsjava,stun4j,activation,mail,restcomm-jain-sip-ha-core,restcomm-jain-sip-ext,commons-codec,restcomm-statistics,metrics-core,gson,slf4j-api,slf4j-simple,httpcore,httpclient ${CATALINA_HOME}/lib @@ -264,7 +289,7 @@ copy-dependencies - jain-sip-api,jain-sip-ri,concurrent,log4j,commons-logging,dnsjava,stun4j,activation,mail,restcomm-jain-sip-ha-core,restcomm-jain-sip-ext,commons-codec + jain-sip-api,jain-sip-ri,concurrent,log4j,commons-logging,dnsjava,stun4j,activation,mail,restcomm-jain-sip-ha-core,restcomm-jain-sip-ext,commons-codec,restcomm-statistics,metrics-core,gson,slf4j-api,slf4j-simple,httpcore,httpclient ${env.CATALINA_HOME}/lib @@ -315,7 +340,7 @@ copy-dependencies - jain-sip-api,jain-sip-ri,log4j,commons-logging,dnsjava,stun4j,activation,mail,restcomm-jain-sip-ha-core,restcomm-jain-sip-ext,commons-codec + jain-sip-api,jain-sip-ri,concurrent,log4j,commons-logging,dnsjava,stun4j,activation,mail,restcomm-jain-sip-ha-core,restcomm-jain-sip-ext,commons-codec,restcomm-statistics,metrics-core,gson,slf4j-api,slf4j-simple,httpcore,httpclient ${CATALINA_HOME}/lib @@ -366,7 +391,7 @@ copy-dependencies - jain-sip-api,jain-sip-ri,concurrent,log4j,commons-logging,dnsjava,stun4j,activation,mail,restcomm-jain-sip-ha-core,restcomm-jain-sip-ext,commons-codec + jain-sip-api,jain-sip-ri,concurrent,log4j,commons-logging,dnsjava,stun4j,activation,mail,restcomm-jain-sip-ha-core,restcomm-jain-sip-ext,commons-codec,restcomm-statistics,metrics-core,gson,slf4j-api,slf4j-simple,httpcore,httpclient ${env.CATALINA_HOME}/lib diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/JainSipUtils.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/JainSipUtils.java index 4b4da510f1..50a6d7d8be 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/JainSipUtils.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/JainSipUtils.java @@ -269,6 +269,8 @@ public final class JainSipUtils { PARAMETERABLE_HEADER_NAMES.add(EventHeader.NAME); // https://github.com/Mobicents/sip-servlets/issues/45 PARAMETERABLE_HEADER_NAMES.add(SubscriptionStateHeader.NAME); + // https://telestax.zendesk.com/agent/tickets/34008 + PARAMETERABLE_HEADER_NAMES.add(SessionExpiresHeader.NAME); } diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/address/ParameterableImpl.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/address/ParameterableImpl.java index 107e2594e3..0290e0fb66 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/address/ParameterableImpl.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/address/ParameterableImpl.java @@ -1,262 +1,321 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.address; - -import java.io.Serializable; -import java.text.ParseException; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; -import java.util.Map.Entry; -import java.util.concurrent.ConcurrentHashMap; - -import javax.servlet.sip.Parameterable; -import javax.sip.header.Header; -import javax.sip.header.Parameters; - -import org.mobicents.servlet.sip.address.AddressImpl.ModifiableRule; - - -/** - * Implementation of the parameterable interface. - * - * @author mranga - * @author jean.deruelle@gmail.com - * - */ - -public abstract class ParameterableImpl implements Parameterable ,Cloneable, Serializable { - private static final long serialVersionUID = 1L; -// private static Logger logger = Logger.getLogger(ParameterableImpl.class.getCanonicalName()); - private static final String PARAM_SEPARATOR = ";"; - private static final String PARAM_NAME_VALUE_SEPARATOR = "="; - - protected Map parameters = new ConcurrentHashMap(); - - protected transient Parameters header = null; - - protected ModifiableRule isModifiable = ModifiableRule.Modifiable; - - protected ParameterableImpl() { - this.parameters = new ConcurrentHashMap(); - } - - /** - * Create parametrable instance. - * @param value - initial value of parametrable value - * @param parameters - parameter map - it can be null; - */ - public ParameterableImpl(Header header, Map params, ModifiableRule isModifiable) { - this.isModifiable = isModifiable; - if(header instanceof Parameters) { - this.header = (Parameters) header; - } - if(params!=null) { - Iterator> entries=params.entrySet().iterator(); - while (entries.hasNext()) { - Map.Entry e=entries.next(); - parameters.put(e.getKey(), e.getValue()); - } - } - } - - /* - * (non-Javadoc) - * @see javax.servlet.sip.Parameterable#getParameter(java.lang.String) - */ - public String getParameter(String name) { - if(name == null) { - throw new NullPointerException("the parameter given in parameter is null !"); - } - String value = this.parameters.get(name); - if(value != null) { - return RFC2396UrlDecoder.decode(value); - } else { - if("lr".equals(name)) return "";// special case to pass Addressing spec test from 289 TCK - } - return null; - } - - /* - * (non-Javadoc) - * @see javax.servlet.sip.Parameterable#getParameterNames() - */ - public Iterator getParameterNames() { - return this.parameters.keySet().iterator(); - } - - /* - * (non-Javadoc) - * @see javax.servlet.sip.Parameterable#removeParameter(java.lang.String) - */ - public void removeParameter(String name) { - if(name == null) { - throw new NullPointerException("parameter name is null ! "); - } - if(isModifiable == ModifiableRule.NotModifiable) { - throw new IllegalStateException("it is forbidden to modify the parameters"); - } - if(name.equalsIgnoreCase("tag") && (isModifiable == ModifiableRule.From || isModifiable == ModifiableRule.To)) { - throw new IllegalStateException("it is forbidden to remove the tag parameter on To or From Header"); - } - if(name.equalsIgnoreCase("branch") && isModifiable == ModifiableRule.Via) { - throw new IllegalStateException("it is forbidden to set the branch parameter on the Via Header"); - } - this.parameters.remove(name); - if(header != null) { - header.removeParameter(name); - } - } - - /* - * (non-Javadoc) - * @see javax.servlet.sip.Parameterable#setParameter(java.lang.String, java.lang.String) - */ - public void setParameter(String name, String value) { - // Global Fix by alexvinn for Issue 1010 : Unable to set flag parameter to parameterable header - if(name == null) { - throw new NullPointerException("parameter name is null ! "); - } - if(value == null) { - removeParameter(name); - return; - } - if(isModifiable == ModifiableRule.NotModifiable) { - throw new IllegalStateException("it is forbidden to modify the parameters"); - } - if(name.equalsIgnoreCase("tag") && (isModifiable == ModifiableRule.From || isModifiable == ModifiableRule.To)) { - throw new IllegalStateException("it is forbidden to set the tag parameter on To or From Header"); - } - if(name.equalsIgnoreCase("branch") && isModifiable == ModifiableRule.Via) { - throw new IllegalStateException("it is forbidden to set the branch parameter on the Via Header"); - } - //Fix from abondar for Issue 494 and angelo.marletta for Issue 502 - this.parameters.put(name.toLowerCase(), value); - if(header != null) { - try { - header.setParameter(name, "".equals(value) ? null : value); - } catch (ParseException e) { - throw new IllegalArgumentException("Problem setting parameter",e); - } - } - } - - /* - * (non-Javadoc) - * @see javax.servlet.sip.Parameterable#getParameters() - */ - public Set> getParameters() { - Map retval = new HashMap (); - for(Entry nameValue : this.parameters.entrySet()) { - retval.put(nameValue.getKey(), (RFC2396UrlDecoder.decode(nameValue.getValue()))); - } - return retval.entrySet(); - } - - /* - * (non-Javadoc) - * @see javax.servlet.sip.Parameterable#getParameters() - */ - public Map getInternalParameters() { - return parameters; - } - - /* - * (non-Javadoc) - * @see java.lang.Object#toString() - */ - public String toString() { - StringBuffer retVal = new StringBuffer(); - boolean firstTime = true; - for(java.util.Map.Entry entry : parameters.entrySet()) { - if(!firstTime) { - retVal.append(PARAM_SEPARATOR); - } - firstTime = false; - String value = entry.getValue(); - if(value != null && value.length() > 0) { - retVal.append(entry.getKey()).append(PARAM_NAME_VALUE_SEPARATOR).append(value); - } else { - retVal.append(entry.getKey()); - } - } - return retVal.toString(); - } - - public void setParameters(Map parameters) { - this.parameters = parameters; - if(header != null) { - for(Entry nameValue : this.parameters.entrySet()) { - try { - header.setParameter(nameValue.getKey(), nameValue.getValue()); - } catch (ParseException e) { - throw new IllegalArgumentException("Problem setting parameter",e); - } - } - } - } - - public abstract Object clone(); - - /* (non-Javadoc) - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((header == null) ? 0 : header.hashCode()); - result = prime * result - + ((parameters == null) ? 0 : parameters.hashCode()); - return result; - } - - /* (non-Javadoc) - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - ParameterableImpl other = (ParameterableImpl) obj; - if (header == null) { - if (other.header != null) - return false; - } else if (!header.equals(other.header)) - return false; - if (parameters == null) { - if (other.parameters != null) - return false; - } else if (!parameters.equals(other.parameters)) - return false; - return true; - } - - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.address; + +import gov.nist.javax.sip.header.ParametersExt; + +import java.io.Serializable; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import javax.servlet.sip.Parameterable; +import javax.sip.header.Header; +import javax.sip.header.Parameters; + +import org.mobicents.servlet.sip.address.AddressImpl.ModifiableRule; +import org.mobicents.servlet.sip.core.SipContext; +import static org.mobicents.servlet.sip.core.SipContext.INTERNAL_ATT_PREFIX; +import org.mobicents.servlet.sip.core.session.SipApplicationSessionCreationThreadLocal; + + +/** + * Implementation of the parameterable interface. + * + * @author mranga + * @author jean.deruelle@gmail.com + * + */ + +public abstract class ParameterableImpl implements Parameterable ,Cloneable, Serializable { + private static final long serialVersionUID = 1L; +// private static Logger logger = Logger.getLogger(ParameterableImpl.class.getCanonicalName()); + private static final String PARAM_SEPARATOR = ";"; + private static final String PARAM_NAME_VALUE_SEPARATOR = "="; + // default quotable params that their values need to be quoted. + private static final String DEFAULT_QUOTABLE_PARAMS = "vendor, model, version, cnonce, nextnonce," + + "nonce, code, oc-algo, cid, text, domain, opaque, qop, realm, response, rspauth, uri, username"; + // Name of the parameter for the list of quotable params + private static final String QUOTABLE_PARAMS = INTERNAL_ATT_PREFIX + ".QUOTABLE_PARAMETER"; + + protected Map parameters = new ConcurrentHashMap(); + + protected transient Parameters header = null; + + protected ModifiableRule isModifiable = ModifiableRule.Modifiable; + + protected ParameterableImpl() { + this.parameters = new ConcurrentHashMap(); + } + + /** + * Create parametrable instance. + * @param value - initial value of parametrable value + * @param parameters - parameter map - it can be null; + */ + public ParameterableImpl(Header header, Map params, ModifiableRule isModifiable) { + this.isModifiable = isModifiable; + if(header instanceof Parameters) { + this.header = (Parameters) header; + } + if(params!=null) { + Iterator> entries=params.entrySet().iterator(); + while (entries.hasNext()) { + Map.Entry e=entries.next(); + parameters.put(e.getKey(), e.getValue()); + } + } + } + + /* + * (non-Javadoc) + * @see javax.servlet.sip.Parameterable#getParameter(java.lang.String) + */ + public String getParameter(String name) { + if(name == null) { + throw new NullPointerException("the parameter given in parameter is null !"); + } + String value = this.parameters.get(name); + if(value != null) { + return RFC2396UrlDecoder.decode(value); + } else { + if("lr".equals(name)) return "";// special case to pass Addressing spec test from 289 TCK + } + return null; + } + + /* + * (non-Javadoc) + * @see javax.servlet.sip.Parameterable#getParameterNames() + */ + public Iterator getParameterNames() { + return this.parameters.keySet().iterator(); + } + + /* + * (non-Javadoc) + * @see javax.servlet.sip.Parameterable#removeParameter(java.lang.String) + */ + public void removeParameter(String name) { + if(name == null) { + throw new NullPointerException("parameter name is null ! "); + } + if(isModifiable == ModifiableRule.NotModifiable) { + throw new IllegalStateException("it is forbidden to modify the parameters"); + } + if(name.equalsIgnoreCase("tag") && (isModifiable == ModifiableRule.From || isModifiable == ModifiableRule.To)) { + throw new IllegalStateException("it is forbidden to remove the tag parameter on To or From Header"); + } + if(name.equalsIgnoreCase("branch") && isModifiable == ModifiableRule.Via) { + throw new IllegalStateException("it is forbidden to set the branch parameter on the Via Header"); + } + this.parameters.remove(name); + if(header != null) { + header.removeParameter(name); + } + } + + /* + * (non-Javadoc) + * @see javax.servlet.sip.Parameterable#setParameter(java.lang.String, java.lang.String) + */ + public void setParameter(String name, String value) { + // Global Fix by alexvinn for Issue 1010 : Unable to set flag parameter to parameterable header + if(name == null) { + throw new NullPointerException("parameter name is null ! "); + } + if(value == null) { + removeParameter(name); + return; + } + if(isModifiable == ModifiableRule.NotModifiable) { + throw new IllegalStateException("it is forbidden to modify the parameters"); + } + if(name.equalsIgnoreCase("tag") && (isModifiable == ModifiableRule.From || isModifiable == ModifiableRule.To)) { + throw new IllegalStateException("it is forbidden to set the tag parameter on To or From Header"); + } + if(name.equalsIgnoreCase("branch") && isModifiable == ModifiableRule.Via) { + throw new IllegalStateException("it is forbidden to set the branch parameter on the Via Header"); + } + //Fix from abondar for Issue 494 and angelo.marletta for Issue 502 + this.parameters.put(name.toLowerCase(), value); + if(header != null) { + try { + if (isQuotableParam(name) && (header instanceof ParametersExt)){ + ((ParametersExt) header).setQuotedParameter(name, value); + }else{ + header.setParameter(name, "".equals(value) ? null : value); + } + } catch (ParseException e) { + throw new IllegalArgumentException("Problem setting parameter",e); + } + } + } + + /* + * Check if the param name is in the list that its value need to be quoted + * + * @param name - a string specifying the parameter name + * + */ + private boolean isQuotableParam(String name){ + boolean isQuotableParameter = false; + List params = getQuotableParams(); + for (String param : params){ + if (param.equalsIgnoreCase(name)){ + isQuotableParameter = true; + break; + } + } + return isQuotableParameter; + } + + /** + * + * @return a list of known params that their values need to be quoted. + */ + private List getQuotableParams(){ + List retValue = new ArrayList(); + SipContext context = SipApplicationSessionCreationThreadLocal.lookupContext(); + if (context != null){ + // bug zendesk#34106, because of JBOSS lifcycle and save the cost, get context param dirrectly + // from init param. + String quotableParameters = context.getServletContext().getInitParameter(QUOTABLE_PARAMS); + if (quotableParameters == null){ + quotableParameters = DEFAULT_QUOTABLE_PARAMS; + } + String[] parameters = quotableParameters.split(","); + for (int i = 0; i < parameters.length; i++){ + String param = parameters[i].trim(); + if (param != null && !param.isEmpty() && !retValue.contains(param)){ + retValue.add(param); + } + } + } + + return retValue; + } + /* + * (non-Javadoc) + * @see javax.servlet.sip.Parameterable#getParameters() + */ + public Set> getParameters() { + Map retval = new HashMap (); + for(Entry nameValue : this.parameters.entrySet()) { + retval.put(nameValue.getKey(), (RFC2396UrlDecoder.decode(nameValue.getValue()))); + } + return retval.entrySet(); + } + + /* + * (non-Javadoc) + * @see javax.servlet.sip.Parameterable#getParameters() + */ + public Map getInternalParameters() { + return parameters; + } + + /* + * (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuffer retVal = new StringBuffer(); + boolean firstTime = true; + for(java.util.Map.Entry entry : parameters.entrySet()) { + if(!firstTime) { + retVal.append(PARAM_SEPARATOR); + } + firstTime = false; + String value = entry.getValue(); + if(value != null && value.length() > 0) { + retVal.append(entry.getKey()).append(PARAM_NAME_VALUE_SEPARATOR).append(value); + } else { + retVal.append(entry.getKey()); + } + } + return retVal.toString(); + } + + public void setParameters(Map parameters) { + this.parameters = parameters; + if(header != null) { + for(Entry nameValue : this.parameters.entrySet()) { + try { + header.setParameter(nameValue.getKey(), nameValue.getValue()); + } catch (ParseException e) { + throw new IllegalArgumentException("Problem setting parameter",e); + } + } + } + } + + public abstract Object clone(); + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((header == null) ? 0 : header.hashCode()); + result = prime * result + + ((parameters == null) ? 0 : parameters.hashCode()); + return result; + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ParameterableImpl other = (ParameterableImpl) obj; + if (header == null) { + if (other.header != null) + return false; + } else if (!header.equals(other.header)) + return false; + if (parameters == null) { + if (other.parameters != null) + return false; + } else if (!parameters.equals(other.parameters)) + return false; + return true; + } + + + +} diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/ApplicationRoutingHeaderComposer.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/ApplicationRoutingHeaderComposer.java index 2b8914a506..6d2bc1d6af 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/ApplicationRoutingHeaderComposer.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/ApplicationRoutingHeaderComposer.java @@ -62,10 +62,12 @@ public final static String[] getAppNameAndSessionId(SipApplicationDispatcher sip // If there is no AR in the string, generate a uniqueValue for the tag // and it will be stored for later. - if(tokens.length > 2) { + if(tokens.length > 2) { // Otherwise extract the uniqueValue from the tag string, it's the first token. final String hashedAppName = tokens[2]; - if(sipApplicationDispatcher.getApplicationServerIdHash().equalsIgnoreCase(tokens[1])) { + // TODO (posfai): Revert to the commented line when the following github issue is resolved: https://github.com/RestComm/sip-servlets/issues/171 + //if(sipApplicationDispatcher.getApplicationServerIdHash().equalsIgnoreCase(tokens[1])) { + if(true) { String appName = sipApplicationDispatcher.getApplicationNameFromHash(hashedAppName); if(appName == null) throw new IllegalArgumentException("The hash doesn't correspond to any app name: " + hashedAppName); diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/DispatcherFSM.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/DispatcherFSM.java new file mode 100644 index 0000000000..215a9cf568 --- /dev/null +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/DispatcherFSM.java @@ -0,0 +1,403 @@ +package org.mobicents.servlet.sip.core; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import org.apache.log4j.Logger; +import static org.mobicents.servlet.sip.core.SipNetworkInterfaceManagerImpl.LISTENING_POINT_ATT; + +/** + * This FSM helps coordinate server bootstrapping, so adding applications, and + * adding connectors parallel flows are in line. These flows need to be + * coordinated in order to notify different Listener specs events at proper + * time. + * + * Since the FSM doesn't know how many connectors will be added in advance, an + * intermediary state approach is taken when adding the first connector. After + * some time without receiving new connectors, the applications will be notified + * about listener events + * + * @author jaime + */ +public class DispatcherFSM { + + private static final Logger logger = Logger.getLogger(SipApplicationDispatcherImpl.class); + + private static final String TIMER_ID_EVENT_DATA = "TimerId"; + private static final String ADD_CONN_TIMER_ID = "addConnTimerId"; + private static final long ADD_CONN_TIMER_DELAY = 5000; + + private final Context context; + + private final Map states = new HashMap(); + + class Context { + + Event lastEvent; + final SipApplicationDispatcherImpl dispatcher; + final Map data = new HashMap(); + + public Context(SipApplicationDispatcherImpl dispatcher) { + this.dispatcher = dispatcher; + } + + } + + enum DispatcherState { + NOT_INIT, INITIATED, STARTED, IN_SERVICE, STOPPED; + } + + enum EventType { + INIT, START, STOP, ADD_CONNECTOR, REMOVE_CONNECTOR, ADD_APP, REMOVE_APP, + SET_CONGESTION, TIMER,IN_SERVICE; + + } + + class Event { + + final EventType type; + final Map data = new HashMap(); + + public Event(EventType type) { + this.type = type; + } + + } + + class SetCongestionCondition implements GuardCondition { + + @Override + public boolean isEnabled(Event eventData, Context ctx) { + Long interval = (Long) eventData.data.get(SipApplicationDispatcherImpl.INTERVAL_ATT); + return interval != ctx.dispatcher.congestionControlCheckingInterval; + } + } + + class IsTypeCondition implements GuardCondition { + + private final EventType expectedType; + + public IsTypeCondition(EventType type) { + this.expectedType = type; + } + + @Override + public boolean isEnabled(Event ev, Context ctx) { + return ev.type.equals(expectedType); + } + } + + class IsTimerCondition implements GuardCondition { + + private final String timerId; + + public IsTimerCondition(String timerId) { + this.timerId = timerId; + } + + @Override + public boolean isEnabled(Event ev, Context ctx) { + return ev.type.equals(EventType.TIMER) && ev.data.get(TIMER_ID_EVENT_DATA).equals(timerId); + } + } + + interface Action { + + void execute(Context ctx); + } + + class NotififyServletInitialized implements Action { + + @Override + public void execute(Context ctx) { + Collection appCtxs = ctx.dispatcher.applicationDeployed.values(); + for (SipContext sipContext : appCtxs) { + if (!ctx.data.containsKey(sipContext.getApplicationName())) { + sipContext.notifySipContextListeners(new SipContextEventImpl(SipContextEventType.SERVLET_INITIALIZED, null)); + ctx.data.put(sipContext.getApplicationName(), "NOTIFIED"); + } else { + logger.debug("Application already notified"); + } + } + } + } + + class NotififyConnectorAdded implements Action { + + @Override + public void execute(Context ctx) { + MobicentsExtendedListeningPoint extendedListeningPoint = (MobicentsExtendedListeningPoint) ctx.lastEvent.data.get(LISTENING_POINT_ATT); + Iterator sipContextIterator = ctx.dispatcher.findSipApplications(); + while (sipContextIterator.hasNext()) { + SipContext sipContext = (SipContext) sipContextIterator.next(); + sipContext.notifySipContextListeners(new SipContextEventImpl(SipContextEventType.SIP_CONNECTOR_ADDED, extendedListeningPoint.getSipConnector())); + } + } + } + + class NotififyConnectorRemoved implements Action { + + @Override + public void execute(Context ctx) { + MobicentsExtendedListeningPoint extendedListeningPoint = (MobicentsExtendedListeningPoint) ctx.lastEvent.data.get(LISTENING_POINT_ATT); + Iterator sipContextIterator = ctx.dispatcher.findSipApplications(); + while (sipContextIterator.hasNext()) { + SipContext sipContext = (SipContext) sipContextIterator.next(); + sipContext.notifySipContextListeners(new SipContextEventImpl(SipContextEventType.SIP_CONNECTOR_REMOVED, extendedListeningPoint.getSipConnector())); + } + } + } + + class ScheduleTimer implements Action, Runnable { + + private final long delay; + private final String timerId; + + public ScheduleTimer(long delay, String timerId) { + this.delay = delay; + this.timerId = timerId; + } + + @Override + public void execute(Context ctx) { + ScheduledFuture future = ctx.dispatcher.getAsynchronousScheduledExecutor().schedule(this, delay, TimeUnit.MILLISECONDS); + ctx.data.put(timerId, future); + } + + @Override + public void run() { + Event event = new Event(EventType.TIMER); + event.data.put(TIMER_ID_EVENT_DATA, timerId); + fireEvent(event); + } + } + + class RemoveCtxDataByEvent implements Action { + String dataKey; + + public RemoveCtxDataByEvent(String dataKey) { + this.dataKey = dataKey; + } + + @Override + public void execute(Context ctx) { + String ctxDataKey = (String) ctx.lastEvent.data.get(dataKey); + ctx.data.remove(ctxDataKey); + } + + } + + class CancelTimer implements Action { + + private final String timerId; + + public CancelTimer(String timerId) { + this.timerId = timerId; + } + + @Override + public void execute(Context ctx) { + Object obj = ctx.data.get(timerId); + if (obj != null) { + ScheduledFuture future = (ScheduledFuture) obj; + future.cancel(false); + } + } + } + + interface GuardCondition { + + boolean isEnabled(Event event, Context ctx); + } + + class Transition { + + GuardCondition condition; + List actions = new ArrayList(); + DispatcherState targetState; + } + + class State { + + List transitions = new ArrayList(); + List entryActions = new ArrayList(); + List exitActions = new ArrayList(); + } + + private DispatcherState currentState = DispatcherState.NOT_INIT; + + public DispatcherFSM(SipApplicationDispatcherImpl dispatcher) { + context = new Context(dispatcher); + + /* Non Initiated state */ + State notInitState = new State(); + + Transition addAppOnNonInit = new Transition(); + addAppOnNonInit.condition = new IsTypeCondition(EventType.ADD_APP); + addAppOnNonInit.targetState = DispatcherState.NOT_INIT; + addAppOnNonInit.actions.add(dispatcher.new AddAppAction()); + notInitState.transitions.add(addAppOnNonInit); + + Transition initTransition = new Transition(); + initTransition.condition = new IsTypeCondition(EventType.INIT); + initTransition.targetState = DispatcherState.INITIATED; + initTransition.actions.add(dispatcher.new InitAction()); + notInitState.transitions.add(initTransition); + states.put(DispatcherState.NOT_INIT, notInitState); + /* Non Initiated state */ + + + /* Initiated state */ + State initiatedState = new State(); + + Transition addConnectorOnInitiated = new Transition(); + addConnectorOnInitiated.condition = new IsTypeCondition(EventType.ADD_CONNECTOR); + addConnectorOnInitiated.targetState = DispatcherState.INITIATED; + addConnectorOnInitiated.actions.add(dispatcher.sipNetworkInterfaceManager.new AddPointAction()); + addConnectorOnInitiated.actions.add(new NotififyConnectorAdded()); + initiatedState.transitions.add(addConnectorOnInitiated); + + Transition startTransition = new Transition(); + startTransition.condition = new IsTypeCondition(EventType.START); + startTransition.targetState = DispatcherState.STARTED; + startTransition.actions.add(dispatcher.new StartAction()); + initiatedState.transitions.add(startTransition); + + Transition addAppOnInit = new Transition(); + addAppOnInit.condition = new IsTypeCondition(EventType.ADD_APP); + addAppOnInit.targetState = DispatcherState.INITIATED; + addAppOnInit.actions.add(dispatcher.new AddAppAction()); + initiatedState.transitions.add(addAppOnInit); + + states.put(DispatcherState.INITIATED, initiatedState); + /* Initiated state */ + + + /* Started state */ + State startedState = new State(); + + Transition addConnectorTransition = new Transition(); + addConnectorTransition.condition = new IsTypeCondition(EventType.ADD_CONNECTOR); + addConnectorTransition.targetState = DispatcherState.STARTED; + addConnectorTransition.actions.add(dispatcher.sipNetworkInterfaceManager.new AddPointAction()); + addConnectorTransition.actions.add(new NotififyConnectorAdded()); + startedState.transitions.add(addConnectorTransition); + + Transition inserviceTransition = new Transition(); + inserviceTransition.condition = new IsTypeCondition(EventType.IN_SERVICE); + inserviceTransition.targetState = DispatcherState.IN_SERVICE; + inserviceTransition.actions.add(new NotififyServletInitialized()); + startedState.transitions.add(inserviceTransition); + + Transition stopTransition = new Transition(); + stopTransition.condition = new IsTypeCondition(EventType.STOP); + stopTransition.targetState = DispatcherState.STOPPED; + stopTransition.actions.add(dispatcher.new StopAction()); + startedState.transitions.add(stopTransition); + + Transition addApp = new Transition(); + addApp.condition = new IsTypeCondition(EventType.ADD_APP); + addApp.targetState = DispatcherState.STARTED; + addApp.actions.add(dispatcher.new AddAppAction()); + startedState.transitions.add(addApp); + + Transition setCongestion = new Transition(); + setCongestion.condition = new IsTypeCondition(EventType.SET_CONGESTION); + setCongestion.targetState = DispatcherState.STARTED; + setCongestion.actions.add(dispatcher.new SetCongAction()); + startedState.transitions.add(setCongestion); + + states.put(DispatcherState.STARTED, startedState); + /* Started state */ + + /* inserviceState state */ + State inserviceState = new State(); + + Transition addConnectorOnInservice= new Transition(); + addConnectorOnInservice.condition = new IsTypeCondition(EventType.ADD_CONNECTOR); + addConnectorOnInservice.targetState = DispatcherState.IN_SERVICE; + addConnectorOnInservice.actions.add(dispatcher.sipNetworkInterfaceManager.new AddPointAction()); + addConnectorOnInservice.actions.add(new NotififyConnectorAdded()); + inserviceState.transitions.add(addConnectorOnInservice); + + Transition rmConnectorTransition = new Transition(); + rmConnectorTransition.condition = new IsTypeCondition(EventType.REMOVE_CONNECTOR); + rmConnectorTransition.targetState = DispatcherState.IN_SERVICE; + rmConnectorTransition.actions.add(dispatcher.sipNetworkInterfaceManager.new RemovePointAction()); + rmConnectorTransition.actions.add(new NotififyConnectorRemoved()); + inserviceState.transitions.add(rmConnectorTransition); + + Transition addAppTransition = new Transition(); + addAppTransition.condition = new IsTypeCondition(EventType.ADD_APP); + addAppTransition.targetState = DispatcherState.IN_SERVICE; + addAppTransition.actions.add(dispatcher.new AddAppAction()); + addAppTransition.actions.add(new NotififyServletInitialized()); + inserviceState.transitions.add(addAppTransition); + + Transition removeAppTransition = new Transition(); + removeAppTransition.condition = new IsTypeCondition(EventType.REMOVE_APP); + removeAppTransition.targetState = DispatcherState.IN_SERVICE; + removeAppTransition.actions.add(dispatcher.new RemoveApp()); + removeAppTransition.actions.add(new RemoveCtxDataByEvent(SipApplicationDispatcherImpl.APP_NAME)); + inserviceState.transitions.add(removeAppTransition); + + inserviceState.transitions.add(stopTransition); + + Transition setCongestionOnConn = new Transition(); + setCongestionOnConn.condition = new IsTypeCondition(EventType.SET_CONGESTION); + setCongestionOnConn.targetState = DispatcherState.IN_SERVICE; + setCongestionOnConn.actions.add(dispatcher.new SetCongAction()); + inserviceState.transitions.add(setCongestionOnConn); + + states.put(DispatcherState.IN_SERVICE, inserviceState); + /* inserviceState state */ + + State stoppedState = new State(); + states.put(DispatcherState.STOPPED, stoppedState); + + } + + private void executeActions(List actions) { + for (Action aAux : actions) { + if (logger.isDebugEnabled()) { + logger.debug("State(" + currentState + ").Executing action:" + aAux); + } + aAux.execute(context); + } + + } + + private void switchToState(DispatcherState newState) { + if (logger.isDebugEnabled()) { + logger.debug("State(" + currentState + ").New state:" + newState); + } + executeActions(states.get(currentState).exitActions); + currentState = newState; + executeActions(states.get(currentState).entryActions); + } + + synchronized void fireEvent(Event event) { + State cState = states.get(currentState); + boolean matched = false; + Iterator iterator = cState.transitions.iterator(); + Transition tAux = null; + while (!matched && iterator.hasNext()) { + tAux = iterator.next(); + if (tAux.condition.isEnabled(event, context)) { + matched = true; + } + } + if (matched && tAux != null) { + context.lastEvent = event; + executeActions(tAux.actions); + switchToState(tAux.targetState); + } else if (logger.isDebugEnabled()) { + logger.debug("State(" + currentState + ").Event discarded:" + event.type); + } + } +} diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/SipApplicationDispatcherImpl.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/SipApplicationDispatcherImpl.java index a77baa45cf..7c29e42b5b 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/SipApplicationDispatcherImpl.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/SipApplicationDispatcherImpl.java @@ -1,6 +1,6 @@ /* * TeleStax, Open Source Cloud Communications - * Copyright 2011-2014, Telestax Inc and individual contributors + * Copyright 2011-2016, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify @@ -48,8 +48,6 @@ import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; import javax.imageio.spi.ServiceRegistry; import javax.management.MBeanRegistration; @@ -131,39 +129,49 @@ import org.mobicents.servlet.sip.proxy.ProxyImpl; import org.mobicents.servlet.sip.router.ManageableApplicationRouter; import org.mobicents.servlet.sip.utils.NamingThreadFactory; +import org.restcomm.commons.statistics.reporter.RestcommStatsReporter; + +import com.codahale.metrics.Counter; +import com.codahale.metrics.MetricRegistry; + +import org.mobicents.javax.servlet.CongestionStartedEvent; +import org.mobicents.javax.servlet.CongestionStoppedEvent; +import org.mobicents.javax.servlet.ContainerEvent; +import org.mobicents.javax.servlet.RequestThrottledEvent; + /** * Implementation of the SipApplicationDispatcher interface. - * Central point getting the sip messages from the different stacks for a Tomcat Service(Engine), - * translating jain sip SIP messages to sip servlets SIP messages, creating a MessageRouter responsible - * for choosing which Dispatcher will be used for routing the message and + * Central point getting the sip messages from the different stacks for a Tomcat Service(Engine), + * translating jain sip SIP messages to sip servlets SIP messages, creating a MessageRouter responsible + * for choosing which Dispatcher will be used for routing the message and * dispatches the messages. - * @author Jean Deruelle + * @author Jean Deruelle */ public class SipApplicationDispatcherImpl implements SipApplicationDispatcher, SipApplicationDispatcherImplMBean, MBeanRegistration, LoadBalancerHeartBeatingListener { - + //list of methods supported by the AR - private static final String[] METHODS_SUPPORTED = + private static final String[] METHODS_SUPPORTED = {"REGISTER", "INVITE", "ACK", "BYE", "CANCEL", "MESSAGE", "INFO", "SUBSCRIBE", "NOTIFY", "UPDATE", "PUBLISH", "REFER", "PRACK", "OPTIONS"}; - - // List of sip extensions supported by the container - private static final String[] EXTENSIONS_SUPPORTED = + + // List of sip extensions supported by the container + private static final String[] EXTENSIONS_SUPPORTED = {"MESSAGE", "INFO", "SUBSCRIBE", "NOTIFY", "UPDATE", "PUBLISH", "REFER", "PRACK", "100rel", "STUN", "path", "join", "outbound", "from-change", "gruu"}; // List of sip rfcs supported by the container - private static final String[] RFC_SUPPORTED = + private static final String[] RFC_SUPPORTED = {"3261", "3428", "2976", "3265", "3311", "3903", "3515", "3262", "3489", "3327", "3911", "5626", "4916", "5627"}; - private static final String[] RESPONSES_PER_CLASS_OF_SC = + private static final String[] RESPONSES_PER_CLASS_OF_SC = {"1XX", "2XX", "3XX", "4XX", "5XX", "6XX", "7XX", "8XX", "9XX"}; - + /** - * Timer task that will gather information about congestion control + * Timer task that will gather information about congestion control * @author Jean Deruelle * @deprecated use JAIN SIP Ext Congestion Control innstead */ @Deprecated - public class CongestionControlTimerTask implements Runnable { - + public class CongestionControlTimerTask implements Runnable { + public void run() { if(logger.isDebugEnabled()) { logger.debug("CongestionControlTimerTask now running "); @@ -178,11 +186,11 @@ public void run() { //TODO wait for JDK 6 new OperatingSystemMXBean // analyzeCPU(); } - } - + } + //the logger private static final Logger logger = Logger.getLogger(SipApplicationDispatcherImpl.class); - + // app server id private String applicationServerId; private String applicationServerIdHash; @@ -194,24 +202,30 @@ public void run() { //sip servlet applications private SipApplicationRouter sipApplicationRouter = null; //map of applications deployed - private Map applicationDeployed = null; + Map applicationDeployed = null; //map hashes to app names private Map mdToApplicationName = null; //map app names to hashes private Map applicationNameToMd = null; //List of host names managed by the container private Set hostNames = null; - - private Boolean started = Boolean.FALSE; - private Lock statusLock = new ReentrantLock(); + + DispatcherFSM fsm; protected SipStack sipStack; - private SipNetworkInterfaceManager sipNetworkInterfaceManager; + SipNetworkInterfaceManagerImpl sipNetworkInterfaceManager; private DNSServerLocator dnsServerLocator; private int dnsTimeout; private DNSResolver dnsResolver; - + // stats + RestcommStatsReporter statsReporter = null; + MetricRegistry metrics = RestcommStatsReporter.getMetricRegistry(); + //define metric name + Counter counterCalls = metrics.counter("calls"); + Counter counterSeconds = metrics.counter("seconds"); + Counter counterMessages = metrics.counter("messages"); + // private boolean gatherStatistics = true; private final AtomicLong requestsProcessed = new AtomicLong(0); private final AtomicLong responsesProcessed = new AtomicLong(0); @@ -222,14 +236,14 @@ public void run() { private final AtomicLong responsesSent= new AtomicLong(0); final Map requestsSentByMethod = new ConcurrentHashMap(); final Map responsesSentByStatusCode = new ConcurrentHashMap(); - + // congestion control - private boolean memoryToHigh = false; + private boolean memoryToHigh = false; private double maxMemory; private int memoryThreshold; private int backToNormalMemoryThreshold; private boolean rejectSipMessages = false; - private long congestionControlCheckingInterval; //30 sec + long congestionControlCheckingInterval; //30 sec @Deprecated protected transient CongestionControlTimerTask congestionControlTimerTask; @Deprecated @@ -238,17 +252,17 @@ public void run() { @Deprecated private int numberOfMessagesInQueue; @Deprecated - private double percentageOfMemoryUsed; + private double percentageOfMemoryUsed; @Deprecated private int queueSize; @Deprecated private int backToNormalQueueSize; //used for graceful stops and congestion control mechanism (which is now deprecated) private ScheduledThreadPoolExecutor asynchronousScheduledThreadPoolExecutor = null; - + // configuration private boolean bypassResponseExecutor = true; - private boolean bypassRequestExecutor = true; + private boolean bypassRequestExecutor = true; private int baseTimerInterval = 500; // base timer interval for jain sip tx private int t2Interval = 4000; // t2 timer interval for jain sip tx private int t4Interval = 5000; // t4 timer interval for jain sip tx @@ -258,19 +272,19 @@ public void run() { private static final int NUMBER_OF_TAG_SEPARATORS = 3; private int tagHashMaxLength = 8; private int callIdMaxLength = -1; - + // This executor is used for async things that don't need to wait on session executors, like CANCEL requests // or when the container is configured to execute every request ASAP without waiting on locks (no concurrency control) private ThreadPoolExecutor asynchronousExecutor = null; - + // fatcory for dispatching SIP messages private MessageDispatcherFactory messageDispatcherFactory; - + //the balancers names to send heartbeat to and our health info - private Set sipLoadBalancers = new CopyOnWriteArraySet(); - + private Set sipLoadBalancers = new CopyOnWriteArraySet(); + /** - * + * */ public SipApplicationDispatcherImpl() { resetStatsCounters(); @@ -282,8 +296,9 @@ public SipApplicationDispatcherImpl() { sipNetworkInterfaceManager = new SipNetworkInterfaceManagerImpl(this); maxMemory = Runtime.getRuntime().maxMemory() / (double) 1024; congestionControlPolicy = CongestionControlPolicy.ErrorResponse; + fsm = new DispatcherFSM(this); } - + @Override public final void resetStatsCounters() { requestsProcessed.set(0); @@ -296,7 +311,7 @@ public final void resetStatsCounters() { for (String classOfSc : RESPONSES_PER_CLASS_OF_SC) { responsesProcessedByStatusCode.put(classOfSc, new AtomicLong(0)); - } + } for (String classOfSc : RESPONSES_PER_CLASS_OF_SC) { responsesSentByStatusCode.put(classOfSc, new AtomicLong(0)); @@ -304,14 +319,14 @@ public final void resetStatsCounters() { for (String method : METHODS_SUPPORTED) { requestsSentByMethod.put(method, new AtomicLong(0)); - } - + } + } - - /** - * {@inheritDoc} - */ - public void init() throws IllegalArgumentException { + + class InitAction implements DispatcherFSM.Action { + + @Override + public void execute(DispatcherFSM.Context ctx) { //load the sip application router from the javax.servlet.sip.ar.spi.SipApplicationRouterProvider system property //and initializes it if present String sipApplicationRouterProviderClassName = System.getProperty("javax.servlet.sip.ar.spi.SipApplicationRouterProvider"); @@ -330,12 +345,12 @@ public void init() throws IllegalArgumentException { throw new IllegalArgumentException("Impossible to load the Sip Application Router",e); } catch (ClassCastException e) { throw new IllegalArgumentException("Sip Application Router defined does not implement " + SipApplicationRouterProvider.class.getName(),e); - } + } } else { if(logger.isInfoEnabled()) { logger.info("Using the Service Provider Framework to load the application router provider"); } - //TODO when moving to JDK 6, use the official http://java.sun.com/javase/6/docs/api/java/util/ServiceLoader.html instead + //TODO when moving to JDK 6, use the official http://java.sun.com/javase/6/docs/api/java/util/ServiceLoader.html instead //http://grep.codeconsult.ch/2007/10/31/the-java-service-provider-spec-and-sunmiscservice/ Iterator providers = ServiceRegistry.lookupProviders(SipApplicationRouterProvider.class); if(providers.hasNext()) { @@ -352,7 +367,7 @@ public void init() throws IllegalArgumentException { } sipApplicationRouter.init(); sipApplicationRouter.applicationDeployed(new ArrayList(applicationDeployed.keySet())); - + // set the DNSServerLocator allowing to support RFC 3263 and do DNS lookups to resolve uris if(sipService.getDnsResolverClass() != null && sipService.getDnsResolverClass().trim().length() > 0) { if(logger.isInfoEnabled()) { @@ -377,12 +392,12 @@ public void init() throws IllegalArgumentException { logger.info("Using default MobicentsDNSResolver since none has been specified."); } dnsResolver = new MobicentsDNSResolver(dnsServerLocator); - } - + } + if( oname == null ) { - try { - oname=new ObjectName(domain + ":type=SipApplicationDispatcher"); - ((MBeanServer) MBeanServerFactory.findMBeanServer(null).get(0)).registerMBean(this, oname); + try { + oname=new ObjectName(domain + ":type=SipApplicationDispatcher"); + ((MBeanServer) MBeanServerFactory.findMBeanServer(null).get(0)).registerMBean(SipApplicationDispatcherImpl.this, oname); if(logger.isInfoEnabled()) { logger.info("Sip Application dispatcher registered under following name " + oname); } @@ -402,8 +417,8 @@ public void init() throws IllegalArgumentException { } int tagHashMaxTotalLength = sipService.getTagHashMaxLength(); if(tagHashMaxTotalLength > 0) { - this.tagHashMaxLength = (tagHashMaxTotalLength - NUMBER_OF_TAG_SEPARATORS) / 4; - APP_ID_HASHING_MAX_LENGTH = tagHashMaxTotalLength - NUMBER_OF_TAG_SEPARATORS - (this.tagHashMaxLength * NUMBER_OF_TAG_SEPARATORS); + tagHashMaxLength = (tagHashMaxTotalLength - NUMBER_OF_TAG_SEPARATORS) / 4; + APP_ID_HASHING_MAX_LENGTH = tagHashMaxTotalLength - NUMBER_OF_TAG_SEPARATORS - (tagHashMaxLength * NUMBER_OF_TAG_SEPARATORS); if(logger.isInfoEnabled()) { logger.info("tagHashMaxLength ? " + tagHashMaxLength); logger.info("DEFAULT_TAG_HASHING_MAX_LENGTH ? " + APP_ID_HASHING_MAX_LENGTH); @@ -411,48 +426,71 @@ public void init() throws IllegalArgumentException { } applicationServerId = "" + UUID.randomUUID(); applicationServerIdHash = GenericUtils.hashString(applicationServerId, tagHashMaxLength); - - messageDispatcherFactory = new MessageDispatcherFactory(this); + + messageDispatcherFactory = new MessageDispatcherFactory(ctx.dispatcher); asynchronousScheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(2, new NamingThreadFactory("sip_servlets_congestion_control"), new ThreadPoolExecutor.CallerRunsPolicy()); - asynchronousScheduledThreadPoolExecutor.prestartAllCoreThreads(); - logger.info("AsynchronousThreadPoolExecutor size is " + sipService.getDispatcherThreadPoolSize()); + asynchronousScheduledThreadPoolExecutor.prestartAllCoreThreads(); + logger.info("AsynchronousThreadPoolExecutor size is " + sipService.getDispatcherThreadPoolSize()); asynchronousExecutor = new ThreadPoolExecutor(sipService.getDispatcherThreadPoolSize(), 64, 90, TimeUnit.SECONDS, new LinkedBlockingQueue(), new ThreadFactory() { private int threadCount = 0; - + public Thread newThread(Runnable pRunnable) { Thread thread = new Thread(pRunnable, String.format("%s-%d", "MSS-Executor-Thread", threadCount++)); thread.setPriority(((SipStackImpl)sipStack).getThreadPriority()); return thread; } - }); + }); asynchronousExecutor.setRejectedExecutionHandler(new RejectedExecutionHandler(){ public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { logger.warn("Executor job was rejected " + r.toString()); - + } - + }); + + if (getGatherStatistics()) { + statsReporter = new RestcommStatsReporter(); + + String statisticsServer = Version.getVersionProperty(Version.STATISTICS_SERVER); + if(statisticsServer == null || !statisticsServer.contains("http")) { + statisticsServer = Version.DEFAULT_STATISTICS_SERVER; + } + //define remote server address (optionally) + statsReporter.setRemoteServer(statisticsServer); + String projectName = System.getProperty("RestcommProjectName", "sipservlets"); + String projectType = System.getProperty("RestcommProjectType", "community"); + String projectVersion = System.getProperty("RestcommProjectVersion", Version.getVersionProperty(Version.RELEASE_VERSION)); + if(logger.isDebugEnabled()) { + logger.debug("Restcomm Stats " + projectName + " " + projectType + " " + projectVersion); + } + statsReporter.setProjectName(projectName); + statsReporter.setProjectType(projectType); + statsReporter.setVersion(projectVersion); + } + + } + } + @Override + public void init() throws IllegalArgumentException { + fsm.fireEvent(fsm.new Event(DispatcherFSM.EventType.INIT)); } - /** - * {@inheritDoc} - */ - public void start() { - statusLock.lock(); - try { - if(started) { - return; - } - started = Boolean.TRUE; - } finally { - statusLock.unlock(); - } + + @Override + public void putInService() throws IllegalArgumentException { + fsm.fireEvent(fsm.new Event(DispatcherFSM.EventType.IN_SERVICE)); + } + + + class StartAction implements DispatcherFSM.Action { + @Override + public void execute(DispatcherFSM.Context ctx) { congestionControlTimerTask = new CongestionControlTimerTask(); - if(congestionControlTimerFuture == null && congestionControlCheckingInterval > 0) { + if(congestionControlTimerFuture == null && congestionControlCheckingInterval > 0) { congestionControlTimerFuture = asynchronousScheduledThreadPoolExecutor.scheduleWithFixedDelay(congestionControlTimerTask, congestionControlCheckingInterval, congestionControlCheckingInterval, TimeUnit.MILLISECONDS); if(logger.isInfoEnabled()) { logger.info("Congestion control background task started and checking every " + congestionControlCheckingInterval + " milliseconds."); @@ -462,160 +500,192 @@ public void start() { logger.info("No Congestion control background task started since the checking interval is equals to " + congestionControlCheckingInterval + " milliseconds."); } } + if (statsReporter != null) { + //define periodicy - default to once a day + statsReporter.start(86400, TimeUnit.SECONDS); + } + Version.printVersion(); // outbound interfaces set here and not in sipstandardcontext because // depending on jboss or tomcat context can be started before or after // connectors resetOutboundInterfaces(); - + // Starting the SIP Stack right before we notify the apps that the container is ready - // to serve and dispatch SIP Messages. + // to serve and dispatch SIP Messages. // In addition, the LB Heartbeat will be started only when apps are ready try { startSipStack(); } catch (Exception e) { throw new IllegalStateException("The SIP Stack couldn't be started " , e); } - - //JSR 289 Section 2.1.1 Step 4.If present invoke SipServletListener.servletInitialized() on each of initialized Servlet's listeners. - for (SipContext sipContext : applicationDeployed.values()) { - sipContext.notifySipContextListeners(new SipContextEventImpl(SipContextEventType.SERVLET_INITIALIZED, null)); - } - + + if(logger.isDebugEnabled()) { logger.debug("SipApplicationDispatcher Started"); - } - } - + } + } + + } + @Override + public void start() { + fsm.fireEvent(fsm .new Event(DispatcherFSM.EventType.START)); + } + /* * (non-Javadoc) * @see org.mobicents.servlet.sip.core.SipApplicationDispatcher#stopGracefully(long) */ public void stopGracefully(long timeToWait) { sipService.stopGracefully(timeToWait); - } - - /** - * {@inheritDoc} - */ - public void stop() { - statusLock.lock(); - try { - if(!started) { - return; - } - started = Boolean.FALSE; - } finally { - statusLock.unlock(); } + + class StopAction implements DispatcherFSM.Action { + + @Override + public void execute(DispatcherFSM.Context ctx) { asynchronousScheduledThreadPoolExecutor.shutdownNow(); - asynchronousExecutor.shutdownNow(); + asynchronousExecutor.shutdownNow(); sipApplicationRouter.destroy(); - - stopSipStack(); - + + stopSipStack(); + + if (statsReporter != null) { + try { + statsReporter.stop(); + } catch (RuntimeException lExp) { + logger.warn("License not found", lExp); + } + } + if(oname != null) { try { ((MBeanServer) MBeanServerFactory.findMBeanServer(null).get(0)).unregisterMBean(oname); } catch (Exception e) { logger.error("Impossible to register the Sip Application dispatcher in domain" + domain, e); } - } + } if(logger.isDebugEnabled()) { logger.debug("SipApplicationDispatcher Stopped"); - } + } } + + } + + public void stop() { + fsm.fireEvent(fsm .new Event(DispatcherFSM.EventType.STOP)); } - + + class AddAppAction implements DispatcherFSM.Action { + + + @Override + public void execute(DispatcherFSM.Context ctx) { + SipContext sipApplication = (SipContext)ctx.lastEvent.data.get(CONTEXT_EV_DATA); + String sipApplicationName = sipApplication.getApplicationName(); + + if (logger.isDebugEnabled()) { + logger.debug("Adding the following sip servlet application " + sipApplicationName + ", SipContext=" + sipApplication); + } + if (sipApplicationName == null) { + throw new IllegalArgumentException("Something when wrong while initializing a sip servlets or converged application "); + } + if (sipApplication == null) { + throw new IllegalArgumentException("Something when wrong while initializing the following application " + sipApplicationName); + } + // Issue 1417 http://code.google.com/p/mobicents/issues/detail?id=1417 + // Deploy 2 applications with the same app-name should fail + SipContext app = applicationDeployed.get(sipApplicationName); + if (app != null) { + logger.error("An application with the app name " + sipApplicationName + " is already deployed under the following context " + app.getPath()); + throw new IllegalStateException("An application with the app name " + sipApplicationName + " is already deployed under the following context " + app.getPath()); + } + //if the application has not set any concurrency control mode, we default to the container wide one + if (sipApplication.getConcurrencyControlMode() == null) { + sipApplication.setConcurrencyControlMode(concurrencyControlMode); + if (logger.isInfoEnabled()) { + logger.info("No concurrency control mode for application " + sipApplicationName + " , defaulting to the container wide one : " + concurrencyControlMode); + } + } else if (logger.isInfoEnabled()) { + logger.info("Concurrency control mode for application " + sipApplicationName + " is " + sipApplication.getConcurrencyControlMode()); + } + sipApplication.getServletContext().setAttribute(ConcurrencyControlMode.class.getCanonicalName(), sipApplication.getConcurrencyControlMode()); + + applicationDeployed.put(sipApplicationName, sipApplication); + + String hash = GenericUtils.hashString(sipApplicationName, tagHashMaxLength); + mdToApplicationName.put(hash, sipApplicationName); + applicationNameToMd.put(sipApplicationName, hash); + + List newlyApplicationsDeployed = new ArrayList(); + newlyApplicationsDeployed.add(sipApplicationName); + if (sipApplicationRouter != null) { + // https://code.google.com/p/sipservlets/issues/detail?id=277 + // sipApplicationRouter may not be initialized yet if container is fast to boot + sipApplicationRouter.applicationDeployed(newlyApplicationsDeployed); + } + + if (logger.isInfoEnabled()) { + logger.info(this + " the following sip servlet application has been added : " + sipApplicationName); + } + if (logger.isInfoEnabled()) { + logger.info("It contains the following Sip Servlets : "); + for (String servletName : sipApplication.getChildrenMap().keySet()) { + logger.info("SipApplicationName : " + sipApplicationName + "/ServletName : " + servletName); + } + if (sipApplication.getSipRubyController() != null) { + logger.info("It contains the following Sip Ruby Controller : " + sipApplication.getSipRubyController()); + } + } + } + + } + + static final String CONTEXT_EV_DATA = "Context"; /** * {@inheritDoc} */ public void addSipApplication(String sipApplicationName, SipContext sipApplication) { - if(logger.isDebugEnabled()) { - logger.debug("Adding the following sip servlet application " + sipApplicationName + ", SipContext=" + sipApplication); - } - if(sipApplicationName == null) { - throw new IllegalArgumentException("Something when wrong while initializing a sip servlets or converged application "); - } - if(sipApplication == null) { - throw new IllegalArgumentException("Something when wrong while initializing the following application " + sipApplicationName); - } - // Issue 1417 http://code.google.com/p/mobicents/issues/detail?id=1417 - // Deploy 2 applications with the same app-name should fail - SipContext app = applicationDeployed.get(sipApplicationName); - if(app != null) { - logger.error("An application with the app name " + sipApplicationName + " is already deployed under the following context " + app.getPath()); - throw new IllegalStateException("An application with the app name " + sipApplicationName + " is already deployed under the following context " + app.getPath()); - } - //if the application has not set any concurrency control mode, we default to the container wide one - if(sipApplication.getConcurrencyControlMode() == null) { - sipApplication.setConcurrencyControlMode(concurrencyControlMode); - if(logger.isInfoEnabled()) { - logger.info("No concurrency control mode for application " + sipApplicationName + " , defaulting to the container wide one : " + concurrencyControlMode); - } - } else { - if(logger.isInfoEnabled()) { - logger.info("Concurrency control mode for application " + sipApplicationName + " is " + sipApplication.getConcurrencyControlMode()); - } - } - sipApplication.getServletContext().setAttribute(ConcurrencyControlMode.class.getCanonicalName(), sipApplication.getConcurrencyControlMode()); - - applicationDeployed.put(sipApplicationName, sipApplication); - - String hash = GenericUtils.hashString(sipApplicationName, tagHashMaxLength); - mdToApplicationName.put(hash, sipApplicationName); - applicationNameToMd.put(sipApplicationName, hash); - - List newlyApplicationsDeployed = new ArrayList(); - newlyApplicationsDeployed.add(sipApplicationName); - if(sipApplicationRouter != null) { - // https://code.google.com/p/sipservlets/issues/detail?id=277 - // sipApplicationRouter may not be initialized yet if container is fast to boot - sipApplicationRouter.applicationDeployed(newlyApplicationsDeployed); - } - //if the ApplicationDispatcher is started, notification is sent that the servlets are ready for service - //otherwise the notification will be delayed until the ApplicationDispatcher has started - statusLock.lock(); - try { - if(started) { - sipApplication.notifySipContextListeners(new SipContextEventImpl(SipContextEventType.SERVLET_INITIALIZED, null)); - } - } finally { - statusLock.unlock(); - } - if(logger.isInfoEnabled()) { - logger.info(this + " the following sip servlet application has been added : " + sipApplicationName); - } - if(logger.isInfoEnabled()) { - logger.info("It contains the following Sip Servlets : "); - for(String servletName : sipApplication.getChildrenMap().keySet()) { - logger.info("SipApplicationName : " + sipApplicationName + "/ServletName : " + servletName); - } - if(sipApplication.getSipRubyController() != null) { - logger.info("It contains the following Sip Ruby Controller : " + sipApplication.getSipRubyController()); - } - } + DispatcherFSM.Event ev = fsm.new Event(DispatcherFSM.EventType.ADD_APP); + ev.data.put(CONTEXT_EV_DATA, sipApplication); + fsm.fireEvent(ev); } - /** - * {@inheritDoc} - */ - public SipContext removeSipApplication(String sipApplicationName) { - SipContext sipContext = applicationDeployed.remove(sipApplicationName); - List applicationsUndeployed = new ArrayList(); - applicationsUndeployed.add(sipApplicationName); - sipApplicationRouter.applicationUndeployed(applicationsUndeployed); - if(sipContext != null) { - sipContext.getSipManager().removeAllSessions(); - } - String hash = GenericUtils.hashString(sipApplicationName, tagHashMaxLength); - mdToApplicationName.remove(hash); - applicationNameToMd.remove(sipApplicationName); - if(logger.isInfoEnabled()) { - logger.info("the following sip servlet application has been removed : " + sipApplicationName); - } - return sipContext; - } - - + + static final String APP_NAME = "AppName"; + + class RemoveApp implements DispatcherFSM.Action { + + @Override + public void execute(DispatcherFSM.Context ctx) { + String sipApplicationName = (String) ctx.lastEvent.data.get(APP_NAME); + SipContext sipContext = applicationDeployed.remove(sipApplicationName); + List applicationsUndeployed = new ArrayList(); + applicationsUndeployed.add(sipApplicationName); + sipApplicationRouter.applicationUndeployed(applicationsUndeployed); + if (sipContext != null) { + sipContext.getSipManager().removeAllSessions(); + } + String hash = GenericUtils.hashString(sipApplicationName, tagHashMaxLength); + mdToApplicationName.remove(hash); + applicationNameToMd.remove(sipApplicationName); + if (logger.isInfoEnabled()) { + logger.info("the following sip servlet application has been removed : " + sipApplicationName); + } + ctx.lastEvent.data.put(CONTEXT_EV_DATA, sipContext); + } + + } + + /** + * {@inheritDoc} + */ + public SipContext removeSipApplication(String sipApplicationName) { + DispatcherFSM.Event ev = fsm.new Event(DispatcherFSM.EventType.REMOVE_APP); + ev.data.put(APP_NAME, sipApplicationName); + fsm.fireEvent(ev); + return (SipContext) ev.data.get(CONTEXT_EV_DATA); + } + + /* * (non-Javadoc) * @see javax.sip.SipListener#processIOException(javax.sip.IOExceptionEvent) @@ -623,19 +693,19 @@ public SipContext removeSipApplication(String sipApplicationName) { public void processIOException(IOExceptionEvent event) { if(event instanceof IOExceptionEventExt && ((IOExceptionEventExt)event).getReason() == gov.nist.javax.sip.IOExceptionEventExt.Reason.KeepAliveTimeout) { IOExceptionEventExt keepAliveTimeout = ((IOExceptionEventExt)event); - + SipConnector connector = findSipConnector( keepAliveTimeout.getLocalHost(), keepAliveTimeout.getLocalPort(), - keepAliveTimeout.getTransport()); - + keepAliveTimeout.getTransport()); + if(connector != null) { for (SipContext sipContext : applicationDeployed.values()) { - final ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); - sipContext.enterSipContext(); - try { + final ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); + sipContext.enterSipContext(); + try { for (SipConnectorListener connectorListener : sipContext.getListeners().getSipConnectorListeners()) { - try { + try { connectorListener.onKeepAliveTimeout(connector, keepAliveTimeout.getPeerHost(), keepAliveTimeout.getPeerPort()); @@ -643,14 +713,14 @@ public void processIOException(IOExceptionEvent event) { logger.error("SipErrorListener threw exception", t); } } - } finally { + } finally { sipContext.exitSipContext(oldClassLoader); } } // return; } } - if(dnsServerLocator != null && event.getSource() instanceof ClientTransaction) { + if(dnsServerLocator != null && event.getSource() instanceof ClientTransaction) { ClientTransaction ioExceptionTx = (ClientTransaction) event.getSource(); if(ioExceptionTx.getApplicationData() != null) { SipServletMessageImpl sipServletMessageImpl = ((TransactionApplicationData)ioExceptionTx.getApplicationData()).getSipServletMessage(); @@ -663,10 +733,10 @@ public void processIOException(IOExceptionEvent event) { } } } - } + } logger.error("An IOException occured on " + event.getHost() + ":" + event.getPort() + "/" + event.getTransport() + " for source " + event.getSource()); } - + /* * Gives the number of pending messages in all queues for all concurrency control modes. */ @@ -702,10 +772,10 @@ public int getNumberOfPendingMessages() { // } // } // } -// +// // return size; } - + private void analyzeQueueCongestionState() { this.numberOfMessagesInQueue = getNumberOfPendingMessages(); if(rejectSipMessages) { @@ -713,28 +783,28 @@ private void analyzeQueueCongestionState() { String message = "Number of pending messages in the queues : " + numberOfMessagesInQueue + " < to the back to normal queue Size : " + backToNormalQueueSize; logger.warn(message + " => stopping to reject requests"); rejectSipMessages = false; - final CongestionControlEvent congestionControlEvent = new CongestionControlEvent( - org.mobicents.javax.servlet.CongestionControlEvent.Reason.Queue, message); - callbackCongestionControlListener(rejectSipMessages, congestionControlEvent); + final CongestionControlEvent congestionControlEvent = new CongestionStoppedEvent( + org.mobicents.javax.servlet.CongestionControlEvent.Reason.Queue, message); + callbackContainerEventListener(congestionControlEvent); } } else { if(numberOfMessagesInQueue > queueSize) { String message = "Number of pending messages in the queues : " + numberOfMessagesInQueue + " > to the queue Size : " + queueSize; logger.warn(message + " => starting to reject requests"); rejectSipMessages = true; - final CongestionControlEvent congestionControlEvent = new CongestionControlEvent( - org.mobicents.javax.servlet.CongestionControlEvent.Reason.Queue, message); - callbackCongestionControlListener(rejectSipMessages, congestionControlEvent); + final CongestionControlEvent congestionControlEvent = new CongestionStartedEvent( + org.mobicents.javax.servlet.CongestionControlEvent.Reason.Queue, message); + callbackContainerEventListener(congestionControlEvent); } } } - + private void analyzeMemory() { - Runtime runtime = Runtime.getRuntime(); - - double allocatedMemory = runtime.totalMemory() / (double) 1024; + Runtime runtime = Runtime.getRuntime(); + + double allocatedMemory = runtime.totalMemory() / (double) 1024; double freeMemory = runtime.freeMemory() / (double) 1024; - + double totalFreeMemory = freeMemory + (maxMemory - allocatedMemory); this.percentageOfMemoryUsed= (((double)100) - ((totalFreeMemory / maxMemory) * ((double)100))); @@ -742,44 +812,50 @@ private void analyzeMemory() { if(percentageOfMemoryUsed < backToNormalMemoryThreshold) { String message = "Memory used: " + percentageOfMemoryUsed + "% < to the back to normal memory threshold : " + backToNormalMemoryThreshold+ "%"; logger.warn(message + " => stopping to reject requests"); - memoryToHigh = false; - final CongestionControlEvent congestionControlEvent = new CongestionControlEvent( - org.mobicents.javax.servlet.CongestionControlEvent.Reason.Memory, message); - callbackCongestionControlListener(memoryToHigh, congestionControlEvent); + memoryToHigh = false; + final CongestionControlEvent congestionControlEvent = new CongestionStoppedEvent( + org.mobicents.javax.servlet.CongestionControlEvent.Reason.Memory, message); + callbackContainerEventListener(congestionControlEvent); } } else { if(percentageOfMemoryUsed > memoryThreshold) { String message = "Memory used: " + percentageOfMemoryUsed + "% > to the memory threshold : " + memoryThreshold+ "%"; logger.warn(message + " => starting to reject requests"); memoryToHigh = true; - final CongestionControlEvent congestionControlEvent = new CongestionControlEvent( - org.mobicents.javax.servlet.CongestionControlEvent.Reason.Memory, message); - callbackCongestionControlListener(memoryToHigh, congestionControlEvent); + final CongestionControlEvent congestionControlEvent = new CongestionStartedEvent( + org.mobicents.javax.servlet.CongestionControlEvent.Reason.Memory, message); + callbackContainerEventListener(congestionControlEvent); } } } - + /* * (non-Javadoc) * @see javax.sip.SipListener#processRequest(javax.sip.RequestEvent) */ - public void processRequest(RequestEvent requestEvent) { + public void processRequest(RequestEvent requestEvent) { final SipProvider sipProvider = (SipProvider)requestEvent.getSource(); ServerTransaction requestTransaction = requestEvent.getServerTransaction(); final Dialog dialog = requestEvent.getDialog(); + if(logger.isDebugEnabled()) { + logger.debug("processRequest - dialog=" + dialog); + if (dialog != null){ + logger.debug("processRequest - dialog.getDialogId()=" + dialog.getDialogId()); + } + } final Request request = requestEvent.getRequest(); // self routing makes the application data cloned, so we make sure to nullify it ((MessageExt)request).setApplicationData(null); final String requestMethod = request.getMethod(); - + final RouteHeader routeHeader = (RouteHeader) request .getHeader(RouteHeader.NAME); - - // congestion control is done here only if we drop messages to avoid generating STX + + // congestion control is done here only if we drop messages to avoid generating STX if(CongestionControlPolicy.DropMessage.equals(congestionControlPolicy) && controlCongestion(request, null, dialog, routeHeader, sipProvider)) { return; } - + if((rejectSipMessages || memoryToHigh) && CongestionControlPolicy.DropMessage.equals(congestionControlPolicy)) { String method = requestEvent.getRequest().getMethod(); boolean goodMethod = method.equals(Request.ACK) || method.equals(Request.PRACK) || method.equals(Request.BYE) || method.equals(Request.CANCEL) || method.equals(Request.UPDATE) || method.equals(Request.INFO); @@ -787,17 +863,17 @@ public void processRequest(RequestEvent requestEvent) { logger.debug("congestion control good method " + goodMethod + ", dialog " + dialog + " routeHeader " + routeHeader); } if(!goodMethod) { - if(dialog == null && (routeHeader == null || ((Parameters)routeHeader.getAddress().getURI()).getParameter(MessageDispatcher.RR_PARAM_PROXY_APP) == null)) { + if(dialog == null && (routeHeader == null || ((Parameters)routeHeader.getAddress().getURI()).getParameter(MessageDispatcher.RR_PARAM_PROXY_APP) == null)) { logger.error("dropping request, memory is too high or too many messages present in queues"); return; } } - } - + } + try { if(logger.isDebugEnabled()) { logger.debug("sipApplicationDispatcher " + this + ", Got a request event " + request.toString()); - } + } if (!Request.ACK.equals(requestMethod) && requestTransaction == null ) { try { //folsson fix : Workaround broken Cisco 7940/7912 @@ -805,42 +881,50 @@ public void processRequest(RequestEvent requestEvent) { request.setHeader(SipFactoryImpl.headerFactory.createMaxForwardsHeader(70)); } requestTransaction = sipProvider.getNewServerTransaction(request); - JainSipUtils.setTransactionTimers(((TransactionExt)requestTransaction), this); + JainSipUtils.setTransactionTimers(((TransactionExt)requestTransaction), this); } catch ( TransactionUnavailableException tae) { logger.error("cannot get a new Server transaction for this request " + request, tae); - // Sends a 500 Internal server error and stops processing. - MessageDispatcher.sendErrorResponse(this, Response.SERVER_INTERNAL_ERROR, requestTransaction, request, sipProvider); + // Sends a 500 Internal server error and stops processing. + MessageDispatcher.sendErrorResponse(this, Response.SERVER_INTERNAL_ERROR, requestTransaction, request, sipProvider); return; } catch ( TransactionAlreadyExistsException taex ) { // This is a retransmission so just return. - return; - } - } + return; + } + } final ServerTransaction transaction = requestTransaction; - + if(logger.isDebugEnabled()) { - logger.debug("ServerTx ref " + transaction); - logger.debug("Dialog ref " + dialog); + logger.debug("ServerTx ref " + transaction); + logger.debug("Dialog ref " + dialog); } - + final SipServletRequestImpl sipServletRequest = (SipServletRequestImpl) sipFactoryImpl.getMobicentsSipServletMessageFactory().createSipServletRequest( request, null, transaction, dialog, - JainSipUtils.DIALOG_CREATING_METHODS.contains(requestMethod)); + JainSipUtils.DIALOG_CREATING_METHODS.contains(requestMethod)); updateRequestsStatistics(request, true); + + if(logger.isDebugEnabled()) { + logger.debug("processRequest - routing state=" + sipServletRequest.getRoutingState()); + } + // Check if the request is meant for me. If so, strip the topmost // Route header. - + //Popping the router header if it's for the container as //specified in JSR 289 - Section 15.8 if(!isRouteExternal(routeHeader)) { + if(logger.isDebugEnabled()) { + logger.debug("processRequest - not external - =routeHeader" + routeHeader); + } request.removeFirst(RouteHeader.NAME); sipServletRequest.setPoppedRoute(routeHeader); final Parameters poppedAddress = (Parameters)routeHeader.getAddress().getURI(); - if(poppedAddress.getParameter(MessageDispatcher.RR_PARAM_PROXY_APP) != null || - // Issue 2850 : Use Request-URI custom Mobicents parameters to route request for misbehaving agents, workaround for Cisco-SIPGateway/IOS-12.x user agent + if(poppedAddress.getParameter(MessageDispatcher.RR_PARAM_PROXY_APP) != null || + // Issue 2850 : Use Request-URI custom Mobicents parameters to route request for misbehaving agents, workaround for Cisco-SIPGateway/IOS-12.x user agent (request.getRequestURI() instanceof javax.sip.address.SipURI && ((Parameters)request.getRequestURI()).getParameter(MessageDispatcher.RR_PARAM_PROXY_APP) != null)) { if(logger.isDebugEnabled()) { logger.debug("the request is for a proxy application, thus it is a subsequent request "); @@ -848,74 +932,80 @@ public void processRequest(RequestEvent requestEvent) { sipServletRequest.setRoutingState(RoutingState.SUBSEQUENT); } if(transaction != null) { + if(logger.isDebugEnabled()) { + logger.debug("processRequest - transaction not null, transaction.getDialog()=" + transaction.getDialog()); + if (transaction.getDialog() != null){ + logger.debug("processRequest - transaction dialog not null, transaction.getDialog().getDialogId()=" + transaction.getDialog().getDialogId()); + } + } TransactionApplicationData transactionApplicationData = (TransactionApplicationData)transaction.getApplicationData(); - if(transactionApplicationData != null && transactionApplicationData.getInitialPoppedRoute() == null) { + if(transactionApplicationData != null && transactionApplicationData.getInitialPoppedRoute() == null) { + if (transaction.getDialog() != null){ + logger.debug("processRequest - setInitialPoppedRoute, routeHeader.getAddress()=" + routeHeader.getAddress()); + } transactionApplicationData.setInitialPoppedRoute(new AddressImpl(routeHeader.getAddress(), null, ModifiableRule.NotModifiable)); } } - } + } if(logger.isDebugEnabled()) { logger.debug("Routing State " + sipServletRequest.getRoutingState()); } - + try { // congestion control is done here so that the STX is created and a response can be generated back - // and that + // and that if(controlCongestion(request, sipServletRequest, dialog, routeHeader, sipProvider)) { return; } + + if(logger.isDebugEnabled()) { + logger.debug("processRequest - dispatching request with sipServletRequest.getAppSessionId()=" + sipServletRequest.getAppSessionId()); + } + messageDispatcherFactory.getRequestDispatcher(sipServletRequest, this). dispatchMessage(sipProvider, sipServletRequest); } catch (DispatcherException e) { - logger.error("Unexpected exception while processing request " + request,e); - // Sends an error response if the subsequent request is not an ACK (otherwise it violates RF3261) and stops processing. + // Change log level from Error to debug: https://github.com/RestComm/jain-sip/issues/116 + if (logger.isDebugEnabled()) { + logger.debug("Unexpected exception while processing request " + request,e); + } + // Sends an error response if the subsequent request is not an ACK (otherwise it violates RF3261) and stops processing. if(!Request.ACK.equalsIgnoreCase(requestMethod)) { MessageDispatcher.sendErrorResponse(this, e.getErrorCode(), sipServletRequest, sipProvider); } return; } catch (Throwable e) { - logger.error("Unexpected exception while processing request " + request,e); - // Sends a 500 Internal server error if the subsequent request is not an ACK (otherwise it violates RF3261) and stops processing. + // Change log level from Error to debug: https://github.com/RestComm/jain-sip/issues/116 + if (logger.isDebugEnabled()) { + logger.debug("Unexpected exception while processing request " + request,e); + } + // Sends a 500 Internal server error if the subsequent request is not an ACK (otherwise it violates RF3261) and stops processing. if(!Request.ACK.equalsIgnoreCase(requestMethod)) { MessageDispatcher.sendErrorResponse(this, Response.SERVER_INTERNAL_ERROR, sipServletRequest, sipProvider); } return; } } catch (Throwable e) { - logger.error("Unexpected exception while processing request " + request,e); - // Sends a 500 Internal server error if the subsequent request is not an ACK (otherwise it violates RF3261) and stops processing. + // Change log level from Error to debug: https://github.com/RestComm/jain-sip/issues/116 + if (logger.isDebugEnabled()) { + logger.debug("Unexpected exception while processing request " + request,e); + } + // Sends a 500 Internal server error if the subsequent request is not an ACK (otherwise it violates RF3261) and stops processing. if(!Request.ACK.equalsIgnoreCase(request.getMethod())) { MessageDispatcher.sendErrorResponse(this, Response.SERVER_INTERNAL_ERROR, requestTransaction, request, sipProvider); } return; } } - - private void callbackCongestionControlListener(boolean triggered, CongestionControlEvent congestionControlEvent) { + + private void callbackContainerEventListener(ContainerEvent congestionControlEvent) { for (SipContext sipContext : applicationDeployed.values()) { - final ContainerListener containerListener = - sipContext.getListeners().getContainerListener(); - - if(containerListener != null) { - final ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); - try { - sipContext.enterSipContext(); - try { - if(triggered) { - containerListener.onCongestionControlStarted(congestionControlEvent); - } else { - containerListener.onCongestionControlStopped(congestionControlEvent); - } - } catch (Throwable t) { - logger.error("ContainerListener threw exception", t); - } - } finally { - sipContext.exitSipContext(oldClassLoader); - } - } + sipContext.getListeners().callbackContainerListener(congestionControlEvent); } } + private static final String THROTTLED_RESPONSE = "org.mobicents.servlet.sip.THROTTLED_RESPONSE"; + private boolean controlCongestion(Request request, SipServletRequestImpl sipServletRequest, Dialog dialog, RouteHeader routeHeader, SipProvider sipProvider) { if(rejectSipMessages || memoryToHigh) { String method = request.getMethod(); @@ -936,26 +1026,29 @@ private boolean controlCongestion(Request request, SipServletRequestImpl sipServ } else if (memoryToHigh) { message = "Memory used: " + percentageOfMemoryUsed + "% > to the memory threshold : " + memoryThreshold + "%"; } - final CongestionControlEvent congestionControlEvent = new CongestionControlEvent( + final RequestThrottledEvent congestionControlEvent = new RequestThrottledEvent(sipServletRequest, org.mobicents.javax.servlet.CongestionControlEvent.Reason.Memory, message); - + for (SipContext sipContext : applicationDeployed.values()) { - final ContainerListener containerListener = + final ContainerListener containerListener = sipContext.getListeners().getContainerListener(); - + if(containerListener != null) { - final ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); - try { - sipContext.enterSipContext(); - try { - sipServletResponse = containerListener.onRequestThrottled(sipServletRequest, congestionControlEvent); + final ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); + try { + sipContext.enterSipContext(); + try { + + containerListener.sendEvent(congestionControlEvent, sipContext.getServletContext()); + sipServletResponse = (SipServletResponse) sipContext.getServletContext().getAttribute(THROTTLED_RESPONSE); + sipServletRequest.getServletContext().removeAttribute(THROTTLED_RESPONSE); } catch (Throwable t) { logger.error("ContainerListener threw exception", t); } - } finally { + } finally { sipContext.exitSipContext(oldClassLoader); } - + if(sipServletResponse != null) { // container listener generated a response, we send it try{ @@ -972,7 +1065,7 @@ private boolean controlCongestion(Request request, SipServletRequestImpl sipServ } // no application implements the container listener or the container listener didn't generate any responses so we send back a generic one. if(sipServletResponse == null) { - MessageDispatcher.sendErrorResponse(this, Response.SERVICE_UNAVAILABLE, (ServerTransaction) sipServletRequest.getTransaction(), request, sipProvider); + MessageDispatcher.sendErrorResponse(this, Response.SERVICE_UNAVAILABLE, (ServerTransaction) sipServletRequest.getTransaction(), request, sipProvider); return true; } } @@ -980,13 +1073,13 @@ private boolean controlCongestion(Request request, SipServletRequestImpl sipServ } return false; } - + /** * @param requestMethod */ public void updateRequestsStatistics(final Request request, final boolean processed) { if(gatherStatistics) { - AtomicLong requestsStats = null; + AtomicLong requestsStats = null; if(processed) { requestsStats = requestsProcessed; } else { @@ -1011,13 +1104,13 @@ public void updateRequestsStatistics(final Request request, final boolean proces } } } - + /** * @param requestMethod */ public void updateResponseStatistics(final Response response, final boolean processed) { if(gatherStatistics) { - AtomicLong responsesStats = null; + AtomicLong responsesStats = null; Map responsesStatsStatusCode = null; if(processed) { responsesStats = responsesProcessed; @@ -1026,7 +1119,7 @@ public void updateResponseStatistics(final Response response, final boolean proc responsesStats = responsesSent; responsesStatsStatusCode = responsesSentByStatusCode; } - responsesStats.incrementAndGet(); + responsesStats.incrementAndGet(); final int statusCode = response.getStatusCode(); int statusCodeDiv = statusCode / 100; switch (statusCodeDiv) { @@ -1057,22 +1150,37 @@ public void updateResponseStatistics(final Response response, final boolean proc case 9: responsesStatsStatusCode.get("9XX").incrementAndGet(); break; - } + } } } + @Override + public void incCalls() { + counterCalls.inc(); + } + + @Override + public void incMessages() { + counterMessages.inc(); + } + + @Override + public void incSeconds(long seconds) { + counterSeconds.inc(seconds); + } + /* * (non-Javadoc) * @see javax.sip.SipListener#processResponse(javax.sip.ResponseEvent) */ public void processResponse(ResponseEvent responseEvent) { - final ResponseEventExt responseEventExt = (ResponseEventExt) responseEvent; + final ResponseEventExt responseEventExt = (ResponseEventExt) responseEvent; final Response response = responseEventExt.getResponse(); - + if(logger.isDebugEnabled()) { logger.debug("Response " + response.toString()); } - + final CSeqHeader cSeqHeader = (CSeqHeader)response.getHeader(CSeqHeader.NAME); //if this is a response to a cancel, the response is dropped if(Request.CANCEL.equalsIgnoreCase(cSeqHeader.getMethod())) { @@ -1084,9 +1192,9 @@ public void processResponse(ResponseEvent responseEvent) { } // self routing makes the application data cloned, so we make sure to nullify it ((MessageExt)response).setApplicationData(null); - + updateResponseStatistics(response, true); - ClientTransaction clientTransaction = responseEventExt.getClientTransaction(); + ClientTransaction clientTransaction = responseEventExt.getClientTransaction(); final Dialog dialog = responseEventExt.getDialog(); final boolean isForkedResponse = responseEventExt.isForkedResponse(); final boolean isRetransmission = responseEventExt.isRetransmission(); @@ -1101,52 +1209,52 @@ public void processResponse(ResponseEvent responseEvent) { logger.debug("Dialog State " + dialog.getState()); } } - // Issue 1468 : Handling forking + // Issue 1468 : Handling forking if(isForkedResponse && originalTransaction != null && !responseEventExt.isRetransmission()) { final Dialog defaultDialog = originalTransaction.getDefaultDialog(); final Dialog orginalTransactionDialog = originalTransaction.getDialog(); - if(logger.isDebugEnabled()) { + if(logger.isDebugEnabled()) { logger.debug("Original Transaction Dialog " + orginalTransactionDialog); logger.debug("Original Transaction Default Dialog " + defaultDialog); } - clientTransaction = originalTransaction; + clientTransaction = originalTransaction; } - + // Transate the response to SipServletResponse - final SipServletResponseImpl sipServletResponse = (SipServletResponseImpl) sipFactoryImpl.getMobicentsSipServletMessageFactory().createSipServletResponse( - response, - clientTransaction, - null, + final SipServletResponseImpl sipServletResponse = (SipServletResponseImpl) sipFactoryImpl.getMobicentsSipServletMessageFactory().createSipServletResponse( + response, + clientTransaction, + null, dialog, true, isRetransmission); - try { + try { messageDispatcherFactory.getResponseDispatcher(sipServletResponse, this). dispatchMessage(((SipProvider)responseEvent.getSource()), sipServletResponse); } catch (Throwable e) { logger.error("An unexpected exception happened while routing the response " + sipServletResponse, e); return; } - } + } /* * (non-Javadoc) * @see javax.sip.SipListener#processDialogTerminated(javax.sip.DialogTerminatedEvent) */ public void processDialogTerminated(final DialogTerminatedEvent dialogTerminatedEvent) { - final Dialog dialog = dialogTerminatedEvent.getDialog(); + final Dialog dialog = dialogTerminatedEvent.getDialog(); if(logger.isDebugEnabled()) { logger.debug("Dialog Terminated => dialog Id : " + dialogTerminatedEvent.getDialog().getDialogId()); } - + getAsynchronousExecutor().execute(new Runnable() { // https://github.com/RestComm/sip-servlets/issues/107 guard against NPEon concurrent cleanup final TransactionApplicationData dialogAppData = (TransactionApplicationData) dialog.getApplicationData(); - public void run() { + public void run() { try { boolean appDataFound = false; - TransactionApplicationData txAppData = null; - if(dialogAppData != null) { + TransactionApplicationData txAppData = null; + if(dialogAppData != null) { if(dialogAppData.getSipServletMessage() == null) { Transaction transaction = dialogAppData.getTransaction(); if(transaction != null && transaction.getApplicationData() != null) { @@ -1155,12 +1263,12 @@ public void run() { } } else { MobicentsSipSessionKey sipSessionKey = dialogAppData.getSipSessionKey(); - tryToInvalidateSession(sipSessionKey, false); + tryToInvalidateSession(sipSessionKey, false); } dialogAppData.cleanUp(); - // since the stack doesn't nullify the app data, we need to do it to let go of the refs + // since the stack doesn't nullify the app data, we need to do it to let go of the refs dialog.setApplicationData(null); - } + } if(!appDataFound && logger.isDebugEnabled()) { logger.debug("no application data for this dialog " + dialog.getDialogId()); } @@ -1176,6 +1284,9 @@ public void run() { * @param sipSessionImpl */ private void tryToInvalidateSession(MobicentsSipSessionKey sipSessionKey, boolean invalidateProxySession) { + if (logger.isDebugEnabled()){ + logger.debug("tryToInvalidateSession - sipSessionKey.getCallId()=" + sipSessionKey.getCallId() + ", sipSessionKey.getFromTag()=" + sipSessionKey.getFromTag() + ", sipSessionKey.getToTag()=" + sipSessionKey.getToTag() + ", sipSessionKey.getApplicationName()=" + sipSessionKey.getApplicationName()); + } //the key can be null if the application already invalidated the session if(sipSessionKey != null) { SipContext sipContext = findSipApplication(sipSessionKey.getApplicationName()); @@ -1183,13 +1294,13 @@ private void tryToInvalidateSession(MobicentsSipSessionKey sipSessionKey, boolea if(sipContext != null) { final ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); try { - sipContext.enterSipContext(); - final SipManager sipManager = sipContext.getSipManager(); + sipContext.enterSipContext(); + final SipManager sipManager = sipContext.getSipManager(); final SipApplicationSessionKey sipApplicationSessionKey = SessionManagerUtil.getSipApplicationSessionKey( - sipSessionKey.getApplicationName(), + sipSessionKey.getApplicationName(), sipSessionKey.getApplicationSessionId(), null); - + MobicentsSipSession sipSessionImpl = null; MobicentsSipApplicationSession sipApplicationSession = null; if(sipManager instanceof DistributableSipManager) { @@ -1199,16 +1310,16 @@ private void tryToInvalidateSession(MobicentsSipSessionKey sipSessionKey, boolea // perf optimization and fix for Issue 1688 : MSS HA on AS5 : Version is null Exception occurs sometimes DistributableSipManager distributableSipManager = (DistributableSipManager) sipManager; sipApplicationSession = distributableSipManager.getSipApplicationSession(sipApplicationSessionKey, false, true); - sipSessionImpl = distributableSipManager.getSipSession(sipSessionKey, false, sipFactoryImpl, sipApplicationSession, true); - } else { + sipSessionImpl = distributableSipManager.getSipSession(sipSessionKey, false, sipFactoryImpl, sipApplicationSession, true); + } else { sipApplicationSession = sipManager.getSipApplicationSession(sipApplicationSessionKey, false); sipSessionImpl = sipManager.getSipSession(sipSessionKey, false, sipFactoryImpl, sipApplicationSession); - } - + } + if(sipSessionImpl != null) { final MobicentsProxy proxy = sipSessionImpl.getProxy(); - if(!invalidateProxySession && - (proxy == null || (proxy != null && + if(!invalidateProxySession && + (proxy == null || (proxy != null && ((proxy.getFinalBranchForSubsequentRequests() != null && (!proxy.getFinalBranchForSubsequentRequests().getRecordRoute()) || proxy.isTerminationSent()))))) { if(logger.isDebugEnabled()) { @@ -1226,7 +1337,7 @@ private void tryToInvalidateSession(MobicentsSipSessionKey sipSessionKey, boolea logger.debug("don't Invalidate Proxy session"); } return; - } + } boolean batchStarted = false; try { sipContext.enterSipApp(sipApplicationSession, sipSessionImpl, false, true); @@ -1238,10 +1349,12 @@ private void tryToInvalidateSession(MobicentsSipSessionKey sipSessionKey, boolea logger.debug("Sip session " + sipSessionKey + " is ready to be invalidated ? :" + sipSessionImpl.isReadyToInvalidateInternal()); } } - if(sipSessionImpl.isValidInternal() && + boolean b2buaOrphaned = sipSessionImpl.isB2BUAOrphan(); + if(sipSessionImpl.isValidInternal() && ( // https://code.google.com/p/sipservlets/issues/detail?id=279 - sipSessionImpl.isReadyToInvalidateInternal()) { - sipSessionImpl.onTerminatedState(); + sipSessionImpl.isReadyToInvalidateInternal() || + b2buaOrphaned)) { + sipSessionImpl.onTerminatedState(); } } finally { sipContext.exitSipAppHa(null, null, batchStarted); @@ -1251,8 +1364,8 @@ private void tryToInvalidateSession(MobicentsSipSessionKey sipSessionKey, boolea if(logger.isDebugEnabled()) { logger.debug("sip session already invalidated" + sipSessionKey); } - } - if(sipApplicationSession != null) { + } + if(sipApplicationSession != null) { try { sipContext.enterSipApp(sipApplicationSession, null, false, true); if(logger.isDebugEnabled()) { @@ -1260,13 +1373,13 @@ private void tryToInvalidateSession(MobicentsSipSessionKey sipSessionKey, boolea if(sipApplicationSession.isValidInternal()) { logger.debug("Sip app session " + sipApplicationSession.getKey() + " is ready to be invalidated ? :" + sipApplicationSession.isReadyToInvalidate()); } - } - if(sipApplicationSession.isValidInternal() && sipApplicationSession.isReadyToInvalidate()) { + } + if(sipApplicationSession.isValidInternal() && sipApplicationSession.isReadyToInvalidate()) { sipApplicationSession.tryToInvalidate(); } } finally { sipContext.exitSipApp(sipApplicationSession, null); - } + } } } finally { @@ -1275,7 +1388,7 @@ private void tryToInvalidateSession(MobicentsSipSessionKey sipSessionKey, boolea } } } - + /* * (non-Javadoc) * @see gov.nist.javax.sip.SipListenerExt#processDialogTimeout(gov.nist.javax.sip.DialogTimeoutEvent) @@ -1284,7 +1397,7 @@ public void processDialogTimeout(final DialogTimeoutEvent timeoutEvent) { final Dialog dialog = timeoutEvent.getDialog(); if(logger.isDebugEnabled()) { logger.info("dialog timeout " + dialog + " reason => " + timeoutEvent.getReason()); - } + } if(timeoutEvent.getReason() == Reason.AckNotReceived) { final TransactionApplicationData tad = (TransactionApplicationData) dialog.getApplicationData(); if(tad != null && tad.getSipServletMessage() != null) { @@ -1293,13 +1406,13 @@ public void processDialogTimeout(final DialogTimeoutEvent timeoutEvent) { final MobicentsSipSessionKey sipSessionKey = sipServletMessage.getSipSessionKey(); final MobicentsSipSession sipSession = sipServletMessage.getSipSession(); getAsynchronousExecutor().execute(new Runnable() { - public void run() { + public void run() { if(logger.isDebugEnabled()) { logger.info("Running process dialog timeout " + dialog + " reason => " + timeoutEvent.getReason()); - } + } try { if(sipSession != null) { - SipContext sipContext = findSipApplication(sipSessionKey.getApplicationName()); + SipContext sipContext = findSipApplication(sipSessionKey.getApplicationName()); //the context can be null if the server is being shutdown if(sipContext != null) { MobicentsSipApplicationSession sipApplicationSession = sipSession.getSipApplicationSession(); @@ -1313,8 +1426,8 @@ public void run() { // Issue 1822 http://code.google.com/p/mobicents/issues/detail?id=1822 // don't delete the dialog so that the app can send the BYE even after the noAckReceived has been called // dialog.delete(); - tryToInvalidateSession(sipSessionKey, false); - } + tryToInvalidateSession(sipSessionKey, false); + } } tad.cleanUp(); tad.cleanUpMessage(); @@ -1338,7 +1451,7 @@ public SipConnector findSipConnector(String ipAddress, int port, String transpor } return null; } - + /* * (non-Javadoc) * @see javax.sip.SipListener#processTimeout(javax.sip.TimeoutEvent) @@ -1374,7 +1487,7 @@ public void run() { logger.debug("time out happened on sipSession " + sipSession); } if(sipSession != null) { - SipContext sipContext = findSipApplication(sipSessionKey.getApplicationName()); + SipContext sipContext = findSipApplication(sipSessionKey.getApplicationName()); //the context can be null if the server is being shutdown if(sipContext != null) { MobicentsSipApplicationSession sipApplicationSession = sipSession.getSipApplicationSession(); @@ -1383,7 +1496,7 @@ public void run() { MobicentsB2BUAHelper b2buaHelperImpl = sipSession.getB2buaHelper(); if(b2buaHelperImpl != null && tad.getSipServletMessage() instanceof SipServletRequestImpl) { - b2buaHelperImpl.unlinkOriginalRequestInternal((SipServletRequestImpl)tad.getSipServletMessage(), false); + b2buaHelperImpl.unlinkRequestInternal((SipServletRequestImpl)tad.getSipServletMessage(), false); } // naoki : Fix for Issue 1618 http://code.google.com/p/mobicents/issues/detail?id=1618 on Timeout don't do the 408 processing for Server Transactions if(logger.isDebugEnabled()) { @@ -1395,7 +1508,7 @@ public void run() { if(proxyBranchImpl != null) { ProxyImpl proxy = (ProxyImpl) proxyBranchImpl.getProxy(); if(proxy.getFinalBranchForSubsequentRequests() != null) { - tad.cleanUp(); + tad.cleanUp(); transaction.setApplicationData(null); return; } @@ -1437,7 +1550,7 @@ public void run() { } } // don't clean up for the same reason we don't invalidate the sip session right above - tad.cleanUp(); + tad.cleanUp(); transaction.setApplicationData(null); } catch (Exception e) { logger.error("Problem handling timeout", e); @@ -1446,7 +1559,7 @@ public void run() { }); } } - + private boolean checkForAckNotReceived(SipServletMessageImpl sipServletMessage) { //notifying SipErrorListener that no ACK has been received for a UAS only final MobicentsSipSession sipSession = sipServletMessage.getSipSession(); @@ -1455,32 +1568,32 @@ private boolean checkForAckNotReceived(SipServletMessageImpl sipServletMessage) final MobicentsProxy proxy = sipSession.getProxy(); if(logger.isDebugEnabled()) { logger.debug("checkForAckNotReceived : request " + sipServletMessage + " last Final Response " + lastFinalResponse); - } + } boolean notifiedApplication = false; if(sipServletMessage instanceof SipServletRequestImpl && Request.INVITE.equals(sipServletMessage.getMethod()) && proxy == null && lastFinalResponse != null) { final SipContext sipContext = sipSession.getSipApplicationSession().getSipContext(); - final List sipErrorListeners = + final List sipErrorListeners = sipContext.getListeners().getSipErrorListeners(); - - final ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); - try { - sipContext.enterSipContext(); - + + final ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); + try { + sipContext.enterSipContext(); + final SipErrorEvent sipErrorEvent = new SipErrorEvent( - (SipServletRequest)sipServletMessage, + (SipServletRequest)sipServletMessage, lastFinalResponse); - + for (SipErrorListener sipErrorListener : sipErrorListeners) { - try { + try { notifiedApplication = true; sipErrorListener.noAckReceived(sipErrorEvent); } catch (Throwable t) { logger.error("SipErrorListener threw exception", t); } } - } finally { + } finally { sipContext.exitSipContext(oldClassLoader); } final Dialog dialog = sipSession.getSessionCreatingDialog(); @@ -1489,8 +1602,8 @@ private boolean checkForAckNotReceived(SipServletMessageImpl sipServletMessage) dialog != null && dialog.getState() != null && !dialog.getState().equals(DialogState.TERMINATED)) { // Issue 1822 http://code.google.com/p/mobicents/issues/detail?id=1822 // RFC 3261 Section 13.3.1.4 The INVITE is Accepted - // "If the server retransmits the 2xx response for 64*T1 seconds without receiving an ACK, - // the dialog is confirmed, but the session SHOULD be terminated. + // "If the server retransmits the 2xx response for 64*T1 seconds without receiving an ACK, + // the dialog is confirmed, but the session SHOULD be terminated. // This is accomplished with a BYE, as described in Section 15." SipServletRequest bye = sipSession.createRequest(Request.BYE); if(logger.isDebugEnabled()) { @@ -1505,7 +1618,7 @@ private boolean checkForAckNotReceived(SipServletMessageImpl sipServletMessage) } return notifiedApplication; } - + private boolean checkForPrackNotReceived(SipServletMessageImpl sipServletMessage) { //notifying SipErrorListener that no ACK has been received for a UAS only final MobicentsSipSession sipSession = sipServletMessage.getSipSession(); @@ -1520,18 +1633,18 @@ private boolean checkForPrackNotReceived(SipServletMessageImpl sipServletMessage proxy == null && lastInfoResponse != null) { final SipContext sipContext = sipSession.getSipApplicationSession().getSipContext(); - final List sipErrorListeners = + final List sipErrorListeners = sipContext.getListeners().getSipErrorListeners(); - + final ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); - try { - sipContext.enterSipContext(); + try { + sipContext.enterSipContext(); final SipErrorEvent sipErrorEvent = new SipErrorEvent( - (SipServletRequest)sipServletMessage, + (SipServletRequest)sipServletMessage, lastInfoResponse); for (SipErrorListener sipErrorListener : sipErrorListeners) { - try { + try { notifiedApplication = true; sipErrorListener.noPrackReceived(sipErrorEvent); } catch (Throwable t) { @@ -1540,11 +1653,11 @@ private boolean checkForPrackNotReceived(SipServletMessageImpl sipServletMessage } } finally { sipContext.exitSipContext(oldClassLoader); - } + } } return notifiedApplication; } - + /* * (non-Javadoc) * @see javax.sip.SipListener#processTransactionTerminated(javax.sip.TransactionTerminatedEvent) @@ -1559,8 +1672,8 @@ public void processTransactionTerminated(final TransactionTerminatedEvent transa final Transaction transaction = eventTransaction; if(logger.isDebugEnabled()) { logger.info("transaction " + transaction + " terminated => " + transaction.getRequest()); - } - + } + final TransactionApplicationData tad = (TransactionApplicationData) transaction.getApplicationData(); final String branchId = transaction.getBranchId(); if(tad != null && tad.getSipServletMessage() != null) { @@ -1573,8 +1686,8 @@ public void run() { try { if(logger.isDebugEnabled()) { logger.info("transaction " + transaction + " terminated => " + sipServletMessageImpl); - } - + } + MobicentsB2BUAHelper b2buaHelperImpl = null; if(sipSession != null) { b2buaHelperImpl = sipSession.getB2buaHelper(); @@ -1584,9 +1697,9 @@ public void run() { logger.debug("no sip session were returned for this key " + sipServletMessageImpl.getSipSessionKey() + " and message " + sipServletMessageImpl); } } - - if(tad.getProxyBranch() != null) { - tad.getProxyBranch().removeTransaction(branchId); + ProxyBranchImpl proxyBranch = tad.getProxyBranch(); + if(proxyBranch != null) { + proxyBranch.removeTransaction(branchId); } // Issue 1333 : B2buaHelper.getPendingMessages(linkedSession, UAMode.UAC) returns empty list @@ -1594,26 +1707,24 @@ public void run() { // to create the ACK on second leg for B2BUA apps if(sipSession != null) { boolean removeTx = true; - if(b2buaHelperImpl != null && (transaction == null || transaction instanceof ClientTransaction) + if(b2buaHelperImpl != null && (transaction == null || transaction instanceof ClientTransaction) && Request.INVITE.equals(sipServletMessageImpl.getMethod())) { removeTx = false; - } - SipContext sipContext = findSipApplication(sipSessionKey.getApplicationName()); + } + SipContext sipContext = findSipApplication(sipSessionKey.getApplicationName()); //the context can be null if the server is being shutdown if(sipContext != null) { MobicentsSipApplicationSession sipApplicationSession = sipSession.getSipApplicationSession(); try { sipContext.enterSipApp(sipApplicationSession, sipSession, false, true); - if(b2buaHelperImpl != null && tad.getSipServletMessage() instanceof SipServletRequestImpl) { - b2buaHelperImpl.unlinkOriginalRequestInternal((SipServletRequestImpl)tad.getSipServletMessage(), false); - } + if(removeTx) { if(b2buaHelperImpl != null && tad.getSipServletMessage() instanceof SipServletRequestImpl) { - b2buaHelperImpl.unlinkOriginalRequestInternal((SipServletRequestImpl)tad.getSipServletMessage(), false); + b2buaHelperImpl.unlinkRequestInternal((SipServletRequestImpl)tad.getSipServletMessage(), false); } sipSession.removeOngoingTransaction(transaction); // Issue 1468 : to handle forking, we shouldn't cleanup the app data since it is needed for the forked responses - boolean nullifyAppData = true; + boolean nullifyAppData = true; if(((SipStackImpl)((SipProvider)transactionTerminatedEvent.getSource()).getSipStack()).getMaxForkTime() > 0 && Request.INVITE.equals(sipServletMessageImpl.getMethod())) { nullifyAppData = false; } @@ -1633,9 +1744,9 @@ public void run() { sipContext.exitSipApp(sipApplicationSession, sipSession); } } - + // If it is a client transaction, do not kill the proxy session http://code.google.com/p/mobicents/issues/detail?id=1024 - tryToInvalidateSession(sipSessionKey, transactionTerminatedEvent.isServerTransaction()); + tryToInvalidateSession(sipSessionKey, transactionTerminatedEvent.isServerTransaction()); } } catch (Exception e) { @@ -1645,38 +1756,38 @@ public void run() { }); } else { if(logger.isDebugEnabled()) { - logger.debug("TransactionApplicationData not available on the following request " + transaction.getRequest().toString()); + logger.debug("TransactionApplicationData not available on the following request " + transaction.getRequest()); } if(tad != null) { tad.cleanUp(); } transaction.setApplicationData(null); - } + } } public String getApplicationNameFromHash(String hash) { return mdToApplicationName.get(hash); } - + public String getHashFromApplicationName(String appName) { return applicationNameToMd.get(appName); } - + @Override - public String getApplicationServerId() { + public String getApplicationServerId() { return applicationServerId; } @Override - public String getApplicationServerIdHash() { + public String getApplicationServerIdHash() { return applicationServerIdHash; } - + @Override public int getTagHashMaxLength() { return tagHashMaxLength; } - + @Override public CallIdHeader getCallId( MobicentsExtendedListeningPoint extendedListeningPoint, String callId) throws ParseException { @@ -1689,10 +1800,10 @@ public CallIdHeader getCallId( } return SipFactoryImpl.headerFactory.createCallIdHeader(callIdString); } - + /** * Check if the route is external - * @param routeHeader the route to check + * @param routeHeader the route to check * @return true if the route is external, false otherwise */ public final boolean isRouteExternal(RouteHeader routeHeader) { @@ -1702,24 +1813,24 @@ public final boolean isRouteExternal(RouteHeader routeHeader) { String routeTransport = routeUri.getTransportParam(); if(routeTransport == null) { routeTransport = ListeningPoint.UDP; - } - return isExternal(routeUri.getHost(), routeUri.getPort(), routeTransport); - } + } + return isExternal(routeUri.getHost(), routeUri.getPort(), routeTransport); + } return true; } - + /** * Check if the via header is external - * @param viaHeader the via header to check + * @param viaHeader the via header to check * @return true if the via header is external, false otherwise */ public final boolean isViaHeaderExternal(ViaHeader viaHeader) { - if (viaHeader != null) { + if (viaHeader != null) { return isExternal(viaHeader.getHost(), viaHeader.getPort(), viaHeader.getTransport()); } return true; } - + /** * Check whether or not the triplet host, port and transport are corresponding to an interface * @param host can be hostname or ipaddress @@ -1729,27 +1840,30 @@ public final boolean isViaHeaderExternal(ViaHeader viaHeader) { * false otherwise */ public final boolean isExternal(String host, int port, String transport) { + if(logger.isDebugEnabled()) { + logger.debug("isExternal - host=" + host + ", port=" + port + ", transport=" + transport); + } boolean isExternal = true; - MobicentsExtendedListeningPoint listeningPoint = sipNetworkInterfaceManager.findMatchingListeningPoint(host, port, transport); + MobicentsExtendedListeningPoint listeningPoint = sipNetworkInterfaceManager.findMatchingListeningPoint(host, port, transport); if((hostNames.contains(host) || hostNames.contains(host+":" + port) || listeningPoint != null)) { if(logger.isDebugEnabled()) { - logger.debug("hostNames.contains(" + host + ")=" + + logger.debug("hostNames.contains(" + host + ")=" + hostNames.contains(host) + - "hostNames.contains(" + host + ":" + port + ")=" + + "hostNames.contains(" + host + ":" + port + ")=" + hostNames.contains(host+":" + port) + " | listeningPoint found = " + listeningPoint); } isExternal = false; - } + } if(logger.isDebugEnabled()) { - logger.debug("the triplet host/port/transport : " + + logger.debug("the triplet host/port/transport : " + host + "/" + port + "/" + transport + " is external : " + isExternal); } return isExternal; - } + } /** * @return the sipApplicationRouter @@ -1764,7 +1878,7 @@ public SipApplicationRouter getSipApplicationRouter() { public void setSipApplicationRouter(SipApplicationRouter sipApplicationRouter) { this.sipApplicationRouter = sipApplicationRouter; } - + /* * (non-Javadoc) * @see org.mobicents.servlet.sip.core.SipApplicationDispatcher#getSipNetworkInterfaceManager() @@ -1772,7 +1886,7 @@ public void setSipApplicationRouter(SipApplicationRouter sipApplicationRouter) { public SipNetworkInterfaceManager getSipNetworkInterfaceManager() { return this.sipNetworkInterfaceManager; } - + /* * (non-Javadoc) * @see org.mobicents.servlet.sip.core.SipApplicationDispatcher#getSipFactory() @@ -1787,8 +1901,8 @@ public MobicentsSipFactory getSipFactory() { */ public List getOutboundInterfaces() { return sipNetworkInterfaceManager.getOutboundInterfaces(); - } - + } + /** * set the outbound interfaces on all servlet context of applications deployed */ @@ -1796,7 +1910,7 @@ private void resetOutboundInterfaces() { List outboundInterfaces = sipNetworkInterfaceManager.getOutboundInterfaces(); for (SipContext sipContext : applicationDeployed.values()) { sipContext.getServletContext().setAttribute(javax.servlet.sip.SipServlet.OUTBOUND_INTERFACES, - outboundInterfaces); + outboundInterfaces); } } @@ -1819,7 +1933,7 @@ public void addHostName(String hostName) { * (non-Javadoc) * @see org.mobicents.servlet.sip.core.SipApplicationDispatcher#findHostNames() */ - public Set findHostNames() { + public Set findHostNames() { return hostNames; } @@ -1838,7 +1952,7 @@ public void removeHostName(String hostName) { } /** - * + * */ public SipApplicationRouterInfo getNextInterestedApplication( MobicentsSipServletRequest sipServletRequest) { @@ -1849,26 +1963,26 @@ public SipApplicationRouterInfo getNextInterestedApplication( stateInfo = sipServletRequest.getSipSession().getStateInfo(); } final Request request = (Request) sipServletRequest.getMessage(); - + sipServletRequest.setReadOnly(true); SipApplicationRouterInfo applicationRouterInfo = sipApplicationRouter.getNextApplication( - sipServletRequest, - routingRegion, - sipServletRequest.getRoutingDirective(), + sipServletRequest, + routingRegion, + sipServletRequest.getRoutingDirective(), null, stateInfo); sipServletRequest.setReadOnly(false); // 15.4.1 Procedure : point 2 final SipRouteModifier sipRouteModifier = applicationRouterInfo.getRouteModifier(); - final String[] routes = applicationRouterInfo.getRoutes(); + final String[] routes = applicationRouterInfo.getRoutes(); try { // ROUTE modifier indicates that SipApplicationRouterInfo.getRoute() returns a valid route, // it is up to container to decide whether it is external or internal. - if(SipRouteModifier.ROUTE.equals(sipRouteModifier)) { + if(SipRouteModifier.ROUTE.equals(sipRouteModifier)) { final Address routeAddress = SipFactoryImpl.addressFactory.createAddress(routes[0]); - final RouteHeader applicationRouterInfoRouteHeader = SipFactoryImpl.headerFactory.createRouteHeader(routeAddress); - if(isRouteExternal(applicationRouterInfoRouteHeader)) { - // push all of the routes on the Route header stack of the request and + final RouteHeader applicationRouterInfoRouteHeader = SipFactoryImpl.headerFactory.createRouteHeader(routeAddress); + if(isRouteExternal(applicationRouterInfoRouteHeader)) { + // push all of the routes on the Route header stack of the request and // send the request externally for (int i = routes.length-1 ; i >= 0; i--) { RouteHeader routeHeader = (RouteHeader) SipFactoryImpl.headerFactory.createHeader(RouteHeader.NAME, routes[i]); @@ -1877,7 +1991,7 @@ public SipApplicationRouterInfo getNextInterestedApplication( ((javax.sip.address.SipURI)routeURI).setLrParam(); } request.addHeader(routeHeader); - } + } } } else if (SipRouteModifier.ROUTE_BACK.equals(sipRouteModifier)) { // Push container Route, pick up the first outbound interface @@ -1885,7 +1999,7 @@ public SipApplicationRouterInfo getNextInterestedApplication( sipURI.setParameter("modifier", "route_back"); Header routeHeader = SipFactoryImpl.headerFactory.createHeader(RouteHeader.NAME, sipURI.toString()); request.addHeader(routeHeader); - // push all of the routes on the Route header stack of the request and + // push all of the routes on the Route header stack of the request and // send the request externally for (int i = routes.length-1 ; i >= 0; i--) { routeHeader = SipFactoryImpl.headerFactory.createHeader(RouteHeader.NAME, routes[i]); @@ -1894,7 +2008,7 @@ public SipApplicationRouterInfo getNextInterestedApplication( } } catch (ParseException e) { logger.error("Impossible to parse the route returned by the application router " + - "into a compliant address",e); + "into a compliant address",e); } return applicationRouterInfo; } @@ -1902,14 +2016,14 @@ public SipApplicationRouterInfo getNextInterestedApplication( public ThreadPoolExecutor getAsynchronousExecutor() { return asynchronousExecutor; } - + public ScheduledThreadPoolExecutor getAsynchronousScheduledExecutor() { return asynchronousScheduledThreadPoolExecutor; } /** - * Serialize the state info in memory and deserialize it and return the new object. - * Since there is no clone method this is the only way to get the same object with a new reference + * Serialize the state info in memory and deserialize it and return the new object. + * Since there is no clone method this is the only way to get the same object with a new reference * @param stateInfo the state info to serialize * @return the state info serialized and deserialized */ @@ -1918,14 +2032,14 @@ public ScheduledThreadPoolExecutor getAsynchronousScheduledExecutor() { // ObjectOutputStream out = null; // ByteArrayInputStream bais = null; // ObjectInputStream in = null; -// +// // try{ // baos = new ByteArrayOutputStream(); // out = new ObjectOutputStream(baos); -// out.writeObject(stateInfo); +// out.writeObject(stateInfo); // bais = new ByteArrayInputStream(baos.toByteArray()); // in =new ObjectInputStream(bais); -// return (Serializable)in.readObject(); +// return (Serializable)in.readObject(); // } catch (IOException e) { // logger.error("Impossible to serialize the state info", e); // return stateInfo; @@ -1967,20 +2081,20 @@ public Iterator findSipApplications() { public SipContext findSipApplication(String applicationName) { return applicationDeployed.get(applicationName); } - - public DNSResolver getDNSResolver() { + + public DNSResolver getDNSResolver() { return dnsResolver; } - - public DNSServerLocator getDNSServerLocator() { + + public DNSServerLocator getDNSServerLocator() { return dnsServerLocator; } public void setDNSServerLocator(DNSServerLocator dnsServerLocator) { this.dnsServerLocator = dnsServerLocator; } - - public int getDNSTimeout() { + + public int getDNSTimeout() { return dnsTimeout; } @@ -1992,11 +2106,11 @@ public void setDNSTimeout(int dnsTimeout) { dnsServerLocator.getDnsLookupPerformer().setDNSTimeout(dnsTimeout); } - + // -------------------- JMX and Registration -------------------- protected String domain; protected ObjectName oname; - protected MBeanServer mserver; + protected MBeanServer mserver; public ObjectName getObjectName() { return oname; @@ -2005,11 +2119,11 @@ public ObjectName getObjectName() { public String getDomain() { return domain; } - + public void setDomain(String domain) { this.domain = domain; } - + /* * (non-Javadoc) * @see javax.management.MBeanRegistration#postDeregister() @@ -2039,7 +2153,7 @@ public ObjectName preRegister(MBeanServer server, ObjectName name) domain=name.getDomain(); return name; } - + /* Exposed methods for the management console. Some of these duplicate existing methods, but * with JMX friendly types. */ @@ -2054,7 +2168,7 @@ public String[] findInstalledSipApplications() { for(int q=0; q> getApplicationRouterConfiguration() { if(this.sipApplicationRouter instanceof ManageableApplicationRouter) { ManageableApplicationRouter router = (ManageableApplicationRouter) this.sipApplicationRouter; @@ -2072,7 +2186,7 @@ public Map> getApplicationRoute throw new RuntimeException("This application router is not manageable"); } } - + public void updateApplicationRouterConfiguration(Object configuration) { if(this.sipApplicationRouter instanceof ManageableApplicationRouter) { ManageableApplicationRouter router = (ManageableApplicationRouter) this.sipApplicationRouter; @@ -2081,7 +2195,7 @@ public void updateApplicationRouterConfiguration(Object configuration) { throw new RuntimeException("This application router is not manageable"); } } - + public Serializable retrieveApplicationRouterConfigurationString() { if(this.sipApplicationRouter instanceof ManageableApplicationRouter) { ManageableApplicationRouter router = (ManageableApplicationRouter) this.sipApplicationRouter; @@ -2090,7 +2204,7 @@ public Serializable retrieveApplicationRouterConfigurationString() { throw new RuntimeException("This application router is not manageable"); } } - + public void updateApplicationRouterConfiguration(Serializable configuration) { if(this.sipApplicationRouter instanceof ManageableApplicationRouter) { ManageableApplicationRouter router = (ManageableApplicationRouter) this.sipApplicationRouter; @@ -2121,40 +2235,40 @@ public void setQueueSize(int queueSize) { logger.info("Queue Size set to " + queueSize); } } - + public void setConcurrencyControlModeByName(String concurrencyControlMode) { this.concurrencyControlMode = ConcurrencyControlMode.valueOf(concurrencyControlMode); if(logger.isInfoEnabled()) { logger.info("Container wide Concurrency Control set to " + concurrencyControlMode); } - } - + } + @Override public String getConcurrencyControlModeByName() { return concurrencyControlMode.toString(); } - + /** * @return the requestsProcessed */ public long getRequestsProcessed() { return requestsProcessed.get(); } - + /** * @return the requestsProcessedByMethod */ - public Map getRequestsProcessedByMethod() { + public Map getRequestsProcessedByMethod() { return requestsProcessedByMethod; } /** * @return the responsesProcessedByStatusCode */ - public Map getResponsesProcessedByStatusCode() { + public Map getResponsesProcessedByStatusCode() { return responsesProcessedByStatusCode; } - + /** * @return the requestsProcessed */ @@ -2165,7 +2279,7 @@ public long getRequestsProcessedByMethod(String method) { } return 0; } - + public long getResponsesProcessedByStatusCode(String statusCode) { AtomicLong responsesProcessed = responsesProcessedByStatusCode.get(statusCode); if(responsesProcessed != null) { @@ -2173,35 +2287,35 @@ public long getResponsesProcessedByStatusCode(String statusCode) { } return 0; } - + /** * @return the requestsProcessed */ public long getResponsesProcessed() { return responsesProcessed.get(); } - + /** * @return the requestsProcessed */ public long getRequestsSent() { return requestsSent.get(); } - + /** * @return the requestsProcessedByMethod */ - public Map getRequestsSentByMethod() { + public Map getRequestsSentByMethod() { return requestsSentByMethod; } /** * @return the responsesProcessedByStatusCode */ - public Map getResponsesSentByStatusCode() { + public Map getResponsesSentByStatusCode() { return responsesSentByStatusCode; } - + /** * @return the requestsProcessed */ @@ -2212,7 +2326,7 @@ public long getRequestsSentByMethod(String method) { } return 0; } - + public long getResponsesSentByStatusCode(String statusCode) { AtomicLong responsesSent = responsesSentByStatusCode.get(statusCode); if(responsesSent != null) { @@ -2220,7 +2334,7 @@ public long getResponsesSentByStatusCode(String statusCode) { } return 0; } - + /** * @return the requestsProcessed */ @@ -2228,34 +2342,35 @@ public long getResponsesSent() { return responsesSent.get(); } + static final String INTERVAL_ATT = "Interval"; + class SetCongAction implements DispatcherFSM.Action { + @Override + public void execute(DispatcherFSM.Context ctx) { + if (congestionControlTimerFuture != null) { + congestionControlTimerFuture.cancel(false); + } + if (congestionControlCheckingInterval > 0) { + congestionControlTimerFuture = asynchronousScheduledThreadPoolExecutor.scheduleWithFixedDelay(congestionControlTimerTask, congestionControlCheckingInterval, congestionControlCheckingInterval, TimeUnit.MILLISECONDS); + if (logger.isInfoEnabled()) { + logger.info("Congestion control background task modified to check every " + congestionControlCheckingInterval + " milliseconds."); + } + } else if (logger.isInfoEnabled()) { + logger.info("No Congestion control background task started since the checking interval is equals to " + congestionControlCheckingInterval + " milliseconds."); + } + } + + } /** * @param congestionControlCheckingInterval the congestionControlCheckingInterval to set */ public void setCongestionControlCheckingInterval( long congestionControlCheckingInterval) { - if(congestionControlCheckingInterval != this.congestionControlCheckingInterval) { - this.congestionControlCheckingInterval = congestionControlCheckingInterval; - statusLock.lock(); - try { - if(started) { - if(congestionControlTimerFuture != null) { - congestionControlTimerFuture.cancel(false); - } - if(congestionControlCheckingInterval > 0) { - congestionControlTimerFuture = asynchronousScheduledThreadPoolExecutor.scheduleWithFixedDelay(congestionControlTimerTask, congestionControlCheckingInterval, congestionControlCheckingInterval, TimeUnit.MILLISECONDS); - if(logger.isInfoEnabled()) { - logger.info("Congestion control background task modified to check every " + congestionControlCheckingInterval + " milliseconds."); - } - } else { - if(logger.isInfoEnabled()) { - logger.info("No Congestion control background task started since the checking interval is equals to " + congestionControlCheckingInterval + " milliseconds."); - } - } - } - } finally { - statusLock.unlock(); - } - } + //save value anyway,during start actual scheduling will take place + this.congestionControlCheckingInterval = congestionControlCheckingInterval; + //fire event so congestion reschedule is only invoked after start. + DispatcherFSM.Event congEvent = fsm.new Event(DispatcherFSM.EventType.SET_CONGESTION); + congEvent.data.put(INTERVAL_ATT, new Long(congestionControlCheckingInterval)); + fsm.fireEvent(congEvent); } /** @@ -2275,14 +2390,14 @@ public void setCongestionControlPolicy(CongestionControlPolicy congestionControl } } - + public void setCongestionControlPolicyByName(String congestionControlPolicy) { this.congestionControlPolicy = CongestionControlPolicy.valueOf(congestionControlPolicy); if(logger.isInfoEnabled()) { logger.info("Congestion Control policy set to " + this.congestionControlPolicy.toString()); } - } - + } + /** * @return the congestionControlPolicy */ @@ -2313,7 +2428,7 @@ public void setMemoryThreshold(int memoryThreshold) { public int getMemoryThreshold() { return memoryThreshold; } - + /** * @return the numberOfMessagesInQueue */ @@ -2381,7 +2496,7 @@ public void setBaseTimerInterval(int baseTimerInterval) { public int getBaseTimerInterval() { return baseTimerInterval; } - + /** * @param t2Interval the t2Interval to set */ @@ -2458,6 +2573,7 @@ public String[] getRfcSupported() { return RFC_SUPPORTED; } + @Override public void loadBalancerAdded(SipLoadBalancer sipLoadBalancer) { sipLoadBalancers.add(sipLoadBalancer); if(sipFactoryImpl.getLoadBalancerToUse() == null) { @@ -2465,9 +2581,10 @@ public void loadBalancerAdded(SipLoadBalancer sipLoadBalancer) { } } + @Override public void loadBalancerRemoved(SipLoadBalancer sipLoadBalancer) { sipLoadBalancers.remove(sipLoadBalancer); - if(sipFactoryImpl.getLoadBalancerToUse() != null && + if(sipFactoryImpl.getLoadBalancerToUse() != null && sipFactoryImpl.getLoadBalancerToUse().equals(sipLoadBalancer)) { if(sipLoadBalancers.size() > 0) { sipFactoryImpl.setLoadBalancerToUse(sipLoadBalancers.iterator().next()); @@ -2475,8 +2592,30 @@ public void loadBalancerRemoved(SipLoadBalancer sipLoadBalancer) { sipFactoryImpl.setLoadBalancerToUse(null); } } - } - + } + + // https://github.com/RestComm/sip-servlets/issues/172 + @Override + public void pingingloadBalancer(SipLoadBalancer balancerDescription) { + SipConnector[] sipConnectors = sipService.findSipConnectors(); + for (SipConnector sipConnector : sipConnectors) { + if(logger.isDebugEnabled()) { + logger.debug("Comparing Balancer Address " + balancerDescription.getAddress().getHostAddress() + + " to sipconnector balancer address " + sipConnector.getLoadBalancerAddress()); + } + if(balancerDescription.getAddress().getHostAddress().equals(sipConnector.getLoadBalancerAddress()) + && sipConnector.getLoadBalancerCustomInformation() != null + && !sipConnector.getLoadBalancerCustomInformation().isEmpty()) { + balancerDescription.setCustomInfo(sipConnector.getLoadBalancerCustomInformation()); + } + } + } + + @Override + public void pingedloadBalancer(SipLoadBalancer balancerDescription) { + // Nothing to do here + } + /** * @param info */ @@ -2488,10 +2627,10 @@ public void sendSwitchoverInstruction(String fromJvmRoute, String toJvmRoute) { return; } for(SipLoadBalancer sipLoadBalancer : sipLoadBalancers) { - sipLoadBalancer.switchover(fromJvmRoute, toJvmRoute); - } + sipLoadBalancer.switchover(fromJvmRoute, toJvmRoute); + } } - + /* * (non-Javadoc) * @see org.mobicents.servlet.sip.core.SipApplicationDispatcher#setGracefulShutdown(boolean) @@ -2501,17 +2640,17 @@ public void setGracefulShutdown(boolean shuttingDownGracefully) { logger.debug("sending graceful shutdown to Load Balancers"); } // for(SipLoadBalancer sipLoadBalancer : sipLoadBalancers) { -// sipLoadBalancer.setGracefulShutdown(shuttingDownGracefully); -// } - } +// sipLoadBalancer.setGracefulShutdown(shuttingDownGracefully); +// } + } /** - * @param skipStatistics the skipStatistics to set + * @param gatherStatistics the skipStatistics to set */ - public void setGatherStatistics(boolean skipStatistics) { - this.gatherStatistics = skipStatistics; + public void setGatherStatistics(boolean gatherStatistics) { + this.gatherStatistics = gatherStatistics; if(logger.isInfoEnabled()) { - logger.info("Gathering Statistics set to " + skipStatistics); + logger.info("Gathering Statistics set to " + gatherStatistics); } } @@ -2521,7 +2660,7 @@ public void setGatherStatistics(boolean skipStatistics) { public boolean isGatherStatistics() { return gatherStatistics; } - + /** * PRESENT TO ACCOMODATE JOPR. NEED TO FILE A BUG ON THIS * @return the skipStatistics @@ -2570,11 +2709,11 @@ public SipStack getSipStack() { } public void setSipStack(SipStack sipStack) { - this.sipStack = sipStack; + this.sipStack = sipStack; } - + protected void startSipStack() throws SipException { - // stopping the sip stack + // stopping the sip stack if(sipStack != null) { sipStack.start(); if(logger.isDebugEnabled()) { @@ -2582,9 +2721,9 @@ protected void startSipStack() throws SipException { } } } - + protected void stopSipStack() { - // stopping the sip stack + // stopping the sip stack if(sipStack != null) { sipStack.stop(); sipStack = null; diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/SipNetworkInterfaceManagerImpl.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/SipNetworkInterfaceManagerImpl.java index fa65c2cad0..8a51f5144a 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/SipNetworkInterfaceManagerImpl.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/SipNetworkInterfaceManagerImpl.java @@ -36,8 +36,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArraySet; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; import javax.servlet.sip.SipURI; import javax.sip.ListeningPoint; @@ -70,12 +68,12 @@ public class SipNetworkInterfaceManagerImpl implements SipNetworkInterfaceManage private static final Logger logger = Logger.getLogger(SipNetworkInterfaceManagerImpl.class); /** - * The maximum int value that could correspond to a port nubmer. + * The maximum int value that could correspond to a port number. */ public static final int MAX_PORT_NUMBER = 65535; /** - * The minimum int value that could correspond to a port nubmer bindable + * The minimum int value that could correspond to a port number bindable * by the SIP Communicator. */ public static final int MIN_PORT_NUMBER = 1024; @@ -85,19 +83,17 @@ public class SipNetworkInterfaceManagerImpl implements SipNetworkInterfaceManage //related to google code issue 563, will be used to check if a request is aimed at a local network or outside Set outboundInterfacesIpAddresses = null; //use only to lookup the hosts for issue 563, need to find a better way and reduce coupling - private SipApplicationDispatcher sipApplicationDispatcher; + private SipApplicationDispatcherImpl sipApplicationDispatcher; //those maps are present to improve the performance of finding a listening point either from a transport // or from a triplet ipaddress, port and transport Map> transportMappingCacheMap = null; Map extendedListeningPointsCacheMap = null; - Lock lock = null; - /** * Default Constructor */ - public SipNetworkInterfaceManagerImpl(SipApplicationDispatcher sipApplicationDispatcher) { + public SipNetworkInterfaceManagerImpl(SipApplicationDispatcherImpl sipApplicationDispatcher) { this.sipApplicationDispatcher = sipApplicationDispatcher; extendedListeningPointList = new CopyOnWriteArraySet(); outboundInterfaces = new CopyOnWriteArrayList(); @@ -113,7 +109,6 @@ public SipNetworkInterfaceManagerImpl(SipApplicationDispatcher sipApplicationDis transportMappingCacheMap.put(ListeningPointExt.WSS.toLowerCase(), new CopyOnWriteArraySet()); // creating the ipaddress/port/transport cache map extendedListeningPointsCacheMap = new ConcurrentHashMap(); - lock = new ReentrantLock(); } /** @@ -124,92 +119,103 @@ public Iterator getExtendedListeningPoints() { return extendedListeningPointList.iterator(); } - /** - * - * @param extendedListeningPoint - */ - public void addExtendedListeningPoint(MobicentsExtendedListeningPoint extendedListeningPoint) { - extendedListeningPointList.add(extendedListeningPoint); - computeOutboundInterfaces(); - // Adding to the transport cache map - Set extendedListeningPoints = - transportMappingCacheMap.get(extendedListeningPoint.getTransport().toLowerCase()); - boolean added = extendedListeningPoints.add(extendedListeningPoint); - if(added) { - if(sipApplicationDispatcher.getDNSServerLocator() != null) { - sipApplicationDispatcher.getDNSServerLocator().addSupportedTransport(extendedListeningPoint.getTransport()); - } - // Adding private ipaddress to the triplet cache map - for(String ipAddress : extendedListeningPoint.getIpAddresses()) { - extendedListeningPointsCacheMap.put(ipAddress + "/" + extendedListeningPoint.getPort() + ":" + extendedListeningPoint.getTransport().toLowerCase(), extendedListeningPoint); - } - // Adding public address if any to the triplet cache map - if(extendedListeningPoint.getGlobalIpAddress() != null) { - extendedListeningPointsCacheMap.put(extendedListeningPoint.getGlobalIpAddress() + "/" + extendedListeningPoint.getPort() + ":" + extendedListeningPoint.getTransport().toLowerCase(), extendedListeningPoint); - extendedListeningPointsCacheMap.put(extendedListeningPoint.getGlobalIpAddress() + "/" + extendedListeningPoint.getGlobalPort() + ":" + extendedListeningPoint.getTransport().toLowerCase(), extendedListeningPoint); - } - // Adding local hostnames if any to the triplet cache map - if(extendedListeningPoint.getSipConnector().getHostNames() != null) { - StringTokenizer tokenizer = new StringTokenizer(extendedListeningPoint.getSipConnector().getHostNames(), ","); - while(tokenizer.hasMoreTokens()) { - String localHostName = tokenizer.nextToken(); - extendedListeningPointsCacheMap.put(localHostName + "/" + extendedListeningPoint.getPort() + ":" + extendedListeningPoint.getTransport().toLowerCase(), extendedListeningPoint); - if(sipApplicationDispatcher.getDNSServerLocator() != null) { - sipApplicationDispatcher.getDNSServerLocator().mapLocalHostNameToIP(localHostName, new CopyOnWriteArraySet(extendedListeningPoint.getIpAddresses())); - } - } - } - - Iterator sipContextIterator = sipApplicationDispatcher.findSipApplications(); - while (sipContextIterator.hasNext()) { - SipContext sipContext = (SipContext) sipContextIterator.next(); - sipContext.notifySipContextListeners(new SipContextEventImpl(SipContextEventType.SIP_CONNECTOR_ADDED, extendedListeningPoint.getSipConnector())); - } - } - } + static final String LISTENING_POINT_ATT = "ListeningPoint"; + + class AddPointAction implements DispatcherFSM.Action { + + + @Override + public void execute(DispatcherFSM.Context ctx) { + MobicentsExtendedListeningPoint extendedListeningPoint = (MobicentsExtendedListeningPoint)ctx.lastEvent.data.get(LISTENING_POINT_ATT); + + extendedListeningPointList.add(extendedListeningPoint); + computeOutboundInterfaces(); + // Adding to the transport cache map + Set extendedListeningPoints + = transportMappingCacheMap.get(extendedListeningPoint.getTransport().toLowerCase()); + boolean added = extendedListeningPoints.add(extendedListeningPoint); + if (added) { + if (sipApplicationDispatcher.getDNSServerLocator() != null) { + sipApplicationDispatcher.getDNSServerLocator().addSupportedTransport(extendedListeningPoint.getTransport()); + } + // Adding private ipaddress to the triplet cache map + for (String ipAddress : extendedListeningPoint.getIpAddresses()) { + extendedListeningPointsCacheMap.put(ipAddress + "/" + extendedListeningPoint.getPort() + ":" + extendedListeningPoint.getTransport().toLowerCase(), extendedListeningPoint); + } + // Adding public address if any to the triplet cache map + if (extendedListeningPoint.getGlobalIpAddress() != null) { + extendedListeningPointsCacheMap.put(extendedListeningPoint.getGlobalIpAddress() + "/" + extendedListeningPoint.getPort() + ":" + extendedListeningPoint.getTransport().toLowerCase(), extendedListeningPoint); + extendedListeningPointsCacheMap.put(extendedListeningPoint.getGlobalIpAddress() + "/" + extendedListeningPoint.getGlobalPort() + ":" + extendedListeningPoint.getTransport().toLowerCase(), extendedListeningPoint); + } + // Adding local hostnames if any to the triplet cache map + if (extendedListeningPoint.getSipConnector().getHostNames() != null) { + StringTokenizer tokenizer = new StringTokenizer(extendedListeningPoint.getSipConnector().getHostNames(), ","); + while (tokenizer.hasMoreTokens()) { + String localHostName = tokenizer.nextToken(); + extendedListeningPointsCacheMap.put(localHostName + "/" + extendedListeningPoint.getPort() + ":" + extendedListeningPoint.getTransport().toLowerCase(), extendedListeningPoint); + if (sipApplicationDispatcher.getDNSServerLocator() != null) { + sipApplicationDispatcher.getDNSServerLocator().mapLocalHostNameToIP(localHostName, new CopyOnWriteArraySet(extendedListeningPoint.getIpAddresses())); + } + } + } + } + } + + } + + @Override + public void addExtendedListeningPoint(MobicentsExtendedListeningPoint extendedListeningPoint) { + DispatcherFSM.Event event = sipApplicationDispatcher.fsm.new Event(DispatcherFSM.EventType.ADD_CONNECTOR); + event.data.put(LISTENING_POINT_ATT, extendedListeningPoint); + this.sipApplicationDispatcher.fsm.fireEvent(event); + } - /** - * - * @param extendedListeningPoint - */ - public void removeExtendedListeningPoint(MobicentsExtendedListeningPoint extendedListeningPoint) { - // notifying the applications before removing the listening point so that apps can still try to send a message on it - if(extendedListeningPointList.contains(extendedListeningPoint)) { - Iterator sipContextIterator = sipApplicationDispatcher.findSipApplications(); - while (sipContextIterator.hasNext()) { - SipContext sipContext = (SipContext) sipContextIterator.next(); - sipContext.notifySipContextListeners(new SipContextEventImpl(SipContextEventType.SIP_CONNECTOR_REMOVED, extendedListeningPoint.getSipConnector())); - } - extendedListeningPointList.remove(extendedListeningPoint); - computeOutboundInterfaces(); - // removing from the transport cache map - Set extendedListeningPoints = - transportMappingCacheMap.get(extendedListeningPoint.getTransport().toLowerCase()); - extendedListeningPoints.remove(extendedListeningPoint); - if(sipApplicationDispatcher.getDNSServerLocator() != null) { - sipApplicationDispatcher.getDNSServerLocator().removeSupportedTransport(extendedListeningPoint.getTransport()); - } - // Removing private ipaddress from the triplet cache map for listening point - for(String ipAddress : extendedListeningPoint.getIpAddresses()) { - extendedListeningPointsCacheMap.remove(ipAddress + "/" + extendedListeningPoint.getPort() + ":" + extendedListeningPoint.getTransport().toLowerCase()); - } - // Removing public address if any from the triplet cache map - if(extendedListeningPoint.getGlobalIpAddress() != null) { - extendedListeningPointsCacheMap.remove(extendedListeningPoint.getGlobalIpAddress() + "/" + extendedListeningPoint.getPort() + ":" + extendedListeningPoint.getTransport().toLowerCase()); - extendedListeningPointsCacheMap.remove(extendedListeningPoint.getGlobalIpAddress() + "/" + extendedListeningPoint.getGlobalPort() + ":" + extendedListeningPoint.getTransport().toLowerCase()); - } - if(extendedListeningPoint.getSipConnector().getHostNames() != null) { - StringTokenizer tokenizer = new StringTokenizer(extendedListeningPoint.getSipConnector().getHostNames(), ","); - while(tokenizer.hasMoreTokens()) { - String localHostName = tokenizer.nextToken(); - extendedListeningPointsCacheMap.remove(localHostName + "/" + extendedListeningPoint.getPort() + ":" + extendedListeningPoint.getTransport().toLowerCase()); - if(sipApplicationDispatcher.getDNSServerLocator() != null) { - sipApplicationDispatcher.getDNSServerLocator().unmapLocalHostNameToIP(localHostName); - } - } - } - } - } + class RemovePointAction implements DispatcherFSM.Action { + @Override + public void execute(DispatcherFSM.Context ctx) { + MobicentsExtendedListeningPoint extendedListeningPoint = (MobicentsExtendedListeningPoint)ctx.lastEvent.data.get(LISTENING_POINT_ATT); + + // notifying the applications before removing the listening point so that apps can still try to send a message on it + if (extendedListeningPointList.contains(extendedListeningPoint)) { + + extendedListeningPointList.remove(extendedListeningPoint); + computeOutboundInterfaces(); + // removing from the transport cache map + Set extendedListeningPoints + = transportMappingCacheMap.get(extendedListeningPoint.getTransport().toLowerCase()); + extendedListeningPoints.remove(extendedListeningPoint); + if (sipApplicationDispatcher.getDNSServerLocator() != null) { + sipApplicationDispatcher.getDNSServerLocator().removeSupportedTransport(extendedListeningPoint.getTransport()); + } + // Removing private ipaddress from the triplet cache map for listening point + for (String ipAddress : extendedListeningPoint.getIpAddresses()) { + extendedListeningPointsCacheMap.remove(ipAddress + "/" + extendedListeningPoint.getPort() + ":" + extendedListeningPoint.getTransport().toLowerCase()); + } + // Removing public address if any from the triplet cache map + if (extendedListeningPoint.getGlobalIpAddress() != null) { + extendedListeningPointsCacheMap.remove(extendedListeningPoint.getGlobalIpAddress() + "/" + extendedListeningPoint.getPort() + ":" + extendedListeningPoint.getTransport().toLowerCase()); + extendedListeningPointsCacheMap.remove(extendedListeningPoint.getGlobalIpAddress() + "/" + extendedListeningPoint.getGlobalPort() + ":" + extendedListeningPoint.getTransport().toLowerCase()); + } + if (extendedListeningPoint.getSipConnector().getHostNames() != null) { + StringTokenizer tokenizer = new StringTokenizer(extendedListeningPoint.getSipConnector().getHostNames(), ","); + while (tokenizer.hasMoreTokens()) { + String localHostName = tokenizer.nextToken(); + extendedListeningPointsCacheMap.remove(localHostName + "/" + extendedListeningPoint.getPort() + ":" + extendedListeningPoint.getTransport().toLowerCase()); + if (sipApplicationDispatcher.getDNSServerLocator() != null) { + sipApplicationDispatcher.getDNSServerLocator().unmapLocalHostNameToIP(localHostName); + } + } + } + } + } + + } + + public void removeExtendedListeningPoint(MobicentsExtendedListeningPoint extendedListeningPoint) { + DispatcherFSM.Event event = sipApplicationDispatcher.fsm.new Event(DispatcherFSM.EventType.REMOVE_CONNECTOR); + event.data.put(LISTENING_POINT_ATT, extendedListeningPoint); + this.sipApplicationDispatcher.fsm.fireEvent(event); + } /** * Retrieve the first matching listening point corresponding to the transport. @@ -288,12 +294,16 @@ public MobicentsExtendedListeningPoint findMatchingListeningPoint( if(logger.isTraceEnabled()) { logger.trace("Comparing listening point " + extendedListeningPoint + " with outbound ipaddress " + outboundInterface.getHost() + " and port " + outboundInterface.getPort()); } - // Fix for http://code.google.com/p/sipservlets/issues/detail?id=159 Bad choice of connectors when multiple of the same transport are available - if(extendedListeningPoint.getIpAddresses().contains(outboundInterface.getHost()) && extendedListeningPoint.getPort() == outboundInterface.getPort()) { - if(logger.isTraceEnabled()) { - logger.trace("Found listening point " + extendedListeningPoint); + String outboundInterfaceHost = extractIPV6Brackets(outboundInterface.getHost()); + for (String ipAddress : extendedListeningPoint.getIpAddresses()) { + // Fix for http://code.google.com/p/sipservlets/issues/detail?id=159 Bad choice of connectors when multiple of the same transport are available + // Ipv6 issue when scope-id is removed out of via header, but the sip-connector is created on ipv6 with scope-id + if (ipAddress.contains(outboundInterfaceHost) && extendedListeningPoint.getPort() == outboundInterface.getPort()) { + if(logger.isTraceEnabled()) { + logger.trace("Found listening point " + extendedListeningPoint); + } + return extendedListeningPoint; } - return extendedListeningPoint; } } throw new RuntimeException("no valid sip connectors could be found to create the sip application session !!!"); @@ -321,7 +331,25 @@ public MobicentsExtendedListeningPoint findMatchingListeningPoint(final String i } // we check first if a listening point can be found (we only do the host resolving if not found to have better perf ) - MobicentsExtendedListeningPoint listeningPoint = extendedListeningPointsCacheMap.get(ipAddress + "/" + portChecked + ":" + tmpTransport.toLowerCase()); + MobicentsExtendedListeningPoint listeningPoint = null; + + if (ipAddress.indexOf(':') != -1) { + String ipAddressTmp = extractIPV6Brackets(ipAddress); + // IPv6 here, Jain-Sip stack remove scope zone which is included in the key of listener object + for(String key: extendedListeningPointsCacheMap.keySet()){ + if (logger.isDebugEnabled()) { + logger.debug("Find listening point for IPv6: " + key + " compare: " + ipAddressTmp + " port " + portChecked + " transport " + tmpTransport.toLowerCase()); + } + if (key.contains(ipAddressTmp) && + key.contains(String.valueOf(portChecked)+ ":" + tmpTransport.toLowerCase())) { + listeningPoint = extendedListeningPointsCacheMap.get(key); + break; + } + } + }else { + listeningPoint = extendedListeningPointsCacheMap.get(ipAddress + "/" + portChecked + ":" + tmpTransport.toLowerCase()); + } + if(logger.isDebugEnabled()) { logger.debug("Checked Listening Point " + ipAddress + "/" + portChecked + ":" + tmpTransport.toLowerCase() + " against existing listening points, found " + listeningPoint); } @@ -354,6 +382,27 @@ public MobicentsExtendedListeningPoint findMatchingListeningPoint(final String i return listeningPoint; } + /** + * If the host is Ipv6, get the host without "[" and "]" + * If the host is Ipv4, get the host as normal. + * @param host + * @return host without square brackets + */ + private String extractIPV6Brackets(String host) { + String ret = host; + // IPv6 here, remove square brackets + if (host.indexOf(':') != -1) { + int startPoint = host.indexOf('['); + int endPoint = host.indexOf(']'); + if (endPoint == -1) endPoint = host.length(); + if (startPoint != -1) { + ret = host.substring(startPoint + 1, endPoint); + } else { + ret = host.substring(0, endPoint); + } + } + return ret; + } /** * Checks if the port is in the UDP-TCP port numbers (0-65355) range * otherwise defaulting to 5060 if UDP, TCP or SCTP or to 5061 if TLS @@ -416,13 +465,10 @@ protected void computeOutboundInterfaces() { } } } - lock.lock(); - try { - outboundInterfaces = newlyComputedOutboundInterfaces; - outboundInterfacesIpAddresses = newlyComputedOutboundInterfacesIpAddresses; - } finally { - lock.unlock(); - } + + outboundInterfaces = newlyComputedOutboundInterfaces; + outboundInterfacesIpAddresses = newlyComputedOutboundInterfacesIpAddresses; + } diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/Version.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/Version.java index 284b4c9d84..6cfdb19328 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/Version.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/Version.java @@ -29,6 +29,12 @@ import org.apache.log4j.Logger; public class Version { + protected static final String RELEASE_REVISION = "release.revision"; + protected static final String RELEASE_DATE = "release.date"; + protected static final String RELEASE_NAME = "release.name"; + protected static final String RELEASE_VERSION = "release.version"; + protected static final String STATISTICS_SERVER = "statistics.server"; + protected static final String DEFAULT_STATISTICS_SERVER = "https://statistics.restcomm.com/rest/"; private static Logger logger = Logger.getLogger(Version.class); public static void printVersion() { if(logger.isInfoEnabled()) { @@ -38,10 +44,10 @@ public static void printVersion() { if(in != null) { releaseProperties.load(in); in.close(); - String releaseVersion = releaseProperties.getProperty("release.version"); - String releaseName = releaseProperties.getProperty("release.name"); - String releaseDate = releaseProperties.getProperty("release.date"); - String releaseRevision = releaseProperties.getProperty("release.revision"); + String releaseVersion = releaseProperties.getProperty(RELEASE_VERSION); + String releaseName = releaseProperties.getProperty(RELEASE_NAME); + String releaseDate = releaseProperties.getProperty(RELEASE_DATE); + String releaseRevision = releaseProperties.getProperty(RELEASE_REVISION); String releaseDisclaimer = releaseProperties.getProperty("release.disclaimer"); if(releaseVersion != null) { // Follow the EAP Convention @@ -70,10 +76,10 @@ public static String getVersion() { if(in != null) { releaseProperties.load(in); in.close(); - String releaseVersion = releaseProperties.getProperty("release.version"); - String releaseName = releaseProperties.getProperty("release.name"); - String releaseDate = releaseProperties.getProperty("release.date"); - String releaseRevision = releaseProperties.getProperty("release.revision"); + String releaseVersion = releaseProperties.getProperty(RELEASE_VERSION); + String releaseName = releaseProperties.getProperty(RELEASE_NAME); + String releaseDate = releaseProperties.getProperty(RELEASE_DATE); + String releaseRevision = releaseProperties.getProperty(RELEASE_REVISION); return "Release ID: (" + releaseName + ") Sip Servlets " + releaseVersion + " (build: Git Hash=" + releaseRevision + " date=" + releaseDate + ")"; } @@ -82,4 +88,19 @@ public static String getVersion() { } return null; } + + public static String getVersionProperty(String property) { + Properties releaseProperties = new Properties(); + try { + InputStream in = SipApplicationDispatcherImpl.class.getResourceAsStream("release.properties"); + if(in != null) { + releaseProperties.load(in); + in.close(); + return releaseProperties.getProperty(property); + } + } catch (Exception e) { + logger.warn("Unable to extract the version of Mobicents Sip Servlets currently running", e); + } + return null; + } } diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/dispatchers/CancelRequestDispatcher.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/dispatchers/CancelRequestDispatcher.java index 8c399d59cc..918e18effa 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/dispatchers/CancelRequestDispatcher.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/dispatchers/CancelRequestDispatcher.java @@ -22,6 +22,7 @@ import gov.nist.javax.sip.ServerTransactionExt; import java.io.IOException; +import java.text.ParseException; import javax.servlet.ServletException; import javax.servlet.sip.SipSession.State; @@ -39,9 +40,12 @@ import org.mobicents.servlet.sip.core.DispatcherException; import org.mobicents.servlet.sip.core.RoutingState; import org.mobicents.servlet.sip.core.SipContext; +import static org.mobicents.servlet.sip.core.SipContext.INTERNAL_ATT_PREFIX; import org.mobicents.servlet.sip.core.proxy.MobicentsProxy; import org.mobicents.servlet.sip.core.session.MobicentsSipApplicationSession; import org.mobicents.servlet.sip.core.session.MobicentsSipSession; +import org.mobicents.servlet.sip.core.session.SipApplicationSessionCreationThreadLocal; +import org.mobicents.servlet.sip.message.SipFactoryImpl; import org.mobicents.servlet.sip.message.SipServletMessageImpl; import org.mobicents.servlet.sip.message.SipServletRequestImpl; import org.mobicents.servlet.sip.message.SipServletResponseImpl; @@ -53,13 +57,13 @@ * application path followed by the INVITE.
CANCEL deserves a special * treatment since they are routed hop by hop. *

- * + * *

* Algorithm used : We can distinguish 2 cases here as per spec : *

    *
  • * Applications that acts as User Agent 11.2.3 Receiving CANCEL : - * + * * When a CANCEL is received for a request which has been passed to an * application, and the application has not responded yet or proxied the * original request, the container responds to the original request with a 487 @@ -74,10 +78,10 @@ * not be notified that a CANCEL request was received. If the container wins and * the servlet tries to send a response before (or for that matter after) being * notified of the CANCEL, the container throws an IllegalStateException.
  • - * + * *
  • - * Applications that acts as proxy : - * + * Applications that acts as proxy : + * * 10.2.6 Receiving CANCEL if the original * request has not been proxied yet the container responds to it with a 487 * final response otherwise, all branches are cancelled, and response processing @@ -89,30 +93,32 @@ * discussed in section 11.2.3 Receiving CANCEL.
  • *
*

- * + * * @author Jean Deruelle - * + * */ public class CancelRequestDispatcher extends RequestDispatcher { private static final Logger logger = Logger.getLogger(CancelRequestDispatcher.class); - + // Name of the parameter for the reason text of 487 request terminated Reason Header + private static final String REQUEST_TERMINATED_REASON = INTERNAL_ATT_PREFIX + ".REQUEST_TERMINATED_REASON"; + public CancelRequestDispatcher() {} - + // public CancelRequestDispatcher( // SipApplicationDispatcher sipApplicationDispatcher) { // super(sipApplicationDispatcher); // } /** - * {@inheritDoc} + * {@inheritDoc} */ public void dispatchMessage(final SipProvider sipProvider, SipServletMessageImpl sipServletMessage) throws DispatcherException { // final SipNetworkInterfaceManager sipNetworkInterfaceManager = sipApplicationDispatcher.getSipNetworkInterfaceManager(); final SipServletRequestImpl sipServletRequest = (SipServletRequestImpl) sipServletMessage; if(logger.isInfoEnabled()) { logger.info("Routing of Cancel Request " + sipServletRequest); - } + } /* * WARNING: routing of CANCEL is special because CANCEL does not contain Route headers as other requests related * to the dialog. But still it has to be routed through the app path @@ -122,19 +128,19 @@ public void dispatchMessage(final SipProvider sipProvider, SipServletMessageImpl * This is needed because of CANCEL which is a subsequent request that might * not have Routes. For example if the callee has'n responded the caller still * doesn't know the route-record and just sends cancel to the outbound proxy. - */ + */ // boolean proxyCancel = false; - ServerTransaction cancelTransaction = + ServerTransaction cancelTransaction = (ServerTransaction) sipServletRequest.getTransaction(); - + if(cancelTransaction != null && !TransactionState.TERMINATED.equals(cancelTransaction.getState())) { if(logger.isDebugEnabled()) { logger.debug("Sending 200 to Cancel " + sipServletRequest); } try { - // First we need to send OK ASAP because of retransmissions both for - //proxy or app - SipServletResponseImpl cancelResponse = (SipServletResponseImpl) + // First we need to send OK ASAP because of retransmissions both for + //proxy or app + SipServletResponseImpl cancelResponse = (SipServletResponseImpl) sipServletRequest.createResponse(200, "Canceling"); Response cancelJsipResponse = (Response) cancelResponse.getMessage(); cancelTransaction.sendResponse(cancelJsipResponse); @@ -146,7 +152,7 @@ public void dispatchMessage(final SipProvider sipProvider, SipServletMessageImpl } if(logger.isDebugEnabled()) { logger.debug("checking what to do with the CANCEL " + sipServletRequest); - } + } DispatchTask dispatchTask = new CancelDispatchTask(sipServletRequest, sipProvider); // Execute CANCEL without waiting for previous requests because if we wait for an INVITE to complete // all responses will be already sent by the time the CANCEL is out of the queue. @@ -155,7 +161,7 @@ public void dispatchMessage(final SipProvider sipProvider, SipServletMessageImpl if(logger.isDebugEnabled()) { logger.debug("Retransmission received for CANCEL " + sipServletRequest + ", transaction " + cancelTransaction); if(cancelTransaction != null) { - logger.debug("Cancel Transaction state " + cancelTransaction.getState()); + logger.debug("Cancel Transaction state " + cancelTransaction.getState()); } } } @@ -166,40 +172,55 @@ public void dispatchMessage(final SipProvider sipProvider, SipServletMessageImpl * @param inviteRequest */ private final static void send487Response(Transaction inviteTransaction, SipServletRequestImpl inviteRequest) throws IllegalStateException, DispatcherException { - SipServletResponseImpl inviteResponse = (SipServletResponseImpl) - inviteRequest.createResponse(Response.REQUEST_TERMINATED); - + SipServletResponseImpl inviteResponse = (SipServletResponseImpl) + inviteRequest.createResponse(Response.REQUEST_TERMINATED); + inviteRequest.setRoutingState(RoutingState.CANCELLED); - //JSR 289 Section 6.2.1.1 Cancel Message Processing : since receiving a CANCEL request causes the UAS - // to respond to an ongoing INVITE transaction with a non-2XX (specifically, 487) response, the SipSession state + //JSR 289 Section 6.2.1.1 Cancel Message Processing : since receiving a CANCEL request causes the UAS + // to respond to an ongoing INVITE transaction with a non-2XX (specifically, 487) response, the SipSession state // normally becomes TERMINATED as a result of the non-2XX final response sent back to the UAC. // Issue 1484 : http://code.google.com/p/mobicents/issues/detail?id=1484 // we terminate the session only for initial requests if(inviteRequest.isInitial()) { - inviteRequest.getSipSession().setState(State.TERMINATED); + inviteRequest.getSipSession().setState(State.TERMINATED); } try { Response requestTerminatedResponse = (Response) inviteResponse.getMessage(); - ((ServerTransaction)inviteTransaction).sendResponse(requestTerminatedResponse); + SipContext context = SipApplicationSessionCreationThreadLocal.lookupContext(); + if (context != null) { + // bug zendesk#34106, because of JBOSS lifcycle and save the cost, get context param dirrectly + // from init param. + String reasonHeaderText = (String) context.getServletContext().getInitParameter(REQUEST_TERMINATED_REASON); + if (reasonHeaderText != null && !reasonHeaderText.isEmpty()) { + if(logger.isDebugEnabled()) { + logger.debug("487 Request Terminated is being sent, adding Reason header with text: " + reasonHeaderText); + } + ReasonHeader reasonHeader = SipFactoryImpl.headerFactory.createReasonHeader("SIP", Response.REQUEST_TERMINATED, reasonHeaderText); + requestTerminatedResponse.addHeader(reasonHeader); + } + } + ((ServerTransaction)inviteTransaction).sendResponse(requestTerminatedResponse); inviteRequest.getSipSession().getSipApplicationSession().getSipContext().getSipApplicationDispatcher().updateResponseStatistics(requestTerminatedResponse, false); } catch (SipException e) { throw new DispatcherException(Response.SERVER_INTERNAL_ERROR, "Impossible to send the 487 to the INVITE transaction corresponding to CANCEL", e); } catch (InvalidArgumentException e) { throw new DispatcherException(Response.SERVER_INTERNAL_ERROR, "Impossible to send the 487 to the INVITE transaction corresponding to CANCEL", e); - } + } catch (ParseException e) { + throw new DispatcherException(Response.SERVER_INTERNAL_ERROR, "Impossible to send the 487 to the INVITE transaction corresponding to CANCEL", e); + } } - + public static class CancelDispatchTask extends DispatchTask { - + CancelDispatchTask(SipServletRequestImpl sipServletRequest, SipProvider sipProvider) { super(sipServletRequest, sipProvider); } - + public void dispatch() throws DispatcherException { final SipServletRequestImpl sipServletRequest = (SipServletRequestImpl)sipServletMessage; - final Request request = (Request) sipServletRequest.getMessage(); + final Request request = (Request) sipServletRequest.getMessage(); final ServerTransaction inviteTransaction = ((ServerTransactionExt) sipServletRequest.getTransaction()).getCanceledInviteTransaction(); - + if(inviteTransaction == null) { if(logger.isDebugEnabled()) { logger.debug("couldn't find the original invite transaction for this cancel " + request + ", it may be a retransmission and the transaction has already been terminated"); @@ -215,10 +236,10 @@ public void dispatch() throws DispatcherException { } final SipServletRequestImpl inviteRequest = (SipServletRequestImpl) inviteAppData.getSipServletMessage(); - final MobicentsSipSession sipSession = inviteRequest.getSipSession(); + final MobicentsSipSession sipSession = inviteRequest.getSipSession(); sipServletRequest.setSipSession(sipSession); sipSession.setRequestsPending(0); - + if(logger.isDebugEnabled()) { logger.debug("message associated with the inviteAppData " + "of the CANCEL " + inviteRequest); @@ -230,22 +251,22 @@ public void dispatch() throws DispatcherException { if(logger.isDebugEnabled()) { logger.debug("app data of the invite transaction associated with the inviteAppData " + "of the CANCEL " + inviteAppData); - } + } if(logger.isDebugEnabled()) { logger.debug("routing state of the INVITE request for the CANCEL = " + inviteRequest.getRoutingState()); } final MobicentsSipApplicationSession sipApplicationSession = sipSession.getSipApplicationSession(); final SipContext sipContext = sipApplicationSession.getSipContext(); try { - sipContext.enterSipApp(sipApplicationSession, sipSession, false, true); + sipContext.enterSipApp(sipApplicationSession, sipSession, false, true); final MobicentsProxy proxy = sipSession.getProxy(); if(proxy != null) { if(logger.isDebugEnabled()) { logger.debug("proxying the CANCEL " + sipServletRequest); - } - // Routing State : PROXY case - if(!RoutingState.PROXIED.equals(inviteRequest.getRoutingState())) { - // 10.2.6 if the original request has not been proxied yet the container + } + // Routing State : PROXY case + if(!RoutingState.PROXIED.equals(inviteRequest.getRoutingState())) { + // 10.2.6 if the original request has not been proxied yet the container // responds to it with a 487 final response try { send487Response(inviteTransaction, inviteRequest); @@ -269,17 +290,17 @@ public void dispatch() throws DispatcherException { callServlet(sipServletRequest); } catch (ServletException e) { throw new DispatcherException(Response.SERVER_INTERNAL_ERROR, "An unexpected servlet exception occured while routing the following CANCEL " + request, e); - } catch (IOException e) { + } catch (IOException e) { throw new DispatcherException(Response.SERVER_INTERNAL_ERROR, "An unexpected IO exception occured while routing the following CANCEL " + request, e); - } catch (Throwable e) { + } catch (Throwable e) { throw new DispatcherException(Response.SERVER_INTERNAL_ERROR, "An unexpected exception occured while routing the following CANCEL " + request, e); - } + } } else if(RoutingState.FINAL_RESPONSE_SENT.equals(inviteRequest.getRoutingState())) { if(logger.isDebugEnabled()) { logger.debug("the final response has already been sent, nothing to do here"); } - } else { - + } else { + if(logger.isDebugEnabled()) { logger.debug("invite transaction of the CANCEL " + inviteTransaction); } @@ -289,9 +310,9 @@ public void dispatch() throws DispatcherException { if(logger.isDebugEnabled()) { logger.debug("invite message : Final response was generated ? " + ((SipServletRequestImpl)inviteAppData.getSipServletMessage()).isFinalResponseGenerated()); } - + if(logger.isDebugEnabled()) { - logger.debug("replying 487 to INVITE cancelled"); + logger.debug("replying 487 to INVITE cancelled"); } //otherwise it means that this is for the app try { @@ -304,15 +325,15 @@ public void dispatch() throws DispatcherException { callServlet(sipServletRequest); } catch (ServletException e) { throw new DispatcherException(Response.SERVER_INTERNAL_ERROR, "An unexpected servlet exception occured while routing the following CANCEL " + request, e); - } catch (IOException e) { + } catch (IOException e) { throw new DispatcherException(Response.SERVER_INTERNAL_ERROR, "An unexpected IO exception occured while routing the following CANCEL " + request, e); - } catch (Throwable e) { + } catch (Throwable e) { throw new DispatcherException(Response.SERVER_INTERNAL_ERROR, "An unexpected exception occured while routing the following CANCEL " + request, e); - } + } } } finally { sipContext.exitSipApp(sipApplicationSession, sipSession); } - } + } } } diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/dispatchers/DispatchTask.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/dispatchers/DispatchTask.java index 7990237df1..0f8c768faf 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/dispatchers/DispatchTask.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/dispatchers/DispatchTask.java @@ -54,15 +54,25 @@ public void run() { } public void dispatchAndHandleExceptions () { + if (logger.isDebugEnabled()){ + logger.debug("dispatchAndHandleExceptions"); + } try { dispatch(); } catch (Throwable t) { logger.error("Unexpected exception while processing message " + sipServletMessage, t); if(sipServletMessage instanceof SipServletRequestImpl) { + if (logger.isDebugEnabled()){ + logger.debug("dispatchAndHandleExceptions - sipServletMessage is instanceof SipServletRequestImpl"); + } + SipServletRequestImpl sipServletRequest = (SipServletRequestImpl) sipServletMessage; if(!Request.ACK.equalsIgnoreCase(sipServletRequest.getMethod()) && !Request.PRACK.equalsIgnoreCase(sipServletRequest.getMethod())) { + if (logger.isDebugEnabled()){ + logger.debug("dispatchAndHandleExceptions - calling sendErrorResponse"); + } MessageDispatcher.sendErrorResponse(sipServletRequest.getSipSession().getSipApplicationSession().getSipContext().getSipApplicationDispatcher(), Response.SERVER_INTERNAL_ERROR, sipServletRequest, sipProvider); } } diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/dispatchers/InitialRequestDispatcher.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/dispatchers/InitialRequestDispatcher.java index f8671a1037..defb9c4cdc 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/dispatchers/InitialRequestDispatcher.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/dispatchers/InitialRequestDispatcher.java @@ -20,6 +20,7 @@ package org.mobicents.servlet.sip.core.dispatchers; import gov.nist.javax.sip.SipStackExt; +import gov.nist.javax.sip.address.GenericURI; import gov.nist.javax.sip.header.extensions.JoinHeader; import gov.nist.javax.sip.header.extensions.ReplacesHeader; @@ -100,6 +101,11 @@ public InitialRequestDispatcher() {} * {@inheritDoc} */ public void dispatchMessage(SipProvider sipProvider, SipServletMessageImpl sipServletMessage) throws DispatcherException { + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - sipProvider=" + sipProvider + + ", sipServletMessage=" + sipServletMessage); + } + final SipApplicationRouter sipApplicationRouter = sipApplicationDispatcher.getSipApplicationRouter(); final MobicentsSipFactory sipFactoryImpl = sipApplicationDispatcher.getSipFactory(); final SipServletRequestImpl sipServletRequest = (SipServletRequestImpl) sipServletMessage; @@ -121,9 +127,15 @@ public void dispatchMessage(SipProvider sipProvider, SipServletMessageImpl sipSe SipApplicationRoutingRegion routingRegion = null; if(poppedRoute != null) { Parameters poppedAddress = (Parameters)poppedRoute.getAddress().getURI(); + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - poppedAddress=" + poppedAddress); + } // get the state info associated with the request because it means // that is has been routed back to the container String directive = poppedAddress.getParameter(ROUTE_PARAM_DIRECTIVE); + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - directive=" + directive); + } if(directive != null && directive.length() > 0) { //If request is received from an application, directive is set either implicitly //or explicitly by the application. @@ -172,11 +184,17 @@ public void dispatchMessage(SipProvider sipProvider, SipServletMessageImpl sipSe // Request-URI (in that order) to see if it contains an encoded URI. // If it does, the container MUST use the encoded URI to locate the targeted SipApplicationSession object URI requestURI = request.getRequestURI(); + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - requestURI=" + requestURI); + } // From horacimacias : Fix for Issue 2115 MSS unable to handle GenericURI URIs // check the URI is an instance of Parameters. GenericURI doesn't implement Parameters String targetedApplicationKey; if(requestURI instanceof Parameters) { targetedApplicationKey = ((Parameters)requestURI).getParameter(MobicentsSipApplicationSession.SIP_APPLICATION_KEY_PARAM_NAME); + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - requestURI is instanceof Parameters - targetedApplicationKey=" + targetedApplicationKey); + } } else { targetedApplicationKey = null; } @@ -184,6 +202,9 @@ public void dispatchMessage(SipProvider sipProvider, SipServletMessageImpl sipSe SipTargetedRequestInfo targetedRequestInfo = null; if(encodeURISipApplicationSession != null) { targetedRequestInfo = new SipTargetedRequestInfo(SipTargetedRequestType.ENCODED_URI, encodeURISipApplicationSession.getApplicationName()); + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - encodeURISipApplicationSession not null - targetedRequestInfo=" + targetedRequestInfo); + } } else if(poppedRoute != null) { Parameters poppedAddress = (Parameters)poppedRoute.getAddress().getURI(); targetedApplicationKey = poppedAddress.getParameter(MobicentsSipApplicationSession.SIP_APPLICATION_KEY_PARAM_NAME); @@ -191,6 +212,12 @@ public void dispatchMessage(SipProvider sipProvider, SipServletMessageImpl sipSe if(encodeURISipApplicationSession != null) { targetedRequestInfo = new SipTargetedRequestInfo(SipTargetedRequestType.ENCODED_URI, encodeURISipApplicationSession.getApplicationName()); } + + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - encodeURISipApplicationSession is null - targetedApplicationKey=" + targetedApplicationKey + + ", encodeURISipApplicationSession=" + encodeURISipApplicationSession + + ", targetedRequestInfo" + targetedRequestInfo); + } } // 15.11.4 Join and Replaces Targeting Mechanism @@ -317,6 +344,27 @@ public void dispatchMessage(SipProvider sipProvider, SipServletMessageImpl sipSe * @throws DispatcherException a problem occured while dispatching the request */ private void dispatchInsideContainer(final SipProvider sipProvider, final SipApplicationRouterInfo applicationRouterInfo, final SipServletRequestImpl sipServletRequest, final MobicentsSipFactory sipFactoryImpl, MobicentsSipSession joinReplacesSipSession, MobicentsSipApplicationSession encodeURISipApplicationSession) throws DispatcherException { + if(logger.isDebugEnabled()) { + logger.debug("dispatchInsideContainer - sipProvider=" + sipProvider + + ", applicationRouterInfo=" + applicationRouterInfo + + ", joinReplacesSipSession=" + joinReplacesSipSession + + ", sipServletRequest=" + sipServletRequest + + ", sipFactoryImpl=" + sipFactoryImpl + + ", encodeURISipApplicationSession=" + encodeURISipApplicationSession); + if (joinReplacesSipSession != null){ + logger.debug("dispatchInsideContainer - joinReplacesSipSession.getCallId()=" + joinReplacesSipSession.getCallId() + + ", joinReplacesSipSession.getId()=" + joinReplacesSipSession.getId() + + ", joinReplacesSipSession.getKey()=" + joinReplacesSipSession.getKey() + + ", joinReplacesSipSession.getApplicationSession()=" + joinReplacesSipSession.getApplicationSession() + + ", joinReplacesSipSession.getSipApplicationSession()=" + joinReplacesSipSession.getSipApplicationSession()); + + if (joinReplacesSipSession.getSipApplicationSession() != null){ + logger.debug("dispatchInsideContainer - joinReplacesSipSession.getSipApplicationSession().getId()=" + joinReplacesSipSession.getSipApplicationSession().getId() + + ", joinReplacesSipSession.getSipApplicationSession().getKey()=" + joinReplacesSipSession.getSipApplicationSession().getKey()); + } + } + } + final String nextApplicationName = applicationRouterInfo.getNextApplicationName(); if(logger.isDebugEnabled()) { logger.debug("Dispatching the request event to " + nextApplicationName); @@ -386,12 +434,22 @@ private void dispatchInsideContainer(final SipProvider sipProvider, final SipApp SipApplicationSessionKey sipApplicationSessionKey = makeAppSessionKey( sipContext, sipServletRequest, nextApplicationName); + + if(logger.isDebugEnabled()) { + logger.debug("dispatchInsideContainer - newly created sipApplicationSessionKey.getId()=" + sipApplicationSessionKey.getId() + + ", sipApplicationSessionKey.getAppGeneratedKey()" + sipApplicationSessionKey.getAppGeneratedKey() + + ", sipApplicationSessionKey.getApplicationName()" + sipApplicationSessionKey.getApplicationName()); + } + sipApplicationSession = sipManager.getSipApplicationSession( sipApplicationSessionKey, true); if(StaticServiceHolder.sipStandardService.isHttpFollowsSip()) { String jvmRoute = StaticServiceHolder.sipStandardService.getJvmRoute(); if(jvmRoute != null) { + if(logger.isDebugEnabled()) { + logger.debug("dispatchInsideContainer - setting jvmRoute to " + jvmRoute); + } sipApplicationSession.setJvmRoute(jvmRoute); } } @@ -634,9 +692,15 @@ private final boolean checkRouteModifier(SipApplicationRouterInfo applicationRou */ private final MobicentsSipApplicationSession retrieveTargetedApplication( String targetedApplicationKey) { + if (logger.isDebugEnabled()){ + logger.debug("retrieveTargetedApplication - targetedApplicationKey=" + targetedApplicationKey); + } if( targetedApplicationKey != null && targetedApplicationKey.length() > 0) { targetedApplicationKey = RFC2396UrlDecoder.decode(targetedApplicationKey); + if (logger.isDebugEnabled()){ + logger.debug("retrieveTargetedApplication - decoded targetedApplicationKey=" + targetedApplicationKey); + } SipApplicationSessionKey targetedApplicationSessionKey; try { targetedApplicationSessionKey = SessionManagerUtil.parseSipApplicationSessionKey(targetedApplicationKey); @@ -646,6 +710,9 @@ private final MobicentsSipApplicationSession retrieveTargetedApplication( } SipContext sipContext = sipApplicationDispatcher.findSipApplication(targetedApplicationSessionKey.getApplicationName()); if(sipContext != null) { + if (logger.isDebugEnabled()){ + logger.debug("retrieveTargetedApplication - sipContext not null"); + } return sipContext.getSipManager().getSipApplicationSession(targetedApplicationSessionKey, false); } } @@ -700,14 +767,36 @@ public static class InitialDispatchTask extends DispatchTask { } public void dispatch() throws DispatcherException { + if(logger.isDebugEnabled()) { + logger.debug("InitialDispatchTask - dispatch"); + } + final SipServletRequestImpl sipServletRequest = (SipServletRequestImpl)sipServletMessage; + if(logger.isDebugEnabled()) { + logger.debug("InitialDispatchTask - dispatch - sipServletRequest=" + sipServletRequest); + } + final MobicentsSipSession sipSessionImpl = sipServletRequest.getSipSession(); + if(logger.isDebugEnabled()) { + logger.debug("InitialDispatchTask - dispatch - sipSessionImpl=" + sipSessionImpl); + } + final MobicentsSipApplicationSession appSession = sipSessionImpl.getSipApplicationSession(); + if(logger.isDebugEnabled()) { + logger.debug("InitialDispatchTask - dispatch - appSession=" + appSession); + } final SipContext sipContext = appSession.getSipContext(); + if(logger.isDebugEnabled()) { + logger.debug("InitialDispatchTask - dispatch - sipContext=" + sipContext); + } final Request request = (Request) sipServletRequest.getMessage(); + if(logger.isDebugEnabled()) { + logger.debug("InitialDispatchTask - dispatch - request=" + request); + } boolean batchStarted = sipContext.enterSipAppHa(true); try { + sipSessionImpl.setSessionCreatingTransactionRequest(sipServletRequest); String sipSessionHandlerName = sipSessionImpl.getHandler(); @@ -725,7 +814,9 @@ public void dispatch() throws DispatcherException { } else { MobicentsSipServletMapping sipServletMapping = sipContext.findSipServletMappings(sipServletRequest); if(sipServletMapping == null && sipContext.getSipRubyController() == null) { - logger.error("Sending 404 because no matching servlet found for this request "); + if(logger.isInfoEnabled()) { + logger.info("Sending 404 because no matching servlet found for this request " + sipServletRequest); + } sendErrorResponse(sipContext.getSipApplicationDispatcher(), Response.NOT_FOUND, sipServletRequest, sipProvider); return; } else if(sipServletMapping != null) { diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/dispatchers/MessageDispatcher.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/dispatchers/MessageDispatcher.java index e051f8a1a6..200bf00acb 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/dispatchers/MessageDispatcher.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/dispatchers/MessageDispatcher.java @@ -121,8 +121,14 @@ public MessageDispatcher() {} // } public static void sendErrorResponse(SipApplicationDispatcher sipApplicationDispatcher, int errorCode, SipServletRequestImpl sipServletRequest, SipProvider sipProvider) { + if(logger.isDebugEnabled()) { + logger.debug("sendErrorResponse - errorCode=" + errorCode + ", sipServletRequest=" + sipServletRequest); + } MessageDispatcher.sendErrorResponse(sipApplicationDispatcher, errorCode, (ServerTransaction) sipServletRequest.getTransaction(), (Request) sipServletRequest.getMessage(), sipProvider); if(sipServletRequest.getSipSession() != null) { + if(logger.isDebugEnabled()) { + logger.debug("sendErrorResponse - sip session is not null"); + } sipServletRequest.getSipSession().updateStateOnResponse((SipServletResponseImpl)sipServletRequest.createResponse(SipServletResponseImpl.SC_SERVER_INTERNAL_ERROR), false); } } @@ -137,6 +143,9 @@ public static void sendErrorResponse(SipApplicationDispatcher sipApplicationDisp public static void sendErrorResponse(SipApplicationDispatcher sipApplicationDispatcher, int errorCode, ServerTransaction transaction, Request request, SipProvider sipProvider) { + if(logger.isDebugEnabled()) { + logger.debug("sendErrorResponse - errorCode=" + errorCode + ", request=" + request); + } try{ Response response=SipFactoryImpl.messageFactory.createResponse (errorCode,request); @@ -153,6 +162,10 @@ public static void sendErrorResponse(SipApplicationDispatcher sipApplicationDisp } protected static SipApplicationSessionKey makeAppSessionKey(SipContext sipContext, SipServletRequestImpl sipServletRequestImpl, String applicationName) throws DispatcherException { + if(logger.isDebugEnabled()) { + logger.debug("makeAppSessionKey - applicationName=" + applicationName); + } + String appGeneratedKey = null; Method appKeyMethod = null; @@ -230,6 +243,10 @@ protected static SipApplicationSessionKey makeAppSessionKey(SipContext sipContex applicationName, null, appGeneratedKey); + + if(logger.isDebugEnabled()) { + logger.debug("makeAppSessionKey - returning sipApplicationSessionKey=" + sipApplicationSessionKey); + } return sipApplicationSessionKey; } diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/dispatchers/ResponseDispatcher.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/dispatchers/ResponseDispatcher.java index ba4f8bfde5..59446c2c98 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/dispatchers/ResponseDispatcher.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/dispatchers/ResponseDispatcher.java @@ -95,6 +95,9 @@ public ResponseDispatcher() {} * {@inheritDoc} */ public void dispatchMessage(final SipProvider sipProvider, SipServletMessageImpl sipServletMessage) throws DispatcherException { + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - sipServletMessage.getAppSessionId()=" + sipServletMessage.getAppSessionId() + ", sipServletMessage.getCallId()=" + sipServletMessage.getCallId()); + } final SipFactoryImpl sipFactoryImpl = (SipFactoryImpl) sipApplicationDispatcher.getSipFactory(); final SipServletResponseImpl sipServletResponse = (SipServletResponseImpl) sipServletMessage; final Response response = sipServletResponse.getResponse(); @@ -484,7 +487,7 @@ public void dispatch() throws DispatcherException { // - Any 2xx response to an INVITE request // A stateful proxy MUST NOT immediately forward any other responses if(sipServletResponse.getMethod().equals(Request.INVITE) && sipServletResponse.getRequest() != null - && sipServletResponse.getRequest().isInitial() && proxy.getBestResponseSent() >= 200 && (status <= 200 || status >= 300)) { + && sipServletResponse.getRequest().isInitial() && proxy.getBestResponseSent() >= 200 && (status < 200 || status >= 300)) { if(logger.isDebugEnabled()) { logger.debug("best final response sent " + proxy.getBestResponseSent() + ", response status " + status + " not forwarding response"); } diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/dispatchers/SubsequentRequestDispatcher.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/dispatchers/SubsequentRequestDispatcher.java index 2a55ed0785..6fed03497a 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/dispatchers/SubsequentRequestDispatcher.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/dispatchers/SubsequentRequestDispatcher.java @@ -35,6 +35,7 @@ import javax.servlet.sip.ServletParseException; import javax.servlet.sip.SipServletResponse; import javax.sip.Dialog; +import javax.sip.ListeningPoint; import javax.sip.ServerTransaction; import javax.sip.SipException; import javax.sip.SipProvider; @@ -101,6 +102,9 @@ public SubsequentRequestDispatcher() {} * {@inheritDoc} */ public void dispatchMessage(final SipProvider sipProvider, SipServletMessageImpl sipServletMessage) throws DispatcherException { + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - sipServletMessage.getAppSessionId()=" + sipServletMessage.getAppSessionId() + ", sipServletMessage.getCallId()=" + sipServletMessage.getCallId()); + } final MobicentsSipFactory sipFactoryImpl = sipApplicationDispatcher.getSipFactory(); final SipServletRequestImpl sipServletRequest = (SipServletRequestImpl) sipServletMessage; if(logger.isDebugEnabled()) { @@ -108,43 +112,114 @@ public void dispatchMessage(final SipProvider sipProvider, SipServletMessageImpl } final Request request = (Request) sipServletRequest.getMessage(); - final Dialog dialog = sipServletRequest.getDialog(); + final Dialog dialog = sipServletRequest.getDialog(); + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - dialog=" + dialog); + if (dialog != null){ + logger.debug("dispatchMessage - dialog.getDialogId()=" + dialog.getDialogId()); + } + } final RouteHeader poppedRouteHeader = sipServletRequest.getPoppedRouteHeader(); final String method = request.getMethod(); String applicationName = null; - String applicationId = null; + String applicationId = null; + + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - poppedRouteHeader=" + poppedRouteHeader); + } + if(poppedRouteHeader != null){ final Parameters poppedAddress = (Parameters)poppedRouteHeader.getAddress().getURI(); + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - poppedAddress=" + poppedAddress); + } // Extract information from the Route Header final String applicationNameHashed = poppedAddress.getParameter(RR_PARAM_APPLICATION_NAME); + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - applicationNameHashed=" + applicationNameHashed); + } if(applicationNameHashed != null && applicationNameHashed.length() > 0) { applicationName = sipApplicationDispatcher.getApplicationNameFromHash(applicationNameHashed); - applicationId = poppedAddress.getParameter(APP_ID); + applicationId = poppedAddress.getParameter(APP_ID); + + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - based on poppedRouteHeader - applicationName=" + applicationName); + logger.debug("dispatchMessage - based on poppedRouteHeader - applicationId=" + applicationId); + } } } + + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - applicationId=" + applicationId); + } + if(applicationId == null) { + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - toHeader applicationId from ToHeader"); + } + final ToHeader toHeader = (ToHeader) request.getHeader(ToHeader.NAME); final String arText = toHeader.getTag(); + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - toHeader applicationId from ToHeader - toHeader=" + toHeader); + logger.debug("dispatchMessage - toHeader applicationId from ToHeader - arText=" + arText); + } try { final String[] tuple = ApplicationRoutingHeaderComposer.getAppNameAndSessionId(sipApplicationDispatcher, arText); applicationName = tuple[1]; applicationId = tuple[2]; + + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - from toHeader - tuples=" + tuple); + if (tuple != null){ + for (String tmp : tuple){ + logger.debug("dispatchMessage - from toHeader - tuple=" + tmp); + } + } + logger.debug("dispatchMessage - from toHeader - applicationName=" + applicationName); + logger.debug("dispatchMessage - from toHeader - applicationId=" + applicationId); + } + } catch(IllegalArgumentException e) { throw new DispatcherException(Response.SERVER_INTERNAL_ERROR, e); } if(applicationId == null && applicationName == null) { + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - applicationName and applicationId are still null"); + } + //gvag Issue 2337 & 2327 javax.sip.address.URI requestURI = request.getRequestURI(); + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - requestURI=" + requestURI); + } // Issue 2850 : Use Request-URI custom Mobicents parameters to route request for misbehaving agents, workaround for Cisco-SIPGateway/IOS-12.x user agent if(request.getRequestURI() instanceof javax.sip.address.SipURI) { + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - requestURI is SipURI"); + } + final String applicationNameHashed = ((Parameters)requestURI).getParameter(RR_PARAM_APPLICATION_NAME); + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - applicationNameHashed=" + applicationNameHashed); + } + if(applicationNameHashed != null && applicationNameHashed.length() > 0) { applicationName = sipApplicationDispatcher.getApplicationNameFromHash(applicationNameHashed); applicationId = ((Parameters)requestURI).getParameter(APP_ID); + + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - applicationName=" + applicationName); + logger.debug("dispatchMessage - applicationId=" + applicationId); + } } } if(applicationId == null && applicationName == null) { + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - applicationName and applicationId are still null again"); + } + boolean isAnotherDomain = false; if(requestURI.isSipURI()){ @@ -152,6 +227,12 @@ public void dispatchMessage(final SipProvider sipProvider, SipServletMessageImpl final int port = ((SipURI) requestURI).getPort(); final String transport = JainSipUtils.findTransport(request); isAnotherDomain = sipApplicationDispatcher.isExternal(host, port, transport); + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - host=" + host + + ", port=" + port + + ", transport=" + transport + + ", isAnotherDomain=" + isAnotherDomain); + } } else { if(logger.isDebugEnabled()) { logger.debug("The Request URI " + requestURI + " is not a SIP URI and the Route Header was null or didn't contain information about an application to call (which would be incorrect) so we assume the request is an ACK for a container generated error response or misrouted"); @@ -160,7 +241,10 @@ public void dispatchMessage(final SipProvider sipProvider, SipServletMessageImpl // Issue 823 (http://code.google.com/p/mobicents/issues/detail?id=823) : // Container should proxy statelessly subsequent requests not targeted at itself - if(isAnotherDomain) { + if(isAnotherDomain) { + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - isAnotherDomain=" + isAnotherDomain); + } if(Request.ACK.equals(method) && sipServletRequest.getTransaction() != null && ((SIPServerTransaction)sipServletRequest.getTransaction()).getLastResponseStatusCode() >= 300) { // Issue 2213 (http://code.google.com/p/mobicents/issues/detail?id=2213) : // ACK for final error response are proxied statelessly for proxy applications @@ -190,11 +274,15 @@ public void dispatchMessage(final SipProvider sipProvider, SipServletMessageImpl } return ; } else { + // Fixed github issue: https://github.com/RestComm/sip-servlets/issues/189 + // RFC 3261: https://tools.ietf.org/html/rfc3261#section-12.2.2 + // If there is no existing dialog for this subsequence, UAS MUST respond to the request with a + // 481 (Call/Transaction Does Not Exist) status code and pass that to the server transaction." if(poppedRouteHeader != null) { - throw new DispatcherException(Response.SERVER_INTERNAL_ERROR, "cannot find the application to handle this subsequent request " + request + + throw new DispatcherException(Response.CALL_OR_TRANSACTION_DOES_NOT_EXIST, "cannot find the application to handle this subsequent request " + request + "in this popped routed header " + poppedRouteHeader); } else { - throw new DispatcherException(Response.SERVER_INTERNAL_ERROR, "cannot find the application to handle this subsequent request " + request); + throw new DispatcherException(Response.CALL_OR_TRANSACTION_DOES_NOT_EXIST, "cannot find the application to handle this subsequent request " + request); } } } @@ -204,10 +292,16 @@ public void dispatchMessage(final SipProvider sipProvider, SipServletMessageImpl boolean inverted = false; if(dialog != null && !dialog.isServer()) { + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - inverted=" + inverted); + } inverted = true; } final SipContext sipContext = sipApplicationDispatcher.findSipApplication(applicationName); + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - sipContext=" + sipContext); + } if(sipContext == null) { if(poppedRouteHeader != null) { throw new DispatcherException(Response.SERVER_INTERNAL_ERROR, "cannot find the application to handle this subsequent request " + request + @@ -222,8 +316,18 @@ public void dispatchMessage(final SipProvider sipProvider, SipServletMessageImpl applicationId, null); + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - creating sipApplicationSessionKey - applicationName=" + applicationName + + ", applicationId=" + applicationId + + ", sipApplicationSessionKey.getId()=" + sipApplicationSessionKey.getId()); + } + MobicentsSipSession tmpSipSession = null; MobicentsSipApplicationSession sipApplicationSession = sipManager.getSipApplicationSession(sipApplicationSessionKey, false); + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - got sip app session based on the newly created key - sipApplicationSession=" + sipApplicationSession); + } + if(sipApplicationSession == null) { if(logger.isDebugEnabled()) { sipManager.dumpSipApplicationSessions(); @@ -231,6 +335,12 @@ public void dispatchMessage(final SipProvider sipProvider, SipServletMessageImpl //trying the join or replaces matching sip app sessions final MobicentsSipApplicationSessionKey joinSipApplicationSessionKey = sipContext.getSipSessionsUtil().getCorrespondingSipApplicationSession(sipApplicationSessionKey, JoinHeader.NAME); final MobicentsSipApplicationSessionKey replacesSipApplicationSessionKey = sipContext.getSipSessionsUtil().getCorrespondingSipApplicationSession(sipApplicationSessionKey, ReplacesHeader.NAME); + + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - joinSipApplicationSessionKey=" + joinSipApplicationSessionKey); + logger.debug("dispatchMessage - replacesSipApplicationSessionKey=" + replacesSipApplicationSessionKey); + } + if(joinSipApplicationSessionKey != null) { sipApplicationSession = sipManager.getSipApplicationSession(joinSipApplicationSessionKey, false); } else if(replacesSipApplicationSessionKey != null) { @@ -239,6 +349,10 @@ public void dispatchMessage(final SipProvider sipProvider, SipServletMessageImpl } // Orphaned requests are routed from here boolean routeOrphanRequests = ((SipFactoryExt)sipContext.getSipFactoryFacade()).isRouteOrphanRequests(); + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - routeOrphanRequests=" + routeOrphanRequests); + } + if(sipApplicationSession == null || sipApplicationSession.isOrphan()) { if(logger.isDebugEnabled()) { logger.debug("routeOrphanRequests = " + routeOrphanRequests + " for context " + sipContext.getApplicationName() + " appSession=" + sipApplicationSession); @@ -252,14 +366,24 @@ public void dispatchMessage(final SipProvider sipProvider, SipServletMessageImpl ", it may already have been invalidated or timed out"); } } else { + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - calling handleOrphanRequest, applicationId=" + applicationId); + } + handleOrphanRequest(sipProvider, sipServletRequest, applicationId, sipContext); return; } } if(StaticServiceHolder.sipStandardService.isHttpFollowsSip()) { + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - isHttpFollowsSip true"); + } String jvmRoute = StaticServiceHolder.sipStandardService.getJvmRoute(); if(jvmRoute != null) { + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - jvmRoute=" + jvmRoute); + } sipApplicationSession.setJvmRoute(jvmRoute); } } @@ -270,6 +394,12 @@ public void dispatchMessage(final SipProvider sipProvider, SipServletMessageImpl " with the following popped route header " + sipServletRequest.getPoppedRoute()); } tmpSipSession = sipManager.getSipSession(key, false, sipFactoryImpl, sipApplicationSession); + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - tmpSipSession=" + tmpSipSession); + if (tmpSipSession != null){ + logger.debug("dispatchMessage - tmpSipSession.getId()=" + tmpSipSession.getId()); + } + } // Added by Vladimir because the inversion detection on proxied requests doesn't work if(tmpSipSession == null) { @@ -279,9 +409,17 @@ public void dispatchMessage(final SipProvider sipProvider, SipServletMessageImpl } key = SessionManagerUtil.getSipSessionKey(sipApplicationSession.getKey().getId(), applicationName, request, !inverted); tmpSipSession = sipManager.getSipSession(key, false, sipFactoryImpl, sipApplicationSession); + if (tmpSipSession != null) { + if(logger.isDebugEnabled()) { + logger.debug("Inverted try worked. sip session found : " + tmpSipSession.getId()); + } + } } if(tmpSipSession == null) { + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - tmpSipSession is still null, calling dumpSipSessions"); + } sipManager.dumpSipSessions(); if(logger.isDebugEnabled()) { logger.debug("routeOrphanRequests = " + routeOrphanRequests + " for context " + sipContext.getApplicationName() + " appSessionId=" + applicationId); @@ -295,13 +433,12 @@ public void dispatchMessage(final SipProvider sipProvider, SipServletMessageImpl ", it may already have been invalidated or timed out"); } } else { + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - calling handleOrphanRequest, applicationId=" + applicationId); + } handleOrphanRequest(sipProvider, sipServletRequest, applicationId, sipContext); return; } - } else { - if(logger.isDebugEnabled()) { - logger.debug("Inverted try worked. sip session found : " + tmpSipSession.getId()); - } } final MobicentsSipSession sipSession = tmpSipSession; @@ -309,16 +446,31 @@ public void dispatchMessage(final SipProvider sipProvider, SipServletMessageImpl final SubsequentDispatchTask dispatchTask = new SubsequentDispatchTask(sipServletRequest, sipProvider); // we enter the sip app here, thus acuiring the semaphore on the session (if concurrency control is set) before the jain sip tx semaphore is released and ensuring that - // the tx serialization is preserved + // the tx serialization is preserved sipContext.enterSipApp(sipApplicationSession, sipSession, false, true); + // Issue 2886 : http://code.google.com/p/mobicents/issues/detail?id=2886 ACK is bound out of replication context // we need to enter the serialization here because validateCSeq below can set the CSeq so we need to replicate it + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - calling sipContext.enterSipApp again..."); + } final boolean batchStarted = sipContext.enterSipAppHa(true); + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - batchStarted=" + batchStarted); + } // Issue 1714 && Issue 2886 : moving the requests pending within the serialization block if(request.getMethod().equals(Request.ACK)) { + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - method is ACK"); + } + sipSession.setRequestsPending(sipSession.getRequestsPending() - 1); } else if(request.getMethod().equals(Request.INVITE)){ + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - method is INVITE"); + } + if(logger.isDebugEnabled()) { logger.debug("INVITE requests pending " + sipSession.getRequestsPending()); } @@ -347,9 +499,21 @@ public void dispatchMessage(final SipProvider sipProvider, SipServletMessageImpl // BEGIN validation delegated to the applicationas per JSIP patch for http://code.google.com/p/mobicents/issues/detail?id=766 boolean orphan = sipSession.isOrphan() || sipApplicationSession.isOrphan(); sipServletRequest.setOrphan(orphan); + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - orphan=" + orphan); + } + if(sipSession.getProxy() == null && !orphan) { boolean isValid = sipSession.validateCSeq(sipServletRequest); + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - sipSession.getProxy() is null and not orphan, isValid=" + isValid); + } + if(!isValid) { + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - calling sipContext.exitSipAppHa"); + } + // Issue 2886 : http://code.google.com/p/mobicents/issues/detail?id=2886 ACK is bound out of replication context // we need to exit the serialization here because validateCSeq above can set the CSeq so we need to replicate it sipContext.exitSipAppHa(sipServletRequest, null, batchStarted); @@ -362,9 +526,17 @@ public void dispatchMessage(final SipProvider sipProvider, SipServletMessageImpl // if the flag is set we bypass the executor. This flag should be made deprecated if(sipApplicationDispatcher.isBypassRequestExecutor() || ConcurrencyControlMode.Transaction.equals((sipContext.getConcurrencyControlMode()))) { + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - bypassing the executor - batchStarted=" + batchStarted); + } + dispatchTask.setBatchStarted(batchStarted); dispatchTask.dispatchAndHandleExceptions(); } else { + if(logger.isDebugEnabled()) { + logger.debug("dispatchMessage - finally calling sipContext.exitSipAppHa"); + } + // Issue 2886 : http://code.google.com/p/mobicents/issues/detail?id=2886 ACK is bound out of replication context // we need to exitSipAppHa because a new thread will be started here sipContext.exitSipAppHa(sipServletRequest, null, batchStarted); @@ -446,22 +618,51 @@ public void setBatchStarted(boolean batchStarted) { } public void dispatch() throws DispatcherException { + if(logger.isDebugEnabled()) { + logger.debug("SubsequentDispatchTask - dispatch"); + } final SipServletRequestImpl sipServletRequest = (SipServletRequestImpl)sipServletMessage; + if(logger.isDebugEnabled()) { + logger.debug("SubsequentDispatchTask - dispatch - sipServletRequest=" + sipServletRequest); + } + final MobicentsSipSession sipSession = sipServletRequest.getSipSession(); + if(logger.isDebugEnabled()) { + logger.debug("SubsequentDispatchTask - dispatch - sipSession=" + sipSession); + } + final MobicentsSipApplicationSession appSession = sipSession.getSipApplicationSession(); + if(logger.isDebugEnabled()) { + logger.debug("SubsequentDispatchTask - dispatch - appSession=" + appSession); + } + final SipContext sipContext = appSession.getSipContext(); + if(logger.isDebugEnabled()) { + logger.debug("SubsequentDispatchTask - dispatch - sipContext=" + sipContext); + } + final Request request = (Request) sipServletRequest.getMessage(); + if(logger.isDebugEnabled()) { + logger.debug("SubsequentDispatchTask - dispatch - request=" + request); + } + if(!sipContext.getSipApplicationDispatcher().isBypassRequestExecutor()) { // Issue 2886 : http://code.google.com/p/mobicents/issues/detail?id=2886 ACK is bound out of replication context // we need to enterSipAppHa because was started in another thread so we need to bind to this thread batchStarted = sipContext.enterSipAppHa(true); + if(logger.isDebugEnabled()) { + logger.debug("SubsequentDispatchTask - dispatch - batchStarted=" + batchStarted); + } } // Issue 2937 : http://code.google.com/p/mobicents/issues/detail?id=2937 // Susbequent Requests whose session is invalidated are still routed to the application if(!appSession.isValidInternal()) { if(appSession.isOrphan() || ((SipFactoryExt)sipContext.getSipFactoryFacade()).isRouteOrphanRequests()) { + if(logger.isDebugEnabled()) { + logger.debug("SubsequentDispatchTask - dispatch - calling handleOrphanRequest"); + } handleOrphanRequest(sipProvider, sipServletRequest, appSession.getId(), sipContext); } else { throw new DispatcherException(Response.CALL_OR_TRANSACTION_DOES_NOT_EXIST, "The corresponding sip application session to this subsequent request " + request + @@ -470,6 +671,9 @@ public void dispatch() throws DispatcherException { } final String requestMethod = sipServletRequest.getMethod(); + if(logger.isDebugEnabled()) { + logger.debug("SubsequentDispatchTask - dispatch - requestMethod=" + requestMethod); + } try { if(!Request.ACK.equalsIgnoreCase(requestMethod)) { // Issue 1494 : http://code.google.com/p/mobicents/issues/detail?id=1494 @@ -480,8 +684,16 @@ public void dispatch() throws DispatcherException { // https://github.com/Mobicents/sip-servlets/issues/66 include UPDATE as well otherwise // creating the 200 OK response to IVNITE for B2BUA after UPDATE is failing !Request.UPDATE.equalsIgnoreCase(requestMethod)) { + + if(logger.isDebugEnabled()) { + logger.debug("SubsequentDispatchTask - dispatch - calling setSessionCreatingTransactionRequest"); + } + sipSession.setSessionCreatingTransactionRequest(sipServletRequest); } + if(logger.isDebugEnabled()) { + logger.debug("SubsequentDispatchTask - dispatch - calling addOngoingTransaction"); + } sipSession.addOngoingTransaction(sipServletRequest.getTransaction()); } try { @@ -506,6 +718,10 @@ public void dispatch() throws DispatcherException { // "Applications are not notified of incoming ACKs for non-2xx final responses to INVITE." boolean callServlet = true; if(Request.ACK.equalsIgnoreCase(requestMethod)) { + if(logger.isDebugEnabled()) { + logger.debug("SubsequentDispatchTask - dispatch - request is ACK"); + } + final Set ongoingTransactions = sipSession.getOngoingTransactions(); // Issue 1837 http://code.google.com/p/mobicents/issues/detail?id=1837 // ACK was received by JAIN-SIP but was not routed to application @@ -561,42 +777,83 @@ public void dispatch() throws DispatcherException { // See if the subsequent request should go directly to the proxy final MobicentsProxy proxy = sipSession.getProxy(); if(proxy != null) { + if(logger.isDebugEnabled()) { + logger.debug("SubsequentDispatchTask - dispatch - proxy is not null"); + } + MobicentsProxyBranch finalBranch = proxy.getFinalBranchForSubsequentRequests(); boolean isPrack = requestMethod.equalsIgnoreCase(Request.PRACK); boolean isUpdate = requestMethod.equalsIgnoreCase(Request.UPDATE); // https://code.google.com/p/sipservlets/issues/detail?id=275 boolean isNotify = requestMethod.equalsIgnoreCase(Request.NOTIFY); + + if(logger.isDebugEnabled()) { + logger.debug("SubsequentDispatchTask - dispatch - proxy is not null, isPrack=" + isPrack + + ", isUpdate=" + isUpdate + + ", isNotify=" + isNotify); + } + // JSR 289 Section 6.2.1 : // any state transition caused by the reception of a SIP message, // the state change must be accomplished by the container before calling // the service() method of any SipServlet to handle the incoming message. sipSession.updateStateOnSubsequentRequest(sipServletRequest, true); - if(finalBranch != null) { + if(finalBranch != null) { + if(logger.isDebugEnabled()) { + logger.debug("SubsequentDispatchTask - dispatch - finalBranch is not null"); + } proxy.setAckReceived(requestMethod.equalsIgnoreCase(Request.ACK)); checkRequestURIForNonCompliantAgents(finalBranch, request); - proxy.setOriginalRequest(sipServletRequest); + //fixes https://github.com/RestComm/sip-servlets/issues/184 + //do not save ACK, is not necessary and holds mem + if(!sipServletRequest.getMethod().equalsIgnoreCase(Request.ACK) ) { + proxy.setOriginalRequest(sipServletRequest); + } // if(!isAckRetranmission) { // We should pass the ack retrans (implied by 10.2.4.1 Handling 2xx Responses to INVITE) // emmartins: JSR 289 10.2.8 - ACKs for non-2xx final responses are just dropped if(callServlet) { + if(logger.isDebugEnabled()) { + logger.debug("SubsequentDispatchTask - dispatch - calling callServlet"); + } callServlet(sipServletRequest); + + if(logger.isDebugEnabled()) { + logger.debug("SubsequentDispatchTask - dispatch - calling proxySubsequentRequest"); + } finalBranch.proxySubsequentRequest(sipServletRequest); } } else if(isPrack || isUpdate // https://code.google.com/p/sipservlets/issues/detail?id=275 || isNotify) { + if(logger.isDebugEnabled()) { + logger.debug("SubsequentDispatchTask - dispatch - calling callServlet"); + } callServlet(sipServletRequest); final List branches = proxy.getProxyBranches(); for(ProxyBranch pb : branches) { final ProxyBranchImpl proxyBranch = (ProxyBranchImpl) pb; if(proxyBranch.isWaitingForPrack() && isPrack) { + if(logger.isDebugEnabled()) { + logger.debug("SubsequentDispatchTask - dispatch - calling proxyDialogStateless"); + } + proxyBranch.proxyDialogStateless(sipServletRequest); proxyBranch.setWaitingForPrack(false); } else { //Issue: https://code.google.com/p/mobicents/issues/detail?id=2264 String requestToTag = ((RequestExt)request).getToHeader().getTag(); + if(logger.isDebugEnabled()) { + logger.debug("SubsequentDispatchTask - dispatch - requestToTag=" + requestToTag); + } + SipServletResponseImpl proxyResponse = (SipServletResponseImpl)(proxyBranch.getResponse()); + + if(logger.isDebugEnabled()) { + logger.debug("SubsequentDispatchTask - dispatch - proxyResponse=" + proxyResponse); + } + if (isNotify && proxyResponse == null) { // https://code.google.com/p/sipservlets/issues/detail?id=275 if(logger.isDebugEnabled()){ @@ -655,12 +912,19 @@ public void dispatch() throws DispatcherException { // If it's not for a proxy then it's just an AR, so go to the next application else { + if(logger.isDebugEnabled()) { + logger.debug("SubsequentDispatchTask - dispatch - not for proxy - calling updateStateOnSubsequentRequest"); + } + // JSR 289 Section 6.2.1 : // any state transition caused by the reception of a SIP message, // the state change must be accomplished by the container before calling // the service() method of any SipServlet to handle the incoming message. sipSession.updateStateOnSubsequentRequest(sipServletRequest, true); if(callServlet) { + if(logger.isDebugEnabled()) { + logger.debug("SubsequentDispatchTask - dispatch - not for proxy - calling callServlet"); + } callServlet(sipServletRequest); } } @@ -677,6 +941,10 @@ public void dispatch() throws DispatcherException { // Issue 1481 http://code.google.com/p/mobicents/issues/detail?id=1481 // proxy should not add or remove subscription since there is no dialog associated with it if(Request.NOTIFY.equals(requestMethod) && sipSession.getProxy() == null) { + if(logger.isDebugEnabled()) { + logger.debug("SubsequentDispatchTask - dispatch - NOTIFY, proxy null"); + } + final SubscriptionStateHeader subscriptionStateHeader = (SubscriptionStateHeader) sipServletRequest.getMessage().getHeader(SubscriptionStateHeader.NAME); @@ -687,8 +955,15 @@ public void dispatch() throws DispatcherException { } if(Request.ACK.equals(requestMethod)){ + if(logger.isDebugEnabled()) { + logger.debug("SubsequentDispatchTask - dispatch - ACK"); + } Transaction transaction = sipServletRequest.getTransaction(); if(transaction != null) { + if(logger.isDebugEnabled()) { + logger.debug("SubsequentDispatchTask - transaction not null"); + } + final TransactionApplicationData tad = (TransactionApplicationData) transaction.getApplicationData(); final MobicentsProxy proxy = sipSession.getProxy(); if(proxy == null && tad != null) { diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SessionManagerUtil.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SessionManagerUtil.java index 89dcc90a00..83c31b3609 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SessionManagerUtil.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SessionManagerUtil.java @@ -59,7 +59,10 @@ public class SessionManagerUtil { * @return the computed key * @throws NullPointerException if application name is null */ - public static SipSessionKey getSipSessionKey(final String applicationSessionId, final String applicationName, final Message message, boolean inverted) { + public static SipSessionKey getSipSessionKey(final String applicationSessionId, final String applicationName, final Message message, boolean inverted) { + if (logger.isDebugEnabled()){ + logger.debug("getSipSessionKey - applicationSessionId=" + applicationSessionId + ", applicationName=" + applicationName + ", message=" + message + ", inverted=" + inverted); + } if(applicationName == null) { throw new NullPointerException("the application name cannot be null for sip session key creation"); } @@ -109,6 +112,9 @@ public static SipSessionKey getSipSessionKey(final String applicationSessionId, * @throws NullPointerException if one of the two parameters is null */ public static SipApplicationSessionKey getSipApplicationSessionKey(final String applicationName, final String id, final String appGeneratedKey) { + if (logger.isDebugEnabled()){ + logger.debug("getSipApplicationSessionKey - applicationName=" + applicationName + ", id=" + id + ", appGeneratedKey=" + appGeneratedKey); + } if(applicationName == null) { throw new NullPointerException("the application name cannot be null for sip application session key creation"); } @@ -159,6 +165,9 @@ public static SipApplicationSessionKey parseSipApplicationSessionKey( */ public static SipSessionKey parseSipSessionKey( String sipSessionKey) throws ParseException { + if(logger.isDebugEnabled()) { + logger.debug("parseSipSessionKey - sipSessionKey=" + sipSessionKey); + } int indexOfLeftParenthesis = sipSessionKey.indexOf("("); // see http://code.google.com/p/sipservlets/issues/detail?id=207 @@ -198,10 +207,10 @@ public static SipSessionKey parseSipSessionKey( */ public static SipSessionKey parseHaSipSessionKey( String sipSessionKey, String sipAppSessionId, String sipApplicationName) throws ParseException { - if(logger.isDebugEnabled()) { - logger.debug("sipSession ha key to parse " + sipSessionKey ); + logger.debug("parseHaSipSessionKey - sipSessionKey=" + sipSessionKey + ", sipAppSessionId=" + sipAppSessionId + ", sipApplicationName=" + sipApplicationName); } + StringTokenizer stringTokenizer = new StringTokenizer(sipSessionKey, SESSION_KEY_SEPARATOR); String fromTag = stringTokenizer.nextToken(); String callId = stringTokenizer.nextToken(); diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipApplicationSessionAsyncTask.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipApplicationSessionAsyncTask.java index abd08a2146..65afc2e0a4 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipApplicationSessionAsyncTask.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipApplicationSessionAsyncTask.java @@ -48,6 +48,10 @@ public SipApplicationSessionAsyncTask(SipApplicationSessionKey key, * @see java.lang.Runnable#run() */ public void run() { + if (logger.isDebugEnabled()){ + logger.debug("run"); + } + final SipContext sipContext = sipFactoryImpl.getSipApplicationDispatcher().findSipApplication(key.getApplicationName()); if(sipContext != null) { SipManager sipManager = sipContext.getSipManager(); diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipApplicationSessionCreationThreadLocal.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipApplicationSessionCreationThreadLocal.java index 55fd976f50..ff9d67adc5 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipApplicationSessionCreationThreadLocal.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipApplicationSessionCreationThreadLocal.java @@ -22,8 +22,10 @@ package org.mobicents.servlet.sip.core.session; +import java.util.Iterator; import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; +import org.mobicents.servlet.sip.core.SipContext; /** * Information related to the application sessions created in the context of a thread when it is passed to the application @@ -37,4 +39,22 @@ public class SipApplicationSessionCreationThreadLocal { public Set getSipApplicationSessions() { return sipApplicationSessions; } + + private static ThreadLocal sessionsTH = new ThreadLocal(); + + public static ThreadLocal getTHRef() { + return sessionsTH; + } + + public static SipContext lookupContext() { + SipContext ctx = null; + SipApplicationSessionCreationThreadLocal get = sessionsTH.get(); + if (get != null) { + Iterator iterator = get.getSipApplicationSessions().iterator(); + if (iterator.hasNext()) { + ctx = iterator.next().getSipContext(); + } + } + return ctx; + } } diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipApplicationSessionImpl.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipApplicationSessionImpl.java index 7883cadcca..c4f7dafa1d 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipApplicationSessionImpl.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipApplicationSessionImpl.java @@ -66,17 +66,17 @@ /** *

Implementation of the SipApplicationSession interface. - * An instance of this sip application session can only be retrieved through the Session Manager + * An instance of this sip application session can only be retrieved through the Session Manager * (extended class from Tomcat's manager classes implementing the Manager interface) * to constrain the creation of sip application session and to make sure that all sessions created - * can be retrieved only through the session manager

- * + * can be retrieved only through the session manager

+ * *

* As a SipApplicationSession represents a call (that can contain multiple call legs, in the B2BUA case by example), - * the call id and the app name are used as a unique key for a given SipApplicationSession instance. + * the call id and the app name are used as a unique key for a given SipApplicationSession instance. *

- * - * @author Jean Deruelle + * + * @author Jean Deruelle */ public class SipApplicationSessionImpl implements MobicentsSipApplicationSession { @@ -85,46 +85,46 @@ public class SipApplicationSessionImpl implements MobicentsSipApplicationSession protected Map sipApplicationSessionAttributeMap; protected transient Set sipSessions; - + protected transient Set httpSessions; - - protected SipApplicationSessionKey key; - + + protected SipApplicationSessionKey key; + protected long lastAccessedTime; - + protected long creationTime; - + protected long expirationTime; - + protected boolean expired; - + protected transient SipApplicationSessionTimerTask expirationTimerTask; - + // protected transient ScheduledFuture expirationTimerFuture; - + protected transient ConcurrentHashMap servletTimers; - + protected transient AtomicBoolean isValidInternal; - + protected transient boolean isValid; - + protected boolean invalidateWhenReady = true; - + protected boolean readyToInvalidate = false; - + /** * The first sip application for subsequent requests. */ protected transient SipContext sipContext; - + protected String currentRequestHandler; - + protected transient Semaphore semaphore; - + protected transient MobicentsSipApplicationSessionFacade facade = null; - + protected long sipApplicationSessionTimeout = -1; - + // Does it need to be synchronized? protected Map getAttributeMap() { if(sipApplicationSessionAttributeMap == null) { @@ -132,15 +132,15 @@ protected Map getAttributeMap() { } return sipApplicationSessionAttributeMap; } - + @SuppressWarnings(value="unchecked") protected SipApplicationSessionImpl(SipApplicationSessionKey key, SipContext sipContext) { - sipSessions = new CopyOnWriteArraySet(); + sipSessions = new CopyOnWriteArraySet(); this.key = key; - creationTime = System.currentTimeMillis(); + creationTime = System.currentTimeMillis(); expired = false; isValid = true; - isValidInternal = new AtomicBoolean(true); + isValidInternal = new AtomicBoolean(true); // the sip context can be null if the AR returned an application that was not deployed if(sipContext != null) { this.sipContext = sipContext; @@ -150,44 +150,44 @@ protected SipApplicationSessionImpl(SipApplicationSessionKey key, SipContext sip } //scheduling the timer for session expiration final int sipContextTimeout = sipContext.getSipApplicationSessionTimeout(); - if(sipContextTimeout > 0) { - sipApplicationSessionTimeout = sipContextTimeout * 60 * 1000L; + if(sipContextTimeout > 0) { + sipApplicationSessionTimeout = sipContextTimeout * 60 * 1000L; } else { if(logger.isDebugEnabled()) { logger.debug("The sip application session "+ key +" will never expire "); } - // If the session timeout value is 0 or less, then an application session timer - // never starts for the SipApplicationSession object and the container does + // If the session timeout value is 0 or less, then an application session timer + // never starts for the SipApplicationSession object and the container does // not consider the object to ever have expired // expirationTime = -1; - } + } } // Last Accessed Time set here instead of at the same time as creationTime - // Contribution from Naoki Nishihara from OKI - // Fix for Issue 1853 http://code.google.com/p/mobicents/issues/detail?id=1853 + // Contribution from Naoki Nishihara from OKI + // Fix for Issue 1853 http://code.google.com/p/mobicents/issues/detail?id=1853 // SipApplicationSession.getExpirationTime() returns 0 in converged app setLastAccessedTime(creationTime); } - + /** - * Notifies the listeners that a lifecycle event occured on that sip application session + * Notifies the listeners that a lifecycle event occured on that sip application session * @param sipApplicationSessionEventType the type of event that happened */ - public void notifySipApplicationSessionListeners(SipApplicationSessionEventType sipApplicationSessionEventType) { - List listeners = + public void notifySipApplicationSessionListeners(SipApplicationSessionEventType sipApplicationSessionEventType) { + List listeners = sipContext.getListeners().getSipApplicationSessionListeners(); if(listeners.size() > 0) { ClassLoader oldClassLoader = java.lang.Thread.currentThread().getContextClassLoader(); - sipContext.enterSipContext(); + sipContext.enterSipContext(); SipApplicationSessionEvent event = new SipApplicationSessionEvent(this.getFacade()); if(logger.isDebugEnabled()) { - logger.debug("notifying sip application session listeners of context " + + logger.debug("notifying sip application session listeners of context " + key.getApplicationName() + " of following event " + sipApplicationSessionEventType); } for (SipApplicationSessionListener sipApplicationSessionListener : listeners) { try { if(logger.isDebugEnabled()) { - logger.debug("notifying sip application session listener " + sipApplicationSessionListener.getClass().getName() + " of context " + + logger.debug("notifying sip application session listener " + sipApplicationSessionListener.getClass().getName() + " of context " + key.getApplicationName() + " of following event " + sipApplicationSessionEventType); } if(SipApplicationSessionEventType.CREATION.equals(sipApplicationSessionEventType)) { @@ -199,15 +199,15 @@ public void notifySipApplicationSessionListeners(SipApplicationSessionEventType } else if (SipApplicationSessionEventType.READYTOINVALIDATE.equals(sipApplicationSessionEventType)) { sipApplicationSessionListener.sessionReadyToInvalidate(event); } - + } catch (Throwable t) { logger.error("SipApplicationSessionListener threw exception", t); } } sipContext.exitSipContext(oldClassLoader); - } + } } - + public boolean addSipSession(MobicentsSipSession mobicentsSipSession) { boolean wasNotPresent = this.sipSessions.add((SipSessionKey)mobicentsSipSession.getKey()); if(logger.isDebugEnabled() && wasNotPresent) { @@ -217,7 +217,7 @@ public boolean addSipSession(MobicentsSipSession mobicentsSipSession) { return wasNotPresent; // sipSessionImpl.setSipApplicationSession(this); } - + public SipSessionKey removeSipSession(MobicentsSipSession mobicentsSipSession) { if(logger.isDebugEnabled()) { logger.debug("Trying to remove sip session " + mobicentsSipSession); @@ -236,7 +236,7 @@ public SipSessionKey removeSipSession(MobicentsSipSession mobicentsSipSession) { MobicentsSipSession derivedSipSession = itDerivedSessions.next(); logger.debug("Derived sip session : " + derivedSipSession.getKey() + " isValid " + derivedSipSession.isValidInternal() + " isReadyToInvalidate " + derivedSipSession.isReadyToInvalidateInternal()); } - } + } return null; } if(parentSession.isValidInternal()) { @@ -260,15 +260,15 @@ public SipSessionKey removeSipSession(MobicentsSipSession mobicentsSipSession) { } if(sipSessions != null) { boolean wasPresent = this.sipSessions.remove(key); - + if(logger.isDebugEnabled() && wasPresent) { logger.debug("Removed sip session " + key + " from sip app session " + getKey()); } return key; - } + } return null; } - + public boolean addHttpSession(HttpSession httpSession) { if(httpSessions == null) { httpSessions = new CopyOnWriteArraySet(); @@ -281,7 +281,7 @@ public boolean addHttpSession(HttpSession httpSession) { // TODO: We assume that there is only one HTTP session in the app session. In this case // we are safe to only assign jvmRoute once here. When we support multiple http sessions // we will need something more sophisticated. - String jvmRoute = JvmRouteUtil.extractJvmRoute(httpSession.getId()); + String jvmRoute = JvmRouteUtil.extractJvmRoute(httpSession.getId()); if(jvmRoute != null) { if(logger.isDebugEnabled()) { logger.debug("JVM Route " + jvmRoute + " for just added http session " + JvmRouteUtil.removeJvmRoute(httpSession.getId())); @@ -290,7 +290,7 @@ public boolean addHttpSession(HttpSession httpSession) { } return wasNotPresent; } - + public boolean removeHttpSession(HttpSession httpSession) { if(httpSessions != null) { if(logger.isDebugEnabled()) { @@ -304,7 +304,7 @@ public boolean removeHttpSession(HttpSession httpSession) { } return false; } - + public HttpSession findHttpSession (String sessionId) { String id = JvmRouteUtil.removeJvmRoute(sessionId); if(httpSessions != null) { @@ -312,13 +312,13 @@ public HttpSession findHttpSession (String sessionId) { try { return (HttpSession)sipContext.getSipManager().findSession(id); } catch (IOException e) { - logger.error("An Unexpected exception happened while retrieving the http session " + id, e); + logger.error("An Unexpected exception happened while retrieving the http session " + id, e); } } } return null; } - + /** * {@inheritDoc} */ @@ -407,8 +407,8 @@ public long getExpirationTime() { } return this.expirationTime; } - - + + /** * {@inheritDoc} @@ -425,13 +425,13 @@ public long getLastAccessedTime() { return lastAccessedTime; } - + protected void setLastAccessedTime(long lastAccessTime) { if(logger.isDebugEnabled()) { logger.debug("lastAccessedTime set to "+ lastAccessTime); } this.lastAccessedTime = lastAccessTime; - //JSR 289 Section 6.3 : starting the sip app session expiry timer anew + //JSR 289 Section 6.3 : starting the sip app session expiry timer anew if(sipApplicationSessionTimeout > 0) { expirationTime = lastAccessedTime + sipApplicationSessionTimeout; if(logger.isDebugEnabled()) { @@ -443,7 +443,7 @@ protected void setLastAccessedTime(long lastAccessTime) { } } } - + /** * Update the accessed time information for this session. This method * should be called by the context when a request comes in for a particular @@ -455,7 +455,7 @@ protected void setLastAccessedTime(long lastAccessTime) { public void access() { setLastAccessedTime(System.currentTimeMillis()); } - + /* * (non-Javadoc) * @see javax.servlet.sip.SipApplicationSession#getSessions() @@ -486,7 +486,7 @@ public Iterator getSessions(String protocol) { } if("SIP".equalsIgnoreCase(protocol)) { return getSipSessions(false).iterator(); - } else if("HTTP".equalsIgnoreCase(protocol)) { + } else if("HTTP".equalsIgnoreCase(protocol)) { return getHttpSessions().iterator(); } else { throw new IllegalArgumentException(protocol + " sessions are not handled by this container"); @@ -507,7 +507,7 @@ public Set getSipSessions(boolean internal) { retSipSessions.add(sipSession.getFacade()); } } - // https://github.com/Mobicents/sip-servlets/issues/41 + // https://github.com/Mobicents/sip-servlets/issues/41 // Adding derived Sessions to the list of returned sip sessions Iterator derivedSessionsIterator = sipSession.getDerivedSipSessions(); while (derivedSessionsIterator.hasNext()) { @@ -524,7 +524,7 @@ public Set getSipSessions(boolean internal) { } return retSipSessions; } - + protected Set getHttpSessions() { Set retHttpSessions = new HashSet(); if(httpSessions != null) { @@ -535,8 +535,8 @@ protected Set getHttpSessions() { retHttpSessions.add(httpSession); } } catch (IOException e) { - logger.error("An Unexpected exception happened while retrieving the http session " + id, e); - } + logger.error("An Unexpected exception happened while retrieving the http session " + id, e); + } } } return retHttpSessions; @@ -561,7 +561,7 @@ public SipSession getSipSession(String id) { isPresent = sipSessions.contains(sipSessionKey); } catch (ParseException e) { //can happen if the id passed is invalid - } + } if(isPresent) { return sipContext.getSipManager().getSipSession(sipSessionKey, false, null, this).getFacade(); } else { @@ -614,7 +614,7 @@ public void removeServletTimer(ServletTimer servletTimer, boolean updateAppSessi updateReadyToInvalidateState(); } } - + /* * (non-Javadoc) * @see javax.servlet.sip.SipApplicationSession#invalidate() @@ -622,11 +622,11 @@ public void removeServletTimer(ServletTimer servletTimer, boolean updateAppSessi public void invalidate() { invalidate(false); } - + public void invalidate(boolean bypassCheck) { //JSR 289 Section 6.1.2.2.1 - //When the IllegalStateException is thrown, the application is guaranteed - //that the state of the SipApplicationSession object will be unchanged from its state prior to the invalidate() + //When the IllegalStateException is thrown, the application is guaranteed + //that the state of the SipApplicationSession object will be unchanged from its state prior to the invalidate() //method call. Even session objects that were eligible for invalidation will not have been invalidated. boolean wasValid = isValidInternal.compareAndSet(true, false); if(!wasValid) { @@ -634,7 +634,7 @@ public void invalidate(boolean bypassCheck) { throw new IllegalStateException("SipApplicationSession " + key + " already invalidated !"); } else { if(logger.isInfoEnabled()) { - logger.info("SipApplicationSession " + key + " already invalidated, doing nothing"); + logger.info("SipApplicationSession " + key + " already invalidated, doing nothing"); } return; } @@ -642,7 +642,7 @@ public void invalidate(boolean bypassCheck) { if(logger.isInfoEnabled()) { logger.info("Invalidating the following sip application session " + key); } - + //doing the invalidation for(MobicentsSipSession session: getSipSessions(true)) { if(session.isValidInternal()) { @@ -684,17 +684,17 @@ public void invalidate(boolean bypassCheck) { } // http://code.google.com/p/mobicents/issues/detail?id=2885 // FQN Memory Leak in HA mode with PESSIMISTIC locking - // remove it before the DELETION notification to avoid the sip application session to be destroyed before + // remove it before the DELETION notification to avoid the sip application session to be destroyed before // and leaking in the JBoss Cache - + //cancelling the timers if(servletTimers != null) { for (Map.Entry servletTimerEntry : servletTimers.entrySet()) { ServletTimer timerEntry = servletTimerEntry.getValue(); if(timerEntry != null) { - timerEntry.cancel(); + timerEntry.cancel(); } - } + } } if(!expired && expirationTimerTask != null) { cancelExpirationTimer(); @@ -708,7 +708,7 @@ public void invalidate(boolean bypassCheck) { */ long timeNow = System.currentTimeMillis(); int timeAlive = (int) ((timeNow - creationTime)/1000); - + synchronized (manager) { if (timeAlive > manager.getSipApplicationSessionMaxAliveTime()) { manager.setSipApplicationSessionMaxAliveTime(timeAlive); @@ -720,11 +720,11 @@ public void invalidate(boolean bypassCheck) { average = ((average * (numExpired-1)) + timeAlive)/numExpired; manager.setSipApplicationSessionAverageAliveTime(average); } - - notifySipApplicationSessionListeners(SipApplicationSessionEventType.DELETION); - + + notifySipApplicationSessionListeners(SipApplicationSessionEventType.DELETION); + isValid = false; - + expirationTimerTask = null; // expirationTimerFuture = null; if(httpSessions != null) { @@ -739,13 +739,13 @@ public void invalidate(boolean bypassCheck) { } if(sipSessions != null) { sipSessions.clear(); - } + } // executorService.shutdown(); -// executorService = null; +// executorService = null; httpSessions = null; sipSessions = null; sipApplicationSessionAttributeMap = null; - servletTimers = null; + servletTimers = null; if(logger.isInfoEnabled()) { logger.info("The following sip application session " + key + " has been invalidated"); } @@ -758,7 +758,7 @@ public void invalidate(boolean bypassCheck) { // } facade = null; } - + public void cancelAllTimers() { cancelExpirationTimer(); if(this.servletTimers != null) { @@ -774,7 +774,7 @@ private void cancelExpirationTimer() { sipContext.getSipApplicationSessionTimerService().cancel(expirationTimerTask); } if(expirationTimerTask != null) { - // http://code.google.com/p/mobicents/issues/detail?id=2322 : expiration Timer task can be null after calling cancel above due to Race condition + // http://code.google.com/p/mobicents/issues/detail?id=2322 : expiration Timer task can be null after calling cancel above due to Race condition expirationTimerTask.setSipApplicationSession(null); expirationTimerTask = null; } @@ -787,7 +787,7 @@ private void cancelExpirationTimer() { public boolean isValid() { return isValid; } - + /* * (non-Javadoc) * @see org.mobicents.servlet.sip.core.session.MobicentsSipApplicationSession#isValidInternal() @@ -796,7 +796,7 @@ public boolean isValidInternal() { return isValidInternal.get(); } - + /** * @param isValid the isValid to set */ @@ -811,7 +811,7 @@ protected void setValid(boolean isValid) { public void removeAttribute(String name) { removeAttribute(name, false); } - + public void removeAttribute(String name, boolean byPassValidCheck) { if (!byPassValidCheck && !isValid()) throw new IllegalStateException( @@ -823,7 +823,7 @@ public void removeAttribute(String name, boolean byPassValidCheck) { return; SipApplicationSessionBindingEvent event = null; - + Object value = this.getAttributeMap().remove(name); // Call the valueUnbound() method if necessary @@ -831,10 +831,10 @@ public void removeAttribute(String name, boolean byPassValidCheck) { event = new SipApplicationSessionBindingEvent(this, name); ((SipApplicationSessionBindingListener) value).valueUnbound(event); } - + SipListeners listeners = sipContext.getListeners(); List listenersList = listeners.getSipApplicationSessionAttributeListeners(); - if(listenersList.size() > 0) { + if(listenersList.size() > 0) { if(event == null) { event = new SipApplicationSessionBindingEvent(this, name); } @@ -881,13 +881,13 @@ public void setAttribute(String key, Object attribute) { try { ((SipApplicationSessionBindingListener) attribute).valueBound(event); } catch (Throwable t){ - logger.error("SipSessionBindingListener threw exception", t); + logger.error("SipSessionBindingListener threw exception", t); } } } - + Object previousValue = this.getAttributeMap().put(key, attribute); - + if (previousValue != null && previousValue != attribute && previousValue instanceof SipApplicationSessionBindingListener) { try { @@ -904,7 +904,7 @@ public void setAttribute(String key, Object attribute) { if(event == null) { event = new SipApplicationSessionBindingEvent(this, key); } - if (previousValue == null) { + if (previousValue == null) { for (SipApplicationSessionAttributeListener listener : listenersList) { if(logger.isDebugEnabled()) { logger.debug("notifying SipApplicationSessionAttributeListener " + listener.getClass().getCanonicalName() + " of attribute added on key "+ key); @@ -915,7 +915,7 @@ public void setAttribute(String key, Object attribute) { logger.error("SipApplicationSessionAttributeListener threw exception", t); } } - } else { + } else { for (SipApplicationSessionAttributeListener listener : listenersList) { if(logger.isDebugEnabled()) { logger.debug("notifying SipApplicationSessionAttributeListener " + listener.getClass().getCanonicalName() + " of attribute replaced on key "+ key); @@ -926,10 +926,10 @@ public void setAttribute(String key, Object attribute) { logger.error("SipApplicationSessionAttributeListener threw exception", t); } } - } + } } } - + /* * (non-Javadoc) * @see javax.servlet.sip.SipApplicationSession#setExpires(int) @@ -942,15 +942,15 @@ public int setExpires(int deltaMinutes) { } expired = false; if(logger.isDebugEnabled()) { - logger.debug("Postponing the expiratin of the sip application session " + logger.debug("Postponing the expiratin of the sip application session " + key +" to expire in " + deltaMinutes + " minutes."); } if(deltaMinutes <= 0) { if(logger.isDebugEnabled()) { logger.debug("The sip application session "+ key +" won't expire anymore "); } - // If the session timeout value is 0 or less, then an application session timer - // never starts for the SipApplicationSession object and the container + // If the session timeout value is 0 or less, then an application session timer + // never starts for the SipApplicationSession object and the container // does not consider the object to ever have expired // this.expirationTime = -1; if(expirationTimerTask != null) { @@ -958,7 +958,7 @@ public int setExpires(int deltaMinutes) { // Fix for Issue 1678 : SipApplicationSession.setExpires() doesn't work sometimes // the global sipApplicationSessionTimeout needs to be reset as well sipApplicationSessionTimeout = deltaMinutes; - } + } return Integer.MAX_VALUE; } else { long deltaMilliseconds = 0; @@ -973,7 +973,7 @@ public int setExpires(int deltaMinutes) { // Fix for Issue 1678 : SipApplicationSession.setExpires() doesn't work sometimes // the global sipApplicationSessionTimeout needs to be reset as well sipApplicationSessionTimeout = deltaMilliseconds; - expirationTime = System.currentTimeMillis() + deltaMilliseconds; + expirationTime = System.currentTimeMillis() + deltaMilliseconds; if(logger.isDebugEnabled()) { logger.debug("Setting expirationTime to "+ expirationTime + " on sip application session " + key); logger.debug("Re-Scheduling sip application session "+ key +" to expire in " + deltaMinutes + " minutes"); @@ -981,24 +981,38 @@ public int setExpires(int deltaMinutes) { calendar.setTimeInMillis(expirationTime); logger.debug("sip application session "+ key +" will expires at " + new SimpleDateFormat().format(calendar.getTime())); } - if(expirationTimerTask != null) { - cancelExpirationTimer(); -// expirationTimerFuture = null; - } - expirationTimerTask = sipContext.getSipApplicationSessionTimerService().createSipApplicationSessionTimerTask(this); - expirationTimerTask = sipContext.getSipApplicationSessionTimerService().schedule(expirationTimerTask, deltaMilliseconds, TimeUnit.MILLISECONDS); + + + final long milisecondsToGive = deltaMilliseconds; + + + //Run the timer in different transaction + new Thread(){ + + @Override + public void run() { + if(expirationTimerTask != null) { + cancelExpirationTimer(); +// expirationTimerFuture = null; + } + expirationTimerTask = sipContext.getSipApplicationSessionTimerService().createSipApplicationSessionTimerTask(SipApplicationSessionImpl.this); + expirationTimerTask = sipContext.getSipApplicationSessionTimerService().schedule(expirationTimerTask, milisecondsToGive, TimeUnit.MILLISECONDS); + } + + }.start(); + return deltaMinutes; - } + } } public boolean hasTimerListener() { return this.sipContext.getListeners().getTimerListener() != null; - } + } public SipContext getSipContext() { return sipContext; - } + } /** * @return the key @@ -1018,7 +1032,7 @@ public void setKey(SipApplicationSessionKey key) { * (non-Javadoc) * @see javax.servlet.sip.SipApplicationSession#getApplicationName() */ - public String getApplicationName() { + public String getApplicationName() { return key.getApplicationName(); } @@ -1032,10 +1046,10 @@ public ServletTimer getTimer(String id) { } if(servletTimers != null) { return servletTimers.get(id); - } + } return null; } - + /** * Perform the internal processing required to passivate * this session. @@ -1060,12 +1074,12 @@ public void passivate() { } } } - + /** * Perform internal processing required to activate this * session. */ - public void activate() { + public void activate() { // Notify ActivationListeners SipApplicationSessionEvent event = null; if(sipApplicationSessionAttributeMap != null) { @@ -1109,11 +1123,11 @@ public Object getSession(String id, Protocol protocol) { switch (protocol) { case SIP : return getSipSession(id); - + case HTTP : return findHttpSession(id); - - default : + + default : break; } return null; @@ -1133,12 +1147,12 @@ public void setInvalidateWhenReady(boolean invalidateWhenReady) { } this.invalidateWhenReady = invalidateWhenReady; } - + public void onSipSessionReadyToInvalidate(MobicentsSipSession mobicentsSipSession) { removeSipSession(mobicentsSipSession); updateReadyToInvalidateState(); } - + private void updateReadyToInvalidateState() { if(isValidInternal() && !readyToInvalidate) { if(logger.isDebugEnabled()) { @@ -1147,10 +1161,11 @@ private void updateReadyToInvalidateState() { for(MobicentsSipSession sipSession : getSipSessions(true)) { if(logger.isDebugEnabled()) { logger.debug("Is Sip Session Key " + sipSession.getKey() + " ready to be invalidated, " - + "isvalidInternal " + sipSession.isValidInternal() + + + "isvalidInternal " + sipSession.isValidInternal() + ", isReadyToInvalidate " + sipSession.isReadyToInvalidateInternal()); } - if(sipSession.isValidInternal() && !sipSession.isReadyToInvalidate()) { + + if( sipSession.isValidInternal() && !sipSession.isReadyToInvalidate()) { if(logger.isDebugEnabled()) { logger.debug("Sip Session not ready to be invalidated : " + sipSession.getKey()); } @@ -1159,7 +1174,7 @@ private void updateReadyToInvalidateState() { } // Fix for Issue 813 : SipApplicationSession invalidates too soon when HttpSession are present // (http://code.google.com/p/mobicents/issues/detail?id=813) - for(HttpSession httpSession: getHttpSessions()) { + for(HttpSession httpSession: getHttpSessions()) { if(httpSession instanceof ConvergedSession) { ConvergedSession convergedSession = (ConvergedSession) httpSession; if(convergedSession.isValidIntern()) { @@ -1168,9 +1183,9 @@ private void updateReadyToInvalidateState() { } return; } - } + } } - + if(servletTimers == null || this.servletTimers.size() <= 0) { if(logger.isDebugEnabled()) { logger.debug("All sip sessions and http session are ready to be invalidated, no timers alive, can invalidate this application session " + key); @@ -1188,16 +1203,16 @@ private void updateReadyToInvalidateState() { this.readyToInvalidate = true; } } - - public void tryToInvalidate() { + + public void tryToInvalidate() { if(logger.isDebugEnabled()) { - logger.debug("tryToInvalidate:[isValidInternal=" + this.isValidInternal() + - ",readyToInvalidate=" + this.readyToInvalidate + + logger.debug("tryToInvalidate:[isValidInternal=" + this.isValidInternal() + + ",readyToInvalidate=" + this.readyToInvalidate + ",invalidateWhenReady=" + invalidateWhenReady + "]"); } // we try to invalidate only when the session is still valid (not invalidated yet) and is ready to be invalidated // and if the invalidateWhenReady flag is true - if(isValidInternal() && readyToInvalidate && invalidateWhenReady) { + if(isValidInternal() && readyToInvalidate && invalidateWhenReady) { boolean allSipSessionsInvalidated = true; for(MobicentsSipSession sipSession : getSipSessions(true)) { if(sipSession.isValidInternal()) { @@ -1214,15 +1229,15 @@ public void tryToInvalidate() { } } if(logger.isDebugEnabled()) { - logger.debug("tryToInvalidate:[allSipSessionInvalidated=" + allSipSessionsInvalidated + "," + logger.debug("tryToInvalidate:[allSipSessionInvalidated=" + allSipSessionsInvalidated + "," + "allHttpSessionsInvalidated=" + allHttpSessionsInvalidated +"]"); } if(allSipSessionsInvalidated && allHttpSessionsInvalidated) { - // An application willing to invalidate a SipApplicationSession cleanly could use the callback mechanism + // An application willing to invalidate a SipApplicationSession cleanly could use the callback mechanism // to perform any application clean up before the SipApplicationSession gets invalidated by the container notifySipApplicationSessionListeners(SipApplicationSessionEventType.READYTOINVALIDATE); - // Applications may also use the callback to call setInvalidateWhenReady(false) - // to indicate to the container to not observe this SipApplicationSession anymore. + // Applications may also use the callback to call setInvalidateWhenReady(false) + // to indicate to the container to not observe this SipApplicationSession anymore. // In this case, the containers MUST not invalidate the SipApplicationSession after the callback if(invalidateWhenReady) { this.invalidate(true); @@ -1243,7 +1258,7 @@ public boolean isExpired() { */ public void setCurrentRequestHandler(String currentRequestHandler) { this.currentRequestHandler = currentRequestHandler; - // Fix for issue 1087 (http://code.google.com/p/mobicents/issues/detail?id=1087) : + // Fix for issue 1087 (http://code.google.com/p/mobicents/issues/detail?id=1087) : // Can not make an instance of SipApplicationSession for servlet-selection type of applications if(sipContext != null && !sipContext.isMainServlet()) { sipContext.setServletHandler(currentRequestHandler); @@ -1267,9 +1282,9 @@ public String getCurrentRequestHandler() { public Semaphore getSemaphore() { return semaphore; } - + @SuppressWarnings(value="unchecked") - public MobicentsSipApplicationSession getFacade() { + public MobicentsSipApplicationSession getFacade() { if (facade == null){ if (sipContext.isPackageProtectionEnabled()){ @@ -1283,11 +1298,11 @@ public Object run(){ facade = new MobicentsSipApplicationSessionFacade(this); } } - return (facade); + return (facade); } protected String jvmRoute; - + public String getJvmRoute() { return this.jvmRoute; } @@ -1299,7 +1314,7 @@ public void setJvmRoute(String jvmRoute) { // Assign the new jvmRoute this.jvmRoute = jvmRoute; } - + @Override public boolean equals(Object obj) { if(obj instanceof MobicentsSipApplicationSession) { @@ -1338,12 +1353,12 @@ public SipApplicationSessionTimerTask getExpirationTimerTask() { public long getSipApplicationSessionTimeout() { return sipApplicationSessionTimeout; } - + public void setExpired(boolean hasExpired) { expired = hasExpired; } - public long getExpirationTimeInternal() { + public long getExpirationTimeInternal() { return expirationTime; } @@ -1354,8 +1369,8 @@ public long getExpirationTimeInternal() { public void scheduleAsynchronousWork( SipApplicationSessionAsynchronousWork work) { sipContext.getSipApplicationDispatcher().getAsynchronousExecutor().execute(new SipApplicationSessionAsyncTask(key, work, (SipFactoryImpl)sipContext.getSipApplicationDispatcher().getSipFactory())); - } - + } + public void acquire() { if(semaphore != null) { if(logger.isDebugEnabled()) { @@ -1363,13 +1378,23 @@ public void acquire() { } try { while(!semaphore.tryAcquire(30000, TimeUnit.MILLISECONDS)){ - logger.warn("Failed to acquire session semaphore " + + logger.warn("Failed to acquire session semaphore " + semaphore + " for 30 secs. We will unlock the " + "semaphore no matter what because the " + "transaction is about to timeout. THIS " + - "MIGHT ALSO BE CONCURRENCY CONTROL RISK." + + "MIGHT ALSO BE CONCURRENCY CONTROL RISK." + " app Session is" + this); + if(logger.isDebugEnabled()) { + logger.debug("releasing semaphore, this=" + this + ", semaphore=" + semaphore); + } semaphore.release(); + if(logger.isDebugEnabled()) { + logger.debug("semaphore released, this=" + this + ", semaphore=" + semaphore); + } + } + + if(logger.isDebugEnabled()) { + logger.debug("proceed, this=" + this + ", semaphore=" + semaphore); } } catch (InterruptedException e) { logger.error("Problem acquiring semaphore on app session " + this, e); @@ -1379,7 +1404,7 @@ public void acquire() { } } } - + public void release() { if(semaphore != null) { if(logger.isDebugEnabled()) { @@ -1397,7 +1422,7 @@ public void release() { } } if(semaphore.availablePermits()<0) { - logger.warn("About to release semaphore but we expected permits = 0. We will adjust to normal " + logger.warn("About to release semaphore but we expected permits = 0. We will adjust to normal " + semaphore + " app session=" + this); while(semaphore.availablePermits()<0) { try { @@ -1405,15 +1430,15 @@ public void release() { } catch (Exception e) { } } - } - + } + semaphore.release(); if(logger.isDebugEnabled()) { logger.debug("After Semaphore released for sipApplicationSession=" + this + " semaphore=" + semaphore); } } } - + protected boolean orphan = false; public boolean isOrphan() { diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipListenersHolder.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipListenersHolder.java index 5e1e0dcb6f..17f781143b 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipListenersHolder.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipListenersHolder.java @@ -1,449 +1,470 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.core.session; - -import java.util.ArrayList; -import java.util.EventListener; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.servlet.ServletContextListener; -import javax.servlet.ServletException; -import javax.servlet.sip.SipApplicationSessionActivationListener; -import javax.servlet.sip.SipApplicationSessionAttributeListener; -import javax.servlet.sip.SipApplicationSessionBindingListener; -import javax.servlet.sip.SipApplicationSessionListener; -import javax.servlet.sip.SipErrorListener; -import javax.servlet.sip.SipServletListener; -import javax.servlet.sip.SipSessionActivationListener; -import javax.servlet.sip.SipSessionAttributeListener; -import javax.servlet.sip.SipSessionBindingListener; -import javax.servlet.sip.SipSessionListener; -import javax.servlet.sip.TimerListener; - -import org.apache.log4j.Logger; -import org.mobicents.javax.servlet.ContainerListener; -import org.mobicents.javax.servlet.sip.ProxyBranchListener; -import org.mobicents.servlet.sip.core.MobicentsSipServlet; -import org.mobicents.servlet.sip.core.SipContext; -import org.mobicents.servlet.sip.core.SipListeners; -import org.mobicents.servlet.sip.listener.SipConnectorListener; - - -public abstract class SipListenersHolder implements SipListeners { - private static final Logger logger = Logger.getLogger(SipListenersHolder.class); - - private List sipApplicationSessionAttributeListeners; - private List sipApplicationSessionBindingListeners; - private List sipApplicationSessionListeners; - private List sipApplicationSessionActivationListeners; - private List sipSessionActivationListeners; - private List sipSessionAttributeListeners; - private List sipSessionBindingListeners; - private List sipSessionListeners; - private List sipServletsListeners; - private List sipErrorListeners; - private List sipConnectorListeners; - private List proxyBranchListeners; - private List servletContextListeners; - protected Map listenerServlets; - // There may be at most one TimerListener defined. - private TimerListener timerListener; - private ContainerListener containerListener; - //the sip context the holder is attached to - protected SipContext sipContext; - - /** - * Default Constructor - */ - public SipListenersHolder(SipContext sipContext) { - this.sipContext = sipContext; - this.sipApplicationSessionAttributeListeners = new ArrayList(); - this.sipApplicationSessionBindingListeners = new ArrayList(); - this.sipApplicationSessionListeners = new ArrayList(); - this.sipApplicationSessionActivationListeners = new ArrayList(); - this.sipSessionActivationListeners = new ArrayList(); - this.sipSessionAttributeListeners = new ArrayList(); - this.sipSessionBindingListeners = new ArrayList(); - this.sipSessionListeners = new ArrayList(); - this.sipServletsListeners = new ArrayList(); - this.sipErrorListeners = new ArrayList(); - this.servletContextListeners = new ArrayList(); - this.sipConnectorListeners = new ArrayList(); - this.proxyBranchListeners = new ArrayList(); - listenerServlets = new HashMap(); - } - - /** - * Load Listeners the given in parameter with the given classloader - * @param listenerList the list of listeners to load - * @param classLoader the classloader to load the listeners with - * @return true if all the listeners have been successfully loaded, false otherwise - */ - public abstract boolean loadListeners(String[] listeners, ClassLoader classLoader); -// { -// // Instantiate all the listeners -// for (String className : listeners) { -// try { -// Class listenerClass = Class.forName(className, false, classLoader); -// EventListener listener = (EventListener) listenerClass.newInstance(); -// ((SipContext)sipContext).getAnnotationProcessor().processAnnotations(listener); -// MobicentsSipServlet sipServletImpl = (MobicentsSipServlet)sipContext.findSipServletByClassName(className); -// if(sipServletImpl != null) { -// listener = (EventListener) sipServletImpl.allocate(); -// listenerServlets.put(listener, sipServletImpl); -// } else { -// SipServlet servlet = (SipServlet) listenerClass.getAnnotation(SipServlet.class); -// if (servlet != null) { -// sipServletImpl = (MobicentsSipServlet)sipContext.findSipServletByName(servlet.name()); -// if(sipServletImpl != null) { -// listener = (EventListener) sipServletImpl.allocate(); -// listenerServlets.put(listener, sipServletImpl); -// } -// } -// } -// addListenerToBunch(listener); -// } catch (Exception e) { -// logger.fatal("Cannot instantiate listener class " + className, -// e); -// return false; -// } -// } -// return true; -// } - - protected void addListenerToBunch(EventListener listener) { - boolean added = false; - if (listener instanceof SipApplicationSessionAttributeListener) { - this.addListener((SipApplicationSessionAttributeListener) listener); - added = true; - } - - if (listener instanceof SipApplicationSessionBindingListener) { - this.addListener((SipApplicationSessionBindingListener) listener); - added = true; - } - - if (listener instanceof SipApplicationSessionActivationListener) { - this.addListener((SipApplicationSessionActivationListener) listener); - added = true; - } - - if (listener instanceof SipApplicationSessionListener) { - this.addListener((SipApplicationSessionListener) listener); - added = true; - } - - if (listener instanceof SipSessionActivationListener) { - this.addListener((SipSessionActivationListener) listener); - added = true; - } - - if (listener instanceof SipSessionAttributeListener) { - this.addListener((SipSessionAttributeListener) listener); - added = true; - } - - if (listener instanceof SipSessionBindingListener) { - this.addListener((SipSessionBindingListener) listener); - added = true; - } - - if (listener instanceof SipSessionListener) { - this.addListener((SipSessionListener) listener); - added = true; - } - - if (listener instanceof SipServletListener) { - this.addListener((SipServletListener) listener); - added = true; - } - - if (listener instanceof SipErrorListener) { - this.addListener((SipErrorListener) listener); - added = true; - } - - if (listener instanceof ServletContextListener) { - this.addListener((ServletContextListener) listener); - added = true; - } - - if (listener instanceof TimerListener) { - this.setTimerListener((TimerListener) listener); - added = true; - } - - if (listener instanceof SipConnectorListener) { - this.addListener((SipConnectorListener) listener); - added = true; - } - - if (listener instanceof ProxyBranchListener) { - this.addListener((ProxyBranchListener) listener); - added = true; - } - - if (listener instanceof ContainerListener) { - this.setContainerListener((ContainerListener) listener); - added = true; - } - - if(!added) { - throw new IllegalArgumentException("Wrong type of LISTENER!!![" - + listener + "]"); - } - } - - // this.sipApplicationSessionAttributeListeners.clear(); - public void addListener(SipApplicationSessionAttributeListener listener) { - this.sipApplicationSessionAttributeListeners.add(listener); - } - - // this.sipApplicationSessionBindingListeners.clear(); - public void addListener(SipApplicationSessionBindingListener listener) { - this.sipApplicationSessionBindingListeners.add(listener); - } - - public void addListener(SipApplicationSessionActivationListener listener) { - this.sipApplicationSessionActivationListeners.add(listener); - } - - // this.sipApplicationSessionListeners.clear(); - public void addListener(SipApplicationSessionListener listener) { - this.sipApplicationSessionListeners.add(listener); - } - - // this.sipSessionActivationListeners.clear(); - public void addListener(SipSessionActivationListener listener) { - this.sipSessionActivationListeners.add(listener); - } - - // this.sipSessionAttributeListeners.clear(); - public void addListener(SipSessionAttributeListener listener) { - this.sipSessionAttributeListeners.add(listener); - } - - // this.sipSessionBindingListeners.clear(); - public void addListener(SipSessionBindingListener listener) { - this.sipSessionBindingListeners.add(listener); - } - - // this.sipSessionListeners.clear(); - public void addListener(SipSessionListener listener) { - this.sipSessionListeners.add(listener); - } - - // this.sipSessionListeners.clear(); - public void addListener(SipServletListener listener) { - this.sipServletsListeners.add(listener); - } - - // this.sipErrorListeners.clear(); - public void addListener(SipErrorListener listener) { - this.sipErrorListeners.add(listener); - } - - // this.servletContextListeners.clear(); - public void addListener(ServletContextListener listener) { - this.servletContextListeners.add(listener); - } - - public void addListener(SipConnectorListener listener) { - this.sipConnectorListeners.add(listener); - } - - public void addListener(ProxyBranchListener listener) { - this.proxyBranchListeners.add(listener); - } - - public void setTimerListener(TimerListener listener) { - if(this.timerListener != null) { - throw new IllegalArgumentException( - "the time listener has already been set ("+timerListener.getClass().getName() + - "), There may be at most one TimerListener defined !"); - } - this.timerListener = listener; - } - - public List getSipApplicationSessionAttributeListeners() { - return sipApplicationSessionAttributeListeners; - } - - public List getSipApplicationSessionBindingListeners() { - return sipApplicationSessionBindingListeners; - } - - public List getSipApplicationSessionActivationListeners() { - return sipApplicationSessionActivationListeners; - } - - public List getSipApplicationSessionListeners() { - return sipApplicationSessionListeners; - } - - public List getSipSessionActivationListeners() { - return sipSessionActivationListeners; - } - - public List getSipSessionAttributeListeners() { - return sipSessionAttributeListeners; - } - - public List getSipSessionBindingListeners() { - return sipSessionBindingListeners; - } - - public List getSipSessionListeners() { - return sipSessionListeners; - } - - public List getSipServletsListeners() { - return sipServletsListeners; - } - - public List getSipErrorListeners() { - return sipErrorListeners; - } - - public List getServletContextListeners() { - return servletContextListeners; - } - - public List getSipConnectorListeners() { - return sipConnectorListeners; - } - - public List getProxyBranchListeners() { - return proxyBranchListeners; - } - - public TimerListener getTimerListener() { - return timerListener; - } - - public void deallocateServletsActingAsListeners () { - //need to deallocate listeners that are servlets... - for(SipApplicationSessionAttributeListener sipApplicationSessionAttributeListener : sipApplicationSessionAttributeListeners) { - checkDeallocateServlet(sipApplicationSessionAttributeListener); - } - for(SipApplicationSessionBindingListener sipApplicationSessionBindingListener : sipApplicationSessionBindingListeners) { - checkDeallocateServlet(sipApplicationSessionBindingListener); - } - for(SipApplicationSessionActivationListener sipApplicationSessionActivationListener : sipApplicationSessionActivationListeners) { - checkDeallocateServlet(sipApplicationSessionActivationListener); - } - for(SipApplicationSessionListener sipApplicationSessionListener : sipApplicationSessionListeners) { - checkDeallocateServlet(sipApplicationSessionListener); - } - for(SipSessionActivationListener sipSessionActivationListener : sipSessionActivationListeners) { - checkDeallocateServlet(sipSessionActivationListener); - } - for(SipSessionAttributeListener sipSessionAttributeListener : sipSessionAttributeListeners) { - checkDeallocateServlet(sipSessionAttributeListener); - } - for(SipSessionBindingListener sipSessionBindingListener : sipSessionBindingListeners) { - checkDeallocateServlet(sipSessionBindingListener); - } - for(SipSessionListener sipSessionListener : sipSessionListeners) { - checkDeallocateServlet(sipSessionListener); - } - for(SipServletListener sipServletListener : sipServletsListeners) { - checkDeallocateServlet(sipServletListener); - } - for(SipErrorListener sipErrorListener : sipErrorListeners) { - checkDeallocateServlet(sipErrorListener); - } - for(ServletContextListener servletContextListener : servletContextListeners) { - checkDeallocateServlet(servletContextListener); - } - for(SipConnectorListener sipConnectorListener : sipConnectorListeners) { - checkDeallocateServlet(sipConnectorListener); - } - for(ProxyBranchListener proxyListener : proxyBranchListeners) { - checkDeallocateServlet(proxyListener); - } - checkDeallocateServlet(timerListener); - checkDeallocateServlet(containerListener); - } - - /** - * Empty vectors to allow garbage collection - */ - public void clean() { - - this.sipApplicationSessionAttributeListeners.clear(); - this.sipApplicationSessionBindingListeners.clear(); - this.sipApplicationSessionActivationListeners.clear(); - this.sipApplicationSessionListeners.clear(); - this.sipSessionActivationListeners.clear(); - this.sipSessionAttributeListeners.clear(); - this.sipSessionBindingListeners.clear(); - this.sipSessionListeners.clear(); - this.sipServletsListeners.clear(); - this.sipErrorListeners.clear(); - this.servletContextListeners.clear(); - this.sipConnectorListeners.clear(); - this.proxyBranchListeners.clear(); - this.listenerServlets.clear(); - this.timerListener = null; - this.containerListener = null; - } - - /** - * @param sipApplicationSessionAttributeListener - */ - private void checkDeallocateServlet( - EventListener eventListener) { - if(eventListener instanceof javax.servlet.sip.SipServlet) { - try { - MobicentsSipServlet wrapper = listenerServlets.get(eventListener); - if(wrapper != null) { - wrapper.deallocate((javax.servlet.sip.SipServlet)eventListener); - } - } catch (ServletException e) { - logger.error("couldn't deallocate listener " + eventListener.getClass().getName()); - } - } - } - - /** - * @return the containerListener - */ - public ContainerListener getContainerListener() { - return containerListener; - } - - /** - * @param containerListener the containerListener to set - */ - public void setContainerListener(ContainerListener containerListener) { - if(this.containerListener != null) { - throw new IllegalArgumentException( - "the Container listener has already been set ("+ this.containerListener.getClass().getName() + - "), There may be at most one ContainerListener defined !"); - } - this.containerListener = containerListener; - } -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.core.session; + +import java.util.ArrayList; +import java.util.EventListener; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.servlet.ServletContextListener; +import javax.servlet.ServletException; +import javax.servlet.sip.SipApplicationSessionActivationListener; +import javax.servlet.sip.SipApplicationSessionAttributeListener; +import javax.servlet.sip.SipApplicationSessionBindingListener; +import javax.servlet.sip.SipApplicationSessionListener; +import javax.servlet.sip.SipErrorListener; +import javax.servlet.sip.SipServletListener; +import javax.servlet.sip.SipSessionActivationListener; +import javax.servlet.sip.SipSessionAttributeListener; +import javax.servlet.sip.SipSessionBindingListener; +import javax.servlet.sip.SipSessionListener; +import javax.servlet.sip.TimerListener; + +import org.apache.log4j.Logger; +import org.mobicents.javax.servlet.ContainerEvent; +import org.mobicents.javax.servlet.ContainerListener; +import org.mobicents.javax.servlet.sip.ProxyBranchListener; +import org.mobicents.servlet.sip.core.MobicentsSipServlet; +import org.mobicents.servlet.sip.core.SipContext; +import org.mobicents.servlet.sip.core.SipListeners; +import org.mobicents.servlet.sip.listener.SipConnectorListener; + + +public abstract class SipListenersHolder implements SipListeners { + private static final Logger logger = Logger.getLogger(SipListenersHolder.class); + + private List sipApplicationSessionAttributeListeners; + private List sipApplicationSessionBindingListeners; + private List sipApplicationSessionListeners; + private List sipApplicationSessionActivationListeners; + private List sipSessionActivationListeners; + private List sipSessionAttributeListeners; + private List sipSessionBindingListeners; + private List sipSessionListeners; + private List sipServletsListeners; + private List sipErrorListeners; + private List sipConnectorListeners; + private List proxyBranchListeners; + private List servletContextListeners; + protected Map listenerServlets; + // There may be at most one TimerListener defined. + private TimerListener timerListener; + private ContainerListener containerListener; + //the sip context the holder is attached to + protected SipContext sipContext; + + /** + * Default Constructor + */ + public SipListenersHolder(SipContext sipContext) { + this.sipContext = sipContext; + this.sipApplicationSessionAttributeListeners = new ArrayList(); + this.sipApplicationSessionBindingListeners = new ArrayList(); + this.sipApplicationSessionListeners = new ArrayList(); + this.sipApplicationSessionActivationListeners = new ArrayList(); + this.sipSessionActivationListeners = new ArrayList(); + this.sipSessionAttributeListeners = new ArrayList(); + this.sipSessionBindingListeners = new ArrayList(); + this.sipSessionListeners = new ArrayList(); + this.sipServletsListeners = new ArrayList(); + this.sipErrorListeners = new ArrayList(); + this.servletContextListeners = new ArrayList(); + this.sipConnectorListeners = new ArrayList(); + this.proxyBranchListeners = new ArrayList(); + listenerServlets = new HashMap(); + } + + /** + * Load Listeners the given in parameter with the given classloader + * @param listenerList the list of listeners to load + * @param classLoader the classloader to load the listeners with + * @return true if all the listeners have been successfully loaded, false otherwise + */ + public abstract boolean loadListeners(String[] listeners, ClassLoader classLoader); +// { +// // Instantiate all the listeners +// for (String className : listeners) { +// try { +// Class listenerClass = Class.forName(className, false, classLoader); +// EventListener listener = (EventListener) listenerClass.newInstance(); +// ((SipContext)sipContext).getAnnotationProcessor().processAnnotations(listener); +// MobicentsSipServlet sipServletImpl = (MobicentsSipServlet)sipContext.findSipServletByClassName(className); +// if(sipServletImpl != null) { +// listener = (EventListener) sipServletImpl.allocate(); +// listenerServlets.put(listener, sipServletImpl); +// } else { +// SipServlet servlet = (SipServlet) listenerClass.getAnnotation(SipServlet.class); +// if (servlet != null) { +// sipServletImpl = (MobicentsSipServlet)sipContext.findSipServletByName(servlet.name()); +// if(sipServletImpl != null) { +// listener = (EventListener) sipServletImpl.allocate(); +// listenerServlets.put(listener, sipServletImpl); +// } +// } +// } +// addListenerToBunch(listener); +// } catch (Exception e) { +// logger.fatal("Cannot instantiate listener class " + className, +// e); +// return false; +// } +// } +// return true; +// } + + protected void addListenerToBunch(EventListener listener) { + boolean added = false; + if (listener instanceof SipApplicationSessionAttributeListener) { + this.addListener((SipApplicationSessionAttributeListener) listener); + added = true; + } + + if (listener instanceof SipApplicationSessionBindingListener) { + this.addListener((SipApplicationSessionBindingListener) listener); + added = true; + } + + if (listener instanceof SipApplicationSessionActivationListener) { + this.addListener((SipApplicationSessionActivationListener) listener); + added = true; + } + + if (listener instanceof SipApplicationSessionListener) { + this.addListener((SipApplicationSessionListener) listener); + added = true; + } + + if (listener instanceof SipSessionActivationListener) { + this.addListener((SipSessionActivationListener) listener); + added = true; + } + + if (listener instanceof SipSessionAttributeListener) { + this.addListener((SipSessionAttributeListener) listener); + added = true; + } + + if (listener instanceof SipSessionBindingListener) { + this.addListener((SipSessionBindingListener) listener); + added = true; + } + + if (listener instanceof SipSessionListener) { + this.addListener((SipSessionListener) listener); + added = true; + } + + if (listener instanceof SipServletListener) { + this.addListener((SipServletListener) listener); + added = true; + } + + if (listener instanceof SipErrorListener) { + this.addListener((SipErrorListener) listener); + added = true; + } + + if (listener instanceof ServletContextListener) { + this.addListener((ServletContextListener) listener); + added = true; + } + + if (listener instanceof TimerListener) { + this.setTimerListener((TimerListener) listener); + added = true; + } + + if (listener instanceof SipConnectorListener) { + this.addListener((SipConnectorListener) listener); + added = true; + } + + if (listener instanceof ProxyBranchListener) { + this.addListener((ProxyBranchListener) listener); + added = true; + } + + if (listener instanceof ContainerListener) { + this.setContainerListener((ContainerListener) listener); + added = true; + } + + if(!added) { + throw new IllegalArgumentException("Wrong type of LISTENER!!![" + + listener + "]"); + } + } + + // this.sipApplicationSessionAttributeListeners.clear(); + public void addListener(SipApplicationSessionAttributeListener listener) { + this.sipApplicationSessionAttributeListeners.add(listener); + } + + // this.sipApplicationSessionBindingListeners.clear(); + public void addListener(SipApplicationSessionBindingListener listener) { + this.sipApplicationSessionBindingListeners.add(listener); + } + + public void addListener(SipApplicationSessionActivationListener listener) { + this.sipApplicationSessionActivationListeners.add(listener); + } + + // this.sipApplicationSessionListeners.clear(); + public void addListener(SipApplicationSessionListener listener) { + this.sipApplicationSessionListeners.add(listener); + } + + // this.sipSessionActivationListeners.clear(); + public void addListener(SipSessionActivationListener listener) { + this.sipSessionActivationListeners.add(listener); + } + + // this.sipSessionAttributeListeners.clear(); + public void addListener(SipSessionAttributeListener listener) { + this.sipSessionAttributeListeners.add(listener); + } + + // this.sipSessionBindingListeners.clear(); + public void addListener(SipSessionBindingListener listener) { + this.sipSessionBindingListeners.add(listener); + } + + // this.sipSessionListeners.clear(); + public void addListener(SipSessionListener listener) { + this.sipSessionListeners.add(listener); + } + + // this.sipSessionListeners.clear(); + public void addListener(SipServletListener listener) { + this.sipServletsListeners.add(listener); + } + + // this.sipErrorListeners.clear(); + public void addListener(SipErrorListener listener) { + this.sipErrorListeners.add(listener); + } + + // this.servletContextListeners.clear(); + public void addListener(ServletContextListener listener) { + this.servletContextListeners.add(listener); + } + + public void addListener(SipConnectorListener listener) { + this.sipConnectorListeners.add(listener); + } + + public void addListener(ProxyBranchListener listener) { + this.proxyBranchListeners.add(listener); + } + + public void setTimerListener(TimerListener listener) { + if(this.timerListener != null) { + throw new IllegalArgumentException( + "the time listener has already been set ("+timerListener.getClass().getName() + + "), There may be at most one TimerListener defined !"); + } + this.timerListener = listener; + } + + public List getSipApplicationSessionAttributeListeners() { + return sipApplicationSessionAttributeListeners; + } + + public List getSipApplicationSessionBindingListeners() { + return sipApplicationSessionBindingListeners; + } + + public List getSipApplicationSessionActivationListeners() { + return sipApplicationSessionActivationListeners; + } + + public List getSipApplicationSessionListeners() { + return sipApplicationSessionListeners; + } + + public List getSipSessionActivationListeners() { + return sipSessionActivationListeners; + } + + public List getSipSessionAttributeListeners() { + return sipSessionAttributeListeners; + } + + public List getSipSessionBindingListeners() { + return sipSessionBindingListeners; + } + + public List getSipSessionListeners() { + return sipSessionListeners; + } + + public List getSipServletsListeners() { + return sipServletsListeners; + } + + public List getSipErrorListeners() { + return sipErrorListeners; + } + + public List getServletContextListeners() { + return servletContextListeners; + } + + public List getSipConnectorListeners() { + return sipConnectorListeners; + } + + public List getProxyBranchListeners() { + return proxyBranchListeners; + } + + public TimerListener getTimerListener() { + return timerListener; + } + + public void deallocateServletsActingAsListeners () { + //need to deallocate listeners that are servlets... + for(SipApplicationSessionAttributeListener sipApplicationSessionAttributeListener : sipApplicationSessionAttributeListeners) { + checkDeallocateServlet(sipApplicationSessionAttributeListener); + } + for(SipApplicationSessionBindingListener sipApplicationSessionBindingListener : sipApplicationSessionBindingListeners) { + checkDeallocateServlet(sipApplicationSessionBindingListener); + } + for(SipApplicationSessionActivationListener sipApplicationSessionActivationListener : sipApplicationSessionActivationListeners) { + checkDeallocateServlet(sipApplicationSessionActivationListener); + } + for(SipApplicationSessionListener sipApplicationSessionListener : sipApplicationSessionListeners) { + checkDeallocateServlet(sipApplicationSessionListener); + } + for(SipSessionActivationListener sipSessionActivationListener : sipSessionActivationListeners) { + checkDeallocateServlet(sipSessionActivationListener); + } + for(SipSessionAttributeListener sipSessionAttributeListener : sipSessionAttributeListeners) { + checkDeallocateServlet(sipSessionAttributeListener); + } + for(SipSessionBindingListener sipSessionBindingListener : sipSessionBindingListeners) { + checkDeallocateServlet(sipSessionBindingListener); + } + for(SipSessionListener sipSessionListener : sipSessionListeners) { + checkDeallocateServlet(sipSessionListener); + } + for(SipServletListener sipServletListener : sipServletsListeners) { + checkDeallocateServlet(sipServletListener); + } + for(SipErrorListener sipErrorListener : sipErrorListeners) { + checkDeallocateServlet(sipErrorListener); + } + for(ServletContextListener servletContextListener : servletContextListeners) { + checkDeallocateServlet(servletContextListener); + } + for(SipConnectorListener sipConnectorListener : sipConnectorListeners) { + checkDeallocateServlet(sipConnectorListener); + } + for(ProxyBranchListener proxyListener : proxyBranchListeners) { + checkDeallocateServlet(proxyListener); + } + checkDeallocateServlet(timerListener); + checkDeallocateServlet(containerListener); + } + + /** + * Empty vectors to allow garbage collection + */ + public void clean() { + + this.sipApplicationSessionAttributeListeners.clear(); + this.sipApplicationSessionBindingListeners.clear(); + this.sipApplicationSessionActivationListeners.clear(); + this.sipApplicationSessionListeners.clear(); + this.sipSessionActivationListeners.clear(); + this.sipSessionAttributeListeners.clear(); + this.sipSessionBindingListeners.clear(); + this.sipSessionListeners.clear(); + this.sipServletsListeners.clear(); + this.sipErrorListeners.clear(); + this.servletContextListeners.clear(); + this.sipConnectorListeners.clear(); + this.proxyBranchListeners.clear(); + this.listenerServlets.clear(); + this.timerListener = null; + this.containerListener = null; + } + + /** + * @param sipApplicationSessionAttributeListener + */ + private void checkDeallocateServlet( + EventListener eventListener) { + if(eventListener instanceof javax.servlet.sip.SipServlet) { + try { + MobicentsSipServlet wrapper = listenerServlets.get(eventListener); + if(wrapper != null) { + wrapper.deallocate((javax.servlet.sip.SipServlet)eventListener); + } + } catch (ServletException e) { + logger.error("couldn't deallocate listener " + eventListener.getClass().getName()); + } + } + } + + /** + * @return the containerListener + */ + public ContainerListener getContainerListener() { + return containerListener; + } + + /** + * @param containerListener the containerListener to set + */ + public void setContainerListener(ContainerListener containerListener) { + if(this.containerListener != null) { + throw new IllegalArgumentException( + "the Container listener has already been set ("+ this.containerListener.getClass().getName() + + "), There may be at most one ContainerListener defined !"); + } + this.containerListener = containerListener; + } + + @Override + public void callbackContainerListener(ContainerEvent event) { + final ContainerListener containerListener + = ((SipContext) sipContext).getListeners().getContainerListener(); + + if (containerListener != null) { + final ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); + try { + ((SipContext) sipContext).enterSipContext(); + try { + containerListener.sendEvent(event, sipContext.getServletContext()); + } catch (Throwable t) { + logger.error("ContainerListener threw exception", t); + } + } finally { + ((SipContext) sipContext).exitSipContext(oldClassLoader); + } + } + } +} diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipManagerDelegate.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipManagerDelegate.java index 353cd8497e..f68885fd90 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipManagerDelegate.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipManagerDelegate.java @@ -199,7 +199,10 @@ public MobicentsSipApplicationSession removeSipApplicationSession(final Mobicent * @param create if set to true, if no session has been found one will be created * @return the sip application session matching the key */ - public MobicentsSipApplicationSession getSipApplicationSession(final SipApplicationSessionKey key, final boolean create) { + public MobicentsSipApplicationSession getSipApplicationSession(final SipApplicationSessionKey key, final boolean create) { + if(logger.isDebugEnabled()) { + logger.debug("getSipApplicationSession with key=" + key); + } MobicentsSipApplicationSession sipApplicationSessionImpl = null; //first we check if the app session can be found by its app generated key final String appGeneratedKey = key.getAppGeneratedKey(); @@ -211,7 +214,11 @@ public MobicentsSipApplicationSession getSipApplicationSession(final SipApplicat } if(sipApplicationSessionImpl == null) { if(logger.isDebugEnabled()) { - logger.debug("trying to find sip application session with key " + key); + logger.debug("getSipApplicationSession - trying to find sip application session with key " + key); + logger.debug("getSipApplicationSession - sip application session keyset: "); + for (SipApplicationSessionKey tmp: sipApplicationSessions.keySet()){ + logger.debug("getSipApplicationSession - element=" + tmp); + } } sipApplicationSessionImpl = sipApplicationSessions.get(key); } @@ -222,6 +229,9 @@ public MobicentsSipApplicationSession getSipApplicationSession(final SipApplicat } protected MobicentsSipApplicationSession createSipApplicationSession(final SipApplicationSessionKey key) { + if(logger.isDebugEnabled()) { + logger.debug("createSipApplicationSession - with key : " + key); + } //http://dmy999.com/article/34/correct-use-of-concurrenthashmap MobicentsSipApplicationSession sipApplicationSessionImpl = null; final MobicentsSipApplicationSession newSipApplicationSessionImpl = @@ -229,7 +239,10 @@ protected MobicentsSipApplicationSession createSipApplicationSession(final SipAp final String appGeneratedKey = key.getAppGeneratedKey(); // Fix for Issue http://code.google.com/p/mobicents/issues/detail?id=2521 // in case od appGeneratedKey use the sipApplicationSessionsByAppGeneratedKey to ensure uniqueness - if(appGeneratedKey != null) { + if(appGeneratedKey != null) { + if(logger.isDebugEnabled()) { + logger.debug("createSipApplicationSession - appGeneratedKey is not null"); + } // gurantees uniqueness on the appgeneratedkey sipApplicationSessionImpl = sipApplicationSessionsByAppGeneratedKey.putIfAbsent(appGeneratedKey, newSipApplicationSessionImpl); if (sipApplicationSessionImpl == null) { @@ -237,19 +250,22 @@ protected MobicentsSipApplicationSession createSipApplicationSession(final SipAp scheduleExpirationTimer(newSipApplicationSessionImpl); // put succeeded, use new value if(logger.isDebugEnabled()) { - logger.debug("Adding a sip application session with the key : " + key); + logger.debug("createSipApplicationSession - Adding a sip application session with the key : " + key); } sipApplicationSessionImpl = newSipApplicationSessionImpl; } - } else { + } else { + if(logger.isDebugEnabled()) { + logger.debug("createSipApplicationSession - appGeneratedKey is null"); + } sipApplicationSessionImpl = sipApplicationSessions.putIfAbsent(key, newSipApplicationSessionImpl); if (sipApplicationSessionImpl == null) { scheduleExpirationTimer(newSipApplicationSessionImpl); // put succeeded, use new value if(logger.isDebugEnabled()) { - logger.debug("Adding a sip application session with the key : " + key); + logger.debug("createSipApplicationSession - Adding a sip application session with the key : " + key); } - sipApplicationSessionImpl = newSipApplicationSessionImpl; + sipApplicationSessionImpl = newSipApplicationSessionImpl; } } @@ -262,7 +278,8 @@ protected void scheduleExpirationTimer(MobicentsSipApplicationSession sipApplica // as for clustering it might not be needed to reschedule them on recreation final SipContext sipContext = sipApplicationSession.getSipContext(); if(sipContext != null) { - if(sipContext.getSipApplicationSessionTimeout() > 0) { + if(sipContext.getSipApplicationSessionTimeout() > 0) { + SipApplicationSessionTimerTask expirationTimerTask = sipContext.getSipApplicationSessionTimerService().createSipApplicationSessionTimerTask(sipApplicationSession); expirationTimerTask = sipContext.getSipApplicationSessionTimerService().schedule(expirationTimerTask, sipApplicationSession.getSipApplicationSessionTimeout(), TimeUnit.MILLISECONDS); sipApplicationSession.setExpirationTimerTask(expirationTimerTask); @@ -284,16 +301,42 @@ protected void scheduleExpirationTimer(MobicentsSipApplicationSession sipApplica * @throws IllegalArgumentException if create is set to true and sip Factory is null */ public MobicentsSipSession getSipSession(final SipSessionKey key, final boolean create, final SipFactoryImpl sipFactoryImpl, final MobicentsSipApplicationSession sipApplicationSessionImpl) { + if(logger.isDebugEnabled()) { + logger.debug("getSipSession - key=" + key + ", create=" + create + ", sipApplicationSessionImpl=" + sipApplicationSessionImpl); + if (sipApplicationSessionImpl != null){ + logger.debug("getSipSession - sipApplicationSessionImpl.getId()=" + sipApplicationSessionImpl.getId()); + + } + } if(create && sipFactoryImpl == null) { throw new IllegalArgumentException("the sip factory should not be null"); } //http://dmy999.com/article/34/correct-use-of-concurrenthashmap MobicentsSipSession sipSessionImpl = sipSessions.get(key); + if(logger.isDebugEnabled()) { + logger.debug("getSipSession - existing sip session keys:"); + if (sipSessions != null){ + for (SipSessionKey tmp: sipSessions.keySet()){ + logger.debug("getSipSession - key.getApplicationSessionId()=" + tmp.getApplicationSessionId() + + ", key.getApplicationName()=" + key.getApplicationName() + + ", key.getCallId()=" + key.getCallId() + + ", key.getFromTag()=" + key.getFromTag() + + ", key.getToTag()=" + key.getToTag()); + } + } + logger.debug("getSipSession - existing sipSessionImpl=" + sipSessionImpl); + } if(sipSessionImpl == null && create) { + if(logger.isDebugEnabled()) { + logger.debug("getSipSession - creating new sip session"); + } sipSessionImpl = createSipSession(key, create, sipFactoryImpl, sipApplicationSessionImpl); } // check if this session key has a to tag. if(sipSessionImpl != null) { + if(logger.isDebugEnabled()) { + logger.debug("getSipSession - calling setToTag"); + } return setToTag(key, sipSessionImpl); } return sipSessionImpl; diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipSessionAsyncTask.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipSessionAsyncTask.java index 8bf9fd948d..d23a9f4811 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipSessionAsyncTask.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipSessionAsyncTask.java @@ -48,6 +48,10 @@ public SipSessionAsyncTask(SipSessionKey key, * @see java.lang.Runnable#run() */ public void run() { + if (logger.isDebugEnabled()){ + logger.debug("run"); + } + final SipContext sipContext = sipFactoryImpl.getSipApplicationDispatcher().findSipApplication(key.getApplicationName()); if(sipContext != null) { SipManager sipManager = sipContext.getSipManager(); diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipSessionImpl.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipSessionImpl.java index c3de9d2336..f590a7b549 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipSessionImpl.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipSessionImpl.java @@ -125,17 +125,17 @@ import org.mobicents.servlet.sip.proxy.ProxyImpl; /** - * + * *

Implementation of the SipSession interface. * An instance of this sip session can only be retrieved through the Session Manager * (extended class from Tomcat's manager classes implementing the Manager interface) * to constrain the creation of sip session and to make sure that all sessions created - * can be retrieved only through the session manager

+ * can be retrieved only through the session manager

* *

- * As a SipApplicationSession represents a dialog, - * the call id and from header URI, from tag, to Header (and to Tag to identify forked requests) - * are used as a unique key for a given SipSession instance. + * As a SipApplicationSession represents a dialog, + * the call id and from header URI, from tag, to Header (and to Tag to identify forked requests) + * are used as a unique key for a given SipSession instance. *

* * @author vralev @@ -144,87 +144,85 @@ * @author George Vagenas */ public class SipSessionImpl implements MobicentsSipSession { - + private static final Logger logger = Logger.getLogger(SipSessionImpl.class); - - protected transient MobicentsSipApplicationSessionKey sipApplicationSessionKey; + + protected transient MobicentsSipApplicationSessionKey sipApplicationSessionKey; //lazy loaded and not serialized protected transient MobicentsSipApplicationSession sipApplicationSession; - + protected ProxyImpl proxy; - - protected B2buaHelperImpl b2buaHelper; - + protected transient int requestsPending; volatile protected Map sipSessionAttributeMap; - + protected transient SipSessionKey key; - + protected transient SipPrincipal userPrincipal; - + protected long cseq = -1; - + protected String transport; - + // protected transient ThreadPoolExecutor executorService = new ThreadPoolExecutor(1, 1, 90, TimeUnit.SECONDS, // new LinkedBlockingQueue()); - + /** * Creation time. */ protected long creationTime; - + /** * Last access time. */ protected long lastAccessedTime; - + /** * Routing region per session/dialog. */ protected transient SipApplicationRoutingRegion routingRegion; - + /** * AR state info */ protected transient Serializable stateInfo; - + /** * AR router info for the next app in chain */ protected transient SipApplicationRouterInfo nextSipApplicationRouterInfo; - + /** * Current state of the session, one of INTITIAL, EARLY, ESTABLISHED and TERMINATED. */ protected State state; - + /** * Is the session valid. */ protected AtomicBoolean isValidInternal; - + protected transient boolean isValid; - + /** * The name of the servlet withing this same app to handle all subsequent requests. */ protected String handlerServlet; - + /** * Subscriber URI should be set for outbound sessions, from requests created in the container. */ protected transient String subscriberURI; - + /** * Outbound interface is one of the allowed values in the Servlet Context attribute * "javax.servlet.ip.outboundinterfaces" * This one is not serialized, it has to be reset by the app on sessionActivated listener method */ protected transient String outboundInterface; - - + + // === THESE ARE THE OBJECTS A SIP SESSION CAN BE ASSIGNED TO === // TODO: Refactor this into two Session classes to avoid nulls // and branching on nulls @@ -233,7 +231,7 @@ public class SipSessionImpl implements MobicentsSipSession { * directly corresponds to the session. */ protected transient Dialog sessionCreatingDialog; - + /** * We use this for REGISTER or MESSAGE, where a dialog doesn't exist to carry the session info. * In this case the session only spans a single transaction. @@ -241,30 +239,30 @@ public class SipSessionImpl implements MobicentsSipSession { protected transient SipServletRequestImpl sessionCreatingTransactionRequest; protected transient boolean isSessionCreatingTransactionServer; // ============================================================= - + // TODO : Can be optimized into separate server tx and client tx to speed up some parts of the code protected transient Set ongoingTransactions; - + volatile protected transient ConcurrentHashMap derivedSipSessions; /* * The almighty provider */ protected transient SipFactoryImpl sipFactory; - + protected boolean invalidateWhenReady = true; - + protected boolean readyToInvalidate = false; /* * If this is a derived session, have a pointer to the parent session. */ protected transient MobicentsSipSession parentSession = null; - - //parties used when this is an outgoing request that has not yet been sent + + //parties used when this is an outgoing request that has not yet been sent protected transient Address localParty = null; protected transient Address remoteParty = null; - + //Subscriptions used for RFC 3265 compliance to be able to determine when the session can be invalidated // A subscription is destroyed when a notifier sends a NOTIFY request with a "Subscription-State" of "terminated". // If a subscription's destruction leaves no other application state associated with the dialog, the dialog terminates @@ -274,22 +272,22 @@ public class SipSessionImpl implements MobicentsSipSession { protected transient boolean okToByeSentOrReceived = false; // Issue 2066 Miss Record-Route in Response To Subsequent Requests for non RFC3261 compliant servers protected transient boolean copyRecordRouteHeadersOnSubsequentResponses = false; - + protected transient Semaphore semaphore; - + protected transient MobicentsSipSessionFacade facade = null; - + protected transient ConcurrentHashMap acksReceived = new ConcurrentHashMap(2); // Added for Issue 2173 http://code.google.com/p/mobicents/issues/detail?id=2173 // Handle Header [Authentication-Info: nextnonce="xyz"] in sip authorization responses protected transient MobicentsSipSessionSecurity sipSessionSecurity; - + /** - * This is the flow for this session, i.e., this uri represents the + * This is the flow for this session, i.e., this uri represents the * remote destination from where the request actually was received on. * We will use this this "flow" whenever we send out a subsequent * request to this destination. See RFC5626 for details. - * + * * TODO: in a fail-over scenario, should we keep this uri? If e.g. this * flow is a TCP connection, that connection will of course not be * failed over to the other server, which then would cause us to not (depending @@ -299,46 +297,46 @@ public class SipSessionImpl implements MobicentsSipSession { * So for now, I'll keep the flow around. */ private javax.sip.address.SipURI flow; - + private boolean bypassLoadBalancer = false; private boolean bypassProxy = false; - + protected SipSessionImpl (SipSessionKey key, SipFactoryImpl sipFactoryImpl, MobicentsSipApplicationSession mobicentsSipApplicationSession) { this.key = key; setSipApplicationSession(mobicentsSipApplicationSession); this.sipFactory = sipFactoryImpl; - this.creationTime = this.lastAccessedTime = System.currentTimeMillis(); + this.creationTime = this.lastAccessedTime = System.currentTimeMillis(); this.state = State.INITIAL; this.isValidInternal = new AtomicBoolean(true); this.isValid = true; this.ongoingTransactions = new CopyOnWriteArraySet(); if(mobicentsSipApplicationSession.getSipContext() != null && ConcurrencyControlMode.SipSession.equals(mobicentsSipApplicationSession.getSipContext().getConcurrencyControlMode())) { - semaphore = new Semaphore(1); - } + semaphore = new Semaphore(1); + } } /** - * Notifies the listeners that a lifecycle event occured on that sip session + * Notifies the listeners that a lifecycle event occured on that sip session * @param sipSessionEventType the type of event that happened */ public void notifySipSessionListeners(SipSessionEventType sipSessionEventType) { MobicentsSipApplicationSession sipApplicationSession = getSipApplicationSession(); if(sipApplicationSession != null) { - SipContext sipContext = sipApplicationSession.getSipContext(); - List sipSessionListeners = - sipContext.getListeners().getSipSessionListeners(); + SipContext sipContext = sipApplicationSession.getSipContext(); + List sipSessionListeners = + sipContext.getListeners().getSipSessionListeners(); if(sipSessionListeners.size() > 0) { if(logger.isDebugEnabled()) { logger.debug("notifying sip session listeners of context " + sipContext.getApplicationName() + " of following event " + sipSessionEventType); } ClassLoader oldClassLoader = java.lang.Thread.currentThread().getContextClassLoader(); - sipContext.enterSipContext(); + sipContext.enterSipContext(); SipSessionEvent sipSessionEvent = new SipSessionEvent(this.getFacade()); for (SipSessionListener sipSessionListener : sipSessionListeners) { try { if(logger.isDebugEnabled()) { - logger.debug("notifying sip session listener " + sipSessionListener.getClass().getName() + " of context " + + logger.debug("notifying sip session listener " + sipSessionListener.getClass().getName() + " of context " + key.getApplicationName() + " of following event " + sipSessionEventType); } if(SipSessionEventType.CREATION.equals(sipSessionEventType)) { @@ -353,7 +351,7 @@ public void notifySipSessionListeners(SipSessionEventType sipSessionEventType) { } } sipContext.exitSipContext(oldClassLoader); - } + } } } @@ -362,6 +360,10 @@ public void notifySipSessionListeners(SipSessionEventType sipSessionEventType) { * @see javax.servlet.sip.SipSession#createRequest(java.lang.String) */ public SipServletRequest createRequest(final String method) { + if(logger.isDebugEnabled()) { + logger.debug("createRequest - method="+ method); + logger.debug("createRequest - getId()="+ getId()); + } if(method.equalsIgnoreCase(Request.ACK) || method.equalsIgnoreCase(Request.PRACK) || method.equalsIgnoreCase(Request.CANCEL)) { throw new IllegalArgumentException( @@ -397,17 +399,17 @@ public SipServletRequest createRequest(final String method) { if(sessionCreatingTransactionRequest == null || sessionCreatingTransactionRequest.getLastFinalResponse() == null || (sessionCreatingTransactionRequest.getLastFinalResponse().getStatus() != 401 && sessionCreatingTransactionRequest.getLastFinalResponse().getStatus() != 407 && // http://code.google.com/p/sipservlets/issues/detail?id=143 RFC 4028 Session Timer : Allow sending retry INVITE after receiving 422 response - sessionCreatingTransactionRequest.getLastFinalResponse().getStatus() != SipServletResponse.SC_SESSION_INTERVAL_TOO_SMALL)) { + sessionCreatingTransactionRequest.getLastFinalResponse().getStatus() != SipServletResponse.SC_SESSION_INTERVAL_TOO_SMALL)) { throw new IllegalStateException("cannot create a subsequent request " + method + " because the dialog " + sessionCreatingDialog + " for session " + key + " is in TERMINATED state"); } } // Issue http://code.google.com/p/mobicents/issues/detail?id=2230 BYE is routed to unexpected IP BYE can be sent on a TERMINATED Dialog - if(this.sessionCreatingDialog != null && - (!DialogState.TERMINATED.equals(sessionCreatingDialog.getState()) || + if(this.sessionCreatingDialog != null && + (!DialogState.TERMINATED.equals(sessionCreatingDialog.getState()) || (DialogState.TERMINATED.equals(sessionCreatingDialog.getState()) && method.equalsIgnoreCase(Request.BYE)))) { - + if(logger.isDebugEnabled()) { - logger.debug("dialog " + sessionCreatingDialog + " used to create the new request " + method); + logger.debug("dialog " + sessionCreatingDialog + " used to create the new request " + method); } try { final Request methodRequest = this.sessionCreatingDialog.createRequest(method); @@ -429,7 +431,7 @@ public SipServletRequest createRequest(final String method) { MobicentsExtendedListeningPoint listeningPoint = JainSipUtils.findListeningPoint(sipFactory.getSipNetworkInterfaceManager(), methodRequest, outboundInterface); if(listeningPoint != null && listeningPoint.isUseLoadBalancer()) { // https://github.com/RestComm/sip-servlets/issues/137 - SipLoadBalancer loadBalancerToUse = null; + SipLoadBalancer loadBalancerToUse = null; if(listeningPoint.getLoadBalancer() == null) { loadBalancerToUse = sipFactory.getLoadBalancerToUse(); if(logger.isDebugEnabled()) { @@ -441,15 +443,15 @@ public SipServletRequest createRequest(final String method) { logger.debug("Using listeningPoint " + listeningPoint + " for connector specific load balancer " + listeningPoint.getLoadBalancer()); } } - + javax.sip.address.SipURI sipURI = SipFactoryImpl.addressFactory.createSipURI(userName, loadBalancerToUse.getAddress().getHostAddress()); sipURI.setHost(loadBalancerToUse.getAddress().getHostAddress()); sipURI.setPort(loadBalancerToUse.getSipPort()); - + // TODO: Is this enough or we must specify the transport somewhere? // We can leave it like this. It will be updated if needed in the send() method sipURI.setTransportParam(ListeningPoint.UDP); - + javax.sip.address.Address contactAddress = SipFactoryImpl.addressFactory.createAddress(sipURI); contactHeader = SipFactoryImpl.headerFactory.createContactHeader(contactAddress); } else { @@ -466,24 +468,24 @@ public SipServletRequest createRequest(final String method) { logger.error("Can not create contact header for subsequent request " + method + " for session " + key, e); } } - // Fix for Issue 1130 (http://code.google.com/p/mobicents/issues/detail?id=1130) : + // Fix for Issue 1130 (http://code.google.com/p/mobicents/issues/detail?id=1130) : // NullPointerException when sending request to client which support both UDP and TCP transport // before removing the via header we store the transport into its app data - ListIterator viaHeaders = methodRequest.getHeaders(ViaHeader.NAME); + ListIterator viaHeaders = methodRequest.getHeaders(ViaHeader.NAME); if(viaHeaders != null && viaHeaders.hasNext()) { ViaHeader viaHeader = viaHeaders.next(); ((MessageExt)methodRequest).setApplicationData(viaHeader.getTransport()); } - //Issue 112 fix by folsson + //Issue 112 fix by folsson methodRequest.removeHeader(ViaHeader.NAME); - + // cater to http://code.google.com/p/sipservlets/issues/detail?id=31 to be able to set the rport in applications final SipApplicationDispatcher sipApplicationDispatcher = sipFactory.getSipApplicationDispatcher(); final String branch = JainSipUtils.createBranch(getSipApplicationSession().getKey().getId(), sipApplicationDispatcher.getHashFromApplicationName(getKey().getApplicationName())); ViaHeader viaHeader = JainSipUtils.createViaHeader( sipFactory.getSipNetworkInterfaceManager(), methodRequest, branch, outboundInterface); methodRequest.addHeader(viaHeader); - + //if a SUBSCRIBE or BYE is sent for exemple, it will reuse the prexisiting dialog sipServletRequest = (SipServletRequestImpl) sipFactory.getMobicentsSipServletMessageFactory().createSipServletRequest( methodRequest, this, null, sessionCreatingDialog, @@ -491,12 +493,12 @@ public SipServletRequest createRequest(final String method) { } catch (SipException e) { logger.error("Cannot create the " + method + " request from the dialog " + sessionCreatingDialog,e); throw new IllegalArgumentException("Cannot create the " + method + " request from the dialog " + sessionCreatingDialog + " for sip session " + key,e); - } - } else { + } + } else { boolean treatAsInitialRequest = false; - // http://code.google.com/p/sipservlets/issues/detail?id=19 + // http://code.google.com/p/sipservlets/issues/detail?id=19 // Retried Request are not considered as initial - if(sessionCreatingTransactionRequest != null && sessionCreatingTransactionRequest.getLastFinalResponse() != null && + if(sessionCreatingTransactionRequest != null && sessionCreatingTransactionRequest.getLastFinalResponse() != null && sessionCreatingTransactionRequest.getLastFinalResponse().getStatus() >= 400 && sessionCreatingTransactionRequest.getLastFinalResponse().getStatus() < 500) { if(logger.isDebugEnabled()) { logger.debug("Treating as Initial Request"); @@ -505,13 +507,17 @@ public SipServletRequest createRequest(final String method) { } //case where other requests are sent with the same session like REGISTER or for challenge requests if(sessionCreatingTransactionRequest != null) { + if(logger.isDebugEnabled()) { + logger.debug("createRequest - sessionCreatingTransactionRequest is not null - id:" + this.getId()); + } + if(!isSessionCreatingTransactionServer) { if(logger.isDebugEnabled()) { logger.debug("orignal tx for creating susbequent request " + method + " on session " + key +" was a Client Tx"); } Request request = (Request) sessionCreatingTransactionRequest.getMessage().clone(); // Issue 1524 : Caused by: java.text.ParseException: CSEQ method mismatch with Request-Line - javax.sip.address.URI requestUri = (javax.sip.address.URI) request.getRequestURI().clone(); + javax.sip.address.URI requestUri = (javax.sip.address.URI) request.getRequestURI().clone(); try { request.setMethod(method); } catch (ParseException e) { @@ -519,37 +525,37 @@ public SipServletRequest createRequest(final String method) { } request.setRequestURI(requestUri); ((MessageExt)request).setApplicationData(null); - - final CSeqHeader cSeqHeader = (CSeqHeader) request.getHeader((CSeqHeader.NAME)); + + final CSeqHeader cSeqHeader = (CSeqHeader) request.getHeader((CSeqHeader.NAME)); try { cSeqHeader.setSeqNumber(cSeqHeader.getSeqNumber() + 1l); cSeqHeader.setMethod(method); } catch (InvalidArgumentException e) { logger.error("Cannot increment the Cseq header to the new " + method + " on the susbequent request to create on session " + key,e); - throw new IllegalArgumentException("Cannot create the " + method + " on the susbequent request to create on session " + key,e); + throw new IllegalArgumentException("Cannot create the " + method + " on the susbequent request to create on session " + key,e); } catch (ParseException e) { - throw new IllegalArgumentException("Cannot set the " + method + " on the susbequent request to create on session " + key,e); + throw new IllegalArgumentException("Cannot set the " + method + " on the susbequent request to create on session " + key,e); } - // Fix for Issue 1130 (http://code.google.com/p/mobicents/issues/detail?id=1130) : + // Fix for Issue 1130 (http://code.google.com/p/mobicents/issues/detail?id=1130) : // NullPointerException when sending request to client which support both UDP and TCP transport // before removing the ViaHeader we store the transport into its app data - ListIterator viaHeaders = request.getHeaders(ViaHeader.NAME); + ListIterator viaHeaders = request.getHeaders(ViaHeader.NAME); if(viaHeaders != null && viaHeaders.hasNext()) { ViaHeader viaHeader = viaHeaders.next(); ((MessageExt)request).setApplicationData(viaHeader.getTransport()); } request.removeHeader(ViaHeader.NAME); - + final SipNetworkInterfaceManager sipNetworkInterfaceManager = sipFactory.getSipNetworkInterfaceManager(); final SipProvider sipProvider = sipNetworkInterfaceManager.findMatchingListeningPoint( JainSipUtils.findTransport(request), false).getSipProvider(); - final SipApplicationDispatcher sipApplicationDispatcher = sipFactory.getSipApplicationDispatcher(); + final SipApplicationDispatcher sipApplicationDispatcher = sipFactory.getSipApplicationDispatcher(); final String branch = JainSipUtils.createBranch(getSipApplicationSession().getKey().getId(), sipApplicationDispatcher.getHashFromApplicationName(getKey().getApplicationName())); - + ViaHeader viaHeader = JainSipUtils.createViaHeader( sipNetworkInterfaceManager, request, branch, outboundInterface); request.addHeader(viaHeader); - + // https://code.google.com/p/sipservlets/issues/detail?id=278 request.removeContent(); // http://code.google.com/p/sipservlets/issues/detail?id=161 @@ -559,11 +565,11 @@ public SipServletRequest createRequest(final String method) { if(treatAsInitialRequest) { dialogToUse = null; } - + sipServletRequest = (SipServletRequestImpl) sipFactory.getMobicentsSipServletMessageFactory().createSipServletRequest( request, this, null, dialogToUse, true); - + // Fix for Issue http://code.google.com/p/mobicents/issues/detail?id=2230 BYE is routed to unexpected IP if(sessionCreatingDialog != null && sessionCreatingDialog.getRemoteTarget() != null) { SipUri sipUri = (SipUri) sessionCreatingDialog.getRemoteTarget().getURI().clone(); @@ -574,7 +580,7 @@ public SipServletRequest createRequest(final String method) { request.setRequestURI(sipUri); } // http://code.google.com/p/sipservlets/issues/detail?id=130 - // removes the Route and Path Headers added previously for requests that the container originated + // removes the Route and Path Headers added previously for requests that the container originated // when the Load Balancer is used to avoid adding them again with each request going out. request.removeHeader(RouteHeader.NAME); request.removeHeader(PathHeader.NAME); @@ -599,7 +605,7 @@ public SipServletRequest createRequest(final String method) { currentRemoteParty, handlerServlet, originalCallId, - fromHeader.getTag()); + fromHeader.getTag()); final Request request = ((Request)sipServletRequest.getMessage()); sipServletRequest.getSipSession().setCseq(((CSeqHeader)request.getHeader(CSeqHeader.NAME)).getSeqNumber()); final Map fromParameters = new HashMap(); @@ -617,8 +623,8 @@ public SipServletRequest createRequest(final String method) { if(sessionCreatingDialog != null || !SipFactoryImpl.FORBIDDEN_PARAMS.contains(parameterName)) { toParameters.put(parameterName, toHeader.getParameter(parameterName)); } - } - + } + final ToHeader newTo = (ToHeader) request.getHeader(ToHeader.NAME); for (Entry fromParameter : fromParameters.entrySet()) { String value = fromParameter.getValue(); @@ -634,7 +640,7 @@ public SipServletRequest createRequest(final String method) { value = ""; } newFrom.setParameter(toParameter.getKey(), value); - } + } // Fix for Issue http://code.google.com/p/mobicents/issues/detail?id=2230 BYE is routed to unexpected IP if(sessionCreatingDialog != null && sessionCreatingDialog.getRemoteTarget() != null) { SipUri sipUri = (SipUri) sessionCreatingDialog.getRemoteTarget().getURI().clone(); @@ -646,34 +652,34 @@ public SipServletRequest createRequest(final String method) { } } catch (ParseException e) { throw new IllegalArgumentException("Problem setting param on the newly created susbequent request " + sipServletRequest,e); - } + } } if(sipSessionSecurity != null && sipSessionSecurity.getNextNonce() != null) { sipServletRequest.updateAuthorizationHeaders(true); - } + } else if (sipSessionSecurity != null) { sipServletRequest.updateAuthorizationHeaders(false); } if(treatAsInitialRequest) { sipServletRequest.setRoutingState(RoutingState.INITIAL); } - + return sipServletRequest; } else { String errorMessage = "Couldn't create the subsequent request " + method + " for this session " + key + ", isValid " + isValid() + ", session state " + state + " , sessionCreatingDialog = " + sessionCreatingDialog; if(sessionCreatingDialog != null) { errorMessage += " , dialog state " + sessionCreatingDialog.getState(); } - errorMessage += " , sessionCreatingTransactionRequest = " + sessionCreatingTransactionRequest; - throw new IllegalStateException(errorMessage); + errorMessage += " , sessionCreatingTransactionRequest = " + sessionCreatingTransactionRequest; + throw new IllegalStateException(errorMessage); } } //Application Routing : //removing the route headers and adding them back again except the one //corresponding to the app that is creating the subsequent request //avoid going through the same app that created the subsequent request - + Request request = (Request) sipServletRequest.getMessage(); final ListIterator routeHeaders = request.getHeaders(RouteHeader.NAME); request.removeHeader(RouteHeader.NAME); @@ -687,19 +693,19 @@ else if (sipSessionSecurity != null) { if(routeAppNameHashed != null) { routeAppName = sipFactory.getSipApplicationDispatcher().getApplicationNameFromHash(routeAppNameHashed); } - if(routeAppName == null || !sipFactory.getSipApplicationDispatcher().getApplicationServerId().equals(routeServerId) || + if(routeAppName == null || !sipFactory.getSipApplicationDispatcher().getApplicationServerId().equals(routeServerId) || !routeAppName.equals(getKey().getApplicationName())) { request.addHeader(routeHeader); } } - + if(sipSessionSecurity != null && sipSessionSecurity.getNextNonce() != null) { sipServletRequest.updateAuthorizationHeaders(true); - } + } else if (sipSessionSecurity != null) { sipServletRequest.updateAuthorizationHeaders(false); - } - + } + return sipServletRequest; } @@ -715,7 +721,7 @@ public SipApplicationSession getApplicationSession() { return sipApplicationSession.getFacade(); } } - + // Does it need to be synchronized? protected Map getAttributeMap() { if(this.sipSessionAttributeMap == null) { @@ -756,7 +762,7 @@ public String getCallId() { return this.sessionCreatingDialog.getCallId().getCallId(); else if(sessionCreatingTransactionRequest != null) return ((CallIdHeader)this.sessionCreatingTransactionRequest.getMessage().getHeader(CallIdHeader.NAME)).getCallId(); - else if(key != null) + else if(key != null) return key.getCallId(); else return null; @@ -789,7 +795,7 @@ public long getLastAccessedTime() { private void setLastAccessedTime(long lastAccessedTime) { this.lastAccessedTime= lastAccessedTime; } - + /** * Update the accessed time information for this session. This method * should be called by the context when a request comes in for a particular @@ -812,7 +818,7 @@ public Address getLocalParty() { } else { FromHeader fromHeader = (FromHeader)sessionCreatingTransactionRequest.getMessage().getHeader(FromHeader.NAME); return new AddressImpl(fromHeader.getAddress(), AddressImpl.getParameters((Parameters)fromHeader), ModifiableRule.NotModifiable); - } + } } else { return localParty; } @@ -834,20 +840,20 @@ public SipApplicationRoutingRegion getRegion() { /** * {@inheritDoc} */ - public SipApplicationRoutingRegion getRegionInternal() { + public SipApplicationRoutingRegion getRegionInternal() { return routingRegion; } - + /** - * This method allows the application to set the region that the application + * This method allows the application to set the region that the application * is in with respect to this SipSession - * @param routingRegion the region that the application is in + * @param routingRegion the region that the application is in */ public void setRoutingRegion(SipApplicationRoutingRegion routingRegion) { this.routingRegion = routingRegion; } - + /** * @return the stateInfo */ @@ -861,7 +867,7 @@ public Serializable getStateInfo() { public void setStateInfo(Serializable stateInfo) { this.stateInfo = stateInfo; } - + /* * (non-Javadoc) * @see javax.servlet.sip.SipSession#getRemoteParty() @@ -901,7 +907,7 @@ public State getStateInternal() { return this.state; } - + // public ThreadPoolExecutor getExecutorService() { // return executorService; // } @@ -914,7 +920,7 @@ public URI getSubscriberURI() { } if (this.subscriberURI == null) throw new IllegalStateException("Subscriber URI is only available for outbound sessions."); - else { + else { try { return sipFactory.createURI(subscriberURI); } catch (ServletParseException e) { @@ -930,30 +936,57 @@ public URI getSubscriberURI() { public void invalidate() { invalidate(false); } - - public void invalidate(boolean bypassCheck) { + + public void invalidate(boolean bypassCheck) { + if(logger.isDebugEnabled()) { + String msg = String.format("About to invalidate sip session [%s], hasParent [%s], hasDerivedSessions [%s], bypassCheck [%s]", key, parentSession!= null, derivedSipSessions != null, bypassCheck); + logger.debug(msg); + } boolean wasValid = isValidInternal.compareAndSet(true, false); if(!wasValid) { if(!bypassCheck) { throw new IllegalStateException("SipSession " + key + " already invalidated !"); } else { if(logger.isInfoEnabled()) { - logger.info("SipSession " + key + " already invalidated, doing nothing"); + logger.info("SipSession " + key + " already invalidated, doing nothing"); } return; } } - + if(logger.isInfoEnabled()) { logger.info("Invalidating the sip session " + key); } - - + + /* + * Compute how long this session has been alive, and update + * session manager's related properties accordingly + */ + final long timeNow = System.currentTimeMillis(); + final int timeAlive = (int) ((timeNow - creationTime)/1000); + + final SipApplicationDispatcher sipApplicationDispatcher = sipFactory.getSipApplicationDispatcher(); + if(sipApplicationDispatcher.isGatherStatistics()) { + if(logger.isDebugEnabled()) { + logger.debug("orginal method " + originalMethod); + } + if(Request.MESSAGE.equalsIgnoreCase(originalMethod)) { + sipFactory.getSipApplicationDispatcher().incMessages(); + } + if(Request.INVITE.equalsIgnoreCase(originalMethod)) { + sipFactory.getSipApplicationDispatcher().incCalls(); + sipFactory.getSipApplicationDispatcher().incSeconds(timeAlive); + if(logger.isDebugEnabled()) { + logger.debug("seconds " + timeAlive); + } + } + } + final MobicentsSipApplicationSession sipApplicationSession = getSipApplicationSession(); SipManager manager = sipApplicationSession.getSipContext().getSipManager(); // http://code.google.com/p/mobicents/issues/detail?id=2885 // FQN Memory Leak in HA mode with PESSIMISTIC locking - // remove it before the DELETION notification to avoid the sip application session to be destroyed before + // remove it before the DELETION notification to avoid the sip application session to be destroyed before // and leaking in the JBoss Cache MobicentsSipSession parentSipSession = getParentSession(); if(parentSipSession == null) { @@ -969,7 +1002,7 @@ public void invalidate(boolean bypassCheck) { removeAttribute(key, true); } } - manager.removeSipSession(key); + manager.removeSipSession(key); sipApplicationSession.getSipContext().getSipSessionsUtil().removeCorrespondingSipSession(key); } else { if(logger.isDebugEnabled()) { @@ -978,7 +1011,7 @@ public void invalidate(boolean bypassCheck) { if(derivedSipSessions != null) { for (MobicentsSipSession session: derivedSipSessions.values()) { if(logger.isDebugEnabled()) { - logger.debug("derived session " + session + " " + isValidInternal + " " + readyToInvalidate + " " + state); + logger.debug("derived session " + session + " " + session.isValidInternal() + " " + session.isReadyToInvalidate() + " " + session.getState()); } if(session.isReadyToInvalidateInternal() && state == State.TERMINATED) { if(logger.isDebugEnabled()) { @@ -995,7 +1028,7 @@ public void invalidate(boolean bypassCheck) { removeAttribute(key, true); } } - manager.removeSipSession(key); + manager.removeSipSession(key); sipApplicationSession.getSipContext().getSipSessionsUtil().removeCorrespondingSipSession(key); } } else { @@ -1014,14 +1047,8 @@ public void invalidate(boolean bypassCheck) { logger.debug("removed derived sip session " + key + " from the list of derived sessions from the parent session " + parentSipSession.getKey()); } } - - /* - * Compute how long this session has been alive, and update - * session manager's related properties accordingly - */ - long timeNow = System.currentTimeMillis(); - int timeAlive = (int) ((timeNow - creationTime)/1000); - synchronized (manager) { + + synchronized (manager) { if (timeAlive > manager.getSipSessionMaxAliveTime()) { manager.setSipSessionMaxAliveTime(timeAlive); } @@ -1032,14 +1059,14 @@ public void invalidate(boolean bypassCheck) { average = ((average * (numExpired-1)) + timeAlive)/numExpired; manager.setSipSessionAverageAliveTime(average); } - - notifySipSessionListeners(SipSessionEventType.DELETION); - + + notifySipSessionListeners(SipSessionEventType.DELETION); + isValid = false; - + if(derivedSipSessions != null - // https://github.com/Mobicents/sip-servlets/issues/41 - // Invalidate derived session only if forcefully asked by the application + // https://github.com/Mobicents/sip-servlets/issues/41 + // Invalidate derived session only if forcefully asked by the application && !bypassCheck) { for (MobicentsSipSession derivedMobicentsSipSession : derivedSipSessions.values()) { if(logger.isDebugEnabled()) { @@ -1047,10 +1074,10 @@ public void invalidate(boolean bypassCheck) { } // https://code.google.com/p/sipservlets/issues/detail?id=279 derivedMobicentsSipSession.invalidate(bypassCheck); - } + } derivedSipSessions.clear(); - } - + } + sipApplicationSession.onSipSessionReadyToInvalidate(this); if(ongoingTransactions != null) { if(logger.isDebugEnabled()) { @@ -1080,19 +1107,16 @@ public void invalidate(boolean bypassCheck) { sipSessionSecurity.getCachedAuthInfos().clear(); } // executorService.shutdown(); - parentSession = null; - userPrincipal = null; + //Don't remove reference to the parentSession, it will be used later to notify parent to invalidate +// parentSession = null; + userPrincipal = null; // executorService = null; // If the sip app session is nullified com.bea.sipservlet.tck.agents.api.javax_servlet_sip.B2buaHelperTest.testCreateResponseToOriginalRequest102 will fail - // because it will try to get the B2BUAHelper after the session has been invalidated + // because it will try to get the B2BUAHelper after the session has been invalidated // sipApplicationSession = null; manager = null; - if(b2buaHelper != null) { - b2buaHelper.unlinkSipSessionsInternal(this, false); - b2buaHelper= null; - } derivedSipSessions = null; - // not collecting it here to avoid race condition from + // not collecting it here to avoid race condition from // http://code.google.com/p/mobicents/issues/detail?id=2130#c19 // handlerServlet = null; localParty = null; @@ -1124,6 +1148,9 @@ public void invalidate(boolean bypassCheck) { } } sessionCreatingTransactionRequest.cleanUp(); + if(logger.isDebugEnabled()) { + logger.debug("invalidate - setting the sessionCreatingTransactionRequest to null, id:" + this.getId()); + } sessionCreatingTransactionRequest = null; } if(proxy != null && !proxy.getAckReceived()) { @@ -1151,16 +1178,16 @@ public void invalidate(boolean bypassCheck) { // semaphore.release(); // semaphore = null; // } - facade = null; - } - + facade = null; + } + /** * Not needed anymore after PFD JSR 289 spec */ // protected void checkInvalidation() { // if(state.equals(State.CONFIRMED) // || state.equals(State.EARLY)) -// throw new IllegalStateException("Can not invalidate sip session in " + +// throw new IllegalStateException("Can not invalidate sip session in " + // state.toString() + " state."); // if(isSupervisedMode() && hasOngoingTransaction()) { // dumpOngoingTransactions(); @@ -1172,7 +1199,7 @@ public void invalidate(boolean bypassCheck) { // private void dumpOngoingTransactions() { // if(logger.isDebugEnabled()) { // logger.debug("ongoing transactions in sip the session " + key); -// +// // for (Transaction transaction : ongoingTransactions) { // logger.debug("Transaction " + transaction + " : state = " + transaction.getState()); // } @@ -1217,7 +1244,7 @@ public boolean isValid() { public boolean isValidInternal() { return isValidInternal.get(); } - + /** * @param isValid the isValid to set */ @@ -1231,16 +1258,16 @@ public void setValid(boolean isValid) { public void removeAttribute(String name) { removeAttribute(name, false); } - + public void removeAttribute(String name, boolean byPassValidCheck) { if(!byPassValidCheck && !isValid()) throw new IllegalStateException("Can not bind object to session that has been invalidated!!"); - + if(name==null) // throw new NullPointerException("Name of attribute to bind cant be null!!!"); return; - + SipSessionBindingEvent event = null; Object value = getAttributeMap().get(name); // Call the valueUnbound() method if necessary @@ -1248,11 +1275,11 @@ public void removeAttribute(String name, boolean byPassValidCheck) { event = new SipSessionBindingEvent(this, name); ((SipSessionBindingListener) value).valueUnbound(event); } - + this.getAttributeMap().remove(name); - - // Notifying Listeners of attribute removal - SipListeners sipListenersHolder = this.getSipApplicationSession().getSipContext().getListeners(); + + // Notifying Listeners of attribute removal + SipListeners sipListenersHolder = this.getSipApplicationSession().getSipContext().getListeners(); List listenersList = sipListenersHolder.getSipSessionAttributeListeners(); if(listenersList.size() > 0) { if(event == null) { @@ -1285,12 +1312,12 @@ public void setAttribute(String key, Object attribute) { if(attribute == null) { throw new NullPointerException("Attribute that is to be bound cant be null!!!"); } - + // Construct an event with the new value SipSessionBindingEvent event = null; // Call the valueBound() method if necessary - if (attribute instanceof SipSessionBindingListener) { + if (attribute instanceof SipSessionBindingListener) { // Don't call any notification if replacing with the same value Object oldValue = getAttributeMap().get(key); if (attribute != oldValue) { @@ -1298,13 +1325,13 @@ public void setAttribute(String key, Object attribute) { try { ((SipSessionBindingListener) attribute).valueBound(event); } catch (Throwable t){ - logger.error("SipSessionBindingListener threw exception", t); + logger.error("SipSessionBindingListener threw exception", t); } } } - + Object previousValue = this.getAttributeMap().put(key, attribute); - + if (previousValue != null && previousValue != attribute && previousValue instanceof SipSessionBindingListener) { try { @@ -1314,13 +1341,13 @@ public void setAttribute(String key, Object attribute) { logger.error("SipSessionBindingListener threw exception", t); } } - - // Notifying Listeners of attribute addition or modification + + // Notifying Listeners of attribute addition or modification SipListeners sipListenersHolder = this.getSipApplicationSession().getSipContext().getListeners(); List listenersList = sipListenersHolder.getSipSessionAttributeListeners(); if(listenersList.size() > 0) { if(event == null) { - event = new SipSessionBindingEvent(this, key); + event = new SipSessionBindingEvent(this, key); } if (previousValue == null) { // This is initial, we need to send value bound event @@ -1345,7 +1372,7 @@ public void setAttribute(String key, Object attribute) { logger.error("SipSessionAttributeListener threw exception", t); } } - } + } } } @@ -1361,12 +1388,12 @@ public void setHandler(String name) throws ServletException { return ; } SipContext sipContext = getSipApplicationSession().getSipContext(); - MobicentsSipServlet container = sipContext.findSipServletByName(name); - + MobicentsSipServlet container = sipContext.findSipServletByName(name); + if(container == null && sipContext.getSipRubyController() == null) { - throw new ServletException("the sip servlet with the name "+ name + + throw new ServletException("the sip servlet with the name "+ name + " doesn't exist in the sip application " + sipContext.getApplicationName()); - } + } this.handlerServlet = name; getSipApplicationSession().setCurrentRequestHandler(handlerServlet); if(logger.isDebugEnabled()) { @@ -1377,7 +1404,7 @@ public void setHandler(String name) throws ServletException { } } } - + /** * Retrieve the handler associated with this sip session * @return the handler associated with this sip session @@ -1390,6 +1417,9 @@ public String getHandler() { * @param dialog the dialog to set */ public void setSessionCreatingDialog(Dialog dialog) { + if(logger.isDebugEnabled()) { + logger.debug("setSessionCreatingDialog - getId()=" + this.getId() + ", dialog=" + System.identityHashCode(dialog)); + } if(proxy == null) { this.sessionCreatingDialog = dialog; if(logger.isDebugEnabled()) { @@ -1416,39 +1446,76 @@ public Dialog getSessionCreatingDialog() { } public MobicentsSipApplicationSession getSipApplicationSession() { + if(logger.isDebugEnabled()) { + logger.debug("getSipApplicationSession"); + } + if(sipApplicationSession == null) { - final String applicationName = key.getApplicationName(); + final String applicationName = key.getApplicationName(); + if(logger.isDebugEnabled()) { + logger.debug("getSipApplicationSession - sipApplicationSession is null, applicationName=" + applicationName); + } + final SipContext sipContext = sipFactory.getSipApplicationDispatcher().findSipApplication(applicationName); if(sipContext != null) { + if(logger.isDebugEnabled()) { + logger.debug("getSipApplicationSession - sipContext is not null"); + } sipApplicationSession = sipContext.getSipManager().getSipApplicationSession(sipApplicationSessionKey, false); } - } + } + + if(logger.isDebugEnabled()) { + logger.debug("getSipApplicationSession - return=" + sipApplicationSession); + } + return sipApplicationSession; } protected void setSipApplicationSession( - MobicentsSipApplicationSession sipApplicationSession) { - if (sipApplicationSession != null) { + MobicentsSipApplicationSession sipApplicationSession) { + if (sipApplicationSession != null) { this.sipApplicationSessionKey = sipApplicationSession.getKey(); - sipApplicationSession.addSipSession(this); + sipApplicationSession.addSipSession(this); } } public SipServletRequestImpl getSessionCreatingTransactionRequest() { return sessionCreatingTransactionRequest; - } + } /** * @param sessionCreatingTransaction the sessionCreatingTransaction to set */ - public void setSessionCreatingTransactionRequest(MobicentsSipServletMessage message) { + public void setSessionCreatingTransactionRequest(MobicentsSipServletMessage message) { + if(logger.isDebugEnabled()) { + logger.debug("setSessionCreatingTransactionRequest - message="+ message + ", id:" + this.getId()); + } if(message != null) { - if(message instanceof SipServletRequestImpl) { + if(logger.isDebugEnabled()) { + logger.debug("setSessionCreatingTransactionRequest - message.getTransaction()=" + message.getTransaction()); + if (message.getTransaction() != null){ + logger.debug("setSessionCreatingTransactionRequest - message.getTransaction().getApplicationData()=" + message.getTransaction().getApplicationData()); + } + } + if(message instanceof SipServletRequestImpl) { + if(logger.isDebugEnabled()) { + logger.debug("setSessionCreatingTransactionRequest - message is instanceof SipServletRequestImpl, id:" + this.getId()); + } this.sessionCreatingTransactionRequest = (SipServletRequestImpl) message; this.isSessionCreatingTransactionServer = message.getTransaction() instanceof ServerTransaction; } else if(message.getTransaction() != null && message.getTransaction().getApplicationData() != null) { + if(logger.isDebugEnabled()) { + logger.debug("setSessionCreatingTransactionRequest - message is not SipServletRequestImpl"); + } SipServletMessageImpl sipServletMessageImpl = ((TransactionApplicationData)message.getTransaction().getApplicationData()).getSipServletMessage(); - if(sipServletMessageImpl != null && sipServletMessageImpl instanceof SipServletRequestImpl) { + if(logger.isDebugEnabled()) { + logger.debug("setSessionCreatingTransactionRequest - sipServletMessageImpl=" + sipServletMessageImpl); + } + if(sipServletMessageImpl != null && sipServletMessageImpl instanceof SipServletRequestImpl) { + if(logger.isDebugEnabled()) { + logger.debug("setSessionCreatingTransactionRequest - sipServletMessageImpl is instanceof SipServletRequestImpl, id:" + this.getId()); + } this.sessionCreatingTransactionRequest = (SipServletRequestImpl) sipServletMessageImpl; this.isSessionCreatingTransactionServer = message.getTransaction() instanceof ServerTransaction; } @@ -1456,8 +1523,11 @@ public void setSessionCreatingTransactionRequest(MobicentsSipServletMessage mess } if(sessionCreatingTransactionRequest != null) { if(originalMethod == null) { + if(logger.isDebugEnabled()) { + logger.debug("setSessionCreatingTransactionRequest - setting originalMethod="+ sessionCreatingTransactionRequest.getMethod()); + } originalMethod = sessionCreatingTransactionRequest.getMethod(); - } + } addOngoingTransaction(sessionCreatingTransactionRequest.getTransaction()); // Issue 906 : CSeq is not increased correctly for REGISTER requests if registrar requires authentication. // http://code.google.com/p/mobicents/issues/detail?id=906 @@ -1469,8 +1539,12 @@ public void setSessionCreatingTransactionRequest(MobicentsSipServletMessage mess } } } + + if(logger.isDebugEnabled()) { + logger.debug("setSessionCreatingTransactionRequest - sessionCreatingTransactionRequest="+ sessionCreatingTransactionRequest + ", id:" + this.getId()); + } } - + public boolean isSupervisedMode() { if(proxy == null) { return true; @@ -1482,15 +1556,15 @@ public boolean isSupervisedMode() { public void setSipSubscriberURI(String subscriberURI) { this.subscriberURI = subscriberURI; } - + public String getSipSubscriberURI() { return subscriberURI; } public String getOutboundInterface() { return outboundInterface; - } - + } + public void onDialogTimeout(Dialog dialog) { if(hasOngoingTransaction()) { throw new IllegalStateException("Dialog timed out, but there are active transactions."); @@ -1504,20 +1578,31 @@ public void setState(State state) { setReadyToInvalidate(true); } } - + public void onTerminatedState() { if(isValidInternal()) { + if(logger.isDebugEnabled()) { + String msg = String.format("SipSession [%s] onTerminateState, hasParent [%s], hasDerivedSessions [%s]", getId(), parentSession !=null, derivedSipSessions != null); + logger.debug(msg); + } + //switch to readyToInvalidate state here + this.setReadyToInvalidate(true); + + //evaluate if we can proceed to invalidation onReadyToInvalidate(); - if(this.parentSession != null) { - Iterator derivedSessionsIterator = parentSession.getDerivedSipSessions(); - while (derivedSessionsIterator.hasNext()) { - MobicentsSipSession mobicentsSipSession = (MobicentsSipSession) derivedSessionsIterator - .next(); - if(mobicentsSipSession.isValidInternal() && !mobicentsSipSession.isReadyToInvalidate()) { - return; - } - } - this.parentSession.onReadyToInvalidate(); + + + if(!this.isValid && this.parentSession != null) { + //Since there is a parent session, and since the current derived sip session + //is already invalidated, ask the parent session to invalidate. + //During parent session invalidation, it will check if there are more pending + //derived session and will proceed accordingly + if(logger.isDebugEnabled()) { + String msg = String.format("SipSession [%s] onTerminateState hasParentSession [%s] that will ask to onReadyToInvalidate()", key, parentSession.getKey()); + logger.debug(msg); + } + + this.parentSession.onReadyToInvalidate(); } } } @@ -1526,8 +1611,8 @@ public void onTerminatedState() { * Add an ongoing tx to the session. */ public void addOngoingTransaction(Transaction transaction) { - - if(transaction != null && ongoingTransactions != null && !isReadyToInvalidate() ) { + + if(transaction != null && ongoingTransactions != null && !isReadyToInvalidate() ) { boolean added = this.ongoingTransactions.add(transaction); if(added) { if(logger.isDebugEnabled()) { @@ -1537,7 +1622,7 @@ public void addOngoingTransaction(Transaction transaction) { } } } - + /** * Remove an ongoing tx to the session. */ @@ -1546,40 +1631,40 @@ public void removeOngoingTransaction(Transaction transaction) { if(this.ongoingTransactions != null) { removed = this.ongoingTransactions.remove(transaction); } - + // if(sessionCreatingTransactionRequest != null && sessionCreatingTransactionRequest.getMessage() != null && JainSipUtils.DIALOG_CREATING_METHODS.contains(sessionCreatingTransactionRequest.getMethod())) { // sessionCreatingTransactionRequest = null; // } - + if (proxy != null) { proxy.removeTransaction(transaction.getBranchId()); } - + if(logger.isDebugEnabled()) { logger.debug("transaction "+ transaction +" has been removed from sip session's ongoingTransactions ? " + removed ); - } - + } + updateReadyToInvalidate(transaction); // nullify the sessionCreatingTransactionRequest only after updateReadyToInvalidate as it is used for error response checking - + final String branchId = transaction.getBranchId(); - if(sessionCreatingTransactionRequest != null && + if(sessionCreatingTransactionRequest != null && branchId != null) { - - // https://github.com/RestComm/sip-servlets/issues/101 fix for NPE happening due to concurrent behavior cleaning the transaction + + // https://github.com/RestComm/sip-servlets/issues/101 fix for NPE happening due to concurrent behavior cleaning the transaction final Transaction sessionCreatingTransactionRequestTransaction = sessionCreatingTransactionRequest.getTransaction(); String sessionCreatingTransactionRequestTransactionBranchId = null; if(sessionCreatingTransactionRequestTransaction != null) { sessionCreatingTransactionRequestTransactionBranchId = sessionCreatingTransactionRequestTransaction.getBranchId(); } final String sessionCreatingTransactionRequestMethod = sessionCreatingTransactionRequest.getMethod(); - - if(sessionCreatingTransactionRequestTransaction != null && + + if(sessionCreatingTransactionRequestTransaction != null && branchId.equals(sessionCreatingTransactionRequestTransactionBranchId)) { - + if(logger.isDebugEnabled()) { - logger.debug("Session " + key + ": cleaning up "+ sessionCreatingTransactionRequest - + " since transaction " + transaction + " with branch id " + branchId + logger.debug("Session " + key + ": cleaning up "+ sessionCreatingTransactionRequest + + " since transaction " + transaction + " with branch id " + branchId + " is the same as sessionCreatingRequestTransaction " + sessionCreatingTransactionRequestTransaction + " with branch id " + sessionCreatingTransactionRequestTransactionBranchId + " and method " + sessionCreatingTransactionRequestMethod); @@ -1588,22 +1673,28 @@ public void removeOngoingTransaction(Transaction transaction) { // https://telestax.atlassian.net/browse/MSS-153 improve performance by cleaning the request for dialog based requests // or proxy case or dialog creating methods if(sessionCreatingDialog != null || proxy != null || JainSipUtils.DIALOG_CREATING_METHODS.contains(sessionCreatingTransactionRequestMethod)) { + if(logger.isDebugEnabled()) { + logger.debug("removeOngoingTransaction - sessionCreatingTransactionRequest=" + sessionCreatingTransactionRequest); + } if(logger.isDebugEnabled() && sessionCreatingTransactionRequest != null) { - logger.debug("nullifying sessionCreatingTransactionRequest" + sessionCreatingTransactionRequest + logger.debug("nullifying sessionCreatingTransactionRequest" + sessionCreatingTransactionRequest + " from Session " + key); } + if(logger.isDebugEnabled()) { + logger.debug("invalidate - setting the sessionCreatingTransactionRequest to null, id:" + this.getId()); + } sessionCreatingTransactionRequest = null; } } } } - + public void cleanDialogInformation(boolean terminate) { if(logger.isDebugEnabled()) { logger.debug("cleanDialogInformation "+ sessionCreatingDialog); logger.debug("cleanDialogInformation terminate "+ terminate); } - if(sessionCreatingDialog != null && sessionCreatingDialog.getApplicationData() != null && + if(sessionCreatingDialog != null && sessionCreatingDialog.getApplicationData() != null && ((TransactionApplicationData)sessionCreatingDialog.getApplicationData()).getSipServletMessage() != null) { TransactionApplicationData dialogAppData = ((TransactionApplicationData)sessionCreatingDialog.getApplicationData()); SipServletMessageImpl sipServletMessage = dialogAppData.getSipServletMessage(); @@ -1626,14 +1717,14 @@ public void cleanDialogInformation(boolean terminate) { logger.debug("cleaning non INVITE Dialog creating method " + sipServletMessage.getMethod()); } cleanDialog = true; - } + } // Dialog Terminating request will be cleaned up on invalidation } if(logger.isDebugEnabled()) { logger.debug("cleanDialog "+ cleanDialog); logger.debug("cleanDialog terminate "+ terminate); } - // https://telestax.atlassian.net/browse/MSS-153 + // https://telestax.atlassian.net/browse/MSS-153 // if we are not an INVITE Based Dialog (but still dialog creating or terminating) or we are INVITE but ACK have been received, we can clean up the app data of its servletmessage to clean memory if(cleanDialog || terminate) { if(logger.isDebugEnabled()) { @@ -1647,12 +1738,12 @@ public void cleanDialogInformation(boolean terminate) { } } } - - + + public Set getOngoingTransactions() { return this.ongoingTransactions; - } - + } + /** * Update the sip session state upon sending/receiving a response * Covers JSR 289 Section 6.2.1 along with updateStateOnRequest method @@ -1661,7 +1752,7 @@ public Set getOngoingTransactions() { */ public void updateStateOnResponse(MobicentsSipServletResponse response, boolean receive) { final String method = response.getMethod(); - + if(sipSessionSecurity != null && response.getStatus() >= 200 && response.getStatus() < 300) { // Issue 2173 http://code.google.com/p/mobicents/issues/detail?id=2173 // it means some credentials were cached need to check if we need to store the nextnonce if the response have one @@ -1671,16 +1762,16 @@ public void updateStateOnResponse(MobicentsSipServletResponse response, boolean if(logger.isDebugEnabled()) { logger.debug("Storing nextNonce " + nextNonce + " for session " + key); } - sipSessionSecurity.setNextNonce(nextNonce); + sipSessionSecurity.setNextNonce(nextNonce); } - + } // JSR 289 Section 6.2.1 Point 2 of rules governing the state of SipSession - // In general, whenever a non-dialog creating request is sent or received, - // the SipSession state remains unchanged. Similarly, a response received - // for a non-dialog creating request also leaves the SipSession state unchanged. - // The exception to the general rule is that it does not apply to requests (e.g. BYE, CANCEL) - // that are dialog terminating according to the appropriate RFC rules relating to the kind of dialog. + // In general, whenever a non-dialog creating request is sent or received, + // the SipSession state remains unchanged. Similarly, a response received + // for a non-dialog creating request also leaves the SipSession state unchanged. + // The exception to the general rule is that it does not apply to requests (e.g. BYE, CANCEL) + // that are dialog terminating according to the appropriate RFC rules relating to the kind of dialog. if(!JainSipUtils.DIALOG_CREATING_METHODS.contains(method) && !JainSipUtils.DIALOG_TERMINATING_METHODS.contains(method)) { if(getSessionCreatingDialog() == null && proxy == null) { @@ -1690,11 +1781,11 @@ public void updateStateOnResponse(MobicentsSipServletResponse response, boolean logger.debug("resetting the to tag since a response to a non dialog creating and terminating method has been received for non proxy session with no dialog in state " + state); } key.setToTag(null, false); - + // https://github.com/Mobicents/sip-servlets/issues/36 - // Memory leak: SipAppSession and contained SipSessions are not cleaned-up + // Memory leak: SipAppSession and contained SipSessions are not cleaned-up // for non dialog creating requests after a 2xx response is received. - // This code sets these SipSessions to ReadyToInvalidate. + // This code sets these SipSessions to ReadyToInvalidate. // Applications that want to create susbequent requests (re REGISTER) should call sipSession.setInvalidateWhenReady(false); if ( state != null && State.INITIAL.equals(state) && response.getStatus() >= 200 && response.getStatus() != 407 && response.getStatus() != 401) { @@ -1707,10 +1798,10 @@ public void updateStateOnResponse(MobicentsSipServletResponse response, boolean return; } // Mapping to the sip session state machine (proxy is covered here too) - if( (State.INITIAL.equals(state) || State.EARLY.equals(state)) && - response.getStatus() >= 200 && response.getStatus() < 300 && + if( (State.INITIAL.equals(state) || State.EARLY.equals(state)) && + response.getStatus() >= 200 && response.getStatus() < 300 && !JainSipUtils.DIALOG_TERMINATING_METHODS.contains(method)) { - this.setState(State.CONFIRMED); + this.setState(State.CONFIRMED); if(this.proxy != null && response.getProxyBranch() != null && !response.getProxyBranch().getRecordRoute()) { // Section 6.2.4.1.2 Invalidate When Ready Mechanism : // "The container determines the SipSession to be in the ready-to-invalidate state under any of the following conditions: @@ -1730,19 +1821,19 @@ public void updateStateOnResponse(MobicentsSipServletResponse response, boolean if(logger.isDebugEnabled()) { logger.debug("the following sip session " + getKey() + " has its state updated to " + state); } - } - if( (State.INITIAL.equals(state) || State.EARLY.equals(state)) && + } + if( (State.INITIAL.equals(state) || State.EARLY.equals(state)) && response.getStatus() >= 300 && response.getStatus() < 700 && - JainSipUtils.DIALOG_CREATING_METHODS.contains(method) && + JainSipUtils.DIALOG_CREATING_METHODS.contains(method) && !JainSipUtils.DIALOG_TERMINATING_METHODS.contains(method)) { - // If the servlet acts as a UAC and sends a dialog creating request, - // then the SipSession state tracks directly the SIP dialog state except - // that non-2XX final responses received in the EARLY or INITIAL states + // If the servlet acts as a UAC and sends a dialog creating request, + // then the SipSession state tracks directly the SIP dialog state except + // that non-2XX final responses received in the EARLY or INITIAL states // cause the SipSession state to return to the INITIAL state rather than going to TERMINATED. // + - // If the servlet acts as a proxy for a dialog creating request then - // the SipSession state tracks the SIP dialog state except that non-2XX - // final responses received from downstream in the EARLY or INITIAL states + // If the servlet acts as a proxy for a dialog creating request then + // the SipSession state tracks the SIP dialog state except that non-2XX + // final responses received from downstream in the EARLY or INITIAL states // cause the SipSession state to return to INITIAL rather than going to TERMINATED. if(receive) { if(proxy == null) { @@ -1752,31 +1843,31 @@ public void updateStateOnResponse(MobicentsSipServletResponse response, boolean } key.setToTag(null, false); } - setState(State.INITIAL); -// readyToInvalidate = true; + setState(State.INITIAL); +// readyToInvalidate = true; if(logger.isDebugEnabled()) { logger.debug("the following sip session " + getKey() + " has its state updated to " + state); } - } - // If the servlet acts as a UAS and receives a dialog creating request, - // then the SipSession state directly tracks the SIP dialog state. - // Unlike a UAC, a non-2XX final response sent by the UAS in the EARLY or INITIAL + } + // If the servlet acts as a UAS and receives a dialog creating request, + // then the SipSession state directly tracks the SIP dialog state. + // Unlike a UAC, a non-2XX final response sent by the UAS in the EARLY or INITIAL // states causes the SipSession state to go directly to the TERMINATED state. // + - // This enables proxy servlets to proxy requests to additional destinations - // when called by the container in the doResponse() method for a tentative - // non-2XX best response. - // After all such additional proxy branches have been responded to and after - // considering any servlet created responses, the container eventually arrives at - // the overall best response and forwards this response upstream. - // If this best response is a non-2XX final response, then when the forwarding takes place, + // This enables proxy servlets to proxy requests to additional destinations + // when called by the container in the doResponse() method for a tentative + // non-2XX best response. + // After all such additional proxy branches have been responded to and after + // considering any servlet created responses, the container eventually arrives at + // the overall best response and forwards this response upstream. + // If this best response is a non-2XX final response, then when the forwarding takes place, // the state of the SipSession object becomes TERMINATED. else { setState(State.TERMINATED); if(logger.isDebugEnabled()) { logger.debug("the following sip session " + getKey() + " has its state updated to " + state); } - } + } } if(((State.CONFIRMED.equals(state) || State.TERMINATED.equals(state)) && response.getStatus() >= 200 && Request.BYE.equals(method) // https://code.google.com/p/sipservlets/issues/detail?id=194 @@ -1785,7 +1876,7 @@ public void updateStateOnResponse(MobicentsSipServletResponse response, boolean // Sip Session become TERMINATED after receiving 487 response to subsequent request => !confirmed clause added || (!State.CONFIRMED.equals(state) && response.getStatus() == 487)) { boolean hasOngoingSubscriptions = false; - if(subscriptions != null) { + if(subscriptions != null) { if(subscriptions.size() > 0) { hasOngoingSubscriptions = true; } @@ -1797,7 +1888,7 @@ public void updateStateOnResponse(MobicentsSipServletResponse response, boolean sessionCreatingDialog.delete(); } } - } + } if(!hasOngoingSubscriptions) { if(getProxy() == null || response.getStatus() != 487) { setState(State.TERMINATED); @@ -1810,36 +1901,36 @@ public void updateStateOnResponse(MobicentsSipServletResponse response, boolean if(logger.isDebugEnabled()) { logger.debug("the following sip session " + getKey() + " has its state updated to " + state); } - okToByeSentOrReceived = true; + okToByeSentOrReceived = true; } // we send the CANCEL only for 1xx responses if(response.getTransactionApplicationData().isCanceled() && response.getStatus() < 200 && !response.getMethod().equals(Request.CANCEL)) { SipServletRequestImpl request = (SipServletRequestImpl) response.getTransactionApplicationData().getSipServletMessage(); if(logger.isDebugEnabled()) { - logger.debug("request to cancel " + request + " routingstate " + request.getRoutingState() + - " requestCseq " + ((MessageExt)request.getMessage()).getCSeqHeader().getSeqNumber() + + logger.debug("request to cancel " + request + " routingstate " + request.getRoutingState() + + " requestCseq " + ((MessageExt)request.getMessage()).getCSeqHeader().getSeqNumber() + " responseCseq " + ((MessageExt)response.getMessage()).getCSeqHeader().getSeqNumber()); } - if(!request.getRoutingState().equals(RoutingState.CANCELLED) && - ((MessageExt)request.getMessage()).getCSeqHeader().getSeqNumber() == + if(!request.getRoutingState().equals(RoutingState.CANCELLED) && + ((MessageExt)request.getMessage()).getCSeqHeader().getSeqNumber() == ((MessageExt)response.getMessage()).getCSeqHeader().getSeqNumber()) { if(response.getStatus() > 100) { request.setRoutingState(RoutingState.CANCELLED); } try { - request.createCancel().send(); + request.createCancel().send(); } catch (IOException e) { if(logger.isEnabledFor(Priority.WARN)) { logger.warn("Couldn't send CANCEL for a transaction that has been CANCELLED but " + "CANCEL was not sent because there was no response from the other side. We" + - " just stopped the retransmissions." + response + "\nThe transaction" + + " just stopped the retransmissions." + response + "\nThe transaction" + response.getTransaction(), e); } } } } } - + /** * Update the sip session state upon sending/receiving a subsequent request * Covers JSR 289 Section 6.2.1 along with updateStateOnResponse method @@ -1848,40 +1939,55 @@ public void updateStateOnResponse(MobicentsSipServletResponse response, boolean */ public void updateStateOnSubsequentRequest( MobicentsSipServletRequest request, boolean receive) { + if(logger.isDebugEnabled()) { + logger.debug("updateStateOnSubsequentRequest - request=" + request + ", receive=" + receive); + } //state updated to TERMINATED for CANCEL only if no final response had been received on the inviteTransaction if(((Request.CANCEL.equalsIgnoreCase(request.getMethod())))) { + if(logger.isDebugEnabled()) { + logger.debug("updateStateOnSubsequentRequest - CANCEL, request.getMethod()=" + request.getMethod()); + } if(!(request.getTransaction() instanceof ServerTransactionExt)) { return; } final Transaction inviteTransaction = ((ServerTransactionExt) request.getTransaction()).getCanceledInviteTransaction(); - TransactionApplicationData inviteAppData = (TransactionApplicationData) - inviteTransaction.getApplicationData(); + TransactionApplicationData inviteAppData = (TransactionApplicationData) + inviteTransaction.getApplicationData(); SipServletRequestImpl inviteRequest = (SipServletRequestImpl)inviteAppData.getSipServletMessage(); // Issue 1484 : http://code.google.com/p/mobicents/issues/detail?id=1484 // we terminate the session only for initial requests - if((inviteRequest != null && inviteRequest.isInitial() && inviteRequest.getLastFinalResponse() == null) || + if(logger.isDebugEnabled()) { + logger.debug("updateStateOnSubsequentRequest - CANCEL - inviteRequest=" + inviteRequest); + } + if((inviteRequest != null && inviteRequest.isInitial() && inviteRequest.getLastFinalResponse() == null) || (proxy != null && proxy.getBestResponse() == null)) { + if(logger.isDebugEnabled()) { + logger.debug("updateStateOnSubsequentRequest - CANCEL - setting state to terminated"); + } this.setState(State.TERMINATED); if(logger.isDebugEnabled()) { logger.debug("the following sip session " + getKey() + " has its state updated to " + state); } } } - + if(Request.ACK.equalsIgnoreCase(request.getMethod())) { + if(logger.isDebugEnabled()) { + logger.debug("updateStateOnSubsequentRequest - ACK, sessionCreatingTransactionRequest=" + sessionCreatingTransactionRequest); + } if(sessionCreatingTransactionRequest != null) { sessionCreatingTransactionRequest.cleanUpLastResponses(); } } - + } - - + + private void updateReadyToInvalidate(Transaction transaction) { // Section 6.2.4.1.2 Invalidate When Ready Mechanism : // "The container determines the SipSession to be in the ready-to-invalidate state under any of the following conditions: - // 3. A SipSession acting as a UAC transitions from the EARLY state back to + // 3. A SipSession acting as a UAC transitions from the EARLY state back to // the INITIAL state on account of receiving a non-2xx final response (6.2.1 Relationship to SIP Dialogs, point 4) // and has not initiated any new requests (does not have any pending transactions)." if(logger.isDebugEnabled()) { @@ -1891,36 +1997,80 @@ private void updateReadyToInvalidate(Transaction transaction) { logger.debug("ongoingTransactions " + null + " for sipsession " + key); } } - if(!readyToInvalidate && (ongoingTransactions == null || ongoingTransactions.isEmpty()) && - transaction instanceof ClientTransaction && getProxy() == null && - state != null && state.equals(State.INITIAL) && + if(!readyToInvalidate && (ongoingTransactions == null || ongoingTransactions.isEmpty()) && + transaction instanceof ClientTransaction && getProxy() == null && + state != null && state.equals(State.INITIAL) && // Fix for Issue 1734 - sessionCreatingTransactionRequest != null && - sessionCreatingTransactionRequest.getLastFinalResponse() != null && + sessionCreatingTransactionRequest != null && + sessionCreatingTransactionRequest.getLastFinalResponse() != null && sessionCreatingTransactionRequest.getLastFinalResponse().getStatus() >= 300) { setReadyToInvalidate(true); } } - + + /** + * + * @return true if session is part of B2BUA but not linked to any session. + */ + public boolean isB2BUAOrphan() { + boolean b2bUAOrphan = getB2buaHelper() != null && + !getB2buaHelper().getSessionMap().isEmpty() && + getB2buaHelper().getLinkedSession(this) == null; + if(logger.isDebugEnabled()) { + logger.debug("isB2BUAOrphan:" + b2bUAOrphan); + } + return b2bUAOrphan; + } /** * This method is called immediately when the conditions for read to invalidate * session are met */ public void onReadyToInvalidate() { - this.setReadyToInvalidate(true); - + + if (isB2BUAOrphan()) { + logger.debug("Session is B2BUA Orphaned, lets invalidate"); + setReadyToInvalidate(true); + } + + if (!readyToInvalidate) { + logger.debug("Session not ready to invalidate, wait next chance."); + return; + } + + boolean allDerivedReady = true; + Iterator derivedSessionsIterator = this.getDerivedSipSessions(); + while (derivedSessionsIterator.hasNext()) { + MobicentsSipSession mobicentsSipSession = (MobicentsSipSession) derivedSessionsIterator + .next(); + boolean derivedIsOrphaned = mobicentsSipSession.isB2BUAOrphan(); + boolean derivedReady = !mobicentsSipSession.isValid() || derivedIsOrphaned; + allDerivedReady = allDerivedReady & derivedReady; + } + + if(logger.isDebugEnabled()) { + String msg = String.format("Session [%s] onReadyToInvalidate, hasParent [%s], hasDerivedSessions [%s], will invalidate [%s]", key, parentSession != null, derivedSipSessions != null, allDerivedReady); + logger.debug(msg); + } + + if (!allDerivedReady) { + logger.debug("Cant invalidate yet, lets wait until all derived to be ready."); + return; + } else { + logger.debug("All Derived ready, lets proceed."); + } + if(logger.isDebugEnabled()) { logger.debug("invalidateWhenReady flag is set to " + invalidateWhenReady); } - + if(isValid() && this.invalidateWhenReady) { this.notifySipSessionListeners(SipSessionEventType.READYTOINVALIDATE); - //If the application does not explicitly invalidate the session in the callback or has not defined a listener, - //the container will invalidate the session. + //If the application does not explicitly invalidate the session in the callback or has not defined a listener, + //the container will invalidate the session. if(isValid()) { invalidate(true); } - } + } } /** @@ -1949,21 +2099,34 @@ public ProxyImpl getProxy() { public void setProxy(MobicentsProxy proxy) { this.proxy = (ProxyImpl) proxy; } - + /** * {@inheritDoc} */ public void setB2buaHelper(MobicentsB2BUAHelper helperImpl) { - this.b2buaHelper = (B2buaHelperImpl) helperImpl; + logger.debug("setting B2BUAHelper"); + SipApplicationSession applicationSession = getApplicationSession(); + if (this.isValid && applicationSession.isValid()) { + applicationSession.setAttribute(B2buaHelperImpl.B2BUA_ATT_NAME, helperImpl); + logger.debug("B2BUAHelper set"); + } } - + /** * {@inheritDoc} */ public B2buaHelperImpl getB2buaHelper() { - return this.b2buaHelper; + B2buaHelperImpl helper = null; + SipApplicationSession applicationSession = getApplicationSession(); + if (this.isValid && applicationSession.isValid()) { + helper = (B2buaHelperImpl) applicationSession.getAttribute(B2buaHelperImpl.B2BUA_ATT_NAME); + } + if (logger.isDebugEnabled()) { + logger.debug("B2BUAHelper got:" + helper); + } + return helper; } - + /** * Perform the internal processing required to passivate * this session. @@ -1988,12 +2151,12 @@ public void passivate() { } } } - + /** * Perform internal processing required to activate this * session. */ - public void activate() { + public void activate() { // Notify ActivationListeners SipSessionEvent event = null; if(sipSessionAttributeMap != null) { @@ -2013,29 +2176,29 @@ public void activate() { } } } - + public SipPrincipal getUserPrincipal() { return userPrincipal; } - + public void setUserPrincipal(SipPrincipal userPrincipal) { this.userPrincipal = userPrincipal; } - + public boolean getInvalidateWhenReady() { if(!isValid()) { throw new IllegalStateException("the session has been invalidated"); } return invalidateWhenReady; } - + public boolean isReadyToInvalidate() { if(!isValid()) { throw new IllegalStateException("the session has been invalidated"); } return readyToInvalidate; } - + /** * @param readyToInvalidate the readyToInvalidate to set */ @@ -2049,14 +2212,14 @@ public void setReadyToInvalidate(boolean readyToInvalidate) { public boolean isReadyToInvalidateInternal() { return readyToInvalidate; } - + public void setInvalidateWhenReady(boolean arg0) { if(!isValid()) { throw new IllegalStateException("the session has been invalidated"); } invalidateWhenReady = arg0; } - + /* * (non-Javadoc) * @see javax.servlet.sip.SipSession#setOutboundInterface(java.net.InetAddress) @@ -2067,7 +2230,7 @@ public void setOutboundInterface(InetAddress inetAddress) { } if(inetAddress == null) { throw new NullPointerException("parameter is null"); - } + } String address = inetAddress.getHostAddress(); List list = sipFactory.getSipNetworkInterfaceManager().getOutboundInterfaces(); SipURI networkInterface = null; @@ -2077,9 +2240,9 @@ public void setOutboundInterface(InetAddress inetAddress) { break; } } - + if(networkInterface == null) throw new IllegalArgumentException("Network interface for " + - address + " not found"); + address + " not found"); try { outboundInterface = new SipURIImpl(SipFactoryImpl.addressFactory.createSipURI(null, address), ModifiableRule.NotModifiable).toString(); } catch (ParseException e) { @@ -2099,7 +2262,7 @@ public void setOutboundInterface(InetSocketAddress inetSocketAddress) { } if(inetSocketAddress == null) { throw new NullPointerException("parameter is null"); - } + } String address = inetSocketAddress.getAddress().getHostAddress() + ":" + inetSocketAddress.getPort(); List list = sipFactory.getSipNetworkInterfaceManager().getOutboundInterfaces(); SipURI networkInterface = null; @@ -2109,7 +2272,7 @@ public void setOutboundInterface(InetSocketAddress inetSocketAddress) { break; } } - + if(networkInterface == null) throw new IllegalArgumentException("Network interface for " + address + " not found"); try { @@ -2120,7 +2283,7 @@ public void setOutboundInterface(InetSocketAddress inetSocketAddress) { throw new IllegalArgumentException("Could not create SIP URI user = " + null + " host = " + address); } } - + /* * (non-Javadoc) * @see org.mobicents.javax.servlet.sip.SipSessionExt#setOutboundInterface(javax.servlet.sip.SipURI) @@ -2131,7 +2294,7 @@ public void setOutboundInterface(SipURI outboundInterface) { } if(outboundInterface == null) { throw new NullPointerException("parameter is null"); - } + } List list = sipFactory.getSipNetworkInterfaceManager().getOutboundInterfaces(); SipURI networkInterface = null; for(SipURI networkInterfaceURI : list) { @@ -2140,7 +2303,7 @@ public void setOutboundInterface(SipURI outboundInterface) { break; } } - + if(networkInterface == null) throw new IllegalArgumentException("Network interface for " + outboundInterface + " not found"); this.outboundInterface = outboundInterface.toString(); @@ -2148,14 +2311,14 @@ public void setOutboundInterface(SipURI outboundInterface) { this.transport = outboundInterface.getTransportParam(); } } - + /** * {@inheritDoc} */ public ServletContext getServletContext() { return getSipApplicationSession().getSipContext().getServletContext(); } - + /* * (non-Javadoc) * @see org.mobicents.servlet.sip.core.session.MobicentsSipSession#removeDerivedSipSession(java.lang.String) @@ -2174,18 +2337,18 @@ public MobicentsSipSession findDerivedSipSession(String toTag) { } return null; } - + private void dumpDerivedSipSessions() { if(logger.isDebugEnabled()) { logger.debug("derived sessions contained in the following sip session " + key); if(derivedSipSessions != null) { for (MobicentsSipSession session: derivedSipSessions.values()) { - logger.debug("derived session " + session + " " + isValidInternal + " " + readyToInvalidate + " " + state); + logger.debug("derived session " + session + " isValidInternal " + session.isValidInternal() + " readyToInvalidate " + session.isReadyToInvalidate() + " state " + session.getState()); } } } } - + /* * (non-Javadoc) * @see org.mobicents.servlet.sip.core.session.MobicentsSipSession#getDerivedSipSessions() @@ -2196,7 +2359,7 @@ public Iterator getDerivedSipSessions() { } return new HashMap().values().iterator(); } - + /* * (non-Javadoc) * @see org.mobicents.servlet.sip.core.session.MobicentsSipSession#setParentSession(org.mobicents.servlet.sip.core.session.MobicentsSipSession) @@ -2204,7 +2367,7 @@ public Iterator getDerivedSipSessions() { public void setParentSession(MobicentsSipSession mobicentsSipSession) { parentSession = mobicentsSipSession; } - + /* * (non-Javadoc) * @see org.mobicents.servlet.sip.core.session.MobicentsSipSession#getParentSession() @@ -2212,7 +2375,7 @@ public void setParentSession(MobicentsSipSession mobicentsSipSession) { public MobicentsSipSession getParentSession() { return parentSession; } - + /* * (non-Javadoc) * @see org.mobicents.servlet.sip.core.session.MobicentsSipSession#setSipSessionAttributeMap(java.util.Map) @@ -2252,14 +2415,14 @@ public void setLocalParty(Address localParty) { public void setRemoteParty(Address remoteParty) { this.remoteParty = remoteParty; } - + /** * {@inheritDoc} */ public void addSubscription(MobicentsSipServletMessage sipServletMessageImpl) throws SipException { EventHeader eventHeader = null; if(sipServletMessageImpl instanceof SipServletResponseImpl) { - eventHeader = (EventHeader) ((SipServletRequestImpl)((SipServletResponseImpl)sipServletMessageImpl).getRequest()).getMessage().getHeader(EventHeader.NAME); + eventHeader = (EventHeader) ((SipServletRequestImpl)((SipServletResponseImpl)sipServletMessageImpl).getRequest()).getMessage().getHeader(EventHeader.NAME); } else { eventHeader = (EventHeader) sipServletMessageImpl.getMessage().getHeader(EventHeader.NAME); } @@ -2270,8 +2433,8 @@ public void addSubscription(MobicentsSipServletMessage sipServletMessageImpl) th if(subscriptions == null) { this.subscriptions = new CopyOnWriteArraySet(); } - subscriptions.add(eventHeader.toString()); - + subscriptions.add(eventHeader.toString()); + if(logger.isDebugEnabled()) { logger.debug("Request from Original Transaction is " + originalMethod); logger.debug("Dialog is " + sessionCreatingDialog); @@ -2281,7 +2444,7 @@ public void addSubscription(MobicentsSipServletMessage sipServletMessageImpl) th } } } - + /** * {@inheritDoc} */ @@ -2297,12 +2460,12 @@ public void removeSubscription(MobicentsSipServletMessage sipServletMessageImpl) if(subscriptions.size() > 0) { hasOngoingSubscriptions = true; } - if(!hasOngoingSubscriptions) { + if(!hasOngoingSubscriptions) { if(subscriptions.size() < 1) { if((originalMethod != null && okToByeSentOrReceived) || !Request.INVITE.equals(originalMethod) ) { setState(State.TERMINATED); } - } + } } } } @@ -2321,11 +2484,11 @@ public void removeSubscription(MobicentsSipServletMessage sipServletMessageImpl) public Semaphore getSemaphore() { return semaphore; } - - public MobicentsSipSessionFacade getFacade() { - MobicentsSipApplicationSession sipApplicationSession = getSipApplicationSession(); + + public MobicentsSipSessionFacade getFacade() { + MobicentsSipApplicationSession sipApplicationSession = getSipApplicationSession(); if (facade == null && sipApplicationSession != null){ - SipContext sipContext = sipApplicationSession.getSipContext(); + SipContext sipContext = sipApplicationSession.getSipContext(); if (sipContext.isPackageProtectionEnabled()){ final MobicentsSipSession fsession = this; facade = (MobicentsSipSessionFacade)AccessController.doPrivileged(new PrivilegedAction(){ @@ -2337,7 +2500,7 @@ public Object run(){ facade = new MobicentsSipSessionFacade(this); } } - return (facade); + return (facade); } @Override public boolean equals(Object obj) { @@ -2347,7 +2510,7 @@ public boolean equals(Object obj) { // Issue 2365 : Derived Sessions should be equal only if their to tag is equal if(sipSession.getKey().getToTag() == null && getKey().getToTag() == null) { return true; - } + } if(sipSession.getKey().getToTag() != null && getKey().getToTag() != null && sipSession.getKey().getToTag().equals(getKey().getToTag())) { return true; } else { @@ -2374,7 +2537,7 @@ public void setNextSipApplicationRouterInfo( SipApplicationRouterInfo routerInfo) { this.nextSipApplicationRouterInfo = routerInfo; } - + /** * Setting ackReceived for CSeq to specified value in second param. * if the second param is true it will try to cleanup earlier cseq as well to save on memory @@ -2390,7 +2553,7 @@ public void setAckReceived(long cSeq, boolean ackReceived) { cleanupAcksReceived(cSeq); } } - + /** * check if the ack has been received for the cseq in param * it may happen that the ackReceived has been removed already if that's the case it will return true @@ -2399,8 +2562,8 @@ public void setAckReceived(long cSeq, boolean ackReceived) { */ protected boolean isAckReceived(long cSeq) { if(acksReceived == null) { - // http://code.google.com/p/sipservlets/issues/detail?id=152 - // if there is no map, it means that the session was already destroyed and it is a retransmission + // http://code.google.com/p/sipservlets/issues/detail?id=152 + // if there is no map, it means that the session was already destroyed and it is a retransmission return true; } Boolean ackReceived = acksReceived.get(cSeq); @@ -2408,12 +2571,12 @@ protected boolean isAckReceived(long cSeq) { logger.debug("isAckReceived for CSeq " + cSeq +" : " + ackReceived); } if(ackReceived == null) { - // if there is no value for it it means that it is a retransmission + // if there is no value for it it means that it is a retransmission return true; } return ackReceived; } - + /** * We clean up the stored acks received when the remoteCSeq in param is greater and * that the ackReceived is true @@ -2430,30 +2593,30 @@ protected void cleanupAcksReceived(long remoteCSeq) { toBeRemoved.add(cSeq); } } - for(Long cSeq: toBeRemoved) { + for(Long cSeq: toBeRemoved) { acksReceived.remove(cSeq); if(logger.isDebugEnabled()) { logger.debug("removed ackReceived for CSeq " + cSeq); } } } - + public long getCseq() { return cseq; } public void setCseq(long cseq) { - this.cseq = cseq; + this.cseq = cseq; } //CSeq validation should only be done for non proxy applications public boolean validateCSeq(MobicentsSipServletRequest sipServletRequest) { final Request request = (Request) sipServletRequest.getMessage(); - final long localCseq = cseq; + final long localCseq = cseq; final long remoteCSeq = ((CSeqHeader) request.getHeader(CSeqHeader.NAME)).getSeqNumber(); final String method = request.getMethod(); final boolean isAck = Request.ACK.equalsIgnoreCase(method); final boolean isPrackCancel= Request.PRACK.equalsIgnoreCase(method) || Request.CANCEL.equalsIgnoreCase(method); boolean resetLocalCSeq = true; - + if(isAck && isAckReceived(remoteCSeq)) { // Filter out ACK retransmissions for JSIP patch for http://code.google.com/p/mobicents/issues/detail?id=766 logger.debug("ACK filtered out as a retransmission. This Sip Session already has been ACKed."); @@ -2463,13 +2626,13 @@ public boolean validateCSeq(MobicentsSipServletRequest sipServletRequest) { if(logger.isDebugEnabled()) { logger.debug("localCSeq : " + localCseq + ", remoteCSeq : " + remoteCSeq); } - setAckReceived(remoteCSeq, true); - } + setAckReceived(remoteCSeq, true); + } if(localCseq == remoteCSeq && !isAck) { logger.debug("dropping retransmission " + request + " since it matches the current sip session cseq " + localCseq); return false; - } - if(localCseq > remoteCSeq) { + } + if(localCseq > remoteCSeq) { if(!isAck && !isPrackCancel) { logger.error("CSeq out of order for the following request " + sipServletRequest); if(Request.INVITE.equalsIgnoreCase(method)) { @@ -2482,11 +2645,11 @@ public boolean validateCSeq(MobicentsSipServletRequest sipServletRequest) { logger.error("Can not send error response", e); } return false; - } else { + } else { // Issue 1714 : if the local cseq is greater then the remote one don't reset the local cseq resetLocalCSeq= false; } - } + } if(logger.isDebugEnabled()) { logger.debug("resetLocalCSeq : " + resetLocalCSeq); } @@ -2495,17 +2658,17 @@ public boolean validateCSeq(MobicentsSipServletRequest sipServletRequest) { if(Request.INVITE.equalsIgnoreCase(method)) { setAckReceived(remoteCSeq, false); } - } + } return true; } - + public String getTransport() { return transport; } public void setTransport(String transport) { this.transport = transport; } - + /* * (non-Javadoc) * @see org.mobicents.javax.servlet.sip.SipSessionExt#scheduleAsynchronousWork(org.mobicents.javax.servlet.sip.SipSessionAsynchronousWork) @@ -2517,12 +2680,12 @@ public int getRequestsPending() { return requestsPending; } public void setRequestsPending(int requests) { - // Sometimes the count might not match due to retransmissing of ACK after OK is missing or CANCEL, + // Sometimes the count might not match due to retransmissing of ACK after OK is missing or CANCEL, // we should never go negative here if(requests < 0) requests = 0; requestsPending = requests; } - + /* * (non-Javadoc) * @see org.mobicents.javax.servlet.sip.SipSessionExt#setCopyRecordRouteHeadersOnSubsequentResponses(boolean) @@ -2553,7 +2716,7 @@ public MobicentsSipSessionSecurity getSipSessionSecurity() { } return sipSessionSecurity; } - + public void acquire() { if(semaphore != null) { if(logger.isDebugEnabled()) { @@ -2561,11 +2724,11 @@ public void acquire() { } try { while(!semaphore.tryAcquire(30000, TimeUnit.MILLISECONDS)){ - logger.warn("Failed to acquire session semaphore " + + logger.warn("Failed to acquire session semaphore " + semaphore + " for 30 secs. We will unlock the " + "semaphore no matter what because the " + "transaction is about to timeout. THIS " + - "MIGHT ALSO BE CONCURRENCY CONTROL RISK." + + "MIGHT ALSO BE CONCURRENCY CONTROL RISK." + " sip Session is" + this); semaphore.release(); } @@ -2577,7 +2740,7 @@ public void acquire() { } } } - + public void release() { if(semaphore != null) { if(logger.isDebugEnabled()) { @@ -2595,7 +2758,7 @@ public void release() { } } if(semaphore.availablePermits()<0) { - logger.warn("About to release semaphore but we expected permits = 0. We will adjust to normal " + logger.warn("About to release semaphore but we expected permits = 0. We will adjust to normal " + semaphore + " sip session=" + this); while(semaphore.availablePermits()<0) { try { @@ -2603,15 +2766,15 @@ public void release() { } catch (Exception e) { } } - } - + } + semaphore.release(); if(logger.isDebugEnabled()) { logger.debug("After Semaphore released for sipSession=" + this + " semaphore=" + semaphore); } } } - + /* * (non-Javadoc) * @see org.mobicents.servlet.sip.core.session.MobicentsSipSession#setFlow(javax.sip.address.SipURI) diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipSessionsUtilImpl.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipSessionsUtilImpl.java index ea3acd776a..2e146d7421 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipSessionsUtilImpl.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/session/SipSessionsUtilImpl.java @@ -71,6 +71,9 @@ public SipApplicationSession getApplicationSessionById(String applicationSession * @see org.mobicents.javax.servlet.sip.SipSessionsUtilExt#getApplicationSessionById(java.lang.String, boolean) */ public SipApplicationSession getApplicationSessionById(String applicationSessionId, boolean isContainerManaged) { + if(logger.isDebugEnabled()) { + logger.debug("getApplicationSessionById - applicationSessionId=" + applicationSessionId); + } if(applicationSessionId == null) { throw new NullPointerException("the given id is null !"); } @@ -113,6 +116,10 @@ public SipApplicationSession getApplicationSessionByKey(String applicationSessio */ public SipApplicationSession getApplicationSessionByKey(String applicationSessionKey, boolean create, boolean isContainerManaged) { + if(logger.isDebugEnabled()) { + logger.debug("getApplicationSessionByKey - applicationSessionKey=" + applicationSessionKey); + } + if(applicationSessionKey == null) { throw new NullPointerException("the given key is null !"); } diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/timers/DefaultProxyTimerService.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/timers/DefaultProxyTimerService.java index 8fa2308507..c816bc761b 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/timers/DefaultProxyTimerService.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/timers/DefaultProxyTimerService.java @@ -56,6 +56,11 @@ public DefaultProxyTimerService(int corePoolSize) { super(corePoolSize); schedulePurgeTaskIfNeeded(); } + + public DefaultProxyTimerService(String applicationName, int corePoolSize) { + super(corePoolSize, new NamingThreadFactory(applicationName + "_sip_default_proxy_timer_service")); + schedulePurgeTaskIfNeeded(); + } /** * @param corePoolSize diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/timers/ProxyTimerServiceImpl.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/timers/ProxyTimerServiceImpl.java index 9d7366cf82..9c4b829ec7 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/timers/ProxyTimerServiceImpl.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/timers/ProxyTimerServiceImpl.java @@ -109,6 +109,9 @@ public void schedule(TimerTask task, long delay) { * @see org.mobicents.servlet.sip.core.timers.ProxyTimerService#stop() */ public void stop() { + if(logger.isDebugEnabled()) { + logger.debug("stop"); + } started.set(false); super.cancel(); if(logger.isDebugEnabled()) { @@ -120,6 +123,9 @@ public void stop() { * @see org.mobicents.servlet.sip.core.timers.ProxyTimerService#start() */ public void start() { + if(logger.isDebugEnabled()) { + logger.debug("start"); + } started.set(true); if(logger.isDebugEnabled()) { logger.debug("Started proxy timer service "+ this); diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/timers/ServletTimerImpl.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/timers/ServletTimerImpl.java index 4dec23815b..fa4318252d 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/timers/ServletTimerImpl.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/core/timers/ServletTimerImpl.java @@ -131,6 +131,22 @@ public ServletTimerImpl(Serializable info, long delay, this(info, delay, false, 0, listener, appSession); isRepeatingTimer = false; } + + /** + * Constructor for non-repeating timer. + * + * @param info + * Information about the timer + * @param delay + * Delay until execution + * @param listener + * Listener that will get timeout events. + */ + public ServletTimerImpl(Serializable info, String timerId, long delay, + TimerListener listener, MobicentsSipApplicationSession appSession) { + this(info, timerId, delay, false, 0, listener, appSession); + isRepeatingTimer = false; + } /** * Constructor for repeating times @@ -149,7 +165,29 @@ public ServletTimerImpl(Serializable info, long delay, public ServletTimerImpl(Serializable info, long delay, boolean fixedDelay, long period, TimerListener listener, MobicentsSipApplicationSession appSession) { - this.id = UUID.randomUUID().toString(); + this(info, UUID.randomUUID().toString(), delay, fixedDelay, period, listener, appSession); + } + + /** + * Constructor for repeating times + * + * @param info + * Information about the timer + * @param timerId + * ID of this timer + * @param delay + * Delay until first execution + * @param fixedDelay + * Whether fixed delay mode should be used + * @param period + * Period between execution + * @param listener + * Listener that will get timeout events. + */ + public ServletTimerImpl(Serializable info, String timerId, long delay, boolean fixedDelay, + long period, TimerListener listener, + MobicentsSipApplicationSession appSession) { + this.id = timerId; this.info = info; this.delay = delay; this.scheduledExecutionTime = delay + System.currentTimeMillis(); @@ -218,7 +256,9 @@ public long getPeriod() { } public MobicentsSipApplicationSession getApplicationSession() { - + if(logger.isDebugEnabled()) { + logger.debug("getApplicationSession with appSessionKey=" + appSessionKey); + } synchronized (TIMER_LOCK) { return sipManager.getSipApplicationSession(appSessionKey, false); } diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/B2buaHelperImpl.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/B2buaHelperImpl.java index 2c2d23af71..6d1e7889ef 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/B2buaHelperImpl.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/B2buaHelperImpl.java @@ -19,12 +19,14 @@ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ - package org.mobicents.servlet.sip.message; import gov.nist.javax.sip.header.HeaderExt; import gov.nist.javax.sip.header.ims.PathHeader; import gov.nist.javax.sip.message.MessageExt; +import gov.nist.javax.sip.message.SIPRequest; +import gov.nist.javax.sip.stack.SIPDialog; +import gov.nist.javax.sip.stack.SIPTransaction; import java.io.Serializable; import java.text.ParseException; @@ -37,8 +39,10 @@ import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import javax.servlet.ServletContext; import javax.servlet.ServletException; +import javax.servlet.sip.SipApplicationSession; import javax.servlet.sip.SipServletMessage; import javax.servlet.sip.SipServletRequest; import javax.servlet.sip.SipServletResponse; @@ -52,7 +56,9 @@ import javax.sip.ListeningPoint; import javax.sip.ServerTransaction; import javax.sip.Transaction; +import javax.sip.TransactionAlreadyExistsException; import javax.sip.TransactionState; +import javax.sip.TransactionUnavailableException; import javax.sip.address.SipURI; import javax.sip.address.URI; import javax.sip.header.CSeqHeader; @@ -70,11 +76,14 @@ import org.apache.log4j.Logger; import org.mobicents.ha.javax.sip.SipLoadBalancer; import org.mobicents.servlet.sip.JainSipUtils; +import org.mobicents.servlet.sip.address.AddressImpl; +import org.mobicents.servlet.sip.address.AddressImpl.ModifiableRule; import org.mobicents.servlet.sip.core.ApplicationRoutingHeaderComposer; import org.mobicents.servlet.sip.core.MobicentsExtendedListeningPoint; import org.mobicents.servlet.sip.core.MobicentsSipFactory; import org.mobicents.servlet.sip.core.RoutingState; import org.mobicents.servlet.sip.core.SipApplicationDispatcher; +import static org.mobicents.servlet.sip.core.SipContext.INTERNAL_ATT_PREFIX; import org.mobicents.servlet.sip.core.SipManager; import org.mobicents.servlet.sip.core.b2bua.MobicentsB2BUAHelper; import org.mobicents.servlet.sip.core.message.MobicentsSipServletMessage; @@ -87,18 +96,22 @@ /** * Implementation of the B2BUA helper class. - * - * + * + * * @author mranga * @author Jean Deruelle */ - public class B2buaHelperImpl implements MobicentsB2BUAHelper, Serializable { - private static final long serialVersionUID = 1L; + + private static final long serialVersionUID = 1L; private static final Logger logger = Logger.getLogger(B2buaHelperImpl.class); - + protected static final Set B2BUA_SYSTEM_HEADERS = new HashSet(); + + private static final String ORIG_REQ_ATT_NAME = INTERNAL_ATT_PREFIX + ".originalRequest"; + public static final String B2BUA_ATT_NAME = INTERNAL_ATT_PREFIX + ".B2BUAHelper"; + static { B2BUA_SYSTEM_HEADERS.add(CallIdHeader.NAME); B2BUA_SYSTEM_HEADERS.add(CSeqHeader.NAME); @@ -106,327 +119,382 @@ public class B2buaHelperImpl implements MobicentsB2BUAHelper, Serializable { // Fix http://code.google.com/p/mobicents/issues/detail?id=3060 // B2buaHelper.createRequest method throws IllegalArgumentException when "Route" header is included in "headerMap" // B2BUA_SYSTEM_HEADERS.add(RouteHeader.NAME); - B2BUA_SYSTEM_HEADERS.add(RecordRouteHeader.NAME); - B2BUA_SYSTEM_HEADERS.add(PathHeader.NAME); - } - - // contact parameters not allowed to be modified as per JSR 289 Section 4.1.3 - protected static final Set CONTACT_FORBIDDEN_PARAMETER = new HashSet(); - static { - CONTACT_FORBIDDEN_PARAMETER.add("method"); - CONTACT_FORBIDDEN_PARAMETER.add("ttl"); - CONTACT_FORBIDDEN_PARAMETER.add("maddr"); - CONTACT_FORBIDDEN_PARAMETER.add("lr"); - } - - //Map to handle linked sessions - private Map sessionMap = null; - //Map to handle linked derived sessions - private Map derivedSessionMap = null; - - //Map to handle responses to original request and cancel on original request - // Issue 1550 http://code.google.com/p/mobicents/issues/detail?id=1550 - // IllegalStateException: Cannot create a response - not a server transaction gov.nist.javax.sip.stack.SIPClientTransaction - // this map should be able to handle multiple linked requests at the same time - private transient Map originalRequestMap = null; - - private transient SipFactoryImpl sipFactoryImpl; - - private transient SipManager sipManager; - - public B2buaHelperImpl() { - sessionMap = new ConcurrentHashMap(); - derivedSessionMap = new ConcurrentHashMap(); - originalRequestMap = new ConcurrentHashMap(); - } - - /* - * (non-Javadoc) - * @see javax.servlet.sip.B2buaHelper#createRequest(javax.servlet.sip.SipServletRequest, boolean, java.util.Map) - */ - public SipServletRequest createRequest(SipServletRequest origRequest, - boolean linked, Map> headerMap) throws TooManyHopsException { - - if(origRequest == null) { - throw new NullPointerException("original request cannot be null"); - } - - if(origRequest.getMaxForwards() == 0) { - throw new TooManyHopsException(); - } - - try { - final SipServletRequestImpl origRequestImpl = (SipServletRequestImpl) origRequest; - Request newRequest = (Request) origRequestImpl.message.clone(); - ((MessageExt)newRequest).setApplicationData(null); - //content should be copied too, so commented out -// newRequest.removeContent(); - //removing the via header from original request - newRequest.removeHeader(ViaHeader.NAME); - - // Remove the route header ( will point to us ). - // commented as per issue 649 + B2BUA_SYSTEM_HEADERS.add(RecordRouteHeader.NAME); + B2BUA_SYSTEM_HEADERS.add(PathHeader.NAME); + } + + // contact parameters not allowed to be modified as per JSR 289 Section 4.1.3 + protected static final Set CONTACT_FORBIDDEN_PARAMETER = new HashSet(); + + static { + CONTACT_FORBIDDEN_PARAMETER.add("method"); + CONTACT_FORBIDDEN_PARAMETER.add("ttl"); + CONTACT_FORBIDDEN_PARAMETER.add("maddr"); + CONTACT_FORBIDDEN_PARAMETER.add("lr"); + } + + //Map to handle linked sessions + private Map sessionMap = null; + + //Map to handle responses to linked request and cancel on linked request + // Issue 1550 http://code.google.com/p/mobicents/issues/detail?id=1550 + // IllegalStateException: Cannot create a response - not a server transaction gov.nist.javax.sip.stack.SIPClientTransaction + // this map should be able to handle multiple linked requests at the same time + private transient Map linkedRequestMap = null; + + private transient SipFactoryImpl sipFactoryImpl; + + private transient SipManager sipManager; + + public B2buaHelperImpl() { + logger.debug("creating new B2BUAhelper"); + sessionMap = new ConcurrentHashMap(); + linkedRequestMap = new ConcurrentHashMap(); + } + + public SipServletRequestImpl cloneDerivedRequest(SipServletRequestImpl origRequestImpl, MobicentsSipSession parentSession) throws TransactionAlreadyExistsException, TransactionUnavailableException { + SIPRequest newRequest = (SIPRequest) origRequestImpl.message.clone(); + String newToTag = ApplicationRoutingHeaderComposer.getHash(sipFactoryImpl.getSipApplicationDispatcher(), + parentSession.getKey().getApplicationName(), + parentSession.getKey().getApplicationSessionId()); + if (logger.isDebugEnabled()) { + logger.debug("derived session has no linked forked session yet, lazily creating one with new ToTag " + newToTag); + } + SipSessionKey newDerivedKey = new SipSessionKey(parentSession.getKey().getFromTag(), + newToTag, + parentSession.getKey().getCallId(), + parentSession.getKey().getApplicationSessionId(), + parentSession.getKey().getApplicationName()); + MobicentsSipSession newDerivedSesion = sipManager.getSipSession(newDerivedKey, false, null, parentSession.getSipApplicationSession()); + + SIPTransaction transaction = (SIPTransaction) origRequestImpl.getTransaction(); + //set transaction dialog to null to force creation of new dialog on server side + if (transaction instanceof ServerTransaction) { + logger.debug("Setting dialog to null on server transaction"); + transaction.setDialog(null, null); + } + + SipServletRequestImpl sipServletRequestImpl = (SipServletRequestImpl) sipFactoryImpl.getMobicentsSipServletMessageFactory().createSipServletRequest(newRequest, + newDerivedSesion, + transaction, + null, + origRequestImpl.getDialog() != null); + sipServletRequestImpl.setLinkedRequest(origRequestImpl.getLinkedRequest()); + sipServletRequestImpl.setPoppedRoute(origRequestImpl.getPoppedRouteHeader()); + sipServletRequestImpl.setSubscriberURI(origRequestImpl.getSubscriberURI()); + sipServletRequestImpl.setAttributeMap(origRequestImpl.getAttributeMap()); + + newDerivedSesion.setSessionCreatingDialog(null); + newDerivedSesion.setAckReceived(newRequest.getCSeq().getSeqNumber(), false); + newDerivedSesion.setB2buaHelper(this); + newDerivedSesion.setSessionCreatingTransactionRequest(sipServletRequestImpl); + setOriginalRequest(newDerivedSesion, sipServletRequestImpl); + return sipServletRequestImpl; + } + + private SipServletRequestImpl cloneRequest(SipServletRequestImpl origRequestImpl, Map> headerMap) throws ParseException, ServletException { + Request newRequest = (Request) origRequestImpl.message.clone(); + ((MessageExt) newRequest).setApplicationData(null); + //content should be copied too, so commented out +// newRequest.removeContent(); + //removing the via header from original request + newRequest.removeHeader(ViaHeader.NAME); + + // Remove the route header ( will point to us ). + // commented as per issue 649 // newRequest.removeHeader(RouteHeader.NAME); // String tag = Integer.toString((int) (Math.random()*1000)); // ((FromHeader) newRequest.getHeader(FromHeader.NAME)).setParameter("tag", tag); - - // Remove the record route headers. This is a new call leg. - newRequest.removeHeader(RecordRouteHeader.NAME); - - // Issue 1490 : http://code.google.com/p/mobicents/issues/detail?id=1490 - // B2buaHelper.createRequest does not decrement Max-forwards - MaxForwardsHeader maxForwardsHeader = (MaxForwardsHeader) newRequest.getHeader(MaxForwardsHeader.NAME); - try { - maxForwardsHeader.setMaxForwards(maxForwardsHeader.getMaxForwards() -1); - } catch (InvalidArgumentException e) { - throw new IllegalArgumentException(e); - } - - //Creating new call id - final Iterator listeningPointsIterator = sipFactoryImpl.getSipNetworkInterfaceManager().getExtendedListeningPoints(); - if(!listeningPointsIterator.hasNext()) { - throw new IllegalStateException("There is no SIP connectors available to create the request"); - } - final MobicentsExtendedListeningPoint extendedListeningPoint = listeningPointsIterator.next(); - final CallIdHeader callIdHeader = sipFactoryImpl.getSipApplicationDispatcher().getCallId(extendedListeningPoint, null); - newRequest.setHeader(callIdHeader); - - final List contactHeaderSet = retrieveContactHeaders(headerMap, - newRequest); - final FromHeader newFromHeader = (FromHeader) newRequest.getHeader(FromHeader.NAME); - newFromHeader.removeParameter("tag"); - ((ToHeader) newRequest.getHeader(ToHeader.NAME)) - .removeParameter("tag"); - - final MobicentsSipSession originalSession = origRequestImpl.getSipSession(); - final MobicentsSipApplicationSession appSession = originalSession - .getSipApplicationSession(); - - newFromHeader.setTag(ApplicationRoutingHeaderComposer.getHash(sipFactoryImpl.getSipApplicationDispatcher(), originalSession.getKey().getApplicationName(), appSession.getKey().getId())); - - final MobicentsSipSessionKey key = SessionManagerUtil.getSipSessionKey(appSession.getKey().getId(), originalSession.getKey().getApplicationName(), newRequest, false); - final MobicentsSipSession session = appSession.getSipContext().getSipManager().getSipSession(key, true, sipFactoryImpl, appSession); - session.setHandler(originalSession.getHandler()); - - - // cater to http://code.google.com/p/sipservlets/issues/detail?id=31 to be able to set the rport in applications - final SipApplicationDispatcher sipApplicationDispatcher = sipFactoryImpl.getSipApplicationDispatcher(); - final String branch = JainSipUtils.createBranch(appSession.getKey().getId(), sipApplicationDispatcher.getHashFromApplicationName(appSession.getKey().getApplicationName())); - ViaHeader viaHeader = JainSipUtils.createViaHeader( - sipFactoryImpl.getSipNetworkInterfaceManager(), newRequest, branch, session.getOutboundInterface()); - newRequest.addHeader(viaHeader); - - final SipServletRequestImpl newSipServletRequest = (SipServletRequestImpl) sipFactoryImpl.getMobicentsSipServletMessageFactory().createSipServletRequest( - newRequest, - session, - null, - null, - JainSipUtils.DIALOG_CREATING_METHODS.contains(newRequest.getMethod())); - //JSR 289 Section 15.1.6 - newSipServletRequest.setRoutingDirective(SipApplicationRoutingDirective.CONTINUE, origRequest); - - final String method = origRequest.getMethod(); - // For non-REGISTER requests, the Contact header field is not copied but is populated by the container as usual but if Contact header is present in the headerMap - // then relevant portions of Contact header is to be used in the request created, in accordance with section 4.1.3 of the specification. - if(Request.REGISTER.equalsIgnoreCase(method)) { - // Issue 2565 http://code.google.com/p/mobicents/issues/detail?id=2565 - // So if the request is REGISTER the Contact Header field is copied and is used - if(contactHeaderSet.size() > 0) { - // And additional contact from the map are added + stripping the forbidden params - for (String contactHeaderValue : contactHeaderSet) { - newSipServletRequest.addHeaderInternal(ContactHeader.NAME, contactHeaderValue, true); - } - ListIterator contactHeaders = newSipServletRequest.getMessage().getHeaders(ContactHeader.NAME); - while (contactHeaders.hasNext()) { - final URI contactURI = contactHeaders.next().getAddress().getURI(); - // and reset its user part and params accoridng to 4.1.3 The Contact Header Field - if(contactURI instanceof SipURI) { - stripForbiddenContactURIParams((SipURI)contactURI); - } - } - } - } else { - newRequest.removeHeader(ContactHeader.NAME); - //Creating container contact header - ContactHeader contactHeader = null; - String fromName = null; - String diaplayName = newFromHeader.getAddress().getDisplayName(); - if(newFromHeader.getAddress().getURI() instanceof javax.sip.address.SipURI) { - fromName = ((javax.sip.address.SipURI) newFromHeader.getAddress().getURI()).getUser(); - } - // if a sip load balancer is present in front of the server, the contact header is the one from the sip lb - // so that the subsequent requests can be failed over - if(sipFactoryImpl.isUseLoadBalancer()) { - MobicentsExtendedListeningPoint listeningPoint = JainSipUtils.findListeningPoint(sipFactoryImpl.getSipNetworkInterfaceManager(), newRequest, session.getOutboundInterface()); - if(listeningPoint != null && listeningPoint.isUseLoadBalancer()) { - // https://github.com/RestComm/sip-servlets/issues/137 - SipLoadBalancer loadBalancerToUse = null; - if(listeningPoint.getLoadBalancer() == null) { - loadBalancerToUse = sipFactoryImpl.getLoadBalancerToUse(); - if(logger.isDebugEnabled()) { - logger.debug("Using listeningPoint " + listeningPoint + " for global load balancer " + sipFactoryImpl.getLoadBalancerToUse()); - } - } else { - loadBalancerToUse = listeningPoint.getLoadBalancer(); - if(logger.isDebugEnabled()) { - logger.debug("Using listeningPoint " + listeningPoint + " for connector specific load balancer " + listeningPoint.getLoadBalancer()); - } - } - - javax.sip.address.SipURI sipURI = sipFactoryImpl.getAddressFactory().createSipURI(fromName, loadBalancerToUse.getAddress().getHostAddress()); - sipURI.setHost(loadBalancerToUse.getAddress().getHostAddress()); - sipURI.setPort(loadBalancerToUse.getSipPort()); - sipURI.setTransportParam(ListeningPoint.UDP); - javax.sip.address.Address contactAddress = sipFactoryImpl.getAddressFactory().createAddress(sipURI); - if(diaplayName != null && diaplayName.length() > 0) { - contactAddress.setDisplayName(diaplayName); - } - contactHeader = sipFactoryImpl.getHeaderFactory().createContactHeader(contactAddress); - } else { - if(logger.isDebugEnabled()) { - logger.debug("Not Using load balancer as it is not enabled for listeningPoint " + listeningPoint); - } - contactHeader = JainSipUtils.createContactHeader(sipFactoryImpl.getSipNetworkInterfaceManager(), newRequest, diaplayName, fromName, session.getOutboundInterface()); - } - } else { - contactHeader = JainSipUtils.createContactHeader(sipFactoryImpl.getSipNetworkInterfaceManager(), newRequest, diaplayName, fromName, session.getOutboundInterface()); - } - if(contactHeaderSet.size() > 0) { - // if the set is not empty then we adjust the values of the set to match the host and port + forbidden params of the container - setContactHeaders(contactHeaderSet, newSipServletRequest, contactHeader); - } else if(JainSipUtils.CONTACT_HEADER_METHODS.contains(method)) { - // otherwise we set the container contact header for allowed methods - newRequest.setHeader(contactHeader); - } - } - - originalRequestMap.put(newSipServletRequest, origRequestImpl); - originalRequestMap.put(origRequestImpl, newSipServletRequest); - - if (linked) { - sessionMap.put(originalSession.getKey(), session.getKey()); - sessionMap.put(session.getKey(), originalSession.getKey()); - dumpLinkedSessions(); - } - session.setB2buaHelper(this); - originalSession.setB2buaHelper(this); - session.setSessionCreatingTransactionRequest(newSipServletRequest); - - return newSipServletRequest; - } catch (ParseException ex) { - logger.error("Unexpected parse exception ", ex); - throw new IllegalArgumentException( - "Illegal arg encountered while creating b2bua", ex); - } catch (ServletException ex) { - logger.error("Unexpected exception ", ex); - throw new IllegalArgumentException( - "Unexpected problem while creating b2bua", ex); - } - } + // Remove the record route headers. This is a new call leg. + newRequest.removeHeader(RecordRouteHeader.NAME); - /* + // Issue 1490 : http://code.google.com/p/mobicents/issues/detail?id=1490 + // B2buaHelper.createRequest does not decrement Max-forwards + MaxForwardsHeader maxForwardsHeader = (MaxForwardsHeader) newRequest.getHeader(MaxForwardsHeader.NAME); + try { + maxForwardsHeader.setMaxForwards(maxForwardsHeader.getMaxForwards() - 1); + } catch (InvalidArgumentException e) { + throw new IllegalArgumentException(e); + } + + //Creating new call id + final Iterator listeningPointsIterator = sipFactoryImpl.getSipNetworkInterfaceManager().getExtendedListeningPoints(); + if (!listeningPointsIterator.hasNext()) { + throw new IllegalStateException("There is no SIP connectors available to create the request"); + } + final MobicentsExtendedListeningPoint extendedListeningPoint = listeningPointsIterator.next(); + final CallIdHeader callIdHeader = sipFactoryImpl.getSipApplicationDispatcher().getCallId(extendedListeningPoint, null); + newRequest.setHeader(callIdHeader); + + final List contactHeaderSet = retrieveContactHeaders(headerMap, + newRequest, origRequestImpl.getSession().getServletContext()); + final FromHeader newFromHeader = (FromHeader) newRequest.getHeader(FromHeader.NAME); + newFromHeader.removeParameter("tag"); + ((ToHeader) newRequest.getHeader(ToHeader.NAME)) + .removeParameter("tag"); + + final MobicentsSipSession originalSession = origRequestImpl.getSipSession(); + final MobicentsSipApplicationSession appSession = originalSession + .getSipApplicationSession(); + + newFromHeader.setTag(ApplicationRoutingHeaderComposer.getHash(sipFactoryImpl.getSipApplicationDispatcher(), originalSession.getKey().getApplicationName(), appSession.getKey().getId())); + + final MobicentsSipSessionKey key = SessionManagerUtil.getSipSessionKey(appSession.getKey().getId(), originalSession.getKey().getApplicationName(), newRequest, false); + final MobicentsSipSession session = appSession.getSipContext().getSipManager().getSipSession(key, true, sipFactoryImpl, appSession); + session.setHandler(originalSession.getHandler()); + + // cater to http://code.google.com/p/sipservlets/issues/detail?id=31 to be able to set the rport in applications + final SipApplicationDispatcher sipApplicationDispatcher = sipFactoryImpl.getSipApplicationDispatcher(); + final String branch = JainSipUtils.createBranch(appSession.getKey().getId(), sipApplicationDispatcher.getHashFromApplicationName(appSession.getKey().getApplicationName())); + ViaHeader viaHeader = JainSipUtils.createViaHeader( + sipFactoryImpl.getSipNetworkInterfaceManager(), newRequest, branch, session.getOutboundInterface()); + newRequest.addHeader(viaHeader); + + final SipServletRequestImpl newSipServletRequest = (SipServletRequestImpl) sipFactoryImpl.getMobicentsSipServletMessageFactory().createSipServletRequest( + newRequest, + session, + null, + null, + JainSipUtils.DIALOG_CREATING_METHODS.contains(newRequest.getMethod())); + //JSR 289 Section 15.1.6 + newSipServletRequest.setRoutingDirective(SipApplicationRoutingDirective.CONTINUE, origRequestImpl); + + final String method = origRequestImpl.getMethod(); + // For non-REGISTER requests, the Contact header field is not copied but is populated by the container as usual but if Contact header is present in the headerMap + // then relevant portions of Contact header is to be used in the request created, in accordance with section 4.1.3 of the specification. + if (Request.REGISTER.equalsIgnoreCase(method)) { + // Issue 2565 http://code.google.com/p/mobicents/issues/detail?id=2565 + // So if the request is REGISTER the Contact Header field is copied and is used + if (contactHeaderSet.size() > 0) { + // And additional contact from the map are added + stripping the forbidden params + for (String contactHeaderValue : contactHeaderSet) { + newSipServletRequest.addHeaderInternal(ContactHeader.NAME, contactHeaderValue, true); + } + ListIterator contactHeaders = newSipServletRequest.getMessage().getHeaders(ContactHeader.NAME); + while (contactHeaders.hasNext()) { + final URI contactURI = contactHeaders.next().getAddress().getURI(); + // and reset its user part and params accoridng to 4.1.3 The Contact Header Field + if (contactURI instanceof SipURI) { + stripForbiddenContactURIParams((SipURI) contactURI); + } + } + } + } else { + newRequest.removeHeader(ContactHeader.NAME); + //Creating container contact header + ContactHeader contactHeader = null; + String fromName = null; + String diaplayName = newFromHeader.getAddress().getDisplayName(); + if (newFromHeader.getAddress().getURI() instanceof javax.sip.address.SipURI) { + fromName = ((javax.sip.address.SipURI) newFromHeader.getAddress().getURI()).getUser(); + } + // if a sip load balancer is present in front of the server, the contact header is the one from the sip lb + // so that the subsequent requests can be failed over + if (sipFactoryImpl.isUseLoadBalancer()) { + MobicentsExtendedListeningPoint listeningPoint = JainSipUtils.findListeningPoint(sipFactoryImpl.getSipNetworkInterfaceManager(), newRequest, session.getOutboundInterface()); + if (listeningPoint != null && listeningPoint.isUseLoadBalancer()) { + // https://github.com/RestComm/sip-servlets/issues/137 + SipLoadBalancer loadBalancerToUse = null; + if (listeningPoint.getLoadBalancer() == null) { + loadBalancerToUse = sipFactoryImpl.getLoadBalancerToUse(); + if (logger.isDebugEnabled()) { + logger.debug("Using listeningPoint " + listeningPoint + " for global load balancer " + sipFactoryImpl.getLoadBalancerToUse()); + } + } else { + loadBalancerToUse = listeningPoint.getLoadBalancer(); + if (logger.isDebugEnabled()) { + logger.debug("Using listeningPoint " + listeningPoint + " for connector specific load balancer " + listeningPoint.getLoadBalancer()); + } + } + + javax.sip.address.SipURI sipURI = sipFactoryImpl.getAddressFactory().createSipURI(fromName, loadBalancerToUse.getAddress().getHostAddress()); + sipURI.setHost(loadBalancerToUse.getAddress().getHostAddress()); + sipURI.setPort(loadBalancerToUse.getSipPort()); + sipURI.setTransportParam(ListeningPoint.UDP); + javax.sip.address.Address contactAddress = sipFactoryImpl.getAddressFactory().createAddress(sipURI); + if (diaplayName != null && diaplayName.length() > 0) { + contactAddress.setDisplayName(diaplayName); + } + contactHeader = sipFactoryImpl.getHeaderFactory().createContactHeader(contactAddress); + } else { + if (logger.isDebugEnabled()) { + logger.debug("Not Using load balancer as it is not enabled for listeningPoint " + listeningPoint); + } + contactHeader = JainSipUtils.createContactHeader(sipFactoryImpl.getSipNetworkInterfaceManager(), newRequest, diaplayName, fromName, session.getOutboundInterface()); + } + } else { + contactHeader = JainSipUtils.createContactHeader(sipFactoryImpl.getSipNetworkInterfaceManager(), newRequest, diaplayName, fromName, session.getOutboundInterface()); + } + if (contactHeaderSet.size() > 0) { + // if the set is not empty then we adjust the values of the set to match the host and port + forbidden params of the container + setContactHeaders(contactHeaderSet, newSipServletRequest, contactHeader); + } else if (JainSipUtils.CONTACT_HEADER_METHODS.contains(method)) { + // otherwise we set the container contact header for allowed methods + newRequest.setHeader(contactHeader); + } + } + + return newSipServletRequest; + } + + /* + * (non-Javadoc) + * @see javax.servlet.sip.B2buaHelper#createRequest(javax.servlet.sip.SipServletRequest, boolean, java.util.Map) + */ + public SipServletRequest createRequest(SipServletRequest origRequest, + boolean linked, Map> headerMap) throws TooManyHopsException { + + if (origRequest == null) { + throw new NullPointerException("original request cannot be null"); + } + + if (origRequest.getMaxForwards() == 0) { + throw new TooManyHopsException(); + } + + try { + SipServletRequestImpl origRequestImpl = (SipServletRequestImpl) origRequest; + SipServletRequestImpl newSipServletRequest = cloneRequest(origRequestImpl, headerMap); + final MobicentsSipSession originalSession = origRequestImpl.getSipSession(); + final MobicentsSipApplicationSession appSession = originalSession + .getSipApplicationSession(); + final MobicentsSipSessionKey key = SessionManagerUtil.getSipSessionKey(appSession.getKey().getId(), originalSession.getKey().getApplicationName(), newSipServletRequest.getMessage(), false); + final MobicentsSipSession session = appSession.getSipContext().getSipManager().getSipSession(key, true, sipFactoryImpl, appSession); + + linkedRequestMap.put(newSipServletRequest, origRequestImpl); + linkedRequestMap.put(origRequestImpl, newSipServletRequest); + + if (linked) { + sessionMap.put(originalSession.getId(), session.getId()); + sessionMap.put(session.getId(), originalSession.getId()); + dumpLinkedSessions(); + } + session.setB2buaHelper(this); + originalSession.setB2buaHelper(this); + session.setSessionCreatingTransactionRequest(newSipServletRequest); + setOriginalRequest(session, newSipServletRequest); + + return newSipServletRequest; + } catch (ParseException ex) { + logger.error("Unexpected parse exception ", ex); + throw new IllegalArgumentException( + "Illegal arg encountered while creating b2bua", ex); + } catch (ServletException ex) { + logger.error("Unexpected exception ", ex); + throw new IllegalArgumentException( + "Unexpected problem while creating b2bua", ex); + } + } + + /* * (non-Javadoc) * @see javax.servlet.sip.B2buaHelper#createRequest(javax.servlet.sip.SipSession, javax.servlet.sip.SipServletRequest, java.util.Map) */ public SipServletRequest createRequest(SipSession session, SipServletRequest origRequest, Map> headerMap) { - - if(origRequest == null) { - throw new NullPointerException("original request cannot be null"); - } - + + if (logger.isDebugEnabled()) { + logger.debug("createRequest - session=" + session + ", origRequest=" + origRequest); + } + + if (origRequest == null) { + throw new NullPointerException("original request cannot be null"); + } + try { final SipServletRequestImpl origRequestImpl = (SipServletRequestImpl) origRequest; final MobicentsSipSession originalSession = origRequestImpl.getSipSession(); final MobicentsSipSession sessionImpl = (MobicentsSipSession) session; final SipServletRequestImpl newSubsequentServletRequest = (SipServletRequestImpl) session.createRequest(origRequest.getMethod()); - - //For non-REGISTER requests, the Contact header field is not copied - //but is populated by the container as usual - - //commented since this is not true in this case since this is a subsequent request - // this is needed for sending challenge requests + + //For non-REGISTER requests, the Contact header field is not copied + //but is populated by the container as usual + //commented since this is not true in this case since this is a subsequent request + // this is needed for sending challenge requests // if(!Request.REGISTER.equalsIgnoreCase(origRequest.getMethod())) { // newSubsequentServletRequest.getMessage().removeHeader(ContactHeader.NAME); // } - //If Contact header is present in the headerMap - //then relevant portions of Contact header is to be used in the request created, - //in accordance with section 4.1.3 of the specification. - //They will be added later after the sip servlet request has been created - final List contactHeaderSet = retrieveContactHeaders(headerMap, - (Request) newSubsequentServletRequest.getMessage()); - - //If Contact header is present in the headerMap - //then relevant portions of Contact header is to be used in the request created, - //in accordance with section 4.1.3 of the specification. - Request subsequentRequest = (Request)newSubsequentServletRequest.getMessage(); - - // Issue 1490 : http://code.google.com/p/mobicents/issues/detail?id=1490 - // B2buaHelper.createRequest does not decrement Max-forwards - MaxForwardsHeader maxForwardsHeader = (MaxForwardsHeader) subsequentRequest.getHeader(MaxForwardsHeader.NAME); - try { - maxForwardsHeader.setMaxForwards(maxForwardsHeader.getMaxForwards() -1); - } catch (InvalidArgumentException e) { - throw new IllegalArgumentException(e); - } - - ContactHeader contactHeader = (ContactHeader) subsequentRequest.getHeader(ContactHeader.NAME); - if(contactHeader != null && contactHeaderSet.size() > 0) { - subsequentRequest.removeHeader(ContactHeader.NAME); - setContactHeaders(contactHeaderSet, newSubsequentServletRequest, contactHeader); - } - - //Fix for Issue 585 by alexandre sova - if(origRequest.getContent() != null && origRequest.getContentType() != null) { - newSubsequentServletRequest.setContentLength(origRequest.getContentLength()); - newSubsequentServletRequest.setContent(origRequest.getContent(), origRequest.getContentType()); - } - - if(logger.isDebugEnabled()) { - logger.debug("newSubsequentServletRequest = " + newSubsequentServletRequest); - } - - // Added for Issue 1409 http://code.google.com/p/mobicents/issues/detail?id=1409 - copyNonSystemHeaders(origRequestImpl, newSubsequentServletRequest); - - originalRequestMap.put(newSubsequentServletRequest, origRequestImpl); - originalRequestMap.put(origRequestImpl, newSubsequentServletRequest); - - sessionMap.put(originalSession.getKey(), sessionImpl.getKey()); - sessionMap.put(sessionImpl.getKey(), originalSession.getKey()); - dumpLinkedSessions(); - - sessionImpl.setB2buaHelper(this); - originalSession.setB2buaHelper(this); - return newSubsequentServletRequest; - } catch (Exception ex) { - logger.error("Unexpected exception ", ex); - throw new IllegalArgumentException( - "Illegal arg encountered while creating b2bua", ex); - } - } + //If Contact header is present in the headerMap + //then relevant portions of Contact header is to be used in the request created, + //in accordance with section 4.1.3 of the specification. + //They will be added later after the sip servlet request has been created + final List contactHeaderSet = retrieveContactHeaders(headerMap, + (Request) newSubsequentServletRequest.getMessage(), + originalSession.getServletContext()); - /** - * Copies all the non system headers from the original request into the new subsequent request - * (Not needed for initial requests since a clone of the request is done) - * - * Added for Issue 1409 http://code.google.com/p/mobicents/issues/detail?id=1409 - */ - private void copyNonSystemHeaders(SipServletRequestImpl origRequestImpl, - SipServletRequestImpl newSubsequentServletRequest) { - final Message origMessage = origRequestImpl.getMessage(); - final Message subsequentMessage = newSubsequentServletRequest.getMessage(); - ListIterator headerNames = origMessage.getHeaderNames(); - while (headerNames.hasNext()) { - String headerName = headerNames.next(); - if(!JainSipUtils.SYSTEM_HEADERS.contains(headerName) && !headerName.equalsIgnoreCase(ContactHeader.NAME) - && !headerName.equalsIgnoreCase(FromHeader.NAME) && !headerName.equalsIgnoreCase(ToHeader.NAME)) { - // Issue 184 : http://code.google.com/p/sipservlets/issues/detail?id=184 - // Not all headers are copied for subsequent requests using B2buaHelper.createRequest(session, request, map) - // Fix by Alexander Saveliev, iterate through all headers and copy them + //If Contact header is present in the headerMap + //then relevant portions of Contact header is to be used in the request created, + //in accordance with section 4.1.3 of the specification. + Request subsequentRequest = (Request) newSubsequentServletRequest.getMessage(); + + // Issue 1490 : http://code.google.com/p/mobicents/issues/detail?id=1490 + // B2buaHelper.createRequest does not decrement Max-forwards + MaxForwardsHeader maxForwardsHeader = (MaxForwardsHeader) subsequentRequest.getHeader(MaxForwardsHeader.NAME); + try { + maxForwardsHeader.setMaxForwards(maxForwardsHeader.getMaxForwards() - 1); + } catch (InvalidArgumentException e) { + throw new IllegalArgumentException(e); + } + + ContactHeader contactHeader = (ContactHeader) subsequentRequest.getHeader(ContactHeader.NAME); + if (contactHeader != null && contactHeaderSet.size() > 0) { + subsequentRequest.removeHeader(ContactHeader.NAME); + setContactHeaders(contactHeaderSet, newSubsequentServletRequest, contactHeader); + } + + //Fix for Issue 585 by alexandre sova + if (origRequest.getContent() != null && origRequest.getContentType() != null) { + newSubsequentServletRequest.setContentLength(origRequest.getContentLength()); + newSubsequentServletRequest.setContent(origRequest.getContent(), origRequest.getContentType()); + } + + if (logger.isDebugEnabled()) { + logger.debug("newSubsequentServletRequest = " + newSubsequentServletRequest); + } + + // Added for Issue 1409 http://code.google.com/p/mobicents/issues/detail?id=1409 + copyNonSystemHeaders(origRequestImpl, newSubsequentServletRequest); + + linkedRequestMap.put(newSubsequentServletRequest, origRequestImpl); + linkedRequestMap.put(origRequestImpl, newSubsequentServletRequest); + + sessionMap.put(originalSession.getId(), sessionImpl.getId()); + sessionMap.put(sessionImpl.getId(), originalSession.getId()); + dumpLinkedSessions(); + + sessionImpl.setB2buaHelper(this); + originalSession.setB2buaHelper(this); + return newSubsequentServletRequest; + } catch (Exception ex) { + logger.error("Unexpected exception ", ex); + throw new IllegalArgumentException( + "Illegal arg encountered while creating b2bua", ex); + } + } + + /** + * Copies all the non system headers from the original request into the new + * subsequent request (Not needed for initial requests since a clone of the + * request is done) + * + * Added for Issue 1409 + * http://code.google.com/p/mobicents/issues/detail?id=1409 + */ + private void copyNonSystemHeaders(SipServletRequestImpl origRequestImpl, + SipServletRequestImpl newSubsequentServletRequest) { + final Message origMessage = origRequestImpl.getMessage(); + final Message subsequentMessage = newSubsequentServletRequest.getMessage(); + ListIterator headerNames = origMessage.getHeaderNames(); + while (headerNames.hasNext()) { + String headerName = headerNames.next(); + if (!JainSipUtils.SYSTEM_HEADERS.contains(headerName) && !headerName.equalsIgnoreCase(ContactHeader.NAME) + && !headerName.equalsIgnoreCase(FromHeader.NAME) && !headerName.equalsIgnoreCase(ToHeader.NAME)) { + // Issue 184 : http://code.google.com/p/sipservlets/issues/detail?id=184 + // Not all headers are copied for subsequent requests using B2buaHelper.createRequest(session, request, map) + // Fix by Alexander Saveliev, iterate through all headers and copy them ListIterator
origHeaderIt = origMessage.getHeaders(headerName); - ListIterator
subsHeaderIt = subsequentMessage.getHeaders(headerName); + ListIterator
subsHeaderIt = subsequentMessage.getHeaders(headerName); while (origHeaderIt.hasNext()) { HeaderExt origHeader = (HeaderExt) origHeaderIt.next(); // Issue http://code.google.com/p/mobicents/issues/detail?id=2094 @@ -462,150 +530,171 @@ private void copyNonSystemHeaders(SipServletRequestImpl origRequestImpl, } } } - } - } - } + } + } + } - /** - * Issue 1151 : - * For Contact header if present only the user part and some parameters are to be used as defined in 4.1.3 The Contact Header Field - * - * @param newRequest - * @param contactHeaderSet - * @param newSipServletRequest - * @param contactHeader - * @throws ParseException - */ - private void setContactHeaders( - final List contactHeaderSet, - final SipServletRequestImpl newSipServletRequest, - ContactHeader contactHeader) throws ParseException { - // we parse and add the contact headers defined in the map - Request newRequest = (Request) newSipServletRequest.getMessage(); - for (String contactHeaderValue : contactHeaderSet) { - newSipServletRequest.addHeaderInternal(ContactHeader.NAME, contactHeaderValue, true); - } - // we set up a list of contact headers to be added to the request - List newContactHeaders = new ArrayList(); - - ListIterator contactHeaders = newRequest.getHeaders(ContactHeader.NAME); - while (contactHeaders.hasNext()) { - // we clone the default Mobicents Sip Servlets Contact Header - ContactHeader newContactHeader = (ContactHeader) contactHeader.clone(); - - ContactHeader newRequestContactHeader = contactHeaders.next(); - final URI newURI = newRequestContactHeader.getAddress().getURI(); - newContactHeader.getAddress().setDisplayName(newRequestContactHeader.getAddress().getDisplayName()); - // and reset its user part and params accoridng to 4.1.3 The Contact Header Field - if(newURI instanceof SipURI) { - SipURI newSipURI = (SipURI) newURI; - SipURI newContactSipURI = (SipURI) newContactHeader.getAddress().getURI(); - ((SipURI)newContactHeader.getAddress().getURI()).setUser(newSipURI.getUser()); - Iterator uriParameters = newSipURI.getParameterNames(); - while (uriParameters.hasNext()) { - String parameter = uriParameters.next(); - if(!CONTACT_FORBIDDEN_PARAMETER.contains(parameter)) { - String value = newSipURI.getParameter(parameter); - newContactSipURI.setParameter(parameter, "".equals(value) ? null : value); - } - } - } - // reset the header params according to 4.1.3 The Contact Header Field - Iterator headerParameters = newRequestContactHeader.getParameterNames(); - while (headerParameters.hasNext()) { - String parameter = headerParameters.next(); - String value = newRequestContactHeader.getParameter(parameter); - newContactHeader.setParameter(parameter, "".equals(value) ? null : value); - } - newContactHeaders.add(newContactHeader); - } - // we remove the previously added contact headers - newRequest.removeHeader(ContactHeader.NAME); - // and set the new correct ones - for (ContactHeader newContactHeader : newContactHeaders) { - newRequest.addHeader(newContactHeader); - } - } - - private void stripForbiddenContactURIParams(SipURI contactURI) { - Iterator uriParameters = contactURI.getParameterNames(); - while (uriParameters.hasNext()) { - String parameter = uriParameters.next(); - if(CONTACT_FORBIDDEN_PARAMETER.contains(parameter)) { - contactURI.removeParameter(parameter); - uriParameters = contactURI.getParameterNames(); - } - } - } - - /** - * @param headerMap - * @param newRequest - * @return - * @throws ParseException - */ - private final List retrieveContactHeaders( - Map> headerMap, Request newRequest) - throws ParseException { - List contactHeaderList = new ArrayList(); - if(headerMap != null) { - for (Entry> entry : headerMap.entrySet()) { - final String headerName = entry.getKey(); - if(!headerName.equalsIgnoreCase(ContactHeader.NAME)) { - if(B2BUA_SYSTEM_HEADERS.contains(headerName)) { - throw new IllegalArgumentException(headerName + " in the provided map is a system header"); - } - // Fix for Issue 1002 : The header field map is then used to - // override the headers in the newly created request so the header copied from the original request is removed - if(entry.getValue().size() > 0) { - newRequest.removeHeader(headerName); - } - for (String value : entry.getValue()) { - final Header header = sipFactoryImpl.getHeaderFactory().createHeader( - headerName, value); - if(! JainSipUtils.SINGLETON_HEADER_NAMES.contains(header.getName())) { - newRequest.addHeader(header); - } else { - newRequest.setHeader(header); - } - } - } else { - contactHeaderList = headerMap.get(headerName); - } - } - } - return contactHeaderList; - } + /** + * Issue 1151 : For Contact header if present only the user part and some + * parameters are to be used as defined in 4.1.3 The Contact Header Field + * + * @param newRequest + * @param contactHeaderSet + * @param newSipServletRequest + * @param contactHeader + * @throws ParseException + */ + private void setContactHeaders( + final List contactHeaderSet, + final SipServletRequestImpl newSipServletRequest, + ContactHeader contactHeader) throws ParseException { + // we parse and add the contact headers defined in the map + Request newRequest = (Request) newSipServletRequest.getMessage(); + for (String contactHeaderValue : contactHeaderSet) { + newSipServletRequest.addHeaderInternal(ContactHeader.NAME, contactHeaderValue, true); + } + // we set up a list of contact headers to be added to the request + List newContactHeaders = new ArrayList(); - /* + ListIterator contactHeaders = newRequest.getHeaders(ContactHeader.NAME); + while (contactHeaders.hasNext()) { + // we clone the default Mobicents Sip Servlets Contact Header + ContactHeader newContactHeader = (ContactHeader) contactHeader.clone(); + + ContactHeader newRequestContactHeader = contactHeaders.next(); + final URI newURI = newRequestContactHeader.getAddress().getURI(); + newContactHeader.getAddress().setDisplayName(newRequestContactHeader.getAddress().getDisplayName()); + // and reset its user part and params accoridng to 4.1.3 The Contact Header Field + if (newURI instanceof SipURI) { + SipURI newSipURI = (SipURI) newURI; + SipURI newContactSipURI = (SipURI) newContactHeader.getAddress().getURI(); + ((SipURI) newContactHeader.getAddress().getURI()).setUser(newSipURI.getUser()); + Iterator uriParameters = newSipURI.getParameterNames(); + while (uriParameters.hasNext()) { + String parameter = uriParameters.next(); + if (!CONTACT_FORBIDDEN_PARAMETER.contains(parameter)) { + String value = newSipURI.getParameter(parameter); + newContactSipURI.setParameter(parameter, "".equals(value) ? null : value); + } + } + } + // reset the header params according to 4.1.3 The Contact Header Field + Iterator headerParameters = newRequestContactHeader.getParameterNames(); + while (headerParameters.hasNext()) { + String parameter = headerParameters.next(); + String value = newRequestContactHeader.getParameter(parameter); + newContactHeader.setParameter(parameter, "".equals(value) ? null : value); + } + newContactHeaders.add(newContactHeader); + } + // we remove the previously added contact headers + newRequest.removeHeader(ContactHeader.NAME); + // and set the new correct ones + for (ContactHeader newContactHeader : newContactHeaders) { + newRequest.addHeader(newContactHeader); + } + } + + private void stripForbiddenContactURIParams(SipURI contactURI) { + Iterator uriParameters = contactURI.getParameterNames(); + while (uriParameters.hasNext()) { + String parameter = uriParameters.next(); + if (CONTACT_FORBIDDEN_PARAMETER.contains(parameter)) { + contactURI.removeParameter(parameter); + uriParameters = contactURI.getParameterNames(); + } + } + } + + /** + * @param headerMap + * @param newRequest + * @return + * @throws ParseException + */ + private final List retrieveContactHeaders( + Map> headerMap, Request newRequest, ServletContext servCtx) + throws ParseException { + List contactHeaderList = new ArrayList(); + if (headerMap != null) { + for (Entry> entry : headerMap.entrySet()) { + final String headerName = entry.getKey(); + if (!headerName.equalsIgnoreCase(ContactHeader.NAME)) { + + if (B2BUA_SYSTEM_HEADERS.contains(headerName)) { + String overridenRuleStr = servCtx.getInitParameter(SipServletMessageImpl.SYS_HDR_MOD_OVERRIDE); + if (overridenRuleStr == null + || !AddressImpl.ModifiableRule.valueOf(overridenRuleStr).equals(ModifiableRule.Modifiable)) { + throw new IllegalArgumentException(headerName + " in the provided map is a system header"); + } + } + // Fix for Issue 1002 : The header field map is then used to + // override the headers in the newly created request so the header copied from the original request is removed + if (entry.getValue().size() > 0) { + newRequest.removeHeader(headerName); + } + for (String value : entry.getValue()) { + final Header header = sipFactoryImpl.getHeaderFactory().createHeader( + headerName, value); + if (!JainSipUtils.SINGLETON_HEADER_NAMES.contains(header.getName())) { + newRequest.addHeader(header); + } else { + newRequest.setHeader(header); + } + } + } else { + contactHeaderList = headerMap.get(headerName); + } + } + } + return contactHeaderList; + } + + /* * (non-Javadoc) * @see javax.servlet.sip.B2buaHelper#createResponseToOriginalRequest(javax.servlet.sip.SipSession, int, java.lang.String) - */ - public SipServletResponse createResponseToOriginalRequest( - SipSession session, int status, String reasonPhrase) { - - if (session == null) { - throw new NullPointerException("Null arg"); - } - final MobicentsSipSession sipSession = (MobicentsSipSession) session; - if(!sipSession.isValidInternal()) { - throw new IllegalArgumentException("sip session " + sipSession.getId() + " is invalid !"); - } - final MobicentsSipServletMessage sipServletMessageImpl = sipSession.getSessionCreatingTransactionRequest(); - if(!(sipServletMessageImpl instanceof SipServletRequestImpl)) { - throw new IllegalStateException("session creating transaction message is not a request !"); - } - final SipServletRequestImpl sipServletRequestImpl = (SipServletRequestImpl) sipServletMessageImpl; - if(RoutingState.FINAL_RESPONSE_SENT.equals(sipServletRequestImpl.getRoutingState())) { - // checked by TCK test com.bea.sipservlet.tck.agents.api.javax_servlet_sip.B2buaHelperTest.testCreateResponseToOriginalRequest101 - throw new IllegalStateException("subsequent response is inconsistent with an already sent response. a Final response has already been sent for this request " + sipServletRequestImpl); - } - if(logger.isDebugEnabled()) { - logger.debug("creating response to original request " + sipServletRequestImpl + " on session " + session); - } - return sipServletRequestImpl.createResponse(status, reasonPhrase); - } - + */ + public SipServletResponse createResponseToOriginalRequest( + SipSession session, int status, String reasonPhrase) { + + if (session == null) { + throw new NullPointerException("Null arg"); + } + final MobicentsSipSession sipSession = (MobicentsSipSession) session; + if (!sipSession.isValidInternal()) { + throw new IllegalArgumentException("sip session " + sipSession.getId() + " is invalid !"); + } + final MobicentsSipServletMessage sipServletMessageImpl = getOriginalRequest(sipSession); + if (!(sipServletMessageImpl instanceof SipServletRequestImpl)) { + throw new IllegalStateException("session creating transaction message is not a request !"); + } + final SipServletRequestImpl sipServletRequestImpl = (SipServletRequestImpl) sipServletMessageImpl; + if (RoutingState.FINAL_RESPONSE_SENT.equals(sipServletRequestImpl.getRoutingState())) { + // checked by TCK test com.bea.sipservlet.tck.agents.api.javax_servlet_sip.B2buaHelperTest.testCreateResponseToOriginalRequest101 + throw new IllegalStateException("subsequent response is inconsistent with an already sent response. a Final response has already been sent for this request " + sipServletRequestImpl); + } + if (logger.isDebugEnabled()) { + logger.debug("creating response to original request " + sipServletRequestImpl + " on session " + session); + } + + //set dialog from session in case is forked/derived + //do this before creating response so proper toTag is selected + SIPTransaction tx = (SIPTransaction) sipServletRequestImpl.getTransaction(); + SIPDialog newDialog = (SIPDialog)sipSession.getSessionCreatingDialog(); + if (newDialog != null && tx != null) { + logger.debug("recovering dialog on transaction before send:" + System.identityHashCode(newDialog)); + tx.setDialog(newDialog, newDialog.getDialogId()); + } + + SipServletResponseImpl response = (SipServletResponseImpl) sipServletRequestImpl.createResponse(status, reasonPhrase); + + + + + + return response; + } + /* * (non-Javadoc) * @see javax.servlet.sip.B2buaHelper#getLinkedSession(javax.servlet.sip.SipSession) @@ -613,481 +702,498 @@ public SipServletResponse createResponseToOriginalRequest( public SipSession getLinkedSession(final SipSession session) { return getLinkedSession(session, true); } - - public SipSession getLinkedSession(final SipSession session, boolean checkSession) { - if ( session == null) { - throw new NullPointerException("the argument is null"); - } - final MobicentsSipSession mobicentsSipSession = (MobicentsSipSession)session; - if(checkSession && !mobicentsSipSession.isValidInternal()) { - throw new IllegalArgumentException("the session " + mobicentsSipSession + " is invalid"); - } - MobicentsSipSessionKey sipSessionKey = this.sessionMap.get(mobicentsSipSession.getKey()); - if(sipSessionKey == null) { - dumpLinkedSessions(); - if(logger.isDebugEnabled()) { - logger.debug("No Linked Session found for this session " + session); - } - return null; - } - if(logger.isDebugEnabled()) { - logger.debug(" trying to find linked session with key " + sipSessionKey + " for session " + mobicentsSipSession); - } - MobicentsSipSession linkedSession = sipManager.getSipSession(sipSessionKey, false, null, mobicentsSipSession.getSipApplicationSession()); - if(logger.isDebugEnabled()) { - if(linkedSession != null) { - logger.debug("Linked Session found : " + linkedSession + " for this session " + session); - } else { - logger.debug("No Linked Session found for this session " + session); - } - } - if(mobicentsSipSession.getParentSession() != null) { - if(logger.isDebugEnabled()) { - logger.debug(mobicentsSipSession + " has a parent session, it means we need to handle a forked case"); - } - // Issue 2354 handling of forking - String linkedDerivedSessionId = derivedSessionMap.get(mobicentsSipSession.getId()); - if(linkedDerivedSessionId == null) { - SipServletRequestImpl originalSipServletRequestImpl = (SipServletRequestImpl) linkedSession.getSessionCreatingTransactionRequest(); - - String newToTag = ApplicationRoutingHeaderComposer.getHash(sipFactoryImpl.getSipApplicationDispatcher(),sipSessionKey.getApplicationName(), sipSessionKey.getApplicationSessionId()); - if(logger.isDebugEnabled()) { - logger.debug("derived session " + mobicentsSipSession + " has no linked forked session yet, lazily creating one with new ToTag " + newToTag); - } - sipSessionKey = new SipSessionKey(sipSessionKey.getFromTag(), newToTag, sipSessionKey.getCallId(), sipSessionKey.getApplicationSessionId(), sipSessionKey.getApplicationName()); - linkedSession = sipManager.getSipSession(sipSessionKey, false, null, mobicentsSipSession.getSipApplicationSession()); - - // need to clone the original request to create the forked response - SipServletRequestImpl clonedOriginalRequest = (SipServletRequestImpl)originalSipServletRequestImpl.clone(); - clonedOriginalRequest.setSipSession(linkedSession); - linkedSession.setSessionCreatingDialog(null); - linkedSession.setSessionCreatingTransactionRequest(clonedOriginalRequest); - - derivedSessionMap.put(mobicentsSipSession.getId(), linkedSession.getId()); - derivedSessionMap.put(linkedSession.getId(), mobicentsSipSession.getId()); - } else { - if(logger.isDebugEnabled()) { - logger.debug("derived session " + mobicentsSipSession + " has already a linked forked session " + linkedDerivedSessionId + " reusing it"); - } - try { - sipSessionKey = SessionManagerUtil.parseSipSessionKey(linkedDerivedSessionId); - if(logger.isDebugEnabled()) { - logger.debug(" trying to find derived linked session with key " + sipSessionKey + " for session " + mobicentsSipSession); - } - linkedSession = sipManager.getSipSession(sipSessionKey, false, null, mobicentsSipSession.getSipApplicationSession()); - } catch (ParseException e) { - logger.error("Couldn't parse linkedDerivedSessionId " + linkedDerivedSessionId + " linked to derived session " + mobicentsSipSession, e); - } - } - } - - if(linkedSession != null) { - return linkedSession.getFacade(); - } else { - return null; - } - } - /* + private MobicentsSipSession lookupSessionById(String sessionId, MobicentsSipApplicationSession appSession) { + MobicentsSipSession sessionFound = null; + try { + SipSessionKey parseSipSessionKey = SessionManagerUtil.parseSipSessionKey(sessionId); + sessionFound = (MobicentsSipSession) sipManager.getSipSession(parseSipSessionKey, false, sipFactoryImpl, appSession); + } catch (Exception ex) { + logger.debug("Failed to find session", ex); + } + return sessionFound; + } + + public SipSession getLinkedSession(final SipSession session, boolean checkSession) { + dumpAppSession((MobicentsSipSession) session); + dumpLinkedSessions(); + if (session == null) { + throw new NullPointerException("the argument is null"); + } + final MobicentsSipSession mobicentsSipSession = (MobicentsSipSession) session; + if (checkSession && !mobicentsSipSession.isValidInternal()) { + throw new IllegalArgumentException("the session " + mobicentsSipSession + " is invalid"); + } + + String sipSessionKey = this.sessionMap.get(mobicentsSipSession.getId()); + if (sipSessionKey == null) { + //check if derived is necessary + if (mobicentsSipSession.getParentSession() != null) { + if (logger.isDebugEnabled()) { + logger.debug(mobicentsSipSession + " has a parent session, it means we need to handle a forked case"); + } + String linkedParentSessionId = this.sessionMap.get(mobicentsSipSession.getParentSession().getId()); + if (linkedParentSessionId != null) { + MobicentsSipSession linkedParentSession = lookupSessionById(linkedParentSessionId, (MobicentsSipApplicationSession) session.getApplicationSession()); + if (linkedParentSession != null) { + SipServletRequestImpl originalSipServletRequestImpl = (SipServletRequestImpl) getOriginalRequest(linkedParentSession); + + // need to clone the original request to create the forked response + try { + SipServletRequestImpl clonedOriginalRequest = cloneDerivedRequest(originalSipServletRequestImpl, linkedParentSession); + sessionMap.put(session.getId(), clonedOriginalRequest.getSession().getId()); + sessionMap.put(clonedOriginalRequest.getSession().getId(), session.getId()); + sipSessionKey = clonedOriginalRequest.getSession().getId(); + } catch (Exception e) { + logger.debug("error cloning request", e); + + } + } + } + } + } + + if (sipSessionKey == null) { + dumpLinkedSessions(); + if (logger.isDebugEnabled()) { + logger.debug("No Linked Session found for this session " + session); + } + return null; + } + if (logger.isDebugEnabled()) { + logger.debug(" trying to find linked session with key " + sipSessionKey + " for session " + mobicentsSipSession); + } + MobicentsSipSession linkedSession = lookupSessionById(sipSessionKey, (MobicentsSipApplicationSession) session.getApplicationSession()); + if (logger.isDebugEnabled()) { + if (linkedSession != null) { + logger.debug("Linked Session found : " + linkedSession + " for this session " + session); + } else { + logger.debug("No Linked Session found for this session " + session); + } + } + + dumpAppSession((MobicentsSipSession) session); + dumpLinkedSessions(); + if (linkedSession != null) { + return linkedSession.getFacade(); + } else { + return null; + } + } + + /* * (non-Javadoc) * @see javax.servlet.sip.B2buaHelper#getLinkedSipServletRequest(javax.servlet.sip.SipServletRequest) - */ - public SipServletRequest getLinkedSipServletRequest(SipServletRequest req) { - if ( req == null) { - throw new NullPointerException("the argument is null"); - } - return originalRequestMap.get(req); - } - - /* + */ + public SipServletRequest getLinkedSipServletRequest(SipServletRequest req) { + if (req == null) { + throw new NullPointerException("the argument is null"); + } + return linkedRequestMap.get(req); + } + + /* * (non-Javadoc) * @see javax.servlet.sip.B2buaHelper#getPendingMessages(javax.servlet.sip.SipSession, javax.servlet.sip.UAMode) - */ - public List getPendingMessages(SipSession session, - UAMode mode) { - final MobicentsSipSession sipSessionImpl = (MobicentsSipSession) session; - if(!sipSessionImpl.isValidInternal()) { - throw new IllegalArgumentException("the session " + sipSessionImpl.getId() + " is invalid"); - } - - final List retval = new ArrayList (); - if (mode.equals(UAMode.UAC)) { - final Set ongoingTransactions = sipSessionImpl.getOngoingTransactions(); - if(ongoingTransactions != null) { - for (Transaction transaction: ongoingTransactions) { - if (transaction instanceof ClientTransaction) { - final TransactionApplicationData tad = (TransactionApplicationData) transaction.getApplicationData(); - // Issue1571 http://code.google.com/p/mobicents/issues/detail?id=1571 - // NullPointerException in SipServletResponseImpl.isCommitted - // race condition can occur between app code thread and processTxTerminated or Timeout thread - if(tad != null) { - final SipServletMessage sipServletMessage = tad.getSipServletMessage(); - if(sipServletMessage != null) { - //not specified if ACK is a committed message in the spec but it seems not since Proxy api test - //testCancel101 method adds a header to the ACK and it cannot be on a committed message - //so we don't want to return ACK as pending messages here. related to TCK test B2BUAHelper.testCreateRequest002 - if (!sipServletMessage.isCommitted() && !Request.ACK.equals(sipServletMessage.getMethod()) && !Request.PRACK.equals(sipServletMessage.getMethod())) { - retval.add(sipServletMessage); - } - final Set sipServletsResponses = tad.getSipServletResponses(); - if(sipServletsResponses != null) { - for(SipServletResponseImpl sipServletResponseImpl : sipServletsResponses) { - if (!sipServletResponseImpl.isCommitted()) { - retval.add(sipServletResponseImpl); - } - } - } - } - } - } - } - } - } else { - final Set ongoingTransactions = sipSessionImpl.getOngoingTransactions(); - if(ongoingTransactions != null) { - for (Transaction transaction: ongoingTransactions) { - if (transaction instanceof ServerTransaction) { - final TransactionApplicationData tad = (TransactionApplicationData) transaction.getApplicationData(); - if(tad != null) { - final SipServletMessage sipServletMessage = tad.getSipServletMessage(); - if(sipServletMessage != null) { - //not specified if ACK is a committed message in the spec but it seems not since Proxy api test - //testCanacel101 method adds a header to the ACK and it cannot be on a committed message - //so we don't want to return ACK as pending messages here. related to TCK test B2BUAHelper.testCreateRequest002 - if (!sipServletMessage.isCommitted() && !Request.ACK.equals(sipServletMessage.getMethod())) { - retval.add(sipServletMessage); - } - } - } - } - } - } - } - return retval; - } - - /* + */ + public List getPendingMessages(SipSession session, + UAMode mode) { + final MobicentsSipSession sipSessionImpl = (MobicentsSipSession) session; + if (!sipSessionImpl.isValidInternal()) { + throw new IllegalArgumentException("the session " + sipSessionImpl.getId() + " is invalid"); + } + + final List retval = new ArrayList(); + if (mode.equals(UAMode.UAC)) { + final Set ongoingTransactions = sipSessionImpl.getOngoingTransactions(); + if (ongoingTransactions != null) { + for (Transaction transaction : ongoingTransactions) { + if (transaction instanceof ClientTransaction) { + final TransactionApplicationData tad = (TransactionApplicationData) transaction.getApplicationData(); + // Issue1571 http://code.google.com/p/mobicents/issues/detail?id=1571 + // NullPointerException in SipServletResponseImpl.isCommitted + // race condition can occur between app code thread and processTxTerminated or Timeout thread + if (tad != null) { + final SipServletMessage sipServletMessage = tad.getSipServletMessage(); + if (sipServletMessage != null) { + //not specified if ACK is a committed message in the spec but it seems not since Proxy api test + //testCancel101 method adds a header to the ACK and it cannot be on a committed message + //so we don't want to return ACK as pending messages here. related to TCK test B2BUAHelper.testCreateRequest002 + if (!sipServletMessage.isCommitted() && !Request.ACK.equals(sipServletMessage.getMethod()) && !Request.PRACK.equals(sipServletMessage.getMethod())) { + retval.add(sipServletMessage); + } + final Set sipServletsResponses = tad.getSipServletResponses(); + if (sipServletsResponses != null) { + for (SipServletResponseImpl sipServletResponseImpl : sipServletsResponses) { + if (!sipServletResponseImpl.isCommitted()) { + //do not return Trying, this makes TCK AppRouter fail. + if (sipServletResponseImpl.getStatus() != 100 + ) { + retval.add(sipServletResponseImpl); + } + } + } + } + } + } + } + } + } + } else { + final Set ongoingTransactions = sipSessionImpl.getOngoingTransactions(); + if (ongoingTransactions != null) { + for (Transaction transaction : ongoingTransactions) { + if (transaction instanceof ServerTransaction) { + final TransactionApplicationData tad = (TransactionApplicationData) transaction.getApplicationData(); + if (tad != null) { + final SipServletMessage sipServletMessage = tad.getSipServletMessage(); + if (sipServletMessage != null) { + //not specified if ACK is a committed message in the spec but it seems not since Proxy api test + //testCanacel101 method adds a header to the ACK and it cannot be on a committed message + //so we don't want to return ACK as pending messages here. related to TCK test B2BUAHelper.testCreateRequest002 + if (!sipServletMessage.isCommitted() && !Request.ACK.equals(sipServletMessage.getMethod())) { + retval.add(sipServletMessage); + } + } + } + } + } + } + } + if (logger.isDebugEnabled()) { + StringBuffer buffer = new StringBuffer(); + buffer.append("############pending messages"); + for (SipServletMessage msg : retval) { + buffer.append(msg); + } + buffer.append("############pending messages"); + logger.debug(buffer.toString()); + } + return retval; + } + + /* * (non-Javadoc) * @see javax.servlet.sip.B2buaHelper#linkSipSessions(javax.servlet.sip.SipSession, javax.servlet.sip.SipSession) - */ - public void linkSipSessions(SipSession session1, SipSession session2) { - if ( session1 == null) { - throw new NullPointerException("First argument is null"); - } - if ( session2 == null) { - throw new NullPointerException("Second argument is null"); - } - - if(!((MobicentsSipSession)session1).isValidInternal() || !((MobicentsSipSession)session2).isValidInternal() || - State.TERMINATED.equals(((MobicentsSipSession)session1).getState()) || - State.TERMINATED.equals(((MobicentsSipSession)session2).getState()) || - !session1.getApplicationSession().equals(session2.getApplicationSession()) || - (sessionMap.get(((MobicentsSipSession)session1).getKey()) != null && sessionMap.get(((MobicentsSipSession)session1).getKey()) != ((MobicentsSipSession)session2).getKey()) || - (sessionMap.get(((MobicentsSipSession)session2).getKey()) != null && sessionMap.get(((MobicentsSipSession)session2).getKey()) != ((MobicentsSipSession)session1).getKey())) { - throw new IllegalArgumentException("either of the specified sessions has been terminated " + - "or the sessions do not belong to the same application session or " + - "one or both the sessions are already linked with some other session(s)"); - } - this.sessionMap.put(((MobicentsSipSession)session1).getKey(), ((MobicentsSipSession)session2).getKey()); - this.sessionMap.put(((MobicentsSipSession)session2).getKey(), ((MobicentsSipSession) session1).getKey()); - // https://github.com/Mobicents/sip-servlets/issues/56 - if(!this.equals(((MobicentsSipSession)session1).getB2buaHelper())) { - if(((MobicentsSipSession)session1).getB2buaHelper() == null) { - ((MobicentsSipSession)session1).setB2buaHelper(this); - } else { - Map forkedSessionMap = ((MobicentsSipSession)session1).getB2buaHelper().getSessionMap(); - forkedSessionMap.put(((MobicentsSipSession)session1).getKey(), ((MobicentsSipSession)session2).getKey()); - forkedSessionMap.put(((MobicentsSipSession)session2).getKey(), ((MobicentsSipSession) session1).getKey()); - } - } - // https://github.com/Mobicents/sip-servlets/issues/56 - if(!this.equals(((MobicentsSipSession)session2).getB2buaHelper())) { - if(((MobicentsSipSession)session2).getB2buaHelper() == null) { - ((MobicentsSipSession)session2).setB2buaHelper(this); - } else { - Map forkedSessionMap = ((MobicentsSipSession)session2).getB2buaHelper().getSessionMap(); - forkedSessionMap.put(((MobicentsSipSession)session1).getKey(), ((MobicentsSipSession)session2).getKey()); - forkedSessionMap.put(((MobicentsSipSession)session2).getKey(), ((MobicentsSipSession) session1).getKey()); - } - } - if(logger.isDebugEnabled()) { - logger.debug("sipsession " + ((MobicentsSipSession)session1).getKey() + " linked to sip session " + ((MobicentsSipSession)session2).getKey()); - } - dumpLinkedSessions(); - } - - /* + */ + public void linkSipSessions(SipSession session1, SipSession session2) { + if (session1 == null) { + throw new NullPointerException("First argument is null"); + } + if (session2 == null) { + throw new NullPointerException("Second argument is null"); + } + + if (!((MobicentsSipSession) session1).isValidInternal() || !((MobicentsSipSession) session2).isValidInternal() + || State.TERMINATED.equals(((MobicentsSipSession) session1).getState()) + || State.TERMINATED.equals(((MobicentsSipSession) session2).getState()) + || !session1.getApplicationSession().equals(session2.getApplicationSession()) + || (sessionMap.get(((MobicentsSipSession) session1).getId()) != null && !sessionMap.get(((MobicentsSipSession) session1).getId()).equals(((MobicentsSipSession) session2).getId())) + || (sessionMap.get(((MobicentsSipSession) session2).getId()) != null + && !sessionMap.get(((MobicentsSipSession) session2).getId()).equals(((MobicentsSipSession) session1).getId()))) { + throw new IllegalArgumentException("either of the specified sessions has been terminated " + + "or the sessions do not belong to the same application session or " + + "one or both the sessions are already linked with some other session(s)"); + } + this.sessionMap.put(((MobicentsSipSession) session1).getId(), ((MobicentsSipSession) session2).getId()); + this.sessionMap.put(((MobicentsSipSession) session2).getId(), ((MobicentsSipSession) session1).getId()); + if (logger.isDebugEnabled()) { + logger.debug("sipsession " + ((MobicentsSipSession) session1).getKey() + " linked to sip session " + ((MobicentsSipSession) session2).getKey()); + } + dumpAppSession((MobicentsSipSession) session1); + dumpLinkedSessions(); + } + + /* * (non-Javadoc) * @see javax.servlet.sip.B2buaHelper#unlinkSipSessions(javax.servlet.sip.SipSession) - */ - public void unlinkSipSessions(SipSession session) { - unlinkSipSessionsInternal(session, true); - } - - /** - * - * @param session - * @param checkSession - */ - public void unlinkSipSessionsInternal(SipSession session, boolean checkSession) { - if ( session == null) { - throw new NullPointerException("the argument is null"); - } - final MobicentsSipSession key = (MobicentsSipSession) session; - final MobicentsSipSessionKey sipSessionKey = key.getKey(); - if(checkSession) { - if(!((MobicentsSipSession)session).isValidInternal() || - State.TERMINATED.equals(key.getState()) || - sessionMap.get(sipSessionKey) == null) { - throw new IllegalArgumentException("the session is not currently linked to another session or it has been terminated"); - } - } - final MobicentsSipSessionKey value = this.sessionMap.get(sipSessionKey); - if (value != null) { - SipSession linkedSipSession = getLinkedSession(session, checkSession); - this.sessionMap.remove(sipSessionKey); - this.sessionMap.remove(value); - if(logger.isDebugEnabled()) { - logger.debug("sipsession " + sipSessionKey + " unlinked from sip session " + value); - } - if(linkedSipSession != null) { - // https://github.com/Mobicents/sip-servlets/issues/56 - MobicentsB2BUAHelper linkedB2buaHelper = ((MobicentsSipSession)linkedSipSession).getB2buaHelper(); - if(!linkedB2buaHelper.equals(this)) { - linkedB2buaHelper.unlinkSipSessionsInternal(linkedSipSession, false); - } else { - linkedB2buaHelper = ((MobicentsSipSession)session).getB2buaHelper(); - linkedB2buaHelper.unlinkSipSessionsInternal(linkedSipSession, false); - } - } - } else if(logger.isDebugEnabled()) { - logger.debug("no sipsession for " + sipSessionKey + " to unlink"); - } - final String linkedDerivedSessionId = this.derivedSessionMap.get(sipSessionKey.toString()); - if (linkedDerivedSessionId != null) { - SipSession linkedSipSession = getLinkedSession(session, checkSession); - this.derivedSessionMap.remove(sipSessionKey.toString()); - this.derivedSessionMap.remove(linkedDerivedSessionId); - if(logger.isDebugEnabled()) { - logger.debug("derived sipsession " + sipSessionKey.toString() + " unlinked from derived sip session " + linkedDerivedSessionId); - } - if(linkedSipSession != null) { - // https://github.com/Mobicents/sip-servlets/issues/56 - MobicentsB2BUAHelper linkedB2buaHelper = ((MobicentsSipSession)linkedSipSession).getB2buaHelper(); - if(!linkedB2buaHelper.equals(this)) { - linkedB2buaHelper.unlinkSipSessions(linkedSipSession); - } else { - linkedB2buaHelper = ((MobicentsSipSession)session).getB2buaHelper(); - linkedB2buaHelper.unlinkSipSessions(linkedSipSession); - } - } - } else if(logger.isDebugEnabled()) { - logger.debug("no derived sipsession for " + sipSessionKey.toString() + " to unlink"); - } - unlinkOriginalRequestInternal(sipSessionKey, !checkSession); - dumpLinkedSessions(); - } - - /** - * - * @param session - * @param checkSession - */ - public void unlinkOriginalRequestInternal(MobicentsSipSessionKey sipSessionKey, boolean force) { - for (Entry linkedRequests : originalRequestMap.entrySet()) { - SipServletRequestImpl request1 = linkedRequests.getKey(); - SipServletRequestImpl request2 = linkedRequests.getValue(); - if(request1 != null && request2 != null) { - MobicentsSipSessionKey key1 = request1.getSipSessionKey(); - MobicentsSipSessionKey key2 = request2.getSipSessionKey(); - if((key1!=null&&key1.equals(sipSessionKey)) || (key2!=null&&key2.equals(sipSessionKey))) { - unlinkOriginalRequestInternal(linkedRequests.getKey(), force); - unlinkOriginalRequestInternal(linkedRequests.getValue(), force); - } - } - } - } - - /** - * - * @param session - * @param checkSession - */ - public void unlinkOriginalRequestInternal(MobicentsSipServletRequest sipServletRequestImpl, boolean force) { - if(sipServletRequestImpl != null) { - SipServletRequestImpl linkedRequest = this.originalRequestMap.get(sipServletRequestImpl); - if(sipServletRequestImpl != null) { - if(linkedRequest != null) { - // Issue 2419 we unlink only if both tx are in terminated state or transaction is null (which means it has already been cleaned up) - Transaction transaction = sipServletRequestImpl.getTransaction(); - Transaction linkedTransaction = linkedRequest.getTransaction(); - if(logger.isDebugEnabled()) { - logger.debug("force " + force); - logger.debug("transaction " + transaction); - logger.debug("Linkedtransaction " + linkedTransaction); - if(transaction != null) { - logger.debug("transaction state " + transaction.getState()); - } - if(linkedTransaction != null) { - logger.debug("linked transaction state " + linkedTransaction.getState()); - } - } - if(!Request.ACK.equalsIgnoreCase(sipServletRequestImpl.getMethod()) && (force || ((transaction == null || TransactionState.TERMINATED.equals(transaction.getState())) && - (linkedTransaction == null || TransactionState.TERMINATED.equals(linkedTransaction.getState()))))) { - this.originalRequestMap.remove(sipServletRequestImpl); - this.originalRequestMap.remove(linkedRequest); - if(logger.isDebugEnabled()) { - logger.debug("following linked request " + linkedRequest + " unlinked from " + sipServletRequestImpl); - } - if(!force) { - // in case of forceful invalidate there is no need to clean up everything here as we will use standard transaction terminated events - // TCK com.bea.sipservlet.tck.apps.apitestapp.B2buaHelper.testGetPendingMessages101 and testGetLinkedSession101 - // don't remove the Linked Transaction if force is null as the response on the original cannot be sent as the transaction will be null - if(linkedTransaction != null) { - linkedRequest.getSipSession().removeOngoingTransaction(linkedTransaction); - if(linkedTransaction.getApplicationData() != null) { - ((TransactionApplicationData)linkedTransaction.getApplicationData()).cleanUp(); - ((TransactionApplicationData)linkedTransaction.getApplicationData()).cleanUpMessage(); - } - } - if(transaction != null) { - sipServletRequestImpl.getSipSession().removeOngoingTransaction(transaction); - if(transaction.getApplicationData() != null) { - ((TransactionApplicationData)transaction.getApplicationData()).cleanUp(); - ((TransactionApplicationData)transaction.getApplicationData()).cleanUpMessage(); - } - } - if(linkedRequest.getSipSession().getOngoingTransactions().isEmpty()) { - linkedRequest.getSipSession().cleanDialogInformation(false); - } - if(sipServletRequestImpl.getSipSession().getOngoingTransactions().isEmpty()) { - sipServletRequestImpl.getSipSession().cleanDialogInformation(false); - } - if(!force && linkedRequest.getSipSession().isValidInternal() && - // https://code.google.com/p/sipservlets/issues/detail?id=279 - linkedRequest.getSipSession().isReadyToInvalidateInternal()) { - linkedRequest.getSipSession().onTerminatedState(); - } - if(sipServletRequestImpl.getSipSession().isValidInternal() && - // https://code.google.com/p/sipservlets/issues/detail?id=279 - sipServletRequestImpl.getSipSession().isReadyToInvalidateInternal()) { - sipServletRequestImpl.getSipSession().onTerminatedState(); - } - } - } - } - } - } - } - - /* + */ + public void unlinkSipSessions(SipSession session) { + unlinkSipSessionsInternal(session, true); + } + + /** + * + * @param session + * @param checkSession + */ + public void unlinkSipSessionsInternal(SipSession session, boolean checkSession) { + if (session == null) { + throw new NullPointerException("the argument is null"); + } + final MobicentsSipSession key = (MobicentsSipSession) session; + final String sipSessionKey = key.getId(); + if (checkSession) { + if (!((MobicentsSipSession) session).isValidInternal() + || State.TERMINATED.equals(key.getState()) + || sessionMap.get(sipSessionKey) == null) { + throw new IllegalArgumentException("the session is not currently linked to another session or it has been terminated"); + } + } + + final String value = this.sessionMap.get(sipSessionKey); + if (value != null) { + SipSession linkedSipSession = getLinkedSession(session, checkSession); + this.sessionMap.remove(sipSessionKey); + this.sessionMap.remove(value); + if (logger.isDebugEnabled()) { + logger.debug("sipsession " + sipSessionKey + " unlinked from sip session " + value); + } + } else if (logger.isDebugEnabled()) { + logger.debug("no sipsession for " + sipSessionKey + " to unlink"); + } + unlinkRequestInternal(sipSessionKey, !checkSession); + dumpLinkedSessions(); + dumpAppSession((MobicentsSipSession) session); + } + + public void unlinkRequestInternal(String sipSessionKey, boolean force) { + for (Entry linkedRequests : linkedRequestMap.entrySet()) { + SipServletRequestImpl request1 = linkedRequests.getKey(); + SipServletRequestImpl request2 = linkedRequests.getValue(); + if (request1 != null && request2 != null) { + String key1 = request1.getSession().getId(); + String key2 = request2.getSession().getId(); + if ((key1 != null && key1.equals(sipSessionKey)) || (key2 != null && key2.equals(sipSessionKey))) { + unlinkRequestInternal(linkedRequests.getKey(), force); + unlinkRequestInternal(linkedRequests.getValue(), force); + } + } + } + } + + public void unlinkRequestInternal(MobicentsSipServletRequest sipServletRequestImpl, boolean force) { + if (sipServletRequestImpl != null) { + SipServletRequestImpl linkedRequest = this.linkedRequestMap.get(sipServletRequestImpl); + if (sipServletRequestImpl != null) { + if (linkedRequest != null) { + // Issue 2419 we unlink only if both tx are in terminated state or transaction is null (which means it has already been cleaned up) + Transaction transaction = sipServletRequestImpl.getTransaction(); + Transaction linkedTransaction = linkedRequest.getTransaction(); + if (logger.isDebugEnabled()) { + logger.debug("force " + force); + logger.debug("transaction " + transaction); + logger.debug("Linkedtransaction " + linkedTransaction); + if (transaction != null) { + logger.debug("transaction state " + transaction.getState()); + } + if (linkedTransaction != null) { + logger.debug("linked transaction state " + linkedTransaction.getState()); + } + } + if (!Request.ACK.equalsIgnoreCase(sipServletRequestImpl.getMethod()) && (force || ((transaction == null || TransactionState.TERMINATED.equals(transaction.getState())) + && (linkedTransaction == null || TransactionState.TERMINATED.equals(linkedTransaction.getState()))))) { + this.linkedRequestMap.remove(sipServletRequestImpl); + this.linkedRequestMap.remove(linkedRequest); + if (logger.isDebugEnabled()) { + logger.debug("following linked request " + linkedRequest + " unlinked from " + sipServletRequestImpl); + } + if (!force) { + // in case of forceful invalidate there is no need to clean up everything here as we will use standard transaction terminated events + // TCK com.bea.sipservlet.tck.apps.apitestapp.B2buaHelper.testGetPendingMessages101 and testGetLinkedSession101 + // don't remove the Linked Transaction if force is null as the response on the original cannot be sent as the transaction will be null + if (linkedTransaction != null) { + linkedRequest.getSipSession().removeOngoingTransaction(linkedTransaction); + if (linkedTransaction.getApplicationData() != null) { + ((TransactionApplicationData) linkedTransaction.getApplicationData()).cleanUp(); + ((TransactionApplicationData) linkedTransaction.getApplicationData()).cleanUpMessage(); + } + } + if (transaction != null) { + sipServletRequestImpl.getSipSession().removeOngoingTransaction(transaction); + if (transaction.getApplicationData() != null) { + ((TransactionApplicationData) transaction.getApplicationData()).cleanUp(); + ((TransactionApplicationData) transaction.getApplicationData()).cleanUpMessage(); + } + } + if (linkedRequest.getSipSession().getOngoingTransactions() == null || + linkedRequest.getSipSession().getOngoingTransactions().isEmpty()) { + linkedRequest.getSipSession().cleanDialogInformation(false); + } + if (sipServletRequestImpl.getSipSession().getOngoingTransactions() == null || + sipServletRequestImpl.getSipSession().getOngoingTransactions().isEmpty()) { + sipServletRequestImpl.getSipSession().cleanDialogInformation(false); + } + if (!force && linkedRequest.getSipSession().isValidInternal() + && // https://code.google.com/p/sipservlets/issues/detail?id=279 + linkedRequest.getSipSession().isReadyToInvalidateInternal()) { + linkedRequest.getSipSession().onTerminatedState(); + } + if (sipServletRequestImpl.getSipSession().isValidInternal() + && // https://code.google.com/p/sipservlets/issues/detail?id=279 + sipServletRequestImpl.getSipSession().isReadyToInvalidateInternal()) { + sipServletRequestImpl.getSipSession().onTerminatedState(); + } + } + } + } + } + } + } + + /* * (non-Javadoc) * @see javax.servlet.sip.B2buaHelper#createRequest(javax.servlet.sip.SipServletRequest) - */ - public SipServletRequest createRequest(SipServletRequest origRequest) { - final SipServletRequestImpl newSipServletRequest = (SipServletRequestImpl) sipFactoryImpl.createRequest(origRequest, false); - final SipServletRequestImpl origRequestImpl = (SipServletRequestImpl) origRequest; - - final MobicentsSipSession originalSession = origRequestImpl.getSipSession(); - final MobicentsSipSession session = newSipServletRequest.getSipSession(); - // B2buaHelperTest.testLinkSipSessions101 assumes the sessions shouldn't be linked together + */ + public SipServletRequest createRequest(SipServletRequest origRequest) { + final SipServletRequestImpl newSipServletRequest = (SipServletRequestImpl) sipFactoryImpl.createRequest(origRequest, false); + final SipServletRequestImpl origRequestImpl = (SipServletRequestImpl) origRequest; + + final MobicentsSipSession originalSession = origRequestImpl.getSipSession(); + final MobicentsSipSession session = newSipServletRequest.getSipSession(); + // B2buaHelperTest.testLinkSipSessions101 assumes the sessions shouldn't be linked together // sessionMap.put(originalSession.getKey(), session.getKey()); -// sessionMap.put(session.getKey(), originalSession.getKey()); +// sessionMap.put(session.getKey(), originalSession.getKey()); // dumpLinkedSessions(); -// originalRequestMap.put(newSipServletRequest, origRequestImpl); -// originalRequestMap.put(origRequestImpl, newSipServletRequest); - - session.setB2buaHelper(this); - originalSession.setB2buaHelper(this); - - return newSipServletRequest; - } +// linkedRequestMap.put(newSipServletRequest, origRequestImpl); +// linkedRequestMap.put(origRequestImpl, newSipServletRequest); + session.setB2buaHelper(this); + originalSession.setB2buaHelper(this); + setOriginalRequest(session, newSipServletRequest); + dumpAppSession(session); + return newSipServletRequest; + } - /** - * {@inheritDoc} - */ - public SipServletRequest createCancel(SipSession session) { - if(session == null) throw new NullPointerException("The session for createCancel cannot be null"); - for (SipServletRequestImpl linkedRequest : originalRequestMap.keySet()) { - if(linkedRequest.getSipSessionKey().equals(((MobicentsSipSession) session).getKey()) && - linkedRequest.getMethod().equalsIgnoreCase(Request.INVITE) && - !linkedRequest.isFinalResponseGenerated() && - // Fix for Issue http://code.google.com/p/mobicents/issues/detail?id=2114 - // In B2b servlet, after re-INVITE, and try to create CANCEL will get "final response already sent!" exception. - linkedRequest.getLastFinalResponse() == null) { - final SipServletRequestImpl sipServletRequestImpl = (SipServletRequestImpl)linkedRequest.createCancel(); - ((MobicentsSipSession)sipServletRequestImpl.getSession()).setB2buaHelper(this); - return sipServletRequestImpl; - } - } - return null; - } + /** + * {@inheritDoc} + */ + public SipServletRequest createCancel(SipSession session) { + if (session == null) { + throw new NullPointerException("The session for createCancel cannot be null"); + } + for (SipServletRequestImpl linkedRequest : linkedRequestMap.keySet()) { + if (linkedRequest.getSipSessionKey().equals(((MobicentsSipSession) session).getKey()) + && linkedRequest.getMethod().equalsIgnoreCase(Request.INVITE) + && !linkedRequest.isFinalResponseGenerated() + && // Fix for Issue http://code.google.com/p/mobicents/issues/detail?id=2114 + // In B2b servlet, after re-INVITE, and try to create CANCEL will get "final response already sent!" exception. + linkedRequest.getLastFinalResponse() == null) { + final SipServletRequestImpl sipServletRequestImpl = (SipServletRequestImpl) linkedRequest.createCancel(); + ((MobicentsSipSession) sipServletRequestImpl.getSession()).setB2buaHelper(this); + return sipServletRequestImpl; + } + } + return null; + } - /** - * @return the sipFactoryImpl - */ - public SipFactoryImpl getSipFactoryImpl() { - return sipFactoryImpl; - } + /** + * @return the sipFactoryImpl + */ + public SipFactoryImpl getSipFactoryImpl() { + return sipFactoryImpl; + } - /** - * @param sipFactoryImpl the sipFactoryImpl to set - */ - public void setMobicentsSipFactory(MobicentsSipFactory sipFactoryImpl) { - this.sipFactoryImpl = (SipFactoryImpl) sipFactoryImpl; - } + /** + * @param sipFactoryImpl the sipFactoryImpl to set + */ + public void setMobicentsSipFactory(MobicentsSipFactory sipFactoryImpl) { + this.sipFactoryImpl = (SipFactoryImpl) sipFactoryImpl; + } - /** - * @return the sipManager - */ - public SipManager getSipManager() { - return sipManager; - } + /** + * @return the sipManager + */ + public SipManager getSipManager() { + return sipManager; + } - /** - * @param sipManager the sipManager to set - */ - public void setSipManager(SipManager sipManager) { - this.sipManager = sipManager; - } - - private void dumpLinkedSessions() { - if(logger.isDebugEnabled()) { - for (MobicentsSipSessionKey key : sessionMap.keySet()) { - logger.debug(key + " tied to session " + sessionMap.get(key)); - } - for (String key : derivedSessionMap.keySet()) { - logger.debug("forked " + key + " tied to forked session " + derivedSessionMap.get(key)); - } - } - } + /** + * @param sipManager the sipManager to set + */ + public void setSipManager(SipManager sipManager) { + this.sipManager = sipManager; + } - /** - * @param sessionMap the sessionMap to set - */ - public void setSessionMap(Map sessionMap) { - this.sessionMap = sessionMap; - } + private void dumpAppSession(MobicentsSipSession session) { + StringBuffer buffer = new StringBuffer(); + buffer.append("######################AppSessionDump\n"); + SipApplicationSession applicationSession = session.getApplicationSession(); + Iterator sessions = applicationSession.getSessions(); + while (sessions.hasNext()) { + Object obj = sessions.next(); + if (obj instanceof MobicentsSipSession) { + MobicentsSipSession sAux = (MobicentsSipSession) obj; + Iterator derivedSipSessions = sAux.getDerivedSipSessions(); + buffer.append("SessionId(" + System.identityHashCode(sAux) +"):" + sAux.getId() + ".State:" + sAux.getState() + "\n"); + while (derivedSipSessions.hasNext()) { + MobicentsSipSession derived = derivedSipSessions.next(); + buffer.append("DerivedSessionId(" + System.identityHashCode(derived) + "):" + derived.getId() + ".State:" + sAux.getState() + "\n"); + buffer.append("++++++++++++++++++++\n"); + } + } + buffer.append("------------------\n"); + } + buffer.append("######################AppSessionDump\n"); + logger.debug(buffer); + } - /** - * @return the sessionMap - */ - public Map getSessionMap() { - return sessionMap; - } + private void dumpLinkedSessions() { - /** - * @return the originalRequestMap - */ - public Map getOriginalRequestMap() { - return originalRequestMap; - } - - /** - * @param originalRequestsMap the originalRequests to set - */ - public void setOriginalRequestMap(Map originalRequestsMap) { - this.originalRequestMap = originalRequestsMap; - } + if (logger.isDebugEnabled()) { + StringBuffer buffer = new StringBuffer(); + buffer.append("######################B2BUASessionMapping\n"); + for (String key : sessionMap.keySet()) { + buffer.append(key + "\n -> " + sessionMap.get(key) + "\n"); + buffer.append("------------------\n"); + } + buffer.append("######################B2BUASessionMapping\n"); + logger.debug(buffer); + } + } + + /** + * @param sessionMap the sessionMap to set + */ + public void setSessionMap(Map sessionMap) { + this.sessionMap = sessionMap; + } + + /** + * @return the sessionMap + */ + public Map getSessionMap() { + return sessionMap; + } + + /** + * @return the linkedRequestMap + */ + public Map getOriginalRequestMap() { + return linkedRequestMap; + } + + /** + * @param originalRequestsMap the originalRequests to set + */ + public void setOriginalRequestMap(Map originalRequestsMap) { + this.linkedRequestMap = originalRequestsMap; + } + + @Override + public void setOriginalRequest(SipSession sipSession, MobicentsSipServletRequest sipServletMessage) { + if (logger.isDebugEnabled()) { + logger.debug("Setting OriginalRequest:" + System.identityHashCode(sipServletMessage) + ", on session:" + sipSession); + } + if (sipSession.isValid()) { + sipSession.setAttribute(ORIG_REQ_ATT_NAME, sipServletMessage); + } else { + logger.debug("OriginalRequest not saved, session is not valid"); + } + } + + @Override + public MobicentsSipServletRequest getOriginalRequest(SipSession sipSession) { + if (logger.isDebugEnabled()) { + logger.debug("Lookfor OrginalRequest on session:" + sipSession); + } + MobicentsSipServletRequest req = (MobicentsSipServletRequest) sipSession.getAttribute(ORIG_REQ_ATT_NAME); + if (req == null) { + throw new IllegalStateException("OrginalRequest is null."); + } + if (logger.isDebugEnabled()) { + logger.debug("OrginalRequest is(" + System.identityHashCode(req) + ").tx:" + req.getTransaction()); + } + return req; + } } diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/MobicentsSipApplicationSessionFacade.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/MobicentsSipApplicationSessionFacade.java index b8c8000592..425e2cdf03 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/MobicentsSipApplicationSessionFacade.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/MobicentsSipApplicationSessionFacade.java @@ -249,6 +249,9 @@ public MobicentsSipApplicationSession getFacade() { public void readExternal(ObjectInput arg0) throws IOException, ClassNotFoundException { + if (logger.isDebugEnabled()){ + logger.debug("readExternal"); + } String sipApplicationSessionId = arg0.readUTF(); SipApplicationSessionKey key = null; try { diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/MobicentsSipSessionFacade.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/MobicentsSipSessionFacade.java index 8ae34b625b..8aec999e6f 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/MobicentsSipSessionFacade.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/MobicentsSipSessionFacade.java @@ -62,11 +62,11 @@ import org.mobicents.servlet.sip.startup.StaticServiceHolder; /** - * The purpose of this class is to be a facade to the real sip session as well as a - * serializable session class that can be put as a session attribute in other sessions or even its own session. + * The purpose of this class is to be a facade to the real sip session as well as a + * serializable session class that can be put as a session attribute in other sessions or even its own session. * Basically instead of replicating the whole attribute map, we will replicate the id, then on the remote side we will * read the ID and look it up in the remote session manager. - * + * * @author vralev * @author jean.deruelle@gmail.com * @author George Vagenas @@ -79,9 +79,9 @@ public class MobicentsSipSessionFacade implements MobicentsSipSession, Serializa private transient MobicentsSipSession sipSession; private MobicentsSipSessionKey sipSessionKey = null; private MobicentsSipApplicationSessionKey sipAppSessionKey = null; - + // public MobicentsSipSessionFacade() { } - + public MobicentsSipSessionFacade(MobicentsSipSession sipSession) { this.sipSession = sipSession; this.sipSessionKey = sipSession.getKey(); @@ -89,6 +89,9 @@ public MobicentsSipSessionFacade(MobicentsSipSession sipSession) { } public SipServletRequest createRequest(String arg0) { + if(logger.isDebugEnabled()) { + logger.debug("createRequest - arg0=" + arg0); + } return getSipSession().createRequest(arg0); } @@ -151,10 +154,10 @@ public URI getSubscriberURI() { public void invalidate() { getSipSession().invalidate(); } - + @Override public void invalidate(boolean bypassCheck) { - getSipSession().invalidate(bypassCheck); + getSipSession().invalidate(bypassCheck); } public boolean isReadyToInvalidate() { @@ -165,11 +168,11 @@ public boolean isReadyToInvalidate() { public boolean isReadyToInvalidateInternal() { return getSipSession().isReadyToInvalidateInternal(); } - + public boolean isValid() { return getSipSession().isValid(); } - + public boolean isValidInternal() { return getSipSession().isValidInternal(); } @@ -197,22 +200,22 @@ public void setOutboundInterface(InetAddress arg0) { public void setOutboundInterface(InetSocketAddress arg0) { getSipSession().setOutboundInterface(arg0); } - + public void setOutboundInterface(SipURI arg0) { getSipSession().setOutboundInterface(arg0); } // public void readExternal(ObjectInput in) throws IOException, -// ClassNotFoundException { -// sipSessionKey = (SipSessionKey) in.readObject(); +// ClassNotFoundException { +// sipSessionKey = (SipSessionKey) in.readObject(); // sipAppSessionKey = (SipApplicationSessionKey) in.readObject(); // if(logger.isDebugEnabled()) { // logger.debug("sip app session key=" + sipAppSessionKey); // logger.debug("sip session key=" + sipSessionKey); -// } +// } // } // -// public void writeExternal(ObjectOutput out) throws IOException { +// public void writeExternal(ObjectOutput out) throws IOException { // out.writeObject(sipSessionKey); // out.writeObject(sipAppSessionKey); // } @@ -235,82 +238,82 @@ public void addSubscription(MobicentsSipServletMessage sipServletMessage) } public MobicentsSipSession findDerivedSipSession(String toTag) { - + return findDerivedSipSession(toTag); } public MobicentsB2BUAHelper getB2buaHelper() { - + return getSipSession().getB2buaHelper(); } public Iterator getDerivedSipSessions() { - + return getSipSession().getDerivedSipSessions(); } public String getHandler() { - + return getSipSession().getHandler(); } public MobicentsSipSessionKey getKey() { - + return getSipSession().getKey(); } public Set getOngoingTransactions() { - + return getSipSession().getOngoingTransactions(); } public String getOutboundInterface() { - + return getSipSession().getOutboundInterface(); } public MobicentsProxy getProxy() { - + return getSipSession().getProxy(); } public SipApplicationRoutingRegion getRegionInternal() { - + return getSipSession().getRegionInternal(); } public Dialog getSessionCreatingDialog() { - + return getSipSession().getSessionCreatingDialog(); } public MobicentsSipServletMessage getSessionCreatingTransactionRequest() { - + return getSipSession().getSessionCreatingTransactionRequest(); } public MobicentsSipApplicationSession getSipApplicationSession() { - + return getSipSession().getSipApplicationSession(); } public Map getSipSessionAttributeMap() { - + return getSipSession().getSipSessionAttributeMap(); } public String getSipSubscriberURI() { - + return getSipSession().getSipSubscriberURI(); } public Serializable getStateInfo() { - + return getSipSession().getStateInfo(); } public SipPrincipal getUserPrincipal() { - + return getSipSession().getUserPrincipal(); } @@ -323,12 +326,12 @@ public void onTerminatedState() { } public MobicentsSipSession removeDerivedSipSession(String toTag) { - + return getSipSession().removeDerivedSipSession(toTag); } public void removeOngoingTransaction(Transaction transaction) { - + getSipSession().removeOngoingTransaction(transaction); } @@ -347,7 +350,7 @@ public void setLocalParty(Address addressImpl) { public void setParentSession(MobicentsSipSession mobicentsSipSession) { getSipSession().setParentSession(mobicentsSipSession); } - + public MobicentsSipSession getParentSession() { return getSipSession().getParentSession(); } @@ -406,7 +409,7 @@ public void updateStateOnSubsequentRequest( public MobicentsSipSession getFacade() { return getSipSession().getFacade(); } - + @Override public boolean equals(Object obj) { return getSipSession().equals(obj); @@ -433,7 +436,7 @@ public void setNextSipApplicationRouterInfo( public void setAckReceived(long cSeq, boolean ackReceived) { getSipSession().setAckReceived(cSeq, ackReceived); - } + } public void setCseq(long cseq) { getSipSession().setCseq(cseq); @@ -442,11 +445,11 @@ public void setCseq(long cseq) { public long getCseq() { return getSipSession().getCseq(); } - + public boolean validateCSeq(MobicentsSipServletRequest request) { return getSipSession().validateCSeq(request); } - + /** * @return the sipSession */ @@ -458,7 +461,7 @@ private MobicentsSipSession getSipSession() { } SipContext sipContext = StaticServiceHolder.sipStandardService .getSipApplicationDispatcher().findSipApplication(sipAppSessionKey.getApplicationName()); - + MobicentsSipApplicationSession sipApplicationSession = sipContext.getSipManager().getSipApplicationSession(sipAppSessionKey, false); sipSession = sipContext.getSipManager().getSipSession(sipSessionKey, false, null, sipApplicationSession); if(sipSession == null) @@ -467,8 +470,8 @@ private MobicentsSipSession getSipSession() { + sipSessionKey); } return sipSession; - } - + } + public MobicentsSipSession getMobicentsSipSession() { return sipSession; } @@ -494,7 +497,7 @@ public void setRequestsPending(int requests) { } public void notifySipSessionListeners(SipSessionEventType creation) { - sipSession.notifySipSessionListeners(creation); + sipSession.notifySipSessionListeners(creation); } public void setCopyRecordRouteHeadersOnSubsequentResponses( @@ -513,7 +516,7 @@ public MobicentsSipSessionSecurity getSipSessionSecurity() { public void setSipSessionSecurity(MobicentsSipSessionSecurity sipSessionSecurity) { sipSession.setSipSessionSecurity(sipSessionSecurity); } - + public void acquire() { sipSession.acquire(); } @@ -521,7 +524,7 @@ public void acquire() { public void release() { sipSession.release(); } - + public void setFlow(final javax.sip.address.SipURI flow) { this.sipSession.setFlow(flow); } @@ -571,9 +574,14 @@ public void setBypassProxy(boolean bypassProxy) { public boolean getBypassProxy() { return this.sipSession.getBypassProxy(); } - + @Override public void cleanDialogInformation(boolean terminate) { this.cleanDialogInformation(terminate); } + + @Override + public boolean isB2BUAOrphan() { + return sipSession.isB2BUAOrphan(); + } } diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/SipFactoryFacade.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/SipFactoryFacade.java index e68da9bb6e..d7540ca86d 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/SipFactoryFacade.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/SipFactoryFacade.java @@ -1,285 +1,304 @@ -/* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2014, Telestax Inc and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - */ - -package org.mobicents.servlet.sip.message; - -import java.io.Serializable; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpSession; -import javax.servlet.sip.Address; -import javax.servlet.sip.AuthInfo; -import javax.servlet.sip.Parameterable; -import javax.servlet.sip.ServletParseException; -import javax.servlet.sip.SipApplicationSession; -import javax.servlet.sip.SipServletRequest; -import javax.servlet.sip.SipURI; -import javax.servlet.sip.URI; - -import org.apache.log4j.Logger; -import org.mobicents.javax.servlet.sip.SipFactoryExt; -import org.mobicents.javax.servlet.sip.SipSessionsUtilExt; -import org.mobicents.servlet.sip.core.SipContext; -import org.mobicents.servlet.sip.core.session.ConvergedSession; -import org.mobicents.servlet.sip.core.session.MobicentsSipApplicationSession; -import org.mobicents.servlet.sip.core.session.MobicentsSipSession; - -/** - * Facade object which masks the internal SipFactoryImpl - * object from the web application. - * - * @author Jean Deruelle - * - */ -public class SipFactoryFacade implements SipFactoryExt, Serializable { - - private static final long serialVersionUID = 1L; - private static final Logger logger = Logger.getLogger(SipFactoryFacade.class - .getName()); - - private SipFactoryImpl sipFactoryImpl; - private transient SipContext sipContext; - private static transient ThreadLocal threadLocalHttpSession = new ThreadLocal();; - - public SipFactoryFacade(SipFactoryImpl sipFactoryImpl, SipContext sipContext) { - this.sipFactoryImpl = sipFactoryImpl; - this.sipContext = sipContext; - } - - /* (non-Javadoc) - * @see javax.servlet.sip.SipFactory#createAddress(java.lang.String) - */ - public Address createAddress(String sipAddress) throws ServletParseException { - return sipFactoryImpl.createAddress(sipAddress); - } - - /* (non-Javadoc) - * @see javax.servlet.sip.SipFactory#createAddress(javax.servlet.sip.URI) - */ - public Address createAddress(URI uri) { - return sipFactoryImpl.createAddress(uri); - } - - /* (non-Javadoc) - * @see javax.servlet.sip.SipFactory#createAddress(javax.servlet.sip.URI, java.lang.String) - */ - public Address createAddress(URI uri, String displayName) { - return sipFactoryImpl.createAddress(uri, displayName); - } - - /* (non-Javadoc) - * @see javax.servlet.sip.SipFactory#createApplicationSession() - */ - public SipApplicationSession createApplicationSession() { - return createApplicationSession(true); - } - - /* - * (non-Javadoc) - * @see org.mobicents.javax.servlet.sip.SipFactoryExt#createApplicationSession(boolean) - */ - public SipApplicationSession createApplicationSession(boolean managed) { - MobicentsSipApplicationSession sipApplicationSessionImpl = null; - HttpSession httpSession = threadLocalHttpSession.get(); - // make sure we don't create a new sip app session if the http session has already one associated - if(httpSession != null) { - ConvergedSession convergedSession = (ConvergedSession) httpSession; - sipApplicationSessionImpl = convergedSession.getApplicationSession(false); - } - if(sipApplicationSessionImpl == null) { - sipApplicationSessionImpl = - (MobicentsSipApplicationSession)sipFactoryImpl.createApplicationSessionByAppName(sipContext.getApplicationName(), managed); - associateHttpSession(sipApplicationSessionImpl); - } - return sipApplicationSessionImpl; - } - - /** - * A servlet wants to create a sip application - * session, we can retrieve its http session in the thread local data - * if it has a sip http session (sip servlet only won't have any http sessions) - * and associate it with the sip app session. - * @param sipApplicationSessionImpl the app session to assocaiate the http session with - */ - private void associateHttpSession( - MobicentsSipApplicationSession sipApplicationSessionImpl) { - - HttpSession httpSession = threadLocalHttpSession.get(); - if(httpSession != null) { - sipApplicationSessionImpl.addHttpSession(httpSession); - } - } - - /* (non-Javadoc) - * @see javax.servlet.sip.SipFactory#createParameterable(java.lang.String) - */ - public Parameterable createParameterable(String s) throws ServletParseException { - return sipFactoryImpl.createParameterable(s); - } - - /* (non-Javadoc) - * @see javax.servlet.sip.SipFactory#createRequest(javax.servlet.sip.SipApplicationSession, java.lang.String, javax.servlet.sip.Address, javax.servlet.sip.Address) - */ - public SipServletRequest createRequest(SipApplicationSession appSession, - String method, Address from, Address to) { - SipServletRequest sipServletRequest = sipFactoryImpl.createRequest(appSession, method, from, to, ((MobicentsSipApplicationSession)appSession).getCurrentRequestHandler(), null, null); - return sipServletRequest; - } - - /* (non-Javadoc) - * @see javax.servlet.sip.SipFactory#createRequest(javax.servlet.sip.SipApplicationSession, java.lang.String, java.lang.String, java.lang.String) - */ - public SipServletRequest createRequest(SipApplicationSession appSession, - String method, String from, String to) throws ServletParseException { - SipServletRequest sipServletRequest = sipFactoryImpl.createRequest(appSession, method, from, to, ((MobicentsSipApplicationSession)appSession).getCurrentRequestHandler()); - return sipServletRequest; - } - - /* (non-Javadoc) - * @see javax.servlet.sip.SipFactory#createRequest(javax.servlet.sip.SipApplicationSession, java.lang.String, javax.servlet.sip.URI, javax.servlet.sip.URI) - */ - public SipServletRequest createRequest(SipApplicationSession appSession, - String method, URI from, URI to) { - SipServletRequest sipServletRequest = sipFactoryImpl.createRequest(appSession, method, from, to, ((MobicentsSipApplicationSession)appSession).getCurrentRequestHandler()); - return sipServletRequest; - } - - /* (non-Javadoc) - * @see javax.servlet.sip.SipFactory#createRequest(javax.servlet.sip.SipServletRequest, boolean) - */ - public SipServletRequest createRequest(SipServletRequest origRequest, - boolean sameCallId) { - SipServletRequest sipServletRequest = sipFactoryImpl.createRequest(origRequest, sameCallId); - checkHandler(sipServletRequest); - return sipServletRequest; - } - - /** - * set the handler for this request if none already exists. - * The handler will be the main servlet of the sip context - * @param request the session of this request will have its handler set. - */ - private void checkHandler(SipServletRequest request) { - MobicentsSipSession sipSessionImpl = (MobicentsSipSession)request.getSession(); - if(sipSessionImpl.getHandler() == null) { - try { - sipSessionImpl.setHandler(sipContext.getServletHandler()); -// ((SipApplicationSessionImpl)sipSessionImpl.getApplicationSession()).setSipContext(sipContext); - } catch (ServletException se) { - //should never happen - logger.error("Impossible to set the default handler on the newly created request "+ request.toString(),se); - } - } - } - - /* (non-Javadoc) - * @see javax.servlet.sip.SipFactory#createSipURI(java.lang.String, java.lang.String) - */ - public SipURI createSipURI(String user, String host) { - return sipFactoryImpl.createSipURI(user, host); - } - - /* (non-Javadoc) - * @see javax.servlet.sip.SipFactory#createURI(java.lang.String) - */ - public URI createURI(String uri) throws ServletParseException { - return sipFactoryImpl.createURI(uri); - } - - /** - * Store the http session in the sip Factory's thread local - * @param httpSession the http session to store for later retrieval - */ - public void storeHttpSession(HttpSession httpSession) { - threadLocalHttpSession.set(httpSession); - } - - /** - * Remove the http session in the sip Factory's thread local - */ - public void removeHttpSession() { - threadLocalHttpSession.set(null); - threadLocalHttpSession.remove(); - } - - /** - * Retrieve the http session previously stored in the sip Factory's thread local - * @return the http session previously stored in the sip Factory's thread local - */ - public HttpSession retrieveHttpSession() { - return threadLocalHttpSession.get(); - } - - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipFactory#createApplicationSessionByKey(java.lang.String) - */ - public SipApplicationSession createApplicationSessionByKey( - String sipApplicationKey) { - return createApplicationSessionByKey(sipApplicationKey, true); - } - - - public SipApplicationSession createApplicationSessionByKey( - String sipApplicationKey, boolean managed) { - MobicentsSipApplicationSession sipApplicationSessionImpl = null; - // make sure we don't create a new sip app session if the http session has already one associated - HttpSession httpSession = threadLocalHttpSession.get(); - if(httpSession != null) { - ConvergedSession convergedSession = (ConvergedSession) httpSession; - sipApplicationSessionImpl = convergedSession.getApplicationSession(false); - } - if(sipApplicationSessionImpl == null) { - sipApplicationSessionImpl = (MobicentsSipApplicationSession) ((SipSessionsUtilExt)sipContext.getSipSessionsUtil()).getApplicationSessionByKey(sipApplicationKey, true, managed); - associateHttpSession(sipApplicationSessionImpl); - } - return sipApplicationSessionImpl; - } - - /** - * {@inheritDoc} - */ - public AuthInfo createAuthInfo() { - return sipFactoryImpl.createAuthInfo(); - } - - /** - * {@inheritDoc} - */ - public SipApplicationSession createApplicationSessionByAppName(String arg0) { - // TODO Auto-generated method stub - return null; - } - - /* - * (non-Javadoc) - * @see org.mobicents.javax.servlet.sip.SipFactoryExt#isRouteOrphanRequests() - */ - public boolean isRouteOrphanRequests() { - return sipFactoryImpl.isRouteOrphanRequests(); - } - - /* - * (non-Javadoc) - * @see org.mobicents.javax.servlet.sip.SipFactoryExt#setRouteOrphanRequest(boolean) - */ - public void setRouteOrphanRequests(boolean routeOrphanRequets) { - sipFactoryImpl.setRouteOrphanRequests(routeOrphanRequets); - } -} +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2014, Telestax Inc and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + */ + +package org.mobicents.servlet.sip.message; + +import java.io.Serializable; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpSession; +import javax.servlet.sip.Address; +import javax.servlet.sip.AuthInfo; +import javax.servlet.sip.Parameterable; +import javax.servlet.sip.ServletParseException; +import javax.servlet.sip.SipApplicationSession; +import javax.servlet.sip.SipServletRequest; +import javax.servlet.sip.SipURI; +import javax.servlet.sip.URI; + +import org.apache.log4j.Logger; +import org.mobicents.javax.servlet.sip.SipFactoryExt; +import org.mobicents.javax.servlet.sip.SipSessionsUtilExt; +import org.mobicents.servlet.sip.core.SipContext; +import org.mobicents.servlet.sip.core.session.ConvergedSession; +import org.mobicents.servlet.sip.core.session.MobicentsSipApplicationSession; +import org.mobicents.servlet.sip.core.session.MobicentsSipSession; + +/** + * Facade object which masks the internal SipFactoryImpl + * object from the web application. + * + * @author Jean Deruelle + * + */ +public class SipFactoryFacade implements SipFactoryExt, Serializable { + + private static final long serialVersionUID = 1L; + private static final Logger logger = Logger.getLogger(SipFactoryFacade.class + .getName()); + + private SipFactoryImpl sipFactoryImpl; + private transient SipContext sipContext; + private static transient ThreadLocal threadLocalHttpSession = new ThreadLocal();; + + public SipFactoryFacade(SipFactoryImpl sipFactoryImpl, SipContext sipContext) { + this.sipFactoryImpl = sipFactoryImpl; + this.sipContext = sipContext; + } + + /* (non-Javadoc) + * @see javax.servlet.sip.SipFactory#createAddress(java.lang.String) + */ + public Address createAddress(String sipAddress) throws ServletParseException { + return sipFactoryImpl.createAddress(sipAddress); + } + + /* (non-Javadoc) + * @see javax.servlet.sip.SipFactory#createAddress(javax.servlet.sip.URI) + */ + public Address createAddress(URI uri) { + return sipFactoryImpl.createAddress(uri); + } + + /* (non-Javadoc) + * @see javax.servlet.sip.SipFactory#createAddress(javax.servlet.sip.URI, java.lang.String) + */ + public Address createAddress(URI uri, String displayName) { + return sipFactoryImpl.createAddress(uri, displayName); + } + + /* (non-Javadoc) + * @see javax.servlet.sip.SipFactory#createApplicationSession() + */ + public SipApplicationSession createApplicationSession() { + return createApplicationSession(true); + } + + /* + * (non-Javadoc) + * @see org.mobicents.javax.servlet.sip.SipFactoryExt#createApplicationSession(boolean) + */ + public SipApplicationSession createApplicationSession(boolean managed) { + MobicentsSipApplicationSession sipApplicationSessionImpl = null; + HttpSession httpSession = threadLocalHttpSession.get(); + // make sure we don't create a new sip app session if the http session has already one associated + if(httpSession != null) { + ConvergedSession convergedSession = (ConvergedSession) httpSession; + sipApplicationSessionImpl = convergedSession.getApplicationSession(false); + } + if(sipApplicationSessionImpl == null) { + sipApplicationSessionImpl = + (MobicentsSipApplicationSession)sipFactoryImpl.createApplicationSessionByAppName(sipContext.getApplicationName(), managed); + associateHttpSession(sipApplicationSessionImpl); + } + return sipApplicationSessionImpl; + } + + /** + * A servlet wants to create a sip application + * session, we can retrieve its http session in the thread local data + * if it has a sip http session (sip servlet only won't have any http sessions) + * and associate it with the sip app session. + * @param sipApplicationSessionImpl the app session to assocaiate the http session with + */ + private void associateHttpSession( + MobicentsSipApplicationSession sipApplicationSessionImpl) { + + HttpSession httpSession = threadLocalHttpSession.get(); + if(httpSession != null) { + sipApplicationSessionImpl.addHttpSession(httpSession); + } + } + + /* (non-Javadoc) + * @see javax.servlet.sip.SipFactory#createParameterable(java.lang.String) + */ + public Parameterable createParameterable(String s) throws ServletParseException { + return sipFactoryImpl.createParameterable(s); + } + + /* (non-Javadoc) + * @see javax.servlet.sip.SipFactory#createRequest(javax.servlet.sip.SipApplicationSession, java.lang.String, javax.servlet.sip.Address, javax.servlet.sip.Address) + */ + public SipServletRequest createRequest(SipApplicationSession appSession, + String method, Address from, Address to) { + SipServletRequest sipServletRequest = sipFactoryImpl.createRequest(appSession, method, from, to, ((MobicentsSipApplicationSession)appSession).getCurrentRequestHandler(), null, null); + return sipServletRequest; + } + + /* (non-Javadoc) + * @see javax.servlet.sip.SipFactory#createRequest(javax.servlet.sip.SipApplicationSession, java.lang.String, java.lang.String, java.lang.String) + */ + public SipServletRequest createRequest(SipApplicationSession appSession, + String method, String from, String to) throws ServletParseException { + SipServletRequest sipServletRequest = sipFactoryImpl.createRequest(appSession, method, from, to, ((MobicentsSipApplicationSession)appSession).getCurrentRequestHandler()); + return sipServletRequest; + } + + /* (non-Javadoc) + * @see javax.servlet.sip.SipFactory#createRequest(javax.servlet.sip.SipApplicationSession, java.lang.String, javax.servlet.sip.URI, javax.servlet.sip.URI) + */ + public SipServletRequest createRequest(SipApplicationSession appSession, + String method, URI from, URI to) { + SipServletRequest sipServletRequest = sipFactoryImpl.createRequest(appSession, method, from, to, ((MobicentsSipApplicationSession)appSession).getCurrentRequestHandler()); + return sipServletRequest; + } + + /* (non-Javadoc) + * @see javax.servlet.sip.SipFactory#createRequest(javax.servlet.sip.SipServletRequest, boolean) + */ + public SipServletRequest createRequest(SipServletRequest origRequest, + boolean sameCallId) { + SipServletRequest sipServletRequest = sipFactoryImpl.createRequest(origRequest, sameCallId); + checkHandler(sipServletRequest); + return sipServletRequest; + } + + /** + * set the handler for this request if none already exists. + * The handler will be the main servlet of the sip context + * @param request the session of this request will have its handler set. + */ + private void checkHandler(SipServletRequest request) { + MobicentsSipSession sipSessionImpl = (MobicentsSipSession)request.getSession(); + if(sipSessionImpl.getHandler() == null) { + try { + sipSessionImpl.setHandler(sipContext.getServletHandler()); +// ((SipApplicationSessionImpl)sipSessionImpl.getApplicationSession()).setSipContext(sipContext); + } catch (ServletException se) { + //should never happen + logger.error("Impossible to set the default handler on the newly created request "+ request.toString(),se); + } + } + } + + /* (non-Javadoc) + * @see javax.servlet.sip.SipFactory#createSipURI(java.lang.String, java.lang.String) + */ + public SipURI createSipURI(String user, String host) { + return sipFactoryImpl.createSipURI(user, host); + } + + /* (non-Javadoc) + * @see javax.servlet.sip.SipFactory#createURI(java.lang.String) + */ + public URI createURI(String uri) throws ServletParseException { + return sipFactoryImpl.createURI(uri); + } + + /** + * Store the http session in the sip Factory's thread local + * @param httpSession the http session to store for later retrieval + */ + public void storeHttpSession(HttpSession httpSession) { + threadLocalHttpSession.set(httpSession); + } + + /** + * Remove the http session in the sip Factory's thread local + */ + public void removeHttpSession() { + threadLocalHttpSession.set(null); + threadLocalHttpSession.remove(); + } + + /** + * Retrieve the http session previously stored in the sip Factory's thread local + * @return the http session previously stored in the sip Factory's thread local + */ + public HttpSession retrieveHttpSession() { + return threadLocalHttpSession.get(); + } + + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipFactory#createApplicationSessionByKey(java.lang.String) + */ + public SipApplicationSession createApplicationSessionByKey( + String sipApplicationKey) { + return createApplicationSessionByKey(sipApplicationKey, true); + } + + + public SipApplicationSession createApplicationSessionByKey( + String sipApplicationKey, boolean managed) { + MobicentsSipApplicationSession sipApplicationSessionImpl = null; + // make sure we don't create a new sip app session if the http session has already one associated + HttpSession httpSession = threadLocalHttpSession.get(); + if(httpSession != null) { + ConvergedSession convergedSession = (ConvergedSession) httpSession; + sipApplicationSessionImpl = convergedSession.getApplicationSession(false); + } + if(sipApplicationSessionImpl == null) { + sipApplicationSessionImpl = (MobicentsSipApplicationSession) ((SipSessionsUtilExt)sipContext.getSipSessionsUtil()).getApplicationSessionByKey(sipApplicationKey, true, managed); + associateHttpSession(sipApplicationSessionImpl); + } + return sipApplicationSessionImpl; + } + + /** + * {@inheritDoc} + */ + public AuthInfo createAuthInfo() { + return sipFactoryImpl.createAuthInfo(); + } + + /** + * {@inheritDoc} + */ + public SipApplicationSession createApplicationSessionByAppName(String arg0) { + // TODO Auto-generated method stub + return null; + } + + /* + * (non-Javadoc) + * @see org.mobicents.javax.servlet.sip.SipFactoryExt#isRouteOrphanRequests() + */ + public boolean isRouteOrphanRequests() { + return sipFactoryImpl.isRouteOrphanRequests(); + } + + /* + * (non-Javadoc) + * @see org.mobicents.javax.servlet.sip.SipFactoryExt#setRouteOrphanRequest(boolean) + */ + public void setRouteOrphanRequests(boolean routeOrphanRequets) { + sipFactoryImpl.setRouteOrphanRequests(routeOrphanRequets); + } + + @Override + public SipServletRequest createRequestWithCallID(SipApplicationSession appSession, String method, Address from, Address to, String callID) { + SipServletRequest sipServletRequest = sipFactoryImpl.createRequestWithCallID(appSession, method, from, to, callID); + return sipServletRequest; + } + + @Override + public SipServletRequest createRequestWithCallID(SipApplicationSession appSession, String method, String from, String to, String callID) throws ServletParseException { + SipServletRequest sipServletRequest = sipFactoryImpl.createRequestWithCallID(appSession, method, from, to, callID); + return sipServletRequest; + } + + @Override + public SipServletRequest createRequestWithCallID(SipApplicationSession appSession, String method, URI from, URI to, String callID) { + SipServletRequest sipServletRequest = sipFactoryImpl.createRequestWithCallID(appSession, method, from, to, callID); + return sipServletRequest; + } + +} diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/SipFactoryImpl.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/SipFactoryImpl.java index eb3b3ad92c..376cc716b8 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/SipFactoryImpl.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/SipFactoryImpl.java @@ -35,6 +35,7 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Set; import javax.servlet.sip.Address; @@ -139,7 +140,7 @@ public void initialize(String pathName, boolean prettyEncoding) { } } } - + public static class NamesComparator implements Comparator, Serializable { private static final long serialVersionUID = 1L; @@ -352,7 +353,79 @@ public SipServletRequest createRequest(SipApplicationSession sipAppSession, return createSipServletRequest(sipAppSession, method, fromA, toA, handler, null, null); } + + @Override + public SipServletRequest createRequestWithCallID(SipApplicationSession sipAppSession, + String method, Address from, Address to, String callID){ + if (logger.isDebugEnabled()) { + logger + .debug("Creating new SipServletRequest for SipApplicationSession[" + + sipAppSession + + "] METHOD[" + + method + + "] FROM_A[" + from + "] TO_A[" + to + "]"); + } + + validateCreation(method, sipAppSession); + + try { + String handler = ((MobicentsSipApplicationSession)sipAppSession).getCurrentRequestHandler(); + //javadoc specifies that a copy of the address should be done hence the clone + return createSipServletRequest(sipAppSession, method, (Address)from.clone(), (Address)to.clone(), handler, callID, null); + } catch (ServletParseException e) { + logger.error("Error creating sipServletRequest", e); + return null; + } + } + + @Override + public SipServletRequest createRequestWithCallID(SipApplicationSession sipAppSession, + String method, String from, String to, String callID) throws ServletParseException{ + if (logger.isDebugEnabled()) { + logger + .debug("Creating new SipServletRequest for SipApplicationSession[" + + sipAppSession + + "] METHOD[" + + method + + "] FROM[" + + from + "] TO[" + to + "]"); + } + validateCreation(method, sipAppSession); + + Address toA = this.createAddress(to); + Address fromA = this.createAddress(from); + String handler = ((MobicentsSipApplicationSession)sipAppSession).getCurrentRequestHandler(); + return createSipServletRequest(sipAppSession, method, fromA, toA, handler, callID, null); + } + + @Override + public SipServletRequest createRequestWithCallID(SipApplicationSession sipAppSession, + String method, URI from, URI to, String callID){ + if (logger.isDebugEnabled()) { + logger + .debug("Creating new SipServletRequest for SipApplicationSession[" + + sipAppSession + + "] METHOD[" + + method + + "] FROM_URI[" + from + "] TO_URI[" + to + "]"); + } + + validateCreation(method, sipAppSession); + + //javadoc specifies that a copy of the uri should be done hence the clone + Address toA = this.createAddress(to.clone()); + Address fromA = this.createAddress(from.clone()); + + try { + String handler = ((MobicentsSipApplicationSession)sipAppSession).getCurrentRequestHandler(); + return createSipServletRequest(sipAppSession, method, fromA, toA, handler, callID, null); + } catch (ServletParseException e) { + logger.error("Error creating sipServletRequest", e); + return null; + } + } + /* * (non-Javadoc) * @@ -500,7 +573,7 @@ public SipServletRequest createRequest(SipServletRequest origRequest, "Illegal arg ecnountered while creatigng b2bua", ex); } } - + /* * (non-Javadoc) * @@ -896,6 +969,12 @@ public boolean isUseLoadBalancer() { public void addLoadBalancerRouteHeader(Request request, MobicentsExtendedListeningPoint mobicentsExtendedListeningPoint) { try { String transport = JainSipUtils.findTransport(request); + if ( mobicentsExtendedListeningPoint != null ) { + transport = mobicentsExtendedListeningPoint.getTransport(); + if (logger.isDebugEnabled()){ + logger.debug("addLoadBalancerRouteHeader - setting transport to " + transport + " from listening point in use"); + } + } String host = null; int port = -1; OutboundProxy proxy = StaticServiceHolder.sipStandardService.getOutboundProxy(); @@ -1040,7 +1119,7 @@ public SipServletRequest createRequest(SipApplicationSession appSession, String method, URI from, URI to) { throw new UnsupportedOperationException("Use the one createRequest(SipApplicationSession appSession, String method, URI from, URI to, String handler) method instead"); } - + /* (non-Javadoc) * @see org.mobicents.servlet.sip.core.MobicentsSipFactoryImpl#getAddressFactory() */ diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/SipServletMessageImpl.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/SipServletMessageImpl.java index 9e836d470f..7c2e0ac6d3 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/SipServletMessageImpl.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/SipServletMessageImpl.java @@ -90,6 +90,7 @@ import org.mobicents.servlet.sip.address.ParameterableHeaderImpl; import org.mobicents.servlet.sip.core.MobicentsExtendedListeningPoint; import org.mobicents.servlet.sip.core.SipContext; +import static org.mobicents.servlet.sip.core.SipContext.INTERNAL_ATT_PREFIX; import org.mobicents.servlet.sip.core.message.MobicentsSipServletMessage; import org.mobicents.servlet.sip.core.security.SipPrincipal; import org.mobicents.servlet.sip.core.session.MobicentsSipApplicationSession; @@ -101,18 +102,18 @@ /** * Implementation of SipServletMessage - * + * * @author mranga * @author jean.deruelle@telestax.com - * + * */ public abstract class SipServletMessageImpl implements MobicentsSipServletMessage, Externalizable { - + private static final long serialVersionUID = 1L; private static final Logger logger = Logger.getLogger(SipServletMessageImpl.class .getCanonicalName()); - + private static final String CONTENT_TYPE_TEXT = "text"; private static final String CONTENT_TYPE_MULTIPART = "multipart"; private static final String MULTIPART_BOUNDARY = "boundary"; @@ -121,7 +122,7 @@ public abstract class SipServletMessageImpl implements MobicentsSipServletMessag private static final String LINE_RETURN_DELIM = "\n"; public static final String REL100_OPTION_TAG = "100rel"; // private static final String HCOLON = " : "; - + protected Message message; protected SipFactoryImpl sipFactoryImpl; protected MobicentsSipSessionKey sessionKey; @@ -135,14 +136,14 @@ public abstract class SipServletMessageImpl implements MobicentsSipServletMessag // used for failover to recover the transaction private String transactionId; private boolean transactionType; - + // We need this object separate from transaction.getApplicationData, because the actualy transaction // may be create later and we still need to accumulate useful data. Also the transaction might be // cleaned up earlier. The transaction and this object have different lifecycle. - protected TransactionApplicationData transactionApplicationData; + protected TransactionApplicationData transactionApplicationData; protected HeaderForm headerForm = HeaderForm.DEFAULT; - + // IP address of the next upstream/downstream hop from which this message // was received. Applications can determine the actual IP address of the UA // that originated the message from the message Via header fields. @@ -154,27 +155,36 @@ public abstract class SipServletMessageImpl implements MobicentsSipServletMessag protected transient String transport = null; protected String currentApplicationName = null; - + protected transient SipPrincipal userPrincipal; - + protected boolean isMessageSent; // Made it transient for Issue 1523 : http://code.google.com/p/mobicents/issues/detail?id=1523 // NotSerializableException happens if a message is stored in the sip session during HA protected transient Dialog dialog; - + protected transient String method; - + // needed for orphan routing boolean orphan; private String appSessionId; - + // needed for externalizable public SipServletMessageImpl () {} - + protected SipServletMessageImpl(Message message, SipFactoryImpl sipFactoryImpl, Transaction transaction, MobicentsSipSession sipSession, Dialog dialog) { + + if(logger.isDebugEnabled()) { + logger.debug("SipServletMessageImpl constructor - sipSession=" + sipSession); + if (sipSession != null){ + logger.debug("SipServletMessageImpl constructor - sipSession.getSipApplicationSession()=" + sipSession.getSipApplicationSession()); + } + } + + if (sipFactoryImpl == null) throw new NullPointerException("Null factory"); if (message == null) @@ -186,18 +196,21 @@ protected SipServletMessageImpl(Message message, this.transaction = transaction; if(sipSession != null) { this.sessionKey = sipSession.getKey(); + if(logger.isDebugEnabled()) { + logger.debug("SipServletMessageImpl constructor - sipSession not null - this.sessionKey=" + this.sessionKey); + } } if(transaction != null && getMethod().equals(Request.INVITE)) { if(transaction.getApplicationData() != null) { this.transactionApplicationData = (TransactionApplicationData) transaction.getApplicationData(); } - } + } if(transactionApplicationData == null){ this.transactionApplicationData = new TransactionApplicationData(this); } isMessageSent = false; this.dialog = dialog; - + if(sipSession != null && dialog != null) { sipSession.setSessionCreatingDialog(dialog); if(dialog.getApplicationData() == null) { @@ -207,9 +220,9 @@ protected SipServletMessageImpl(Message message, dialog.setApplicationData(transactionApplicationData); } } - + // good behaviour, lets make some default - //seems like bad behavior finally + //seems like bad behavior finally //check http://forums.java.net/jive/thread.jspa?messageID=260944 // => commented out // if (this.message.getContentEncoding() == null) @@ -258,15 +271,15 @@ public void addAddressHeader(String name, Address addr, boolean first) + first + "] value [" + addr + "]"); } - //we should test for - //This method can be used with headers which are defined to contain one + //we should test for + //This method can be used with headers which are defined to contain one //or more entries matching (name-addr | addr-spec) *(SEMI generic-param) as defined in RFC 3261 // if (!isAddressTypeHeader(hName)) { // logger.error("Header [" + hName + "] is not address type header"); // throw new IllegalArgumentException("Header[" + hName // + "] is not of an address type"); // } - + if (isSystemHeaderAndNotGruu(getModifiableRule(hName), (Parameterable)addr.getURI())) { logger.error("Error, can't add system header [" + hName + "]"); throw new IllegalArgumentException("Header[" + hName @@ -309,13 +322,13 @@ public void addHeaderInternal(String name, String value, boolean bypassSystemHea } String nameToAdd = getCorrectHeaderName(hName); - + try { - // Fix to Issue 1015 by alexander.kozlov.IV + // Fix to Issue 1015 by alexander.kozlov.IV if(JainSipUtils.SINGLETON_HEADER_NAMES.contains(name)) { Header header = SipFactory.getInstance().createHeaderFactory().createHeader(nameToAdd, value); - this.message.setHeader(header); - } else { + this.message.setHeader(header); + } else { // Dealing with Allow:INVITE, ACK, CANCEL, OPTIONS, BYE kind of values if(JainSipUtils.LIST_HEADER_NAMES.contains(name)) { List
headers = SipFactory.getInstance().createHeaderFactory() @@ -328,14 +341,18 @@ public void addHeaderInternal(String name, String value, boolean bypassSystemHea Header header = SipFactory.getInstance().createHeaderFactory() .createHeader(name, value); this.message.addLast(header); - } + } } } catch (Exception ex) { throw new IllegalArgumentException("Illegal args supplied ", ex); } } - + public void setHeaderInternal(String name, String value, boolean bypassSystemHeaderCheck) { + if(logger.isDebugEnabled()) { + logger.debug("setHeaderInternal - name=" + name + ", value=" + value); + } + if(name == null) { throw new NullPointerException ("name parameter is null"); } @@ -344,17 +361,17 @@ public void setHeaderInternal(String name, String value, boolean bypassSystemHea } if(!bypassSystemHeaderCheck && isSystemHeader(getModifiableRule(name))) { throw new IllegalArgumentException(name + " is a system header !"); - } - + } + try { Header header = SipFactory.getInstance().createHeaderFactory() .createHeader(name, value); - this.message.setHeader(header); + this.message.setHeader(header); } catch (Exception e) { throw new IllegalArgumentException("Error creating header!", e); } } - + //check if the submitted value is of the form header-value *(COMMA header-value) // private boolean isMultipleValue(String value) { // StringTokenizer tokenizer = new StringTokenizer(value, ","); @@ -367,6 +384,10 @@ public void setHeaderInternal(String name, String value, boolean bypassSystemHea * @see javax.servlet.sip.SipServletMessage#addHeader(java.lang.String, java.lang.String) */ public void addHeader(String name, String value) { + if(logger.isDebugEnabled()) { + logger.debug("addHeader - name=" + name + ", value=" + value); + } + checkCommitted(); addHeaderInternal(name, value, false); } @@ -377,6 +398,10 @@ public void addHeader(String name, String value) { */ public void addParameterableHeader(String name, Parameterable param, boolean first) { + if(logger.isDebugEnabled()) { + logger.debug("addParameterableHeader - name=" + name + ", param=" + param + ", first=" + first); + } + checkCommitted(); try { String hName = getFullHeaderName(name); @@ -405,7 +430,7 @@ public void addParameterableHeader(String name, Parameterable param, * @see javax.servlet.sip.SipServletMessage#getAcceptLanguage() */ public Locale getAcceptLanguage() { - // See section 14.4 of RFC 2616 (HTTP/1.1) for more information about how the Accept-Language header + // See section 14.4 of RFC 2616 (HTTP/1.1) for more information about how the Accept-Language header // must interpreted to determine the preferred language of the client. Locale preferredLocale = null; float q = 0; @@ -481,7 +506,7 @@ public Address getAddressHeader(String name) throws ServletParseException { } else { Parameterable parametrable = createParameterable(first, first.getName(), message instanceof Request); try { - logger.debug("parametrable Value " + parametrable.getValue()); + logger.debug("parametrable Value " + parametrable.getValue()); if(this.isCommitted()) { return new AddressImpl(SipFactoryImpl.addressFactory.createAddress(parametrable.getValue()), ((ParameterableHeaderImpl)parametrable).getInternalParameters(), ModifiableRule.NotModifiable); } else { @@ -503,6 +528,9 @@ public Address getAddressHeader(String name) throws ServletParseException { @SuppressWarnings("unchecked") public ListIterator
getAddressHeaders(String name) throws ServletParseException { + if(logger.isDebugEnabled()) { + logger.debug("getAddressHeaders - name=" + name); + } String hName = getFullHeaderName(name); @@ -541,12 +569,19 @@ public ListIterator
getAddressHeaders(String name) /* * (non-Javadoc) - * + * * @see javax.servlet.sip.SipServletMessage#getApplicationSession() */ public SipApplicationSession getApplicationSession() { + if(logger.isDebugEnabled()) { + logger.debug("getApplicationSession"); + } + MobicentsSipApplicationSession sipApplicationSession = getSipApplicationSession(true); if(sipApplicationSession == null) { + if(logger.isDebugEnabled()) { + logger.debug("getApplicationSession - sipApplicationSession is null"); + } return null; } else { return sipApplicationSession.getFacade(); @@ -555,10 +590,14 @@ public SipApplicationSession getApplicationSession() { /* * (non-Javadoc) - * + * * @see javax.servlet.sip.SipServletMessage#getApplicationSession(boolean) */ public SipApplicationSession getApplicationSession(boolean create) { + if(logger.isDebugEnabled()) { + logger.debug("getApplicationSession - create=" + create); + } + MobicentsSipApplicationSession sipApplicationSession = getSipApplicationSession(create); if(sipApplicationSession == null) { return null; @@ -566,8 +605,11 @@ public SipApplicationSession getApplicationSession(boolean create) { return sipApplicationSession.getFacade(); } } - + public MobicentsSipApplicationSession getSipApplicationSession(boolean create) { + if(logger.isDebugEnabled()) { + logger.debug("getSipApplicationSession - create=" + create); + } MobicentsSipSession sipSession = getSipSession(); if(sipSession != null) { MobicentsSipApplicationSession sipApplicationSession = sipSession.getSipApplicationSession(); @@ -575,11 +617,17 @@ public MobicentsSipApplicationSession getSipApplicationSession(boolean create) { return sipApplicationSession; } } - + String applicationName = getCurrentApplicationName(); if(sessionKey != null) { applicationName = sessionKey.getApplicationName(); + if(logger.isDebugEnabled()) { + logger.debug("getApplicationSession - sessionKey not null, applicationName=" + applicationName); + } } else { + if(logger.isDebugEnabled()) { + logger.debug("getApplicationSession - sessionKey is null"); + } if(this instanceof SipServletRequestImpl && isOrphan()) { if(logger.isDebugEnabled()) { logger.debug("Orphans session " + applicationName + " " + sessionKey); @@ -588,13 +636,16 @@ public MobicentsSipApplicationSession getSipApplicationSession(boolean create) { sessionKey = SessionManagerUtil.getSipSessionKey( SessionManagerUtil.getSipApplicationSessionKey(applicationName, getAppSessionId(), null).getId(), applicationName, message, false); + if(logger.isDebugEnabled()) { + logger.debug("getApplicationSession - Orphans session, sessionKey=" + sessionKey); + } } } if(applicationName != null && sessionKey != null) { final SipContext sipContext = sipFactoryImpl.getSipApplicationDispatcher().findSipApplication(applicationName); //call id not needed anymore since the sipappsessionkey is not a callid anymore but a random uuid final SipApplicationSessionKey sipApplicationSessionKey = SessionManagerUtil.getSipApplicationSessionKey( - applicationName, + applicationName, sessionKey.getApplicationSessionId(), null); if(logger.isDebugEnabled()) { logger.debug("trying to load the sip app session with Key " + sipApplicationSessionKey + " and create = " + true); @@ -603,7 +654,7 @@ public MobicentsSipApplicationSession getSipApplicationSession(boolean create) { if(applicationSession != null) { // application session can be null if create is false and it is an orphan request applicationSession.setOrphan(isOrphan()); - } + } return applicationSession; } return null; @@ -614,6 +665,9 @@ public MobicentsSipApplicationSession getSipApplicationSession(boolean create) { * @see javax.servlet.sip.SipServletMessage#getAttribute(java.lang.String) */ public Object getAttribute(String name) { + if(logger.isDebugEnabled()) { + logger.debug("getAttribute - name=" + sessionKey); + } if (name == null) throw new NullPointerException("Attribute name can not be null."); return this.getAttributeMap().get(name); @@ -636,10 +690,17 @@ public String getCallId() { CallIdHeader id = (CallIdHeader) this.message .getHeader(getCorrectHeaderName(CallIdHeader.NAME)); - if (id != null) + if (id != null){ + if(logger.isDebugEnabled()) { + logger.debug("getCallId - return=" + id.getCallId()); + } return id.getCallId(); - else + } else { + if(logger.isDebugEnabled()) { + logger.debug("getCallId - returning null"); + } return null; + } } /* @@ -663,18 +724,18 @@ public String getCharacterEncoding() { * @see javax.servlet.sip.SipServletMessage#getContent() */ public Object getContent() throws IOException, UnsupportedEncodingException { - ContentTypeHeader contentTypeHeader = (ContentTypeHeader) + ContentTypeHeader contentTypeHeader = (ContentTypeHeader) this.message.getHeader(ContentTypeHeader.NAME); if(contentTypeHeader != null && logger.isDebugEnabled()) { logger.debug("Content type " + contentTypeHeader.getContentType()); logger.debug("Content sub type " + contentTypeHeader.getContentSubType()); - } + } if(contentTypeHeader!= null && CONTENT_TYPE_TEXT.equals(contentTypeHeader.getContentType())) { String content = null; if(message.getRawContent() != null) { String charset = this.getCharacterEncoding(); if(charset == null) { - content = new String(message.getRawContent()); + content = new String(message.getRawContent()); } else { content = new String(message.getRawContent(), charset); } @@ -684,7 +745,7 @@ public Object getContent() throws IOException, UnsupportedEncodingException { return content; } else if(contentTypeHeader!= null && CONTENT_TYPE_MULTIPART.equals(contentTypeHeader.getContentType())) { try { - return new MimeMultipart(new ByteArrayDataSource(message.getRawContent(), + return new MimeMultipart(new ByteArrayDataSource(message.getRawContent(), contentTypeHeader.toString().replaceAll(ContentTypeHeader.NAME+": ", ""))); } catch (MessagingException e) { logger.warn("Problem with multipart message.", e); @@ -706,25 +767,25 @@ private static MimeMultipart getContentAsMimeMultipart(ContentTypeHeader content // Issue 1123 : http://code.google.com/p/mobicents/issues/detail?id=1123 : Multipart type is supported String delimiter = contentTypeHeader.getParameter(MULTIPART_BOUNDARY); String start = contentTypeHeader.getParameter(MULTIPART_START); - + MimeMultipart mimeMultipart = new MimeMultipart(contentTypeHeader.getContentSubType()); if (delimiter == null) { - MimeBodyPart mbp = new MimeBodyPart(); + MimeBodyPart mbp = new MimeBodyPart(); DataSource ds = new ByteArrayDataSource(rawContent, contentTypeHeader.getContentSubType()); try { mbp.setDataHandler(new DataHandler(ds)); - mimeMultipart.addBodyPart(mbp); + mimeMultipart.addBodyPart(mbp); } catch (MessagingException e) { throw new IllegalArgumentException("couldn't create the multipart object from the message content " + rawContent, e); } } else { // splitting the body content by delimiter String[] fragments = new String(rawContent).split(MULTIPART_BOUNDARY_DELIM + delimiter); - for (String fragment: fragments) { + for (String fragment: fragments) { final String trimmedFragment = fragment.trim(); // skipping empty fragment and ending fragment looking like -- if(trimmedFragment.length() > 0 && !MULTIPART_BOUNDARY_DELIM.equals(trimmedFragment)) { - String fragmentHeaders = null; + String fragmentHeaders = null; String fragmentBody = fragment; // if there is a start, it means that there is probably headers before the content that need to be added to the mime body part // so we split headers from body content @@ -732,17 +793,17 @@ private static MimeMultipart getContentAsMimeMultipart(ContentTypeHeader content int indexOfStart = fragment.indexOf(start); if(indexOfStart != -1) { fragmentHeaders = fragmentBody.substring(0, indexOfStart + start.length()); - fragmentBody = fragmentBody.substring(indexOfStart + start.length()).trim(); + fragmentBody = fragmentBody.substring(indexOfStart + start.length()).trim(); } } - MimeBodyPart mbp = new MimeBodyPart(); + MimeBodyPart mbp = new MimeBodyPart(); try { String contentType = contentTypeHeader.getContentSubType(); // check if the body content start with a Content-Type header // if so we strip it from the content body if(fragmentBody.startsWith(ContentTypeHeader.NAME)) { int indexOfLineReturn = fragmentBody.indexOf(LINE_RETURN_DELIM); - contentType = fragmentBody.substring(0, indexOfLineReturn -1).trim(); + contentType = fragmentBody.substring(0, indexOfLineReturn -1).trim(); fragmentBody = fragmentBody.substring(indexOfLineReturn).trim(); } // setting the content body stripped from the headers @@ -758,12 +819,12 @@ private static MimeMultipart getContentAsMimeMultipart(ContentTypeHeader content } } } - mimeMultipart.addBodyPart(mbp); + mimeMultipart.addBodyPart(mbp); } catch (MessagingException e) { throw new IllegalArgumentException("couldn't create the multipart object from the message content " + rawContent, e); } } - } + } } return mimeMultipart; } @@ -803,10 +864,10 @@ public String getContentType() { // getContentType doesn't return the full header value // String contentType = cth.getContentType(); // String contentSubType = cth.getContentSubType(); -// if(contentSubType != null) +// if(contentSubType != null) // return contentType + "/" + contentSubType; return ((HeaderExt)cth).getValue(); - } + } return null; } @@ -836,7 +897,7 @@ public Address getFrom() { throw new IllegalArgumentException("Couldn't parse From Header " + from, e); } } - + /* * (non-Javadoc) * @see javax.servlet.sip.SipServletMessage#getHeader(java.lang.String) @@ -849,9 +910,9 @@ public String getHeader(String name) { value = ((SIPHeader) this.message.getHeader(nameToSearch)) .getValue(); } -// if(logger.isDebugEnabled()) { -// logger.debug("getHeader "+ name+ ", value="+ value ); -// } + if(logger.isDebugEnabled()) { + logger.debug("getHeader "+ name+ ", value="+ value ); + } return value; } @@ -895,7 +956,7 @@ public ListIterator getHeaders(String name) { /* * (non-Javadoc) - * + * * @see javax.servlet.sip.SipServletMessage#getMethod() */ public final String getMethod() { @@ -903,6 +964,9 @@ public final String getMethod() { method = message instanceof Request ? ((Request) message).getMethod() : ((CSeqHeader) message.getHeader(CSeqHeader.NAME)).getMethod(); } + if(logger.isDebugEnabled()) { + logger.debug("getMethod - return=" + method); + } return method; } @@ -912,6 +976,9 @@ public final String getMethod() { */ public Parameterable getParameterableHeader(String name) throws ServletParseException { + if(logger.isDebugEnabled()) { + logger.debug("getParameterableHeader - name=" + name); + } if (name == null) throw new NullPointerException( @@ -920,15 +987,15 @@ public Parameterable getParameterableHeader(String name) String nameToSearch = getCorrectHeaderName(name); Header h = this.message.getHeader(nameToSearch); - + if(!isParameterable(name)) { throw new ServletParseException(name + " header is not parameterable !"); } - + if(h == null) { return null; } - + return createParameterable(h, getFullHeaderName(name), message instanceof Request); } @@ -950,11 +1017,11 @@ public ListIterator getParameterableHeaders(String name) if(!isParameterable(name)) { throw new ServletParseException(name + " header is not parameterable !"); - } - + } + return result.listIterator(); } - + /* * (non-Javadoc) * @see javax.servlet.sip.SipServletMessage#getProtocol() @@ -968,13 +1035,13 @@ public String getProtocol() { * (non-Javadoc) * @see javax.servlet.sip.SipServletMessage#getRawContent() */ - public byte[] getRawContent() throws IOException { + public byte[] getRawContent() throws IOException { if (message != null) return message.getRawContent(); else return null; } - + /** * {@inheritDoc} */ @@ -992,7 +1059,7 @@ public int getInitialRemotePort() { /** * {@inheritDoc} */ - public String getInitialTransport() { + public String getInitialTransport() { return transactionApplicationData.getInitialRemoteTransport(); } @@ -1056,7 +1123,7 @@ public int getRemotePort() { return port; } } - + /* * (non-Javadoc) * @see javax.servlet.sip.SipServletMessage#getTransport() @@ -1068,7 +1135,7 @@ public String getTransport() { return null; } } - + /* * (non-Javadoc) * @see javax.servlet.sip.SipServletMessage#getRemoteUser() @@ -1082,42 +1149,57 @@ public String getRemoteUser() { /* * (non-Javadoc) - * + * * @see javax.servlet.sip.SipServletMessage#getSession() */ public SipSession getSession() { + if(logger.isDebugEnabled()) { + logger.debug("getSession"); + } return getSession(true); } /* * (non-Javadoc) - * + * * @see javax.servlet.sip.SipServletMessage#getSession(boolean) */ public SipSession getSession(boolean create) { - + if(logger.isDebugEnabled()) { + logger.debug("getSession - create=" + create); + } + MobicentsSipSession session = getSipSession(); if (session == null && create) { MobicentsSipApplicationSession sipApplicationSessionImpl = (MobicentsSipApplicationSession)getSipApplicationSession(create); - MobicentsSipSessionKey sessionKey = SessionManagerUtil.getSipSessionKey(sipApplicationSessionImpl.getKey().getId(), currentApplicationName, message, false); - session = sipApplicationSessionImpl.getSipContext().getSipManager().getSipSession(sessionKey, create, - sipFactoryImpl, sipApplicationSessionImpl); - session.setSessionCreatingTransactionRequest(this); - session.setOrphan(isOrphan()); - sessionKey = session.getKey(); - } - + if (sipApplicationSessionImpl != null) { + MobicentsSipSessionKey sessionKey = SessionManagerUtil.getSipSessionKey(sipApplicationSessionImpl.getKey().getId(), currentApplicationName, message, false); + session = sipApplicationSessionImpl.getSipContext().getSipManager().getSipSession(sessionKey, create, + sipFactoryImpl, sipApplicationSessionImpl); + session.setSessionCreatingTransactionRequest(this); + session.setOrphan(isOrphan()); + sessionKey = session.getKey(); + } + } + if(session != null) { return session.getFacade(); } + if(logger.isDebugEnabled()) { + logger.debug("getSession - returning null"); + } return null; } - + /** * Retrieve the sip session implementation * @return the sip session implementation */ - public final MobicentsSipSession getSipSession() { + public final MobicentsSipSession getSipSession() { + if(logger.isDebugEnabled()) { + logger.debug("getSipSession"); + } + if(sipSession == null && sessionKey == null) { sessionKey = getSipSessionKey(); if(logger.isDebugEnabled()) { @@ -1133,7 +1215,7 @@ public final MobicentsSipSession getSipSession() { } else if (transaction != null && transaction.getApplicationData() != null) { this.sessionKey = ((TransactionApplicationData)transaction.getApplicationData()).getSipSessionKey(); if(logger.isDebugEnabled()) { - logger.debug("session Key is " + sessionKey + ", retrieved from the transaction txAppData " + + logger.debug("session Key is " + sessionKey + ", retrieved from the transaction txAppData " + (TransactionApplicationData)transaction.getApplicationData()); } } else { @@ -1153,35 +1235,47 @@ public final MobicentsSipSession getSipSession() { if(logger.isDebugEnabled()) { logger.debug("session is null, trying to load the session from the sessionKey " + sessionKey); } - final String applicationName = sessionKey.getApplicationName(); + final String applicationName = sessionKey.getApplicationName(); final SipContext sipContext = sipFactoryImpl.getSipApplicationDispatcher().findSipApplication(applicationName); SipApplicationSessionKey sipApplicationSessionKey = new SipApplicationSessionKey(sessionKey.getApplicationSessionId(), sessionKey.getApplicationName(), null); MobicentsSipApplicationSession sipApplicationSession = sipContext.getSipManager().getSipApplicationSession(sipApplicationSessionKey, false); - sipSession = sipContext.getSipManager().getSipSession(sessionKey, false, sipFactoryImpl, sipApplicationSession); + sipSession = sipContext.getSipManager().getSipSession(sessionKey, false, sipFactoryImpl, sipApplicationSession); if(logger.isDebugEnabled()) { if(sipSession == null) { logger.debug("couldn't find any session with sessionKey " + sessionKey); } else { logger.debug("reloaded session session " + sipSession + " with sessionKey " + sessionKey); - } + } } - } - return sipSession; + } + return sipSession; } /** * @param session the session to set */ public void setSipSession(MobicentsSipSession session) { - // we store the session in JVM to cope with race conditions on session invalidation + if(logger.isDebugEnabled()) { + logger.debug("setSipSession - session=" + session); + if (session != null){ + logger.debug("setSipSession - session.getSipApplicationSession()=" + session.getSipApplicationSession()); + if (session.getSipApplicationSession() != null){ + logger.debug("setSipSession - session.getSipApplicationSession().getId()=" + session.getSipApplicationSession().getId()); + } + } + } + // we store the session in JVM to cope with race conditions on session invalidation // See Issue 1294 http://code.google.com/p/mobicents/issues/detail?id=1294 // but it will not be persisted to avoid unecessary replication if the message is persisted this.sipSession = session; if (session != null){ this.sessionKey = session.getKey(); + if(logger.isDebugEnabled()) { + logger.debug("setSipSession - this.sessionKey=" + this.sessionKey); + } } else { this.sessionKey = null; - } + } } /** @@ -1192,9 +1286,12 @@ public MobicentsSipSessionKey getSipSessionKey() { } public void setSipSessionKey(MobicentsSipSessionKey sessionKey) { + if(logger.isDebugEnabled()) { + logger.debug("setSipSessionKey - sessionKey=" + sessionKey); + } this.sessionKey = sessionKey; } - + /* * (non-Javadoc) * @see javax.servlet.sip.SipServletMessage#getTo() @@ -1210,7 +1307,7 @@ public Address getTo() { throw new IllegalArgumentException("Couldn't parse From Header " + to, e); } } - + /* * (non-Javadoc) * @see javax.servlet.sip.SipServletMessage#getUserPrincipal() @@ -1223,7 +1320,7 @@ public SipPrincipal getUserPrincipal() { } return this.userPrincipal; } - + public void setUserPrincipal(SipPrincipal principal) { this.userPrincipal = principal; } @@ -1232,7 +1329,7 @@ public void setUserPrincipal(SipPrincipal principal) { * (non-Javadoc) * @see javax.servlet.sip.SipServletMessage#isSecure() */ - public boolean isSecure() { + public boolean isSecure() { return ListeningPoint.TLS.equalsIgnoreCase(JainSipUtils.findTransport(message)); } @@ -1252,16 +1349,22 @@ public boolean isUserInRole(String role) { * @see javax.servlet.sip.SipServletMessage#removeAttribute(java.lang.String) */ public void removeAttribute(String name) { + if(logger.isDebugEnabled()) { + logger.debug("removeAttribute - name=" + name); + } if(attributes != null) { this.attributes.remove(name); } } - + /* * (non-Javadoc) * @see javax.servlet.sip.SipServletMessage#removeHeader(java.lang.String) */ public void removeHeader(String name) { + if(logger.isDebugEnabled()) { + logger.debug("removeHeader - name=" + name); + } checkCommitted(); String hName = getFullHeaderName(name); @@ -1277,7 +1380,7 @@ public void removeHeader(String name) { + hName + "]"); } } - + if (hName.equalsIgnoreCase("From") || hName.equalsIgnoreCase("To")) { logger.error("Error, can't remove From or To header [" + hName + "]"); throw new IllegalArgumentException( @@ -1289,8 +1392,11 @@ public void removeHeader(String name) { this.message.removeHeader(nameToSearch); } - + public void removeHeaderInternal(String name, boolean bypassSystemHeaderCheck) { + if(logger.isDebugEnabled()) { + logger.debug("removeHeaderInternal - name=" + name + ", bypassSystemHeaderCheck=" + bypassSystemHeaderCheck); + } String hName = getFullHeaderName(name); if (logger.isDebugEnabled()) @@ -1306,7 +1412,7 @@ public void removeHeaderInternal(String name, boolean bypassSystemHeaderCheck) { String nameToRemove = getCorrectHeaderName(hName); try { - message.removeHeader(nameToRemove); + message.removeHeader(nameToRemove); } catch (Exception ex) { throw new IllegalArgumentException("Illegal args supplied ", ex); } @@ -1335,6 +1441,9 @@ public void setAcceptLanguage(Locale locale) { * @see javax.servlet.sip.SipServletMessage#setAddressHeader(java.lang.String, javax.servlet.sip.Address) */ public void setAddressHeader(String name, Address addr) { + if(logger.isDebugEnabled()) { + logger.debug("setAddressHeader - name=" + name + ", addr=" + addr); + } checkCommitted(); String hName = getFullHeaderName(name); @@ -1368,7 +1477,7 @@ public void setAddressHeader(String name, Address addr) { this.message.setHeader(h); } catch (ParseException e) { logger.error("Parsing problem while setting address header with name " - + name + " and address "+ addr, e); + + name + " and address "+ addr, e); } } @@ -1377,6 +1486,9 @@ public void setAddressHeader(String name, Address addr) { * @see javax.servlet.sip.SipServletMessage#setAttribute(java.lang.String, java.lang.Object) */ public void setAttribute(String name, Object o) { + if(logger.isDebugEnabled()) { + logger.debug("setAttribute - name=" + name + ", object=" + o); + } if (name == null) throw new NullPointerException("Attribute name can not be null."); this.getAttributeMap().put(name, o); @@ -1389,7 +1501,7 @@ public void setAttribute(String name, Object o) { public void setCharacterEncoding(String enc) throws UnsupportedEncodingException { new String("testEncoding".getBytes(),enc); checkCommitted(); - try { + try { this.message.setContentEncoding(SipFactoryImpl.headerFactory .createContentEncodingHeader(enc)); } catch (Exception ex) { @@ -1397,7 +1509,7 @@ public void setCharacterEncoding(String enc) throws UnsupportedEncodingException } } - + /* * (non-Javadoc) * @see javax.servlet.sip.SipServletMessage#setContent(java.lang.Object, java.lang.String) @@ -1405,17 +1517,17 @@ public void setCharacterEncoding(String enc) throws UnsupportedEncodingException public void setContent(Object content, String contentType) throws UnsupportedEncodingException { // https://code.google.com/p/sipservlets/issues/detail?id=202 - if(getSipSession().getProxy() == null) { + if(getSipSession().getProxy() == null) { checkMessageState(); } checkContentType(contentType); checkCommitted(); - + if(contentType != null && contentType.length() > 0) { this.addHeader(ContentTypeHeader.NAME, contentType); - ContentTypeHeader contentTypeHeader = (ContentTypeHeader)this.message.getHeader(ContentTypeHeader.NAME); + ContentTypeHeader contentTypeHeader = (ContentTypeHeader)this.message.getHeader(ContentTypeHeader.NAME); String charset = this.getCharacterEncoding(); - try { + try { // https://code.google.com/p/sipservlets/issues/detail?id=169 if(contentType.contains(CONTENT_TYPE_MULTIPART) && content instanceof Multipart) { // Fix for Issue 2667 : Correct Handling of MimeMultipart @@ -1435,11 +1547,11 @@ public void setContent(Object content, String contentType) } catch (UnsupportedEncodingException uee) { throw uee; } catch (Exception e) { - throw new IllegalArgumentException("Parse error reading content " + content + " with content type " + contentType, e); - } + throw new IllegalArgumentException("Parse error reading content " + content + " with content type " + contentType, e); + } } } - + protected abstract void checkMessageState(); /** @@ -1452,7 +1564,7 @@ private void checkContentType(String contentType) { throw new IllegalArgumentException("the content type cannot be null"); } int indexOfSlash = contentType.indexOf("/"); - if(indexOfSlash != -1) { + if(indexOfSlash != -1) { if(!JainSipUtils.IANA_ALLOWED_CONTENT_TYPES.contains(contentType.substring(0, indexOfSlash))) { throw new IllegalArgumentException("the given content type " + contentType + " is not allowed"); } @@ -1467,11 +1579,11 @@ private void checkContentType(String contentType) { */ public void setContentLanguage(Locale locale) { checkCommitted(); - ContentLanguageHeader contentLanguageHeader = + ContentLanguageHeader contentLanguageHeader = SipFactoryImpl.headerFactory.createContentLanguageHeader(locale); this.message.setContentLanguage(contentLanguageHeader); } - + /* * (non-Javadoc) * @see javax.servlet.sip.SipServletMessage#setContentLength(int) @@ -1512,8 +1624,8 @@ public void setContentType(String type) { */ public void setExpires(int seconds) { try { - ExpiresHeader expiresHeader = - SipFactoryImpl.headerFactory.createExpiresHeader(seconds); + ExpiresHeader expiresHeader = + SipFactoryImpl.headerFactory.createExpiresHeader(seconds); expiresHeader.setExpires(seconds); this.message.setExpires(expiresHeader); } catch (Exception e) { @@ -1526,6 +1638,10 @@ public void setExpires(int seconds) { * @see javax.servlet.sip.SipServletMessage#setHeader(java.lang.String, java.lang.String) */ public void setHeader(String name, String value) { + if(logger.isDebugEnabled()) { + logger.debug("setHeader - name=" + name + ", value=" + value); + } + if(name == null) { throw new NullPointerException ("name parameter is null"); } @@ -1536,7 +1652,7 @@ public void setHeader(String name, String value) { throw new IllegalArgumentException(name + " is a system header !"); } checkCommitted(); - + try { // Dealing with Allow:INVITE, ACK, CANCEL, OPTIONS, BYE kind of headers if(JainSipUtils.LIST_HEADER_NAMES.contains(name)) { @@ -1569,8 +1685,8 @@ public void setHeaderForm(HeaderForm form) { // action is performed if(form == HeaderForm.DEFAULT) return; - -// if(form == HeaderForm.COMPACT) { + +// if(form == HeaderForm.COMPACT) { // for(String fullName : headerFull2CompactNamesMappings.keySet()) { // if(message.getHeader(fullName) != null) { // try { @@ -1585,12 +1701,16 @@ public void setHeaderForm(HeaderForm form) { // } // } } - + /* * (non-Javadoc) * @see javax.servlet.sip.SipServletMessage#setParameterableHeader(java.lang.String, javax.servlet.sip.Parameterable) */ public void setParameterableHeader(String name, Parameterable param) { + if(logger.isDebugEnabled()) { + logger.debug("setParameterableHeader - name=" + name + ", param=" + param); + } + checkCommitted(); if(isSystemHeader(getModifiableRule(name))) { throw new IllegalArgumentException(name + " is a system header !"); @@ -1610,23 +1730,23 @@ public void setParameterableHeader(String name, Parameterable param) { * and responses, 3xx and 485 responses, and 200/OPTIONS responses. * Additionally, for containers implementing the reliable provisional * responses extension, RAck and RSeq are considered system headers also. - * + * * This method should return true if passed name - full or compact is name * of system header in context of this message. Each subclass has to * implement it in the manner that it conforms to semantics of wrapping * class - * + * * @param headerName - * either long or compact header name * @return */ public abstract ModifiableRule getModifiableRule(String headerName); - private static final String SYS_HDR_MOD_OVERRIDE ="org.restcomm.servlets.sip.OVERRIDE_SYSTEM_HEADER_MODIFICATION"; + static final String SYS_HDR_MOD_OVERRIDE = INTERNAL_ATT_PREFIX + ".OVERRIDE_SYSTEM_HEADER_MODIFICATION"; /** * Allows to override the System header modifiable rule assignment. - * + * * @return if the InitParameter is present at servletContext, or null * otherwise */ @@ -1641,10 +1761,10 @@ protected ModifiableRule retrieveModifiableOverriden() { overridenRule = ModifiableRule.valueOf(overridenRuleStr); } } - return overridenRule; + return overridenRule; } - - + + /** * Applications must not add, delete, or modify so-called "system" headers. @@ -1654,12 +1774,12 @@ protected ModifiableRule retrieveModifiableOverriden() { * and responses, 3xx and 485 responses, and 200/OPTIONS responses. * Additionally, for containers implementing the reliable provisional * responses extension, RAck and RSeq are considered system headers also. - * + * * This method should return true if passed name - full or compact is name * of system header in context of this message. Each subclass has to * implement it in the manner that it conforms to semantics of wrapping * class - * + * * @param headerName - * either long or compact header name * @return @@ -1671,7 +1791,7 @@ public static boolean isSystemHeader(ModifiableRule modifiableRule) { return false; } } - + /** * Support for GRUU https://github.com/Mobicents/sip-servlets/issues/51 * if the header contains one of the gruu, gr, temp-gruu or pub-gruu, it is allowed to set the Contact Header @@ -1679,8 +1799,8 @@ public static boolean isSystemHeader(ModifiableRule modifiableRule) { */ public static boolean isSystemHeaderAndNotGruu(ModifiableRule modifiableRule, Parameterable parameterable) { boolean isSettingGruu = false; - if(modifiableRule == ModifiableRule.ContactSystem && - (parameterable.getParameter("gruu") != null || + if(modifiableRule == ModifiableRule.ContactSystem && + (parameterable.getParameter("gruu") != null || parameterable.getParameter("gr") != null)) { isSettingGruu = true; if (logger.isDebugEnabled()) @@ -1688,10 +1808,10 @@ public static boolean isSystemHeaderAndNotGruu(ModifiableRule modifiableRule, Pa } return !isSettingGruu && isSystemHeader(modifiableRule); } - + public static boolean isSystemHeaderAndNotGruu(ModifiableRule modifiableRule, String value) { boolean isSettingGruu = false; - if(modifiableRule == ModifiableRule.ContactSystem && + if(modifiableRule == ModifiableRule.ContactSystem && (value.indexOf("gruu") != -1 || value.indexOf("gr=") != -1)) { isSettingGruu = true; @@ -1700,11 +1820,11 @@ public static boolean isSystemHeaderAndNotGruu(ModifiableRule modifiableRule, St } return !isSettingGruu && isSystemHeader(modifiableRule); } - + /** * This method checks if passed name is name of address type header - * according to rfc 3261 - * + * * @param headerName - * name of header - either full or compact * @return @@ -1718,7 +1838,7 @@ public static boolean isAddressTypeHeader(String headerName) { /** * This method tries to resolve header name - meaning if it is compact - it * returns full name, if its not, it returns passed value. - * + * * @param headerName * @return */ @@ -1742,7 +1862,7 @@ protected static String getFullHeaderName(String headerName) { * compact form it is returned, otherwise method tries to find compact name - * if it is found, string rpresenting compact name is returned, otherwise * null!!! - * + * * @param headerName * @return */ @@ -1793,7 +1913,7 @@ public Transaction getTransaction() { if (logger.isDebugEnabled()) { logger.debug("transaction " + transaction + " transactionId = " + transactionId + " transactionType " + transactionType); } - if(transaction == null && transactionId != null) { + if(transaction == null && transactionId != null) { // used for early dialog failover purposes, lazily load the transaction setTransaction(((ClusteredSipStack)StaticServiceHolder.sipStandardService.getSipStack()).findTransaction(transactionId, transactionType)); if(transaction != null) { @@ -1843,7 +1963,7 @@ public void setTransaction(Transaction transaction) { public void setTransport(String transport) { this.transport = transport; } - + protected static int countChars(String string, char c) { int count = 0; for(int w=0; w") // || !isParameterable(getFullHeaderName(hName))) { - + Map paramMap = new HashMap(); String value = stringHeader; String displayName = null; @@ -1874,29 +1994,29 @@ protected static Parameterable createParameterable(Header header, String hName, String displayNameString = stringHeader.substring(1); int nextIndexOfDoubleQuote = displayNameString.indexOf("\""); displayName = stringHeader.substring(0, nextIndexOfDoubleQuote + 2); - stringHeader = stringHeader.substring(nextIndexOfDoubleQuote + 2).trim(); + stringHeader = stringHeader.substring(nextIndexOfDoubleQuote + 2).trim(); } - + boolean hasLaRaQuotes = false; if(stringHeader.trim().indexOf("<") == 0) { - + stringHeader = stringHeader.substring(1); int indexOfBracket = stringHeader.indexOf(">"); if(indexOfBracket != -1) { hasLaRaQuotes = true; } //String[] split = stringHeader.split(">"); - - value = stringHeader.substring(0, indexOfBracket);//split[0]; + + value = stringHeader.substring(0, indexOfBracket);//split[0]; String restOfHeader = stringHeader.substring(indexOfBracket+1) ; - + if (restOfHeader.length() > 1 && restOfHeader.contains(";")) { // repleace first ";" with "" because it separates us from the URI that we romved restOfHeader = restOfHeader.replaceFirst(";", ""); String[] split = restOfHeader.split(";"); - + // Now concatenate the items that have quotes that represent nested parameters http://code.google.com/p/sipservlets/issues/detail?id=105 - // example ;expires=500;+sip.instance="";gruu="sip:100@ocs14.com;opaque=user:epid:xxxxxxxxxxxxxxxxxxxxxxxx;gruu" + // example ;expires=500;+sip.instance="";gruu="sip:100@ocs14.com;opaque=user:epid:xxxxxxxxxxxxxxxxxxxxxxxx;gruu" ArrayList resplitListWithQuotes = new ArrayList(); // here we collect the items and append related entries that are part of the same quotation zone int resplitIndex = 0; boolean addToPrevious = false; @@ -1912,7 +2032,7 @@ protected static Parameterable createParameterable(Header header, String hName, addToPrevious = true; } } else { // if mod 2 then there are no unclosed quotes in that item - if(addToPrevious) { // we will add any data + if(addToPrevious) { // we will add any data resplitListWithQuotes.get(resplitIndex-1).append(";" + split[q]); // must reappend the ";" symbol because we lost it in the split } else { resplitListWithQuotes.add(new StringBuffer(split[q])); // this is the normal case without quotes to take care of @@ -1920,19 +2040,19 @@ protected static Parameterable createParameterable(Header header, String hName, } } } - + if(addToPrevious) { // Lets warn if something is really that wrong throw new RuntimeException("Unclosed quote sign in this string " + whole); } - + // Change the split array now with the adjusted array String[] newSplit = new String[resplitListWithQuotes.size()]; for(int q=0; q 1 && value.contains(";")) { // repleace first ";" with "" String parameters = value.substring(value.indexOf(";") + 1); - value = value.substring(0, value.indexOf(";")); + value = value.substring(0, value.indexOf(";")); String[] split = parameters.split(";"); - + for (String pair : split) { String[] vals = pair.split("="); if (vals.length > 2) { @@ -1972,7 +2092,7 @@ protected static Parameterable createParameterable(Header header, String hName, "Wrong parameter format, expected value or name[" + pair + "]"); } - // Fix to Issue 1010 (http://code.google.com/p/mobicents/issues/detail?id=1010) : Unable to set flag parameter to parameterable header + // Fix to Issue 1010 (http://code.google.com/p/mobicents/issues/detail?id=1010) : Unable to set flag parameter to parameterable header // from Alexander Kozlov from Codeminders paramMap.put(vals[0], vals.length == 2 ? vals[1] : ""); } @@ -1980,9 +2100,9 @@ protected static Parameterable createParameterable(Header header, String hName, // Deals with https://code.google.com/p/sipservlets/issues/detail?id=239 // repleace first ";" with "" // String parameters = value.substring(value.indexOf(",") + 1); -// value = value.substring(0, value.indexOf(",")); +// value = value.substring(0, value.indexOf(",")); String[] split = value.split(","); - + for (String pair : split) { String[] vals = pair.split("="); if (vals.length > 2) { @@ -2002,13 +2122,13 @@ protected static Parameterable createParameterable(Header header, String hName, paramMap.put(vals[0], paramValue); } } - } - + } + // quotes are parts of the value as well as the display Name if(hasLaRaQuotes) { value = "<" + value + ">"; } - + // if a display name is present then we need add the quote back if(displayName != null) { value = displayName.concat(value); @@ -2064,8 +2184,8 @@ public String getCurrentApplicationName() { */ public void setCurrentApplicationName(String currentApplicationName) { this.currentApplicationName = currentApplicationName; - } - + } + /* * (non-Javadoc) @@ -2077,9 +2197,9 @@ public String getLocalAddr() { return sipTransaction.getHost(); } else { final String transport = JainSipUtils.findTransport(message); - final MobicentsExtendedListeningPoint listeningPoint = sipFactoryImpl.getSipNetworkInterfaceManager().findMatchingListeningPoint(transport, false); + final MobicentsExtendedListeningPoint listeningPoint = sipFactoryImpl.getSipNetworkInterfaceManager().findMatchingListeningPoint(transport, false); return listeningPoint.getHost(true); - } + } } /* @@ -2092,13 +2212,13 @@ public int getLocalPort() { return sipTransaction.getPort(); } else { final String transport = JainSipUtils.findTransport(message); - final MobicentsExtendedListeningPoint listeningPoint = sipFactoryImpl.getSipNetworkInterfaceManager().findMatchingListeningPoint(transport, false); + final MobicentsExtendedListeningPoint listeningPoint = sipFactoryImpl.getSipNetworkInterfaceManager().findMatchingListeningPoint(transport, false); return listeningPoint.getPort(); } } // Fix for Issue 1552 http://code.google.com/p/mobicents/issues/detail?id=1552 // Container does not recognise 100rel if there are other extensions on the Require or Supported line - // we check all the values of Require and Supported headers to make sure the 100rel is present + // we check all the values of Require and Supported headers to make sure the 100rel is present protected boolean containsRel100(Message message) { ListIterator requireHeaders = message.getHeaders(RequireHeader.NAME); if(requireHeaders != null) { @@ -2118,32 +2238,41 @@ protected boolean containsRel100(Message message) { } return false; } - + public abstract void cleanUp(); - + protected Map getAttributeMap() { if(this.attributes == null) { this.attributes = new ConcurrentHashMap(); } return this.attributes; } - + // Issue 2354 protected void setAttributeMap(Map atttributes) { this.attributes = atttributes; } - + /* * (non-Javadoc) * @see java.io.Externalizable#readExternal(java.io.ObjectInput) */ public void readExternal(ObjectInput in) throws IOException, - ClassNotFoundException { + ClassNotFoundException { + if(logger.isDebugEnabled()) { + logger.debug("readExternal"); + } sipFactoryImpl = (SipFactoryImpl) in.readObject(); String sessionKeyString = in.readUTF(); + if(logger.isDebugEnabled()) { + logger.debug("readExternal - sessionKeyString=" + sessionKeyString); + } if (sessionKeyString.length() > 0) { try { sessionKey = SessionManagerUtil.parseSipSessionKey(sessionKeyString); + if(logger.isDebugEnabled()) { + logger.debug("readExternal - sessionKey=" + sessionKey); + } } catch (ParseException e) { throw new IllegalArgumentException("SIP Sesion Key " + sessionKeyString + " previously serialized could not be reparsed", e); } @@ -2175,7 +2304,7 @@ public void readExternal(ObjectInput in) throws IOException, if(transactionId != null) { if(transactionId.equals("")) { transactionId = null; - } else { + } else { transactionType = in.readBoolean(); if (logger.isDebugEnabled()) { logger.debug("readExternal transactionType = " + transactionType); @@ -2184,12 +2313,16 @@ public void readExternal(ObjectInput in) throws IOException, } } } - + /* * (non-Javadoc) * @see java.io.Externalizable#writeExternal(java.io.ObjectOutput) */ public void writeExternal(ObjectOutput out) throws IOException { + if(logger.isDebugEnabled()) { + logger.debug("writeExternal - sessionKey=" + sessionKey); + } + out.writeObject(sipFactoryImpl); if(sessionKey != null) { out.writeUTF(sessionKey.toString()); @@ -2205,10 +2338,10 @@ public void writeExternal(ObjectOutput out) throws IOException { Object[][] attributesArray = new Object[2][attributes.size()]; int i = 0; for (Entry entry : attributes.entrySet()) { - attributesArray [0][i] = entry.getKey(); + attributesArray [0][i] = entry.getKey(); attributesArray [1][i] = entry.getValue(); i++; - } + } out.writeObject(attributesArray); } else { out.writeInt(0); @@ -2225,7 +2358,7 @@ public void writeExternal(ObjectOutput out) throws IOException { } else { out.writeUTF(""); } - out.writeBoolean(isMessageSent); + out.writeBoolean(isMessageSent); if(ReplicationStrategy.EarlyDialog == StaticServiceHolder.sipStandardService.getReplicationStrategy()) { if (logger.isDebugEnabled()) { logger.debug("writeExternal transaction = " + transaction); @@ -2274,8 +2407,8 @@ public boolean equals(Object obj) { return true; } - - + + // public void cleanUp() { // if(logger.isDebugEnabled()) { // logger.debug("cleaning up the message " + message); @@ -2288,13 +2421,13 @@ public boolean equals(Object obj) { // dialog = null; // headerForm= null; // message= null; -// +// // remoteAddr = null; //// sessionKey = null; -//// sipFactoryImpl = null; +//// sipFactoryImpl = null; // sipSession = null; // method = null; -// +// //// if(transactionApplicationData != null) { //// transactionApplicationData.cleanUp(false); // transactionApplicationData = null; @@ -2304,22 +2437,29 @@ public boolean equals(Object obj) { // userPrincipal= null; // } public void setOrphan(boolean orphan) { + if(logger.isDebugEnabled()) { + logger.debug("setOrphan - orphan=" + orphan); + } this.orphan = orphan; } public boolean isOrphan() { return orphan; - } + } public String getAppSessionId() { return appSessionId; } - + public void setAppSessionId(String appSessionId) { + if(logger.isDebugEnabled()) { + logger.debug("setAppSessionId - appSessionId=" + appSessionId); + } this.appSessionId = appSessionId; } - + public boolean isMessageSent() { return isMessageSent; } } + diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/SipServletRequestImpl.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/SipServletRequestImpl.java index 06c3f6f98b..63d5c2ee15 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/SipServletRequestImpl.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/SipServletRequestImpl.java @@ -28,6 +28,7 @@ import gov.nist.javax.sip.stack.IllegalTransactionStateException; import gov.nist.javax.sip.stack.IllegalTransactionStateException.Reason; import gov.nist.javax.sip.stack.SIPTransaction; +import gov.nist.javax.sip.SipProviderImpl; import java.io.BufferedReader; import java.io.IOException; @@ -92,6 +93,7 @@ import javax.sip.message.Message; import javax.sip.message.Request; import javax.sip.message.Response; +import gov.nist.javax.sip.stack.SIPDialog; import org.apache.log4j.Logger; import org.mobicents.ext.javax.sip.dns.DNSAwareRouter; @@ -133,23 +135,23 @@ public abstract class SipServletRequestImpl extends SipServletMessageImpl implem private static final long serialVersionUID = 1L; private static final Logger logger = Logger.getLogger(SipServletRequestImpl.class); - + private static final String EXCEPTION_MESSAGE = "The context does not allow you to modify this request !"; - + public static final Set NON_INITIAL_SIP_REQUEST_METHODS = new HashSet(); - + static { NON_INITIAL_SIP_REQUEST_METHODS.add("CANCEL"); NON_INITIAL_SIP_REQUEST_METHODS.add("BYE"); NON_INITIAL_SIP_REQUEST_METHODS.add("PRACK"); NON_INITIAL_SIP_REQUEST_METHODS.add("ACK"); NON_INITIAL_SIP_REQUEST_METHODS.add("UPDATE"); - NON_INITIAL_SIP_REQUEST_METHODS.add("INFO"); + NON_INITIAL_SIP_REQUEST_METHODS.add("INFO"); }; - + /* Linked request (for b2bua) */ private SipServletRequestImpl linkedRequest; - + private boolean createDialog; /* * Popped route header - when we are the UAS we pop and keep the route @@ -162,11 +164,11 @@ public abstract class SipServletRequestImpl extends SipServletMessageImpl implem private SipApplicationRoutingDirective routingDirective = SipApplicationRoutingDirective.NEW; private RoutingState routingState; - + private transient SipServletResponse lastFinalResponse; - + private transient SipServletResponse lastInformationalResponse; - + /** * Routing region. */ @@ -175,38 +177,46 @@ public abstract class SipServletRequestImpl extends SipServletMessageImpl implem private transient URI subscriberURI; private boolean isInitial; - + private boolean isFinalResponseGenerated; - - private boolean is1xxResponseGenerated; - - private transient boolean isReadOnly; - + + private boolean is1xxResponseGenerated; + + private transient boolean isReadOnly; + // This field is only used in CANCEL requests where we need the INVITe transaction private transient Transaction inviteTransactionToCancel; - + // needed for externalizable public SipServletRequestImpl () {} - + protected SipServletRequestImpl(Request request, SipFactoryImpl sipFactoryImpl, MobicentsSipSession sipSession, Transaction transaction, Dialog dialog, boolean createDialog) { super(request, sipFactoryImpl, transaction, sipSession, dialog); + this.createDialog = createDialog; routingState = checkRoutingState(this, dialog); + if(logger.isDebugEnabled()) { + logger.debug("SipServletRequestImpl constructor - routingState=" + routingState); + logger.debug("SipServletRequestImpl constructor - dialog=" + dialog); + if (request != null){ + logger.debug("SipServletRequestImpl constructor - request.getMethod()=" + request.getMethod()); + } + } if(RoutingState.INITIAL.equals(routingState)) { isInitial = true; } isFinalResponseGenerated = false; } - + @Override public ModifiableRule getModifiableRule(String headerName) { ModifiableRule overriden = retrieveModifiableOverriden(); if ( overriden != null ) { return overriden; } - + String hName = getFullHeaderName(headerName); /* @@ -216,7 +226,7 @@ public ModifiableRule getModifiableRule(String headerName) { * as a special treatment */ boolean isSystemHeader = JainSipUtils.SYSTEM_HEADERS.contains(hName); - + if (isSystemHeader) { return ModifiableRule.NotModifiable; } @@ -236,16 +246,16 @@ public ModifiableRule getModifiableRule(String headerName) { return ModifiableRule.NotModifiable; } } - - if(hName.equals(ContactHeader.NAME)) { + + if(hName.equalsIgnoreCase(ContactHeader.NAME)) { Request request = (Request) this.message; - + String method = request.getMethod(); if (method.equals(Request.REGISTER)) { return ModifiableRule.ContactNotSystem; } else { return ModifiableRule.ContactSystem; - } + } } else { return ModifiableRule.Modifiable; } @@ -268,8 +278,8 @@ public SipServletRequest createCancel() { throw new IllegalStateException("final response already sent!"); } } - - try { + + try { Request cancelRequest = ((ClientTransaction) getTransaction()) .createCancel(); SipServletRequestImpl newRequest = (SipServletRequestImpl) sipFactoryImpl.getMobicentsSipServletMessageFactory().createSipServletRequest( @@ -285,21 +295,21 @@ cancelRequest, getSipSession(), /* * (non-Javadoc) - * + * * @see javax.servlet.sip.SipServletRequest#createResponse(int) */ public SipServletResponse createResponse(int statusCode) { return createResponse(statusCode, null, true, false); } - + /* * (non-Javadoc) * @see javax.servlet.sip.SipServletRequest#createResponse(int, java.lang.String) */ public SipServletResponse createResponse(final int statusCode, final String reasonPhrase) { return createResponse(statusCode, reasonPhrase, true, false); - } - + } + public SipServletResponse createResponse(final int statusCode, final String reasonPhrase, boolean validate, boolean hasBeenReceived) { checkReadOnly(); final Transaction transaction = getTransaction(); @@ -319,7 +329,7 @@ public SipServletResponse createResponse(final int statusCode, final String reas try { final Request request = (Request) this.getMessage(); final Response response = SipFactoryImpl.messageFactory.createResponse( - statusCode, request); + statusCode, request); if(reasonPhrase!=null) { response.setReasonPhrase(reasonPhrase); } @@ -330,15 +340,17 @@ public SipServletResponse createResponse(final int statusCode, final String reas final ToHeader toHeader = (ToHeader) response .getHeader(ToHeader.NAME); // If we already have a to tag, dont create new - if (toHeader.getTag() == null) { + if (toHeader.getTag() == null) { // if a dialog has already been created // reuse local tag final Dialog dialog = transaction.getDialog(); if(session != null && dialog != null && dialog.getLocalTag() != null && dialog.getLocalTag().length() > 0 && session.getKey().getToTag() != null && session.getKey().getToTag().length() >0) { - if(!dialog.getLocalTag().equals(session.getKey().getToTag())) { + if(session.getB2buaHelper() == null && + !dialog.getLocalTag().equals(session.getKey().getToTag())) { // Issue 2354 : if the dialog to tag is different than the session to tag use the session to tag // so that we send the forked response out with the correct to tag + //Added B2BUA condition becuase this actually makes the forking cases to fail if(logger.isDebugEnabled()) { logger.debug("setting session ToTag: " + session.getKey().getToTag()); } @@ -349,7 +361,7 @@ public SipServletResponse createResponse(final int statusCode, final String reas } toHeader.setTag(dialog.getLocalTag()); } - } else if(session != null && session.getSipApplicationSession() != null) { + } else if(session != null && session.getSipApplicationSession() != null) { final MobicentsSipApplicationSessionKey sipAppSessionKey = session.getSipApplicationSession().getKey(); final MobicentsSipSessionKey sipSessionKey = session.getKey(); // Fix for Issue 1044 : javax.sip.SipException: Tag mismatch dialogTag during process B2B response @@ -367,9 +379,9 @@ public SipServletResponse createResponse(final int statusCode, final String reas if(logger.isDebugEnabled()) { logger.debug("setting ToTag: " + toTag); } - toHeader.setTag(toTag); - } - } else { + toHeader.setTag(toTag); + } + } else { //if the sessions are null, it means it is a cancel response toHeader.setTag(Integer.toString(new Random().nextInt(10000000))); } @@ -377,20 +389,20 @@ public SipServletResponse createResponse(final int statusCode, final String reas // Following restrictions in JSR 289 Section 4.1.3 Contact Header Field // + constraints from Issue 1687 : Contact Header is present in SIP Message where it shouldn't boolean setContactHeader = true; - if ((statusCode >= 300 && statusCode < 400) || statusCode == 485 + if ((statusCode >= 300 && statusCode < 400) || statusCode == 485 || Request.REGISTER.equals(requestMethod) || Request.OPTIONS.equals(requestMethod) || Request.BYE.equals(requestMethod) || Request.CANCEL.equals(requestMethod) || Request.PRACK.equals(requestMethod) || Request.MESSAGE.equals(requestMethod) || Request.PUBLISH.equals(requestMethod)) { // don't set the contact header in those case - setContactHeader = false; - } - if(setContactHeader) { + setContactHeader = false; + } + if(setContactHeader) { String outboundInterface = null; if(session != null) { outboundInterface = session.getOutboundInterface(); } - // Add the contact header for the dialog. + // Add the contact header for the dialog. ContactHeader contactHeader = JainSipUtils.createContactHeader( super.sipFactoryImpl.getSipNetworkInterfaceManager(), request, null, null, outboundInterface); String transport = "udp"; @@ -421,7 +433,7 @@ public SipServletResponse createResponse(final int statusCode, final String reas // RouteHeader routeHeader = SipFactoryImpl.headerFactory.createRouteHeader(recordRouteHeader.getAddress()); // response.addHeader(routeHeader); // } - + if(session != null && session.getCopyRecordRouteHeadersOnSubsequentResponses() && !isInitial() && Request.INVITE.equals(requestMethod)) { // Miss Record-Route in Response for non compliant Server in reINVITE http://code.google.com/p/mobicents/issues/detail?id=2066 final ListIterator recordRouteHeaders = request.getHeaders(RecordRouteHeader.NAME); @@ -431,24 +443,24 @@ public SipServletResponse createResponse(final int statusCode, final String reas response.addHeader(recordRouteHeader); } } - + final SipServletResponseImpl newSipServletResponse = (SipServletResponseImpl) sipFactoryImpl.getMobicentsSipServletMessageFactory().createSipServletResponse( - response, + response, validate ? (ServerTransaction) transaction : transaction, session, getDialog(), hasBeenReceived, false); newSipServletResponse.setOriginalRequest(this); - if(!Request.PRACK.equals(requestMethod) && statusCode >= Response.OK && - statusCode <= Response.SESSION_NOT_ACCEPTABLE) { + if(!Request.PRACK.equals(requestMethod) && statusCode >= Response.OK && + statusCode <= Response.SESSION_NOT_ACCEPTABLE) { isFinalResponseGenerated = true; } - if(statusCode >= Response.TRYING && - statusCode < Response.OK) { + if(statusCode >= Response.TRYING && + statusCode < Response.OK) { is1xxResponseGenerated = true; } return newSipServletResponse; } catch (ParseException ex) { throw new IllegalArgumentException("Bad status code " + statusCode, ex); - } + } } public B2buaHelper getB2buaHelper() { @@ -462,12 +474,13 @@ public B2buaHelper getB2buaHelper() { b2buaHelper = new B2buaHelperImpl(); b2buaHelper.setMobicentsSipFactory(sipFactoryImpl); b2buaHelper.setSipManager(session.getSipApplicationSession().getSipContext().getSipManager()); + b2buaHelper.setOriginalRequest(sipSession, this); if(JainSipUtils.DIALOG_CREATING_METHODS.contains(getMethod())) { this.createDialog = true; // flag that we want to create a dialog for outgoing request. } session.setB2buaHelper(b2buaHelper); return b2buaHelper; - } + } public ServletInputStream getInputStream() throws IOException { return null; @@ -480,7 +493,7 @@ public int getMaxForwards() { /* * (non-Javadoc) - * + * * @see javax.servlet.sip.SipServletRequest#getPoppedRoute() */ public Address getPoppedRoute() { @@ -490,14 +503,14 @@ public Address getPoppedRoute() { } return poppedRoute; } - + public RouteHeader getPoppedRouteHeader() { return poppedRouteHeader; } /** * Set the popped route - * + * * @param routeHeader * the popped route header to set */ @@ -519,10 +532,13 @@ public Proxy getProxy() throws TooManyHopsException { * {@inheritDoc} */ public Proxy getProxy(boolean create) throws TooManyHopsException { + if (logger.isDebugEnabled()){ + logger.debug("getProxy - create=" + create); + } checkReadOnly(); final MobicentsSipSession session = getSipSession(); if (session.getB2buaHelper() != null ) throw new IllegalStateException("Cannot proxy request"); - + final MaxForwardsHeader mfHeader = (MaxForwardsHeader)this.message.getHeader(MaxForwardsHeader.NAME); if(mfHeader.getMaxForwards()<=0) { try { @@ -532,20 +548,20 @@ public Proxy getProxy(boolean create) throws TooManyHopsException { } throw new TooManyHopsException(); } - + // For requests like PUBLISH dialogs(sessions) do not exist, but some clients // attempt to send them in sequence as if they support dialogs and when such a subsequent request // comes in it gets assigned to the previous request session where the proxy is destroyed. // In this case we must create a new proxy. And we recoginze this case by additionally checking // if this request is initial. TODO: Consider deleting the session contents too? JSR 289 says // the session is keyed against the headers, not against initial/non-initial... - if (create) { + if (create) { MobicentsProxy proxy = session.getProxy(); boolean createNewProxy = false; if(isInitial() && proxy != null && proxy.getOriginalRequest() == null) { createNewProxy = true; } - if(proxy == null || createNewProxy) { + if(proxy == null || createNewProxy) { session.setProxy(new ProxyImpl(this, super.sipFactoryImpl)); } } @@ -570,7 +586,7 @@ public URI getRequestURI() { else if (request.getRequestURI() instanceof javax.sip.address.TelURL) return new TelURLImpl((javax.sip.address.TelURL) request .getRequestURI()); - else + else // From horacimacias : Fix for Issue 2115 MSS unable to handle GenericURI URIs return new GenericURIImpl(request.getRequestURI()); } @@ -579,16 +595,19 @@ else if (request.getRequestURI() instanceof javax.sip.address.TelURL) * {@inheritDoc} */ public boolean isInitial() { - return isInitial && !isOrphan(); + if(logger.isDebugEnabled()) { + logger.debug("isInitial - isInitial=" + isInitial + ", isOrphan=" + isOrphan() + ", return=" + (isInitial && !isOrphan())); + } + return isInitial && !isOrphan(); } - + /* * (non-Javadoc) * @see javax.servlet.sip.SipServletMessage#isCommitted() */ - public boolean isCommitted() { + public boolean isCommitted() { //the message is an incoming request for which a final response has been generated - if(getTransaction() instanceof ServerTransaction && + if(getTransaction() instanceof ServerTransaction && (RoutingState.FINAL_RESPONSE_SENT.equals(routingState) || isFinalResponseGenerated)) { return true; } @@ -602,13 +621,13 @@ public boolean isCommitted() { }*/ return false; } - + protected void checkMessageState() { if(isMessageSent || getTransaction() instanceof ServerTransaction) { throw new IllegalStateException("Message already sent or incoming message"); } } - + /** * {@inheritDoc} */ @@ -620,7 +639,7 @@ public void pushPath(Address uri) { if(uri.getURI() instanceof TelURL) { throw new IllegalArgumentException("Cannot push a TelUrl as a path !"); } - + if (logger.isDebugEnabled()) logger.debug("Pushing path into message of value [" + uri + "]"); @@ -643,7 +662,7 @@ public void pushRoute(Address address) { if(address.getURI() instanceof TelURL) { throw new IllegalArgumentException("Cannot push a TelUrl as a route !"); } - + javax.sip.address.SipURI sipUri = (javax.sip.address.SipURI) ((AddressImpl) address) .getAddress().getURI(); pushRoute(sipUri); @@ -653,7 +672,7 @@ public void pushRoute(Address address) { * (non-Javadoc) * @see javax.servlet.sip.SipServletRequest#pushRoute(javax.servlet.sip.SipURI) */ - public void pushRoute(SipURI uri) { + public void pushRoute(SipURI uri) { checkReadOnly(); javax.sip.address.SipURI sipUri = ((SipURIImpl) uri).getSipURI(); sipUri.setLrParam(); @@ -667,15 +686,15 @@ public void pushRoute(SipURI uri) { private void pushRoute(javax.sip.address.SipURI sipUri) { if(!isInitial() && getSipSession().getProxy() == null) { //as per JSR 289 Section 11.1.3 Pushing Route Header Field Values - // pushRoute can only be done on the initial requests. - // Subsequent requests within a dialog follow the route set. - // Any attempt to do a pushRoute on a subsequent request in a dialog + // pushRoute can only be done on the initial requests. + // Subsequent requests within a dialog follow the route set. + // Any attempt to do a pushRoute on a subsequent request in a dialog // MUST throw and IllegalStateException. throw new IllegalStateException("Cannot push route on subsequent requests, only intial ones"); } else { if (logger.isDebugEnabled()) logger.debug("Pushing route into message of value [" + sipUri + "]"); - + sipUri.setLrParam(); try { javax.sip.header.Header p = SipFactoryImpl.headerFactory @@ -688,7 +707,7 @@ private void pushRoute(javax.sip.address.SipURI sipUri) { } } } - + public void setMaxForwards(int n) { checkReadOnly(); MaxForwardsHeader mfh = (MaxForwardsHeader) this.message @@ -724,17 +743,21 @@ public void setRequestURI(URI uri) { */ public void setRoutingDirective(SipApplicationRoutingDirective directive, SipServletRequest origRequest) throws IllegalStateException { + if(logger.isDebugEnabled()) { + logger.debug("setRoutingDirective - directive=" + directive + ", origRequest=" + origRequest); + } + checkReadOnly(); SipServletRequestImpl origRequestImpl = (SipServletRequestImpl) origRequest; final MobicentsSipSession session = getSipSession(); //@jean.deruelle Commenting this out, why origRequestImpl.isCommitted() is needed ? // if ((directive == SipApplicationRoutingDirective.REVERSE || directive == SipApplicationRoutingDirective.CONTINUE) // && (!origRequestImpl.isInitial() || origRequestImpl.isCommitted())) { - // If directive is CONTINUE or REVERSE, the parameter origRequest must be an - //initial request dispatched by the container to this application, + // If directive is CONTINUE or REVERSE, the parameter origRequest must be an + //initial request dispatched by the container to this application, //i.e. origRequest.isInitial() must be true - if ((directive == SipApplicationRoutingDirective.REVERSE || - directive == SipApplicationRoutingDirective.CONTINUE)){ + if ((directive == SipApplicationRoutingDirective.REVERSE || + directive == SipApplicationRoutingDirective.CONTINUE)){ if(origRequestImpl == null || !origRequestImpl.isInitial()) { if(logger.isDebugEnabled()) { @@ -753,9 +776,9 @@ public void setRoutingDirective(SipApplicationRoutingDirective directive, origRequestImpl.setLinkedRequest(this); setLinkedRequest(origRequestImpl); } - } else { - //This request must be a request created in a new SipSession - //or from an initial request, and must not have been sent. + } else { + //This request must be a request created in a new SipSession + //or from an initial request, and must not have been sent. //If any one of these preconditions are not met, the method throws an IllegalStateException. Set ongoingTransactions = session.getOngoingTransactions(); if(!State.INITIAL.equals(session.getState()) && ongoingTransactions != null && ongoingTransactions.size() > 0) { @@ -783,17 +806,17 @@ public void setRoutingDirective(SipApplicationRoutingDirective directive, // } else if (directive == SipApplicationRoutingDirective.CONTINUE) { // sipUri.setParameter("rd", "CONTINUE"); // } -// +// // } catch (Exception ex) { // String s = "error while setting routing directive"; // logger.error(s, ex); // throw new IllegalArgumentException(s, ex); -// } +// } } /* * (non-Javadoc) - * + * * @see javax.servlet.ServletRequest#getLocalName() */ public String getLocalName() { @@ -813,18 +836,18 @@ public Enumeration getLocales() { /* * (non-Javadoc) - * + * * @see javax.servlet.ServletRequest#getParameter(java.lang.String) */ public String getParameter(String name) { // JSR 289 Section 5.6.1 Parameters : // For initial requests where a preloaded Route header specified the application to be invoked, the parameters are those of the SIP or SIPS URI in that Route header. - // For initial requests where the application is invoked the parameters are those present on the request URI, + // For initial requests where the application is invoked the parameters are those present on the request URI, // if this is a SIP or a SIPS URI. For other URI schemes, the parameter set is undefined. - // For subsequent requests in a dialog, the parameters presented to the application are those that the application itself - // set on the Record-Route header for the initial request or response (see 10.4 Record-Route Parameters). - // These will typically be the URI parameters of the top Route header field but if the upstream SIP element is a - // "strict router" they may be returned in the request URI (see RFC 3261). + // For subsequent requests in a dialog, the parameters presented to the application are those that the application itself + // set on the Record-Route header for the initial request or response (see 10.4 Record-Route Parameters). + // These will typically be the URI parameters of the top Route header field but if the upstream SIP element is a + // "strict router" they may be returned in the request URI (see RFC 3261). // It is the containers responsibility to recognize whether the upstream element is a strict router and determine the right parameter set accordingly. if(this.getPoppedRoute() != null) { return this.getPoppedRoute().getURI().getParameter(name); @@ -833,7 +856,7 @@ public String getParameter(String name) { } } - + /* * (non-Javadoc) * @see javax.servlet.ServletRequest#getParameterNames() @@ -841,19 +864,19 @@ public String getParameter(String name) { public Enumeration getParameterNames() { // JSR 289 Section 5.6.1 Parameters : // For initial requests where a preloaded Route header specified the application to be invoked, the parameters are those of the SIP or SIPS URI in that Route header. - // For initial requests where the application is invoked the parameters are those present on the request URI, + // For initial requests where the application is invoked the parameters are those present on the request URI, // if this is a SIP or a SIPS URI. For other URI schemes, the parameter set is undefined. - // For subsequent requests in a dialog, the parameters presented to the application are those that the application itself - // set on the Record-Route header for the initial request or response (see 10.4 Record-Route Parameters). - // These will typically be the URI parameters of the top Route header field but if the upstream SIP element is a - // "strict router" they may be returned in the request URI (see RFC 3261). + // For subsequent requests in a dialog, the parameters presented to the application are those that the application itself + // set on the Record-Route header for the initial request or response (see 10.4 Record-Route Parameters). + // These will typically be the URI parameters of the top Route header field but if the upstream SIP element is a + // "strict router" they may be returned in the request URI (see RFC 3261). // It is the containers responsibility to recognize whether the upstream element is a strict router and determine the right parameter set accordingly. Vector retval = new Vector(); if(this.getPoppedRoute() != null) { Iterator parameterNamesIt = this.getPoppedRoute().getURI().getParameterNames(); while (parameterNamesIt.hasNext()) { String parameterName = parameterNamesIt.next(); - retval.add(parameterName); + retval.add(parameterName); } } else { Iterator parameterNamesIt = this.getRequestURI().getParameterNames(); @@ -861,19 +884,19 @@ public Enumeration getParameterNames() { String parameterName = parameterNamesIt.next(); retval.add(parameterName); } - } - - return retval.elements(); + } + + return retval.elements(); } /* * (non-Javadoc) - * + * * @see javax.servlet.ServletRequest#getParameterValues(java.lang.String) */ public String[] getParameterValues(String name) { // JSR 289 Section 5.6.1 Parameters : - // The getParameterValues method returns an array of String objects containing all the parameter values associated with a parameter name. + // The getParameterValues method returns an array of String objects containing all the parameter values associated with a parameter name. // The value returned from the getParameter method must always equal the first value in the array of String objects returned by getParameterValues. // Note:Support for multi-valued parameters is defined mainly for HTTP because HTML forms may contain multi-valued parameters in form submissions. return new String[] {getParameter(name)}; @@ -944,8 +967,11 @@ public SipApplicationRoutingDirective getRoutingDirective() { */ @Override public void send() throws IOException { + if(logger.isDebugEnabled()) { + logger.debug("send - method=" + this.getMethod()); + } checkReadOnly(); - // Cope with com.bea.sipservlet.tck.agents.api.javax_servlet_sip.SipServletMessageTest.testSend101 + // Cope with com.bea.sipservlet.tck.agents.api.javax_servlet_sip.SipServletMessageTest.testSend101 // make sure a message received cannot be sent out checkMessageState(); final Request request = (Request) super.message; @@ -957,7 +983,7 @@ public void send() throws IOException { // RFC 3263 support if(dnsServerLocator != null) { if(Request.CANCEL.equals(requestMethod)) { - // RFC 3263 Section 4 : a CANCEL for a particular SIP request MUST be sent to the same SIP + // RFC 3263 Section 4 : a CANCEL for a particular SIP request MUST be sent to the same SIP // server that the SIP request was delivered to. TransactionApplicationData inviteTxAppData = ((TransactionApplicationData)inviteTransactionToCancel.getApplicationData()); if(inviteTxAppData != null && inviteTxAppData.getHops() != null) { @@ -966,7 +992,7 @@ public void send() throws IOException { } else { javax.sip.address.URI uriToResolve = request.getRequestURI(); RouteHeader routeHeader = (RouteHeader) request.getHeader(RouteHeader.NAME); - if(routeHeader != null) { + if(routeHeader != null) { uriToResolve = routeHeader.getAddress().getURI(); } else { // RFC5626 - see if we are to find a flow for this request. @@ -977,11 +1003,11 @@ public void send() throws IOException { // up right now... uriToResolve = resolveSipOutbound(uriToResolve); } - String uriToResolveTransport = ((javax.sip.address.SipURI)uriToResolve).getTransportParam(); + String uriToResolveTransport = ((javax.sip.address.SipURI)uriToResolve).getTransportParam(); boolean transportParamModified = false; if(session.getProxy() == null && session.getTransport() != null && uriToResolve.isSipURI() && uriToResolveTransport == null && // no need to modify the Request URI for UDP which is the default transport - !session.getTransport().equalsIgnoreCase(ListeningPoint.UDP)) { + !session.getTransport().equalsIgnoreCase(ListeningPoint.UDP)) { try { ((javax.sip.address.SipURI)uriToResolve).setTransportParam(session.getTransport()); transportParamModified = true; @@ -1006,22 +1032,25 @@ public void send() throws IOException { if(hops != null && hops.size() > 0) { // RFC 3263 support don't remove the current hop, it will be the one to reuse for CANCEL and ACK to non 2xx transactions hop = hops.peek(); - transactionApplicationData.setHops(hops); + transactionApplicationData.setHops(hops); } } } + if(logger.isDebugEnabled()) { + logger.debug("send - calling send(hop) - hop=" + hop); + } send(hop); } - - + + /** * Check to see if the uri to resolve contains a "ob" parameter and if so, try * and locate a "flow" for this uri. - * + * * This is part of the RFC5626 implementation - * + * * @param uriToResolve - * @return the flow uri or if no flow was found, the same uri + * @return the flow uri or if no flow was found, the same uri * that was passed into the method */ private javax.sip.address.URI resolveSipOutbound(final javax.sip.address.URI uriToResolve) { @@ -1045,24 +1074,28 @@ private javax.sip.address.URI resolveSipOutbound(final javax.sip.address.URI uri return uriToResolve; } - + public void send(Hop hop) throws IOException { + if(logger.isDebugEnabled()) { + logger.debug("send - hop=" + hop + ", method=" + this.getMethod()); + } + final Request request = (Request) super.message; final String requestMethod = getMethod(); final MobicentsSipSession session = getSipSession(); final String sessionTransport = session.getTransport(); final SipNetworkInterfaceManager sipNetworkInterfaceManager = sipFactoryImpl.getSipNetworkInterfaceManager(); final MobicentsSipApplicationSession sipApplicationSession = session.getSipApplicationSession(); - + try { if(logger.isDebugEnabled()) { logger.debug("session transport is " + sessionTransport); } // Because proxy decides transport in different way, it allows inbound and outbound transport to be different. if(session != null && session.getProxy() == null) { - ((MessageExt)message).setApplicationData(session.getTransport()); - } - + ((MessageExt)message).setApplicationData(session.getTransport()); + } + if(Request.CANCEL.equals(requestMethod)) { getSipSession().setRequestsPending(0); Transaction tx = inviteTransactionToCancel; @@ -1083,8 +1116,8 @@ public void send(Hop hop) throws IOException { logger.debug("Can not send CANCEL because no responses arrived. " + "Can not stop retransmissions. The transaction is null"); } - } - + } + if(logger.isDebugEnabled()) { logger.debug("hop " + hop ); } @@ -1093,10 +1126,10 @@ public void send(Hop hop) throws IOException { if(hop != null) { ((MessageExt)message).setApplicationData(hop.getTransport()); } - + // adding via header and update via branch if null checkViaHeaderAddition(hop); - + final String transport = JainSipUtils.findTransport(request); if(sessionTransport == null) { session.setTransport(transport); @@ -1106,14 +1139,14 @@ public void send(Hop hop) throws IOException { } MobicentsExtendedListeningPoint matchingListeningPoint = null; - // Issue 159 : http://code.google.com/p/sipservlets/issues/detail?id=159 - // Bad choice of connectors when multiple of the same transport are available + // Issue 159 : http://code.google.com/p/sipservlets/issues/detail?id=159 + // Bad choice of connectors when multiple of the same transport are available String outboundInterface = session.getOutboundInterface(); if(outboundInterface != null) { if(logger.isDebugEnabled()) { logger.debug("Trying to find listening point with outbound interface " + outboundInterface); } - javax.sip.address.SipURI outboundInterfaceURI = null; + javax.sip.address.SipURI outboundInterfaceURI = null; try { outboundInterfaceURI = (javax.sip.address.SipURI) SipFactoryImpl.addressFactory.createURI(outboundInterface); } catch (ParseException e) { @@ -1134,14 +1167,14 @@ public void send(Hop hop) throws IOException { logger.debug("Matching listening point " + matchingListeningPoint); } } - + final SipProvider sipProvider = matchingListeningPoint.getSipProvider(); SipConnector sipConnector = matchingListeningPoint.getSipConnector(); - + //we update the via header after the sip connector has been found for the correct transport checkViaHeaderUpdateOrForStaticExternalAddressUsage(matchingListeningPoint, hop); - + if(Request.ACK.equals(requestMethod)) { // DNS Route need to be added for ACK // See RFC 3263 : "Because the ACK request for 2xx responses to INVITE constitutes a @@ -1150,11 +1183,11 @@ public void send(Hop hop) throws IOException { addDnsRoute(hop, request); sendAck(transport, sipConnector, matchingListeningPoint); return; - } + } boolean addDNSRoute = true; - //Added for initial requests only not for subsequent requests - if(isInitial()) { - // https://telestax.atlassian.net/browse/MSS-124 commented as this breaks AR for REGISTER + //Added for initial requests only not for subsequent requests + if(isInitial()) { + // https://telestax.atlassian.net/browse/MSS-124 commented as this breaks AR for REGISTER // && !Request.REGISTER.equalsIgnoreCase(requestMethod)) { final SipApplicationRouterInfo routerInfo = sipFactoryImpl.getNextInterestedApplication(this); if(routerInfo.getNextApplicationName() != null) { @@ -1162,13 +1195,13 @@ public void send(Hop hop) throws IOException { logger.debug("routing back to the container " + "since the following app is interested " + routerInfo.getNextApplicationName()); } - //add a route header to direct the request back to the container + //add a route header to direct the request back to the container //to check if there is any other apps interested in it addInfoForRoutingBackToContainer(routerInfo, session.getSipApplicationSession().getKey().getId(), session.getKey().getApplicationName()); addDNSRoute = false; } } - + if(addDNSRoute) { if(logger.isDebugEnabled()) { logger.debug("routing outside the container " + @@ -1177,7 +1210,7 @@ public void send(Hop hop) throws IOException { // Adding Route Header for LB if the request is initial or // http://code.google.com/p/sipservlets/issues/detail?id=130 // if we are in a HA configuration and the request is an out of dialog request - if(isInitial() || dialog == null) { + if(isInitial() || dialog == null) { //Issue: https://code.google.com/p/sipservlets/issues/detail?id=284 //Issue: https://telestax.atlassian.net/browse/MSS-121 if(logger.isDebugEnabled()) { @@ -1209,34 +1242,42 @@ else if(!session.getBypassProxy() && StaticServiceHolder.sipStandardService.getO } } } - + if(addDNSRoute) { // we add the DNS Route only if we don't redirect back to the container or if there is no outgoing load balancer defined addDnsRoute(hop, request); } - + if(logger.isDebugEnabled()) { getSipSession().getSipApplicationSession().getSipContext().getSipManager().dumpSipSessions(); } - if (super.getTransaction() == null) { - setSystemContactHeader(sipConnector, matchingListeningPoint, transport); - /* + if (super.getTransaction() == null) { + setSystemContactHeader(sipConnector, matchingListeningPoint, transport); + /* * If we the next hop is in this container we optimize the traffic by directing it here instead of going through load balancers. * This is must be done before creating the transaction, otherwise it will go to the host/port specified prior to the changes here. */ if(!isInitial() && sipConnector != null && // Initial requests already use local address in RouteHeader. sipConnector.isUseStaticAddress()) { JainSipUtils.optimizeRouteHeaderAddressForInternalRoutingrequest(sipConnector, request, session, sipFactoryImpl, transport); - } + } if(logger.isDebugEnabled()) { logger.debug("Getting new Client Tx for request " + request); } - final ClientTransaction ctx = sipProvider.getNewClientTransaction(request); + final ClientTransaction ctx = sipProvider.getNewClientTransaction(request); JainSipUtils.setTransactionTimers((TransactionExt) ctx, sipFactoryImpl.getSipApplicationDispatcher()); Dialog dialog = null; if(session.getProxy() != null) { + if(logger.isDebugEnabled()) { + logger.debug("send - session.getProxy is not null"); + } + // take care of the RRH if(isInitial()) { + if(logger.isDebugEnabled()) { + logger.debug("send - isInitial true"); + } + if(session.getProxy().getRecordRoute()) { ListIterator li = request.getHeaders(RecordRouteHeader.NAME); while(li.hasNext()) { @@ -1248,7 +1289,7 @@ else if(!session.getBypassProxy() && StaticServiceHolder.sipStandardService.getO } else { javax.sip.address.URI uri = rrh.getAddress().getURI(); if(uri.isSipURI()) { - + javax.sip.address.SipURI sipUri = (javax.sip.address.SipURI) uri; String serverId = sipUri.getParameter(MessageDispatcher.RR_PARAM_SERVER_NAME); String nextApp = sipUri.getParameter(MessageDispatcher.RR_PARAM_APPLICATION_NAME); @@ -1271,10 +1312,13 @@ else if(!session.getBypassProxy() && StaticServiceHolder.sipStandardService.getO } } else { // no dialogs in proxy + if(logger.isDebugEnabled()) { + logger.debug("send - session.getProxy is null"); + } dialog = ctx.getDialog(); } - - if (dialog == null && this.createDialog && JainSipUtils.DIALOG_CREATING_METHODS.contains(getMethod())) { + + if (dialog == null && this.createDialog && JainSipUtils.DIALOG_CREATING_METHODS.contains(getMethod())) { dialog = sipProvider.getNewDialog(ctx); ((DialogExt)dialog).disableSequenceNumberValidation(); session.setSessionCreatingDialog(dialog); @@ -1289,28 +1333,31 @@ else if(!session.getBypassProxy() && StaticServiceHolder.sipStandardService.getO // Make the dialog point here so that when the dialog event // comes in we can find the session quickly. if (dialog != null) { + if(logger.isDebugEnabled()) { + logger.debug("send - calling dialog.setApplicationData"); + } dialog.setApplicationData(this.transactionApplicationData); } - + // SIP Request is ALWAYS pointed to by the client tx. // Notice that the tx appplication data is cached in the request // copied over to the tx so it can be quickly accessed when response - // arrives. - ctx.setApplicationData(this.transactionApplicationData); + // arrives. + ctx.setApplicationData(this.transactionApplicationData); super.setTransaction(ctx); session.setSessionCreatingTransactionRequest(this); - } else if (Request.PRACK.equals(request.getMethod())) { + } else if (Request.PRACK.equals(request.getMethod())) { final ClientTransaction ctx = sipProvider.getNewClientTransaction(request); JainSipUtils.setTransactionTimers((TransactionExt) ctx, sipFactoryImpl.getSipApplicationDispatcher()); - + if(linkedRequest != null) { updateLinkedRequestAppDataMapping(ctx, dialog); } // SIP Request is ALWAYS pointed to by the client tx. // Notice that the tx appplication data is cached in the request // copied over to the tx so it can be quickly accessed when response - // arrives. + // arrives. ctx.setApplicationData(this.transactionApplicationData); setTransaction(ctx); } else { @@ -1321,27 +1368,32 @@ else if(!session.getBypassProxy() && StaticServiceHolder.sipStandardService.getO //tells the application dispatcher to stop routing the linked request // (in this case it would be the original request) since it has been relayed - if(linkedRequest != null && + if(linkedRequest != null && !SipApplicationRoutingDirective.NEW.equals(routingDirective)) { if(!RoutingState.PROXIED.equals(linkedRequest.getRoutingState())) { + + if(logger.isDebugEnabled()) { + logger.debug("send - setRoutingState to RELAYED"); + } + linkedRequest.setRoutingState(RoutingState.RELAYED); } - } + } session.addOngoingTransaction(getTransaction()); // Update Session state session.updateStateOnSubsequentRequest(this, false); // Issue 1481 http://code.google.com/p/mobicents/issues/detail?id=1481 // proxy should not add or remove subscription since there is no dialog associated with it - checkSubscriptionStateHeaders(session); + checkSubscriptionStateHeaders(session); - //updating the last accessed times + //updating the last accessed times session.access(); sipApplicationSession.access(); Dialog dialog = getDialog(); if(session.getProxy() != null) dialog = null; if(request.getMethod().equals(Request.CANCEL)) dialog = null; - - // Issue 1791 : using a different classloader created outside the application loader + + // Issue 1791 : using a different classloader created outside the application loader // to avoid leaks on startup/shutdown final ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); try { @@ -1350,30 +1402,42 @@ else if(!session.getBypassProxy() && StaticServiceHolder.sipStandardService.getO // If dialog does not exist or has no state. if (dialog == null || dialog.getState() == null // https://github.com/Mobicents/sip-servlets/issues/66 include UPDATE as well so it is sent indialog - || (dialog.getState() == DialogState.EARLY && !Request.PRACK.equals(requestMethod) && !Request.UPDATE.equals(requestMethod)) + || (dialog.getState() == DialogState.EARLY && !Request.PRACK.equals(requestMethod) && !Request.UPDATE.equals(requestMethod)) || Request.CANCEL.equals(requestMethod)) { if(logger.isDebugEnabled()) { - logger.debug("Sending the request " + request); + logger.debug("Sending the request " + request + ", transaction=" + super.getTransaction()); + logger.debug("Sending the request " + request + ", transaction.getState()=" + super.getTransaction().getState()); + logger.debug("Sending the request " + request + ", transaction.getDialog()=" + super.getTransaction().getDialog()); + logger.debug("Sending the request " + request + ", transaction.getRequest()=" + super.getTransaction().getRequest()); } ((ClientTransaction) super.getTransaction()).sendRequest(); } else { - // This is a subsequent (an in-dialog) request. + // This is a subsequent (an in-dialog) request. // we don't redirect it to the container for now if(logger.isDebugEnabled()) { - logger.debug("Sending the in dialog request " + request); + logger.debug("Sending the in dialog request " + request + ", dialog=" + dialog + ", transaction=" + getTransaction()); } + // If there are multiple connectors on the same transport, JAIN-SIP.HA sets sip-provider which is not containing the needed listening point. + ((SIPDialog) dialog).setSipProvider((SipProviderImpl)sipProvider); dialog.sendRequest((ClientTransaction) getTransaction()); - } + } + if(logger.isDebugEnabled()) { + logger.debug("send - message is sent - calling updateRequestsStatistics"); + } sipFactoryImpl.getSipApplicationDispatcher().updateRequestsStatistics(request, false); isMessageSent = true; - + if(method.equals(Request.INVITE)) { session.setRequestsPending(session.getRequestsPending()+1); } } finally { Thread.currentThread().setContextClassLoader(oldClassLoader); } - } catch (Exception ex) { + } catch (Exception ex) { + if(logger.isDebugEnabled()) { + logger.debug("send - exception while trying to send the request", ex); + } + // The second condition for SipExcpetion is to cover com.bea.sipservlet.tck.agents.spec.ProxyBranchTest.testCreatingBranchParallel() where they send a request twice, the second // time it does a "Request already sent" jsip exception but the tx is going on and must not be destroyed boolean skipTxTermination = false; @@ -1389,6 +1453,9 @@ else if(!session.getBypassProxy() && StaticServiceHolder.sipStandardService.getO // https://code.google.com/p/sipservlets/issues/detail?id=250 retry directly on TCP boolean nextHopVisited = visitNextHop(); if(nextHopVisited) { + if(logger.isDebugEnabled()) { + logger.debug("send - returning after exception"); + } return; } } @@ -1398,22 +1465,22 @@ else if(!session.getBypassProxy() && StaticServiceHolder.sipStandardService.getO message.removeFirst(ContactHeader.NAME); setTransaction(null); - if(ex.getCause() != null && ex.getCause() instanceof IOException) { + if(ex.getCause() != null && ex.getCause() instanceof IOException) { throw (IOException) ex.getCause(); } } throw new IllegalStateException("Error sending request " + request,ex); - } + } } /** - * + * * @param hop - * @param request + * @param request */ private void addDnsRoute(Hop hop, final Request request) throws ParseException, SipException { - if(hop != null && sipFactoryImpl.getSipApplicationDispatcher().isExternal(hop.getHost(), hop.getPort(), hop.getTransport())) { + if(hop != null && sipFactoryImpl.getSipApplicationDispatcher().isExternal(hop.getHost(), hop.getPort(), hop.getTransport())) { javax.sip.address.SipURI nextHopUri = SipFactoryImpl.addressFactory.createSipURI(null, hop.getHost()); nextHopUri.setLrParam(); nextHopUri.setPort(hop.getPort()); @@ -1422,29 +1489,29 @@ private void addDnsRoute(Hop hop, final Request request) } // Deal with http://code.google.com/p/mobicents/issues/detail?id=2346 nextHopUri.setParameter(DNSAwareRouter.DNS_ROUTE, Boolean.TRUE.toString()); - final javax.sip.address.Address nextHopRouteAddress = + final javax.sip.address.Address nextHopRouteAddress = SipFactoryImpl.addressFactory.createAddress(nextHopUri); - final RouteHeader nextHopRouteHeader = + final RouteHeader nextHopRouteHeader = SipFactoryImpl.headerFactory.createRouteHeader(nextHopRouteAddress); if(logger.isDebugEnabled()) { - logger.debug("Adding next hop found by RFC 3263 lookups as route header" + nextHopRouteHeader); + logger.debug("Adding next hop found by RFC 3263 lookups as route header" + nextHopRouteHeader); } - + request.addFirst(nextHopRouteHeader); } } /** - * + * */ private void checkViaHeaderAddition(Hop hop) throws ParseException { - final SipNetworkInterfaceManager sipNetworkInterfaceManager = sipFactoryImpl.getSipNetworkInterfaceManager(); + final SipNetworkInterfaceManager sipNetworkInterfaceManager = sipFactoryImpl.getSipNetworkInterfaceManager(); final Request request = (Request) super.message; final MobicentsSipSession session = getSipSession(); final MobicentsSipApplicationSession sipApplicationSession = session.getSipApplicationSession(); final MobicentsProxy proxy = session.getProxy(); ViaHeader viaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME); - + if(!request.getMethod().equals(Request.CANCEL) && viaHeader == null) { //Issue 112 fix by folsson boolean addViaHeader = false; @@ -1457,8 +1524,8 @@ private void checkViaHeaderAddition(Hop hop) throws ParseException { } else if(proxy.getFinalBranchForSubsequentRequests() != null && proxy.getFinalBranchForSubsequentRequests().getRecordRoute()) { addViaHeader = true; } - if(addViaHeader) { - // Issue + if(addViaHeader) { + // Issue viaHeader = JainSipUtils.createViaHeader( sipNetworkInterfaceManager, request, null, session.getOutboundInterface()); message.addHeader(viaHeader); @@ -1468,7 +1535,7 @@ private void checkViaHeaderAddition(Hop hop) throws ParseException { } } if(viaHeader.getBranch() == null) { - final String branch = JainSipUtils.createBranch(sipApplicationSession.getKey().getId(), sipFactoryImpl.getSipApplicationDispatcher().getHashFromApplicationName(session.getKey().getApplicationName())); + final String branch = JainSipUtils.createBranch(sipApplicationSession.getKey().getId(), sipFactoryImpl.getSipApplicationDispatcher().getHashFromApplicationName(session.getKey().getApplicationName())); viaHeader.setBranch(branch); } // https://github.com/Mobicents/sip-servlets/issues/62 modify the Via transport to match either the hop, the route or the request URI transport @@ -1479,7 +1546,7 @@ private void checkViaHeaderAddition(Hop hop) throws ParseException { } String viaTransport = viaHeader.getTransport(); if(logger.isDebugEnabled()) { - logger.debug("viaHeader transport " + viaTransport + + logger.debug("viaHeader transport " + viaTransport + ", hopTransport " + hopTransport + ", transportFromRouteOrRequestUri " + transportFromRouteOrRequestUri); } if(hopTransport != null && !viaTransport.equalsIgnoreCase(hopTransport)) { @@ -1493,11 +1560,11 @@ private void checkViaHeaderAddition(Hop hop) throws ParseException { } viaHeader.setTransport(transportFromRouteOrRequestUri); } - + } /** - * + * * @param mobicentsExtendedListeningPoint * @param hop * @throws ParseException @@ -1505,13 +1572,13 @@ private void checkViaHeaderAddition(Hop hop) throws ParseException { */ private void checkViaHeaderUpdateOrForStaticExternalAddressUsage(final MobicentsExtendedListeningPoint mobicentsExtendedListeningPoint, final Hop hop) throws ParseException, InvalidArgumentException { - + final SipConnector sipConnector = mobicentsExtendedListeningPoint.getSipConnector(); - final Request request = (Request) super.message; + final Request request = (Request) super.message; ViaHeader viaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME); - + if(sipConnector != null) { - //Issue: https://code.google.com/p/sipservlets/issues/detail?id=284 + //Issue: https://telestax.atlassian.net/browse/MSS-121 if(sipConnector.isUseStaticAddress() && !((MobicentsSipSession)getSession()).getBypassLoadBalancer() ) { javax.sip.address.URI uri = request.getRequestURI(); RouteHeader route = (RouteHeader) request.getHeader(RouteHeader.NAME); @@ -1550,9 +1617,9 @@ private void checkViaHeaderUpdateOrForStaticExternalAddressUsage(final Mobicents javax.sip.address.SipURI outboundInterfaceURI = (javax.sip.address.SipURI) SipFactoryImpl.addressFactory.createURI(outboundInterface); ipAddressToCheckAgainst = ((gov.nist.javax.sip.address.SipUri)outboundInterfaceURI).getHost(); } - - - if(!viaHeader.getHost().equalsIgnoreCase(ipAddressToCheckAgainst) || + + + if(!viaHeader.getHost().equalsIgnoreCase(ipAddressToCheckAgainst) || !viaHeader.getTransport().equalsIgnoreCase(sipConnector.getTransport()) || viaHeader.getPort() != sipConnector.getPort()) { if(logger.isTraceEnabled()) { @@ -1567,17 +1634,20 @@ private void checkViaHeaderUpdateOrForStaticExternalAddressUsage(final Mobicents } } } - + } - + /** * Keeping the transactions mapping in application data for CANCEL handling - * + * * @param ctx * @param dialog */ private void updateLinkedRequestAppDataMapping(final ClientTransaction ctx, Dialog dialog) { + if(logger.isDebugEnabled()) { + logger.debug("updateLinkedRequestAppDataMapping"); + } final Transaction linkedTransaction = linkedRequest.getTransaction(); final Dialog linkedDialog = linkedRequest.getDialog(); //keeping the client transaction in the server transaction's application data @@ -1601,20 +1671,20 @@ private void updateLinkedRequestAppDataMapping(final ClientTransaction ctx, private void checkSubscriptionStateHeaders(final MobicentsSipSession session) throws SipException { if(Request.NOTIFY.equals(getMethod()) && session.getProxy() == null) { - final SubscriptionStateHeader subscriptionStateHeader = (SubscriptionStateHeader) - getMessage().getHeader(SubscriptionStateHeader.NAME); - + final SubscriptionStateHeader subscriptionStateHeader = (SubscriptionStateHeader) + getMessage().getHeader(SubscriptionStateHeader.NAME); + // RFC 3265 : If a matching NOTIFY request contains a "Subscription-State" of "active" or "pending", it creates // a new subscription and a new dialog (unless they have already been // created by a matching response, as described above). - if (subscriptionStateHeader != null && + if (subscriptionStateHeader != null && (SubscriptionStateHeader.ACTIVE.equalsIgnoreCase(subscriptionStateHeader.getState()) || - SubscriptionStateHeader.PENDING.equalsIgnoreCase(subscriptionStateHeader.getState()))) { + SubscriptionStateHeader.PENDING.equalsIgnoreCase(subscriptionStateHeader.getState()))) { session.addSubscription(this); } // A subscription is destroyed when a notifier sends a NOTIFY request // with a "Subscription-State" of "terminated". - if (subscriptionStateHeader != null && + if (subscriptionStateHeader != null && SubscriptionStateHeader.TERMINATED.equalsIgnoreCase(subscriptionStateHeader.getState())) { session.removeSubscription(this); } @@ -1632,15 +1702,15 @@ private void checkSubscriptionStateHeaders(final MobicentsSipSession session) private void setSystemContactHeader(final SipConnector sipConnector, final MobicentsExtendedListeningPoint matchingListeningPoint, String transportForRequest) throws ParseException { - + final SipNetworkInterfaceManager sipNetworkInterfaceManager = sipFactoryImpl.getSipNetworkInterfaceManager(); final Request request = (Request) super.message; final String requestMethod = getMethod(); final MobicentsSipSession session = getSipSession(); final MobicentsProxy proxy = session.getProxy(); - + ContactHeader contactHeader = (ContactHeader)request.getHeader(ContactHeader.NAME); - if(contactHeader != null && (((Parameters)contactHeader.getAddress().getURI()).getParameter("gruu") != null || + if(contactHeader != null && (((Parameters)contactHeader.getAddress().getURI()).getParameter("gruu") != null || ((Parameters)contactHeader.getAddress().getURI()).getParameter("gr") != null)) { if(logger.isDebugEnabled()) { logger.debug("not changing existing contact header " + contactHeader + " as it contains gruu"); @@ -1655,9 +1725,9 @@ private void setSystemContactHeader(final SipConnector sipConnector, if(fromUri instanceof javax.sip.address.SipURI) { fromName = ((javax.sip.address.SipURI)fromUri).getUser(); } - // Create the contact name address. - contactHeader = - JainSipUtils.createContactHeader(sipNetworkInterfaceManager, request, displayName, fromName, session.getOutboundInterface()); + // Create the contact name address. + contactHeader = + JainSipUtils.createContactHeader(sipNetworkInterfaceManager, request, displayName, fromName, session.getOutboundInterface()); request.addHeader(contactHeader); } @@ -1671,8 +1741,8 @@ private void setSystemContactHeader(final SipConnector sipConnector, contactSipUri.setPort(sipConnector.getStaticServerPort()); //https://telestax.atlassian.net/browse/MSS-103 //contactSipUri.setUser(null); - } - // http://code.google.com/p/sipservlets/issues/detail?id=156 + } + // http://code.google.com/p/sipservlets/issues/detail?id=156 // MSS overwrites host part of Contact Header in REGISTER requests else if(JainSipUtils.CONTACT_HEADER_METHODS.contains(requestMethod)) { //Issue: https://code.google.com/p/sipservlets/issues/detail?id=210 @@ -1681,10 +1751,10 @@ else if(JainSipUtils.CONTACT_HEADER_METHODS.contains(requestMethod)) { javax.sip.address.SipURI outboundInterfaceURI = (javax.sip.address.SipURI) SipFactoryImpl.addressFactory.createURI(outboundInterface); String outboundHost = ((gov.nist.javax.sip.address.SipUri)outboundInterfaceURI).getHost(); contactSipUri.setHost(outboundHost); - } else { + } else { boolean usePublicAddress = JainSipUtils.findUsePublicAddress( sipNetworkInterfaceManager, request, matchingListeningPoint); - contactSipUri.setHost(matchingListeningPoint.getIpAddress(usePublicAddress)); + contactSipUri.setHost(matchingListeningPoint.getIpAddress(usePublicAddress)); } contactSipUri.setPort(matchingListeningPoint.getPort()); } @@ -1692,8 +1762,8 @@ else if(JainSipUtils.CONTACT_HEADER_METHODS.contains(requestMethod)) { if(transportForRequest != null) { if(!ListeningPoint.UDP.equalsIgnoreCase(transportForRequest)) { contactSipUri.setTransportParam(transportForRequest); - } - + } + // If the transport for the request was changed in the last moment we need to update the header String transportParam = contactSipUri.getTransportParam(); if(transportParam != null && !transportParam.equalsIgnoreCase(transportForRequest)) { @@ -1707,17 +1777,17 @@ else if(JainSipUtils.CONTACT_HEADER_METHODS.contains(requestMethod)) { if(requestURI.isSipURI() && ((javax.sip.address.SipURI)requestURI).isSecure()) { contactSipUri.setSecure(true); } else if(requestURI.isSipURI() && !((javax.sip.address.SipURI)requestURI).isSecure() && contactSipUri.isSecure()) { - // if the Request URI is non secure but the contact is make sure to move it back to non secure to handle Microsoft OCS interop + // if the Request URI is non secure but the contact is make sure to move it back to non secure to handle Microsoft OCS interop contactSipUri.setSecure(false); } } } - } + } } } - + /** - * + * * @return */ public boolean visitNextHop() { @@ -1739,11 +1809,11 @@ public boolean visitNextHop() { logger.debug("visitNextHop nextHop " + nextHop); } if(nextHop != null) { - // If a failure occurs, the client SHOULD create a new request, + // If a failure occurs, the client SHOULD create a new request, // which is identical to the previous, but getMessage().removeFirst(RouteHeader.NAME); // has a different value of the Via branch ID than the previous (and - // therefore constitutes a new SIP transaction). + // therefore constitutes a new SIP transaction). ViaHeader viaHeader = (ViaHeader) getMessage().getHeader(ViaHeader.NAME); viaHeader.removeParameter("branch"); message = (Message) message.clone(); @@ -1763,7 +1833,7 @@ public boolean visitNextHop() { } } return false; - + } /** @@ -1773,15 +1843,15 @@ public boolean visitNextHop() { * @throws ParseException * @throws SipException */ - private void sendAck(final String transport, final SipConnector sipConnector, + private void sendAck(final String transport, final SipConnector sipConnector, final MobicentsExtendedListeningPoint matchingListeningPoint) throws ParseException, SipException { - - final Request request = (Request) super.message; + + final Request request = (Request) super.message; final MobicentsSipSession session = getSipSession(); final MobicentsSipApplicationSession sipApplicationSession = session.getSipApplicationSession(); - - // Issue 1791 : using a different classloader created outside the application loader + + // Issue 1791 : using a different classloader created outside the application loader // to avoid leaks on startup/shutdown final ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); try { @@ -1791,7 +1861,7 @@ private void sendAck(final String transport, final SipConnector sipConnector, sipConnector.isUseStaticAddress()) { JainSipUtils.optimizeRouteHeaderAddressForInternalRoutingrequest(sipConnector, request, session, sipFactoryImpl, transport); } - //Issue 2588 : updating the last accessed times for ACK as well + //Issue 2588 : updating the last accessed times for ACK as well session.access(); sipApplicationSession.access(); if(logger.isDebugEnabled()) { @@ -1814,7 +1884,7 @@ private void sendAck(final String transport, final SipConnector sipConnector, } if(tad != null) { // Issue 1468 : to handle forking, we shouldn't cleanup the app data since it is needed for the forked responses - boolean nullifyAppData = true; + boolean nullifyAppData = true; if(((SipStackImpl)(sipFactoryImpl.getSipApplicationDispatcher().getSipStack())).getMaxForkTime() > 0) { nullifyAppData = false; } @@ -1827,7 +1897,7 @@ private void sendAck(final String transport, final SipConnector sipConnector, } } } - final SipProvider sipProvider = matchingListeningPoint.getSipProvider(); + final SipProvider sipProvider = matchingListeningPoint.getSipProvider(); // Issue 1468 : to handle forking, we shouldn't cleanup the app data since it is needed for the forked responses if(((SipStackImpl)sipProvider.getSipStack()).getMaxForkTime() == 0 && transaction != null) { transaction.setApplicationData(null); @@ -1842,32 +1912,32 @@ private void sendAck(final String transport, final SipConnector sipConnector, * Add a route header to route back to the container * @param applicationName the application name that was chosen by the AR to route the request * @throws ParseException - * @throws SipException - * @throws NullPointerException + * @throws SipException + * @throws NullPointerException */ - private void addInfoForRoutingBackToContainer(SipApplicationRouterInfo routerInfo, String applicationSessionId, String applicationName) throws ParseException, SipException { + private void addInfoForRoutingBackToContainer(SipApplicationRouterInfo routerInfo, String applicationSessionId, String applicationName) throws ParseException, SipException { final Request request = (Request) super.message; final javax.sip.address.SipURI sipURI = JainSipUtils.createRecordRouteURI( - sipFactoryImpl.getSipNetworkInterfaceManager(), + sipFactoryImpl.getSipNetworkInterfaceManager(), request); sipURI.setLrParam(); - sipURI.setParameter(MessageDispatcher.ROUTE_PARAM_DIRECTIVE, + sipURI.setParameter(MessageDispatcher.ROUTE_PARAM_DIRECTIVE, routingDirective.toString()); if(getSipSession().getRegionInternal() != null) { - sipURI.setParameter(MessageDispatcher.ROUTE_PARAM_REGION_LABEL, + sipURI.setParameter(MessageDispatcher.ROUTE_PARAM_REGION_LABEL, getSipSession().getRegionInternal().getLabel()); - sipURI.setParameter(MessageDispatcher.ROUTE_PARAM_REGION_TYPE, + sipURI.setParameter(MessageDispatcher.ROUTE_PARAM_REGION_TYPE, getSipSession().getRegionInternal().getType().toString()); } - sipURI.setParameter(MessageDispatcher.ROUTE_PARAM_PREV_APPLICATION_NAME, + sipURI.setParameter(MessageDispatcher.ROUTE_PARAM_PREV_APPLICATION_NAME, applicationName); - sipURI.setParameter(MessageDispatcher.ROUTE_PARAM_PREV_APP_ID, + sipURI.setParameter(MessageDispatcher.ROUTE_PARAM_PREV_APP_ID, applicationSessionId); - final javax.sip.address.Address routeAddress = + final javax.sip.address.Address routeAddress = SipFactoryImpl.addressFactory.createAddress(sipURI); - final RouteHeader routeHeader = + final RouteHeader routeHeader = SipFactoryImpl.headerFactory.createRouteHeader(routeAddress); - request.addFirst(routeHeader); + request.addFirst(routeHeader); // adding the application router info to avoid calling the AppRouter twice // See Issue 791 : http://code.google.com/p/mobicents/issues/detail?id=791 final MobicentsSipSession session = getSipSession(); @@ -1881,7 +1951,7 @@ public void setLinkedRequest(SipServletRequestImpl linkedRequest) { public SipServletRequestImpl getLinkedRequest() { return this.linkedRequest; - } + } /** * @return the routingState @@ -1894,30 +1964,36 @@ public RoutingState getRoutingState() { * @param routingState the routingState to set */ public void setRoutingState(RoutingState routingState) throws IllegalStateException { + if(logger.isDebugEnabled()) { + logger.debug("setRoutingState - routingState=" + routingState); + } //JSR 289 Section 11.2.3 && 10.2.6 - if(routingState.equals(RoutingState.CANCELLED) && - (this.routingState.equals(RoutingState.FINAL_RESPONSE_SENT) || + if(routingState.equals(RoutingState.CANCELLED) && + (this.routingState.equals(RoutingState.FINAL_RESPONSE_SENT) || this.routingState.equals(RoutingState.PROXIED))) { throw new IllegalStateException("Cannot cancel final response already sent!"); } - if((routingState.equals(RoutingState.FINAL_RESPONSE_SENT)|| + if((routingState.equals(RoutingState.FINAL_RESPONSE_SENT)|| routingState.equals(RoutingState.PROXIED)) && this.routingState.equals(RoutingState.CANCELLED)) { throw new IllegalStateException("Cancel received and already replied with a 487!"); } if(routingState.equals(RoutingState.SUBSEQUENT)) { isInitial = false; } - // http://code.google.com/p/sipservlets/issues/detail?id=19 + // http://code.google.com/p/sipservlets/issues/detail?id=19 // Retried Request are not considered as initial if(routingState.equals(RoutingState.INITIAL)) { + if(logger.isDebugEnabled()) { + logger.debug("setRoutingState - isInitial=" + isInitial); + } isInitial = true; } if(logger.isDebugEnabled()) { logger.debug("setting routing state to " + routingState); } - this.routingState = routingState; + this.routingState = routingState; } - + /* * (non-Javadoc) * @see javax.servlet.sip.SipServletRequest#addAuthHeader(javax.servlet.sip.SipServletResponse, javax.servlet.sip.AuthInfo) @@ -1935,7 +2011,7 @@ public void addAuthHeader(SipServletResponse challengeResponse, String username, String password) { addAuthHeader(challengeResponse, username, password, false); } - + /* * (non-Javadoc) * @see org.mobicents.javax.servlet.sip.SipServletRequestExt#addAuthHeader(javax.servlet.sip.SipServletResponse, javax.servlet.sip.AuthInfo, boolean) @@ -1944,58 +2020,58 @@ public void addAuthHeader(SipServletResponse challengeResponse, AuthInfo authInfo, boolean cacheCredentials) { checkReadOnly(); AuthInfoImpl authInfoImpl = (AuthInfoImpl) authInfo; - - SipServletResponseImpl challengeResponseImpl = + + SipServletResponseImpl challengeResponseImpl = (SipServletResponseImpl) challengeResponse; - + Response response = (Response) challengeResponseImpl.getMessage(); // First check for WWWAuthentication headers - ListIterator authHeaderIterator = + ListIterator authHeaderIterator = response.getHeaders(WWWAuthenticateHeader.NAME); while(authHeaderIterator.hasNext()) { - WWWAuthenticateHeader wwwAuthHeader = + WWWAuthenticateHeader wwwAuthHeader = (WWWAuthenticateHeader) authHeaderIterator.next(); - // Fix for Issue 1832 : http://code.google.com/p/mobicents/issues/detail?id=1832 + // Fix for Issue 1832 : http://code.google.com/p/mobicents/issues/detail?id=1832 // Authorization header is growing when nonce become stale, don't take into account stale headers // in the challenge request removeStaleAuthHeaders(wwwAuthHeader); // String uri = wwwAuthHeader.getParameter("uri"); AuthInfoEntry authInfoEntry = authInfoImpl.getAuthInfo(wwwAuthHeader.getRealm()); - + if(authInfoEntry == null) throw new SecurityException( "Cannot add authorization header. No credentials for the following realm: " + wwwAuthHeader.getRealm()); - + addChallengeResponse(wwwAuthHeader, authInfoEntry.getUserName(), authInfoEntry.getPassword(), this.getRequestURI().toString()); - + if(cacheCredentials) { getSipSession().getSipSessionSecurity().addCachedAuthInfo(wwwAuthHeader.getRealm(), authInfoEntry); } } - + // Now check for Proxy-Authentication - authHeaderIterator = + authHeaderIterator = response.getHeaders(ProxyAuthenticateHeader.NAME); while(authHeaderIterator.hasNext()) { - ProxyAuthenticateHeader proxyAuthHeader = + ProxyAuthenticateHeader proxyAuthHeader = (ProxyAuthenticateHeader) authHeaderIterator.next(); - // Fix for Issue 1832 : http://code.google.com/p/mobicents/issues/detail?id=1832 + // Fix for Issue 1832 : http://code.google.com/p/mobicents/issues/detail?id=1832 // Authorization header is growing when nonce become stale, don't take into account stale headers // in the challenge request removeStaleAuthHeaders(proxyAuthHeader); // String uri = wwwAuthHeader.getParameter("uri"); AuthInfoEntry authInfoEntry = authInfoImpl.getAuthInfo(proxyAuthHeader.getRealm()); - + if(authInfoEntry == null) throw new SecurityException( "No credentials for the following realm: " + proxyAuthHeader.getRealm()); - + addChallengeResponse(proxyAuthHeader, authInfoEntry.getUserName(), authInfoEntry.getPassword(), this.getRequestURI().toString()); - + if(cacheCredentials) { getSipSession().getSipSessionSecurity().addCachedAuthInfo(proxyAuthHeader.getRealm(), authInfoEntry); } @@ -2009,55 +2085,55 @@ public void addAuthHeader(SipServletResponse challengeResponse, public void addAuthHeader(SipServletResponse challengeResponse, String username, String password, boolean cacheCredentials) { checkReadOnly(); - SipServletResponseImpl challengeResponseImpl = + SipServletResponseImpl challengeResponseImpl = (SipServletResponseImpl) challengeResponse; - + Response response = (Response) challengeResponseImpl.getMessage(); - ListIterator
authHeaderIterator = + ListIterator
authHeaderIterator = response.getHeaders(WWWAuthenticateHeader.NAME); - + // First while(authHeaderIterator.hasNext()) { - WWWAuthenticateHeader wwwAuthHeader = + WWWAuthenticateHeader wwwAuthHeader = (WWWAuthenticateHeader) authHeaderIterator.next(); - // Fix for Issue 1832 : http://code.google.com/p/mobicents/issues/detail?id=1832 + // Fix for Issue 1832 : http://code.google.com/p/mobicents/issues/detail?id=1832 // Authorization header is growing when nonce become stale, don't take into account stale headers // in the challenge request removeStaleAuthHeaders(wwwAuthHeader); // String uri = wwwAuthHeader.getParameter("uri"); addChallengeResponse(wwwAuthHeader, username, password, this.getRequestURI().toString()); - + if(cacheCredentials) { getSipSession().getSipSessionSecurity().addCachedAuthInfo(wwwAuthHeader.getRealm(), new AuthInfoEntry(response.getStatusCode(), username, password)); } } - - - authHeaderIterator = + + + authHeaderIterator = response.getHeaders(ProxyAuthenticateHeader.NAME); - + while(authHeaderIterator.hasNext()) { - ProxyAuthenticateHeader proxyAuthHeader = + ProxyAuthenticateHeader proxyAuthHeader = (ProxyAuthenticateHeader) authHeaderIterator.next(); - // Fix for Issue 1832 : http://code.google.com/p/mobicents/issues/detail?id=1832 + // Fix for Issue 1832 : http://code.google.com/p/mobicents/issues/detail?id=1832 // Authorization header is growing when nonce become stale, don't take into account stale headers // in the challenge request removeStaleAuthHeaders(proxyAuthHeader); String uri = proxyAuthHeader.getParameter("uri"); if(uri == null) uri = this.getRequestURI().toString(); addChallengeResponse(proxyAuthHeader, username, password, uri); - + if(cacheCredentials) { getSipSession().getSipSessionSecurity().addCachedAuthInfo(proxyAuthHeader.getRealm(), new AuthInfoEntry(response.getStatusCode(), username, password)); } } } - + /* * Fix for Issue 1832 : http://code.google.com/p/mobicents/issues/detail?id=1832 * Authorization header is growing when nonce become stale, don't take into account stale headers * in the subsequent request - * + * * From RFC 2617 : stale * A flag, indicating that the previous request from the client was * rejected because the nonce value was stale. If stale is TRUE @@ -2072,41 +2148,41 @@ public void addAuthHeader(SipServletResponse challengeResponse, */ protected void removeStaleAuthHeaders(WWWAuthenticateHeader responseAuthHeader) { String realm = responseAuthHeader.getRealm(); - - ListIterator
authHeaderIterator = + + ListIterator
authHeaderIterator = message.getHeaders(AuthorizationHeader.NAME); if(authHeaderIterator.hasNext()) { message.removeHeader(AuthorizationHeader.NAME); while(authHeaderIterator.hasNext()) { - AuthorizationHeader wwwAuthHeader = + AuthorizationHeader wwwAuthHeader = (AuthorizationHeader) authHeaderIterator.next(); if(realm != null && !realm.equalsIgnoreCase(wwwAuthHeader.getRealm())) { message.addHeader(wwwAuthHeader); } } } - - authHeaderIterator = + + authHeaderIterator = message.getHeaders(ProxyAuthorizationHeader.NAME); if(authHeaderIterator.hasNext()) { message.removeHeader(ProxyAuthorizationHeader.NAME); while(authHeaderIterator.hasNext()) { - ProxyAuthorizationHeader proxyAuthHeader = + ProxyAuthorizationHeader proxyAuthHeader = (ProxyAuthorizationHeader) authHeaderIterator.next(); if(realm != null && !realm.equalsIgnoreCase(proxyAuthHeader.getRealm())) { message.addHeader(proxyAuthHeader); } - } + } } } - - + + private void addChallengeResponse( WWWAuthenticateHeader wwwAuthHeader, String username, String password, String uri) { - + int nc = generateNcFromMessage(message); AuthorizationHeader authorization = getSipSession().getSipApplicationSession().getSipContext().getDigestAuthenticator().getAuthorizationHeader( @@ -2118,7 +2194,7 @@ private void addChallengeResponse( password, wwwAuthHeader.getNonce(), nc); - + message.addHeader(authorization); } @@ -2132,8 +2208,8 @@ public SipServletResponse getLastFinalResponse() { /** * @param response the finalResponse to set */ - public void setResponse(SipServletResponseImpl response) { - if(response.getStatus() >= 200 && + public void setResponse(SipServletResponseImpl response) { + if(response.getStatus() >= 200 && (lastFinalResponse == null || lastFinalResponse.getStatus() < response.getStatus())) { if(logger.isDebugEnabled()) { logger.debug("last final response " + response + " set on " + this); @@ -2141,7 +2217,7 @@ public void setResponse(SipServletResponseImpl response) { this.lastFinalResponse = response; } // we keep the last informational response for noPrackReceived only - if(containsRel100(response.getMessage()) && (response.getStatus() > 100 && response.getStatus() < 200) && + if(containsRel100(response.getMessage()) && (response.getStatus() > 100 && response.getStatus() < 200) && (lastInformationalResponse == null || lastInformationalResponse.getStatus() < response.getStatus())) { if(logger.isDebugEnabled()) { logger.debug("last informational response " + lastInformationalResponse + " set on " + this); @@ -2165,11 +2241,11 @@ public Address getInitialPoppedRoute() { public SipApplicationRoutingRegion getRegion() { return routingRegion; } - + /** - * This method allows the application to set the region that the application + * This method allows the application to set the region that the application * is in with respect to this SipSession - * @param routingRegion the region that the application is in + * @param routingRegion the region that the application is in */ public void setRoutingRegion(SipApplicationRoutingRegion routingRegion) { this.routingRegion = routingRegion; @@ -2178,14 +2254,14 @@ public void setRoutingRegion(SipApplicationRoutingRegion routingRegion) { /** * {@inheritDoc} */ - public URI getSubscriberURI() { + public URI getSubscriberURI() { return subscriberURI; - } - - public void setSubscriberURI(URI uri) { + } + + public void setSubscriberURI(URI uri) { this.subscriberURI = uri; } - + /** * Method checking whether or not the sip servlet request in parameter is initial * according to algorithm defined in JSR289 Appendix B @@ -2194,45 +2270,54 @@ public void setSubscriberURI(URI uri) { * @return true if the request is initial false otherwise */ private static RoutingState checkRoutingState(SipServletRequestImpl sipServletRequest, Dialog dialog) { - // 2. Ongoing Transaction Detection - Employ methods of Section 17.2.3 in RFC 3261 - //to see if the request matches an existing transaction. + // 2. Ongoing Transaction Detection - Employ methods of Section 17.2.3 in RFC 3261 + //to see if the request matches an existing transaction. //If it does, stop. The request is not an initial request. if(dialog != null && DialogState.CONFIRMED.equals(dialog.getState())) { + if (logger.isDebugEnabled()){ + logger.debug("checkRoutingState - dialog not null and dialog state is CONFIRMED"); + } return RoutingState.SUBSEQUENT; - } - // 3. Examine Request Method. If it is CANCEL, BYE, PRACK or ACK, stop. + } + // 3. Examine Request Method. If it is CANCEL, BYE, PRACK or ACK, stop. //The request is not an initial request for which application selection occurs. if(NON_INITIAL_SIP_REQUEST_METHODS.contains(sipServletRequest.getMethod())) { + if (logger.isDebugEnabled()){ + logger.debug("checkRoutingState - sipServletRequest.getMethod() is element of NON_INITIAL_SIP_REQUEST_METHODS, sipServletRequest.getMethod()=" + sipServletRequest.getMethod()); + } return RoutingState.SUBSEQUENT; } - // 4. Existing Dialog Detection - If the request has a tag in the To header field, - // the container computes the dialog identifier (as specified in section 12 of RFC 3261) - // corresponding to the request and compares it with existing dialogs. - // If it matches an existing dialog, stop. The request is not an initial request. - // The request is a subsequent request and must be routed to the application path - // associated with the existing dialog. - // If the request has a tag in the To header field, - // but the dialog identifier does not match any existing dialogs, - // the container must reject the request with a 481 (Call/Transaction Does Not Exist). - // Note: When this occurs, RFC 3261 says either the UAS has crashed or the request was misrouted. - // In the latter case, the misrouted request is best handled by rejecting the request. - // For the Sip Servlet environment, a UAS crash may mean either an application crashed - // or the container itself crashed. In either case, it is impossible to route the request - // as a subsequent request and it is inappropriate to route it as an initial request. + // 4. Existing Dialog Detection - If the request has a tag in the To header field, + // the container computes the dialog identifier (as specified in section 12 of RFC 3261) + // corresponding to the request and compares it with existing dialogs. + // If it matches an existing dialog, stop. The request is not an initial request. + // The request is a subsequent request and must be routed to the application path + // associated with the existing dialog. + // If the request has a tag in the To header field, + // but the dialog identifier does not match any existing dialogs, + // the container must reject the request with a 481 (Call/Transaction Does Not Exist). + // Note: When this occurs, RFC 3261 says either the UAS has crashed or the request was misrouted. + // In the latter case, the misrouted request is best handled by rejecting the request. + // For the Sip Servlet environment, a UAS crash may mean either an application crashed + // or the container itself crashed. In either case, it is impossible to route the request + // as a subsequent request and it is inappropriate to route it as an initial request. // Therefore, the only viable approach is to reject the request. if(dialog != null && !DialogState.EARLY.equals(dialog.getState())) { + if (logger.isDebugEnabled()){ + logger.debug("checkRoutingState - dialog not null and dialog state is not EARLY"); + } return RoutingState.SUBSEQUENT; } - - // 6. Detection of Requests Sent to Encoded URIs - - // Requests may be sent to a container instance addressed to a URI obtained by calling - // the encodeURI() method of a SipApplicationSession managed by this container instance. - // When a container receives such a request, stop. This request is not an initial request. - // Refer to section 15.11.1 Session Targeting and Application Selection + + // 6. Detection of Requests Sent to Encoded URIs - + // Requests may be sent to a container instance addressed to a URI obtained by calling + // the encodeURI() method of a SipApplicationSession managed by this container instance. + // When a container receives such a request, stop. This request is not an initial request. + // Refer to section 15.11.1 Session Targeting and Application Selection //for more information on how a request sent to an encoded URI is handled by the container. //This part will be done in routeIntialRequest since this is where the Session Targeting retrieval is done - - return RoutingState.INITIAL; + + return RoutingState.INITIAL; } /** @@ -2241,7 +2326,7 @@ private static RoutingState checkRoutingState(SipServletRequestImpl sipServletRe public boolean is1xxResponseGenerated() { return is1xxResponseGenerated; } - + /** * @return the isFinalResponseGenerated */ @@ -2259,119 +2344,119 @@ public SipServletResponse getLastInformationalResponse() { public void setReadOnly(boolean isReadOnly) { this.isReadOnly = isReadOnly; } - + protected void checkReadOnly() { if(isReadOnly) { throw new IllegalStateException(EXCEPTION_MESSAGE); } } - + @Override public void addAcceptLanguage(Locale locale) { checkReadOnly(); super.addAcceptLanguage(locale); } - + @Override public void addAddressHeader(String name, Address addr, boolean first) throws IllegalArgumentException { checkReadOnly(); super.addAddressHeader(name, addr, first); } - + @Override public void addHeader(String name, String value) { checkReadOnly(); super.addHeader(name, value); } - + @Override public void addParameterableHeader(String name, Parameterable param, boolean first) { checkReadOnly(); super.addParameterableHeader(name, param, first); } - + @Override public void removeAttribute(String name) { checkReadOnly(); super.removeAttribute(name); } - + @Override public void removeHeader(String name) { checkReadOnly(); super.removeHeader(name); } - + @Override public void setAcceptLanguage(Locale locale) { checkReadOnly(); super.setAcceptLanguage(locale); } - + @Override public void setAddressHeader(String name, Address addr) { checkReadOnly(); super.setAddressHeader(name, addr); } - + @Override public void setAttribute(String name, Object o) { checkReadOnly(); super.setAttribute(name, o); } - + @Override public void setCharacterEncoding(String enc) throws UnsupportedEncodingException { checkReadOnly(); super.setCharacterEncoding(enc); } - + @Override public void setContent(Object content, String contentType) throws UnsupportedEncodingException { checkReadOnly(); super.setContent(content, contentType); } - + @Override public void setContentLanguage(Locale locale) { checkReadOnly(); super.setContentLanguage(locale); } - + @Override public void setContentType(String type) { checkReadOnly(); super.setContentType(type); } - + @Override public void setExpires(int seconds) { checkReadOnly(); super.setExpires(seconds); } - + @Override public void setHeader(String name, String value) { checkReadOnly(); super.setHeader(name, value); } - + @Override public void setHeaderForm(HeaderForm form) { checkReadOnly(); super.setHeaderForm(form); } - + @Override public void setParameterableHeader(String name, Parameterable param) { checkReadOnly(); super.setParameterableHeader(name, param); } - + /** * {@inheritDoc} */ @@ -2387,11 +2472,11 @@ public String getInitialRemoteAddr() { return null; } return ((SIPRequest)message).getPeerPacketSourceAddress().getHostAddress(); - } else if (message != null && - message instanceof SIPRequest && + } else if (message != null && + message instanceof SIPRequest && ((SIPRequest)message).getPeerPacketSourceAddress() != null ) { //https://github.com/Mobicents/jain-sip/issues/42 - //take advantage of new message methods to extract addr from msg + //take advantage of new message methods to extract addr from msg return ((SIPRequest)message).getPeerPacketSourceAddress().getHostAddress(); } else if(getTransaction() != null) { if(logger.isTraceEnabled()) { @@ -2409,7 +2494,7 @@ public String getInitialRemoteAddr() { ViaHeader via = (ViaHeader) message.getHeader(ViaHeader.NAME); if(via == null || // https://github.com/Mobicents/sip-servlets/issues/47 - // check if the via is container generated, if it is then it means + // check if the via is container generated, if it is then it means // this is an outgoing request or response and thus should return null !sipFactoryImpl.getSipApplicationDispatcher().isViaHeaderExternal(via) ) { return null; @@ -2434,7 +2519,7 @@ public int getInitialRemotePort() { return -1; } return ((SIPRequest)message).getPeerPacketSourcePort(); - } else if (message != null && + } else if (message != null && message instanceof SIPRequest ) { //https://github.com/Mobicents/jain-sip/issues/42 //take advantage of new message methods to extract port from msg @@ -2455,7 +2540,7 @@ public int getInitialRemotePort() { ViaHeader via = (ViaHeader) message.getHeader(ViaHeader.NAME); if(via == null || // https://github.com/Mobicents/sip-servlets/issues/47 - // check if the via is container generated, if it is then it means + // check if the via is container generated, if it is then it means // this is an outgoing request or response and thus should return null !sipFactoryImpl.getSipApplicationDispatcher().isViaHeaderExternal(via) ) { return -1; @@ -2469,14 +2554,14 @@ public int getInitialRemotePort() { /** * {@inheritDoc} */ - public String getInitialTransport() { + public String getInitialTransport() { if(getTransaction() != null) { return ((SIPTransaction)getTransaction()).getTransport(); } else { ViaHeader via = (ViaHeader) message.getHeader(ViaHeader.NAME); if(via == null || // https://github.com/Mobicents/sip-servlets/issues/47 - // check if the via is container generated, if it is then it means + // check if the via is container generated, if it is then it means // this is an outgoing request or response and thus should return null !sipFactoryImpl.getSipApplicationDispatcher().isViaHeaderExternal(via) ) { return null; @@ -2485,7 +2570,7 @@ public String getInitialTransport() { } } } - + public void cleanUp() { // super.cleanUp(); if(transactionApplicationData != null) { @@ -2500,10 +2585,10 @@ public void cleanUp() { routingState = null; subscriberURI = null; // lastFinalResponse = null; -// lastInformationalResponse = null; +// lastInformationalResponse = null; linkedRequest = null; } - + public void cleanUpLastResponses() { if(logger.isDebugEnabled()) { logger.debug("cleaning up last responses on " + this); @@ -2511,13 +2596,17 @@ public void cleanUpLastResponses() { lastFinalResponse = null; lastInformationalResponse = null; } - + /* * (non-Javadoc) * @see java.io.Externalizable#readExternal(java.io.ObjectInput) */ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + if(logger.isDebugEnabled()) { + logger.debug("readExternal"); + } + super.readExternal(in); String messageString = in.readUTF(); try { @@ -2543,10 +2632,13 @@ public void readExternal(ObjectInput in) throws IOException, routingRegion = (SipApplicationRoutingRegion) in.readObject(); } isInitial = in.readBoolean(); + if(logger.isDebugEnabled()) { + logger.debug("readExternal - isInitial=" + isInitial); + } isFinalResponseGenerated = in.readBoolean(); - is1xxResponseGenerated = in.readBoolean(); + is1xxResponseGenerated = in.readBoolean(); } - + /* * (non-Javadoc) * @see java.io.Externalizable#writeExternal(java.io.ObjectOutput) @@ -2577,8 +2669,11 @@ public void writeExternal(ObjectOutput out) throws IOException { out.writeBoolean(false); } out.writeBoolean(isInitial); + if(logger.isDebugEnabled()) { + logger.debug("writeExternal - isInitial=" + isInitial); + } out.writeBoolean(isFinalResponseGenerated); - out.writeBoolean(is1xxResponseGenerated); + out.writeBoolean(is1xxResponseGenerated); } private static int generateNcFromMessage(Message message) { @@ -2598,20 +2693,20 @@ public void updateAuthorizationHeaders(boolean useNextNonce) { if(logger.isDebugEnabled()) { logger.debug("Updating authorization headers with nextnonce " + getSipSession().getSipSessionSecurity().getNextNonce()); } - int nc = -1; - + int nc = -1; + List
authorizationHeaders = new ArrayList
(); - + // First check for WWWAuthentication headers - ListIterator authHeaderIterator = + ListIterator authHeaderIterator = message.getHeaders(AuthorizationHeader.NAME); while(authHeaderIterator.hasNext()) { - AuthorizationHeader wwwAuthHeader = + AuthorizationHeader wwwAuthHeader = (AuthorizationHeader) authHeaderIterator.next(); MobicentsAuthInfoEntry authInfoEntry = getSipSession().getSipSessionSecurity().getCachedAuthInfos().get(wwwAuthHeader.getRealm()); - + if(authInfoEntry != null) { - + if(nc < 0) { nc = generateNcFromMessage(message); } @@ -2621,7 +2716,7 @@ public void updateAuthorizationHeaders(boolean useNextNonce) { } else { nextNonce = wwwAuthHeader.getNonce(); } - + AuthorizationHeader authorization = getSipSession().getSipApplicationSession().getSipContext().getDigestAuthenticator().getAuthorizationHeader( getMethod(), this.getRequestURI().toString(), @@ -2637,18 +2732,18 @@ public void updateAuthorizationHeaders(boolean useNextNonce) { authorizationHeaders.add(wwwAuthHeader); } } - + // Now check for Proxy-Authentication - authHeaderIterator = + authHeaderIterator = message.getHeaders(ProxyAuthorizationHeader.NAME); while(authHeaderIterator.hasNext()) { - ProxyAuthorizationHeader proxyAuthHeader = + ProxyAuthorizationHeader proxyAuthHeader = (ProxyAuthorizationHeader) authHeaderIterator.next(); // String uri = wwwAuthHeader.getParameter("uri"); MobicentsAuthInfoEntry authInfoEntry = getSipSession().getSipSessionSecurity().getCachedAuthInfos().get(proxyAuthHeader.getRealm()); - - if(authInfoEntry != null) { - + + if(authInfoEntry != null) { + if(nc < 0) { nc = generateNcFromMessage(message); } @@ -2673,10 +2768,10 @@ public void updateAuthorizationHeaders(boolean useNextNonce) { authorizationHeaders.add(proxyAuthHeader); } } - + message.removeHeader(AuthorizationHeader.NAME); message.removeHeader(ProxyAuthorizationHeader.NAME); - + for(Header header : authorizationHeaders) { message.addHeader(header); } @@ -2690,5 +2785,5 @@ public Object clone() { sipServletRequestImpl.setSubscriberURI(subscriberURI); sipServletRequestImpl.setAttributeMap(getAttributeMap()); return sipServletRequestImpl; - } + } } diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/SipServletResponseImpl.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/SipServletResponseImpl.java index e798af61e8..fafd8699df 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/SipServletResponseImpl.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/SipServletResponseImpl.java @@ -168,7 +168,7 @@ public ModifiableRule getModifiableRule(String headerName) { return ModifiableRule.NotModifiable; } - if(hName.equals(ContactHeader.NAME)) { + if(hName.equalsIgnoreCase(ContactHeader.NAME)) { Response sipResponse = (Response) this.message; String method = ((CSeqHeader) sipResponse.getHeader(CSeqHeader.NAME)) diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/TransactionApplicationData.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/TransactionApplicationData.java index e921157ba2..c2e2483e23 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/TransactionApplicationData.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/message/TransactionApplicationData.java @@ -68,7 +68,7 @@ public class TransactionApplicationData implements Serializable, MobicentsTransa public TransactionApplicationData(SipServletMessageImpl sipServletMessage ) { this.sipServletMessage = sipServletMessage; this.sipSessionKey = sipServletMessage.getSipSessionKey(); - sipServletResponses = null; + sipServletResponses = null; // Added for https://github.com/RestComm/sip-servlets/issues/107 messageCleanedUp = new AtomicBoolean(false); } @@ -258,7 +258,7 @@ public void cleanUp() { hops = null; if(logger.isDebugEnabled()) { logger.debug("cleaned up tx app data hops"); - } + } } } diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/proxy/ProxyBranchImpl.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/proxy/ProxyBranchImpl.java index b62a28c250..8f45fcdc86 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/proxy/ProxyBranchImpl.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/proxy/ProxyBranchImpl.java @@ -142,16 +142,25 @@ public TransactionRequest(String branch, SipServletRequestImpl request) { } // empty constructor used only for Externalizable interface - public ProxyBranchImpl() {} + public ProxyBranchImpl() { + + if(logger.isDebugEnabled()) { + logger.debug("ProxyBranchImpl no-argument constructor"); + } + + } public ProxyBranchImpl(URI uri, ProxyImpl proxy) { + if(logger.isDebugEnabled()) { + logger.debug("ProxyBranchImpl constructor - proxy=" + proxy); + } this.targetURI = uri.toString(); this.proxy = proxy; isAddToPath = proxy.getAddToPath(); this.originalRequest = (SipServletRequestImpl) proxy.getOriginalRequest(); if(proxy.recordRouteURI != null) { - this.recordRouteURI = proxy.recordRouteURI; + this.recordRouteURI = proxy.recordRouteURI; } if(proxy.recordRouteURIString != null) { this.recordRouteURIString = proxy.recordRouteURIString; @@ -395,6 +404,9 @@ public boolean isStarted() { * @see javax.servlet.sip.ProxyBranch#setProxyBranchTimeout(int) */ public void setProxyBranchTimeout(int seconds) { + if(logger.isDebugEnabled()) { + logger.debug("setProxyBranchTimeout"); + } if(seconds<=0) throw new IllegalArgumentException("Negative or zero timeout not allowed"); @@ -412,6 +424,10 @@ public void setProxyBranchTimeout(int seconds) { * specified destination. Subsequent requests are proxied through proxySubsequentRequest */ public void start() { + if(logger.isDebugEnabled()) { + logger.debug("start"); + } + if(started) { throw new IllegalStateException("Proxy branch alredy started!"); } @@ -426,6 +442,9 @@ public void start() { } // Initialize these here for efficiency. + if(logger.isDebugEnabled()) { + logger.debug("start - calling updateTimer"); + } updateTimer(false, originalRequest.getSipApplicationSession(false)); SipURI recordRoute = null; @@ -446,7 +465,7 @@ public void start() { recordRoute = recordRouteURI; } addTransaction(originalRequest); - + URI destination = null; //app may have modified the branch request, so give it priority //fixes https://github.com/RestComm/sip-servlets/issues/131 @@ -502,7 +521,14 @@ private void forwardRequest(Request request, boolean subsequent) { null, null, null, false); + if(logger.isDebugEnabled()) { + logger.debug("forwardRequest - clonedRequest=" + clonedRequest); + } + if(subsequent) { + if(logger.isDebugEnabled()) { + logger.debug("forwardRequest - setRoutingState to SUBSEQUENT"); + } clonedRequest.setRoutingState(RoutingState.SUBSEQUENT); } @@ -510,13 +536,24 @@ private void forwardRequest(Request request, boolean subsequent) { // Initialize the sip session for the new request if initial final MobicentsSipSession originalSipSession = originalRequest.getSipSession(); + if(logger.isDebugEnabled()) { + logger.debug("forwardRequest - originalSipSession=" + originalSipSession); + logger.debug("forwardRequest - originalRequest.getCurrentApplicationName()=" + originalRequest.getCurrentApplicationName()); + } + clonedRequest.setCurrentApplicationName(originalRequest.getCurrentApplicationName()); if(clonedRequest.getCurrentApplicationName() == null && subsequent) { + if(logger.isDebugEnabled()) { + logger.debug("forwardRequest - originalSipSession.getSipApplicationSession().getApplicationName()=" + originalSipSession.getSipApplicationSession().getApplicationName()); + } clonedRequest.setCurrentApplicationName(originalSipSession.getSipApplicationSession().getApplicationName()); } clonedRequest.setSipSession(originalSipSession); final MobicentsSipSession newSession = (MobicentsSipSession) clonedRequest.getSipSession(); try { + if(logger.isDebugEnabled()) { + logger.debug("forwardRequest - calling setHandler - originalSipSession.getHandler()=" + originalSipSession.getHandler()); + } newSession.setHandler(originalSipSession.getHandler()); } catch (ServletException e) { logger.error("could not set the session handler while forwarding the request", e); @@ -531,8 +568,14 @@ private void forwardRequest(Request request, boolean subsequent) { newSession.setProxy(proxy); try { + if(logger.isDebugEnabled()) { + logger.debug("forwardRequest - calling checkRequest"); + } RFC5626Helper.checkRequest(this, request, originalRequest); } catch (IncorrectFlowIdentifierException e1) { + if(logger.isDebugEnabled()) { + logger.debug("forwardRequest - checkRequest threw an exception", e1); + } logger.warn(e1.getMessage()); this.cancel(); try { @@ -544,11 +587,20 @@ private void forwardRequest(Request request, boolean subsequent) { } //JSR 289 Section 15.1.6 if(!subsequent) { + if(logger.isDebugEnabled()) { + logger.debug("forwardRequest - not subsequent"); + } // Subsequent requests can't have a routing directive? clonedRequest.setRoutingDirective(SipApplicationRoutingDirective.CONTINUE, originalRequest); } + if(logger.isDebugEnabled()) { + logger.debug("forwardRequest - setting the proxy branch"); + } clonedRequest.getTransactionApplicationData().setProxyBranch(this); try { + if(logger.isDebugEnabled()) { + logger.debug("forwardRequest - sending the cloned request=" + clonedRequest); + } clonedRequest.send(); } catch (IOException e) { throw new IllegalStateException(e); @@ -794,7 +846,10 @@ public void proxySubsequentRequest(MobicentsSipServletRequest sipServletRequest) // } // https://telestax.atlassian.net/browse/MSS-153 perf optimization : we update the timer only on non ACK - if(!clonedRequest.getMethod().equalsIgnoreCase(Request.ACK) ) { + if(!clonedRequest.getMethod().equalsIgnoreCase(Request.ACK) ) { + if(logger.isDebugEnabled()) { + logger.debug("proxySubsequentRequest - calling updateTimer - request " + request); + } updateTimer(false, request.getSipApplicationSession(false)); } @@ -802,6 +857,10 @@ public void proxySubsequentRequest(MobicentsSipServletRequest sipServletRequest) // Reset the proxy supervised state to default Chapter 6.2.1 - page down list bullet number 6 proxy.setSupervised(true); if(clonedRequest.getMethod().equalsIgnoreCase(Request.ACK) ) { //|| clonedRequest.getMethod().equalsIgnoreCase(Request.PRACK)) { + if(logger.isDebugEnabled()) { + logger.debug("proxySubsequentRequest - clonedRequest is ACK - request " + request); + } + // we mark them as accessed so that HA replication can occur final MobicentsSipSession sipSession = request.getSipSession(); final MobicentsSipApplicationSession sipApplicationSession = sipSession.getSipApplicationSession(); @@ -837,6 +896,9 @@ public void proxySubsequentRequest(MobicentsSipServletRequest sipServletRequest) sipFactoryImpl.getSipApplicationDispatcher().updateRequestsStatistics(clonedRequest, false); } else { + if(logger.isDebugEnabled()) { + logger.debug("proxySubsequentRequest - calling forwardRequest - request " + request); + } forwardRequest(clonedRequest, true); } @@ -1002,13 +1064,13 @@ public void onTimeout(ResponseType responseType) throws DispatcherException } this.timedOut = true; if(originalRequest != null) { - List proxyBranchListeners = originalRequest.getSipSession().getSipApplicationSession().getSipContext().getListeners().getProxyBranchListeners(); - if(proxyBranchListeners != null) { - for (ProxyBranchListener proxyBranchListener : proxyBranchListeners) { - proxyBranchListener.onProxyBranchResponseTimeout(responseType, this); + List proxyBranchListeners = originalRequest.getSipSession().getSipApplicationSession().getSipContext().getListeners().getProxyBranchListeners(); + if(proxyBranchListeners != null) { + for (ProxyBranchListener proxyBranchListener : proxyBranchListeners) { + proxyBranchListener.onProxyBranchResponseTimeout(responseType, this); + } } } - } // Just do a timeout response proxy.onBranchTimeOut(this); logger.warn("Proxy branch has timed out"); @@ -1024,6 +1086,13 @@ public void onTimeout(ResponseType responseType) throws DispatcherException * */ public void updateTimer(boolean cancel1xxTimer, MobicentsSipApplicationSession mobicentsSipApplicationSession) { + if(logger.isDebugEnabled()) { + logger.debug("updateTimer - cancel1xxTimer=" + cancel1xxTimer + ", mobicentsSipApplicationSession=" + mobicentsSipApplicationSession); + if (mobicentsSipApplicationSession != null){ + logger.debug("updateTimer - cancel1xxTimer=" + cancel1xxTimer + ", mobicentsSipApplicationSession.getApplicationName()=" + mobicentsSipApplicationSession.getApplicationName()); + logger.debug("updateTimer - cancel1xxTimer=" + cancel1xxTimer + ", mobicentsSipApplicationSession.getSipContext()=" + mobicentsSipApplicationSession.getSipContext()); + } + } if(cancel1xxTimer) { cancel1xxTimer(); } @@ -1035,6 +1104,10 @@ public void updateTimer(boolean cancel1xxTimer, MobicentsSipApplicationSession m final ProxyBranchTimerTask timerCTask = new ProxyBranchTimerTask(this, ResponseType.FINAL, mobicentsSipApplicationSession); if(logger.isDebugEnabled()) { logger.debug("Proxy Branch Timeout set to " + proxyBranchTimeout); + logger.debug("updateTimer - proxy=" + proxy); + if (proxy != null){ + logger.debug("updateTimer - proxy.getProxyTimerService()=" + proxy.getProxyTimerService()); + } } proxy.getProxyTimerService().schedule(timerCTask, proxyBranchTimeout * 1000L); proxyTimeoutTask = timerCTask; @@ -1244,6 +1317,9 @@ public void setWaitingForPrack(boolean waitingForPrack) { * @param proxy the proxy to set */ public void setProxy(ProxyImpl proxy) { + if(logger.isDebugEnabled()) { + logger.debug("setProxy - proxy=" + proxy); + } this.proxy = proxy; } diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/proxy/ProxyImpl.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/proxy/ProxyImpl.java index fb3fa8c0b7..1cc9dec0dd 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/proxy/ProxyImpl.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/proxy/ProxyImpl.java @@ -143,11 +143,27 @@ public class ProxyImpl implements MobicentsProxy, Externalizable { private ProxyTerminationInfo terminationInfo; // Object to store termination information // empty constructor used only for Externalizable interface - public ProxyImpl() {} + public ProxyImpl() { + if (logger.isDebugEnabled()){ + logger.debug("ProxyImpl no-argument constructor"); + } + } public ProxyImpl(SipServletRequestImpl request, SipFactoryImpl sipFactoryImpl) { + if (logger.isDebugEnabled()){ + logger.debug("ProxyImpl constructor"); + } this.proxyTimerService = ((MobicentsSipApplicationSession)request.getSipApplicationSession(false)).getSipContext().getProxyTimerService(); + if (logger.isDebugEnabled()){ + logger.debug("ProxyImpl constructor - this.proxyTimerService=" + this.proxyTimerService); + if (((MobicentsSipApplicationSession)request.getSipApplicationSession(false)) != null){ + logger.debug("ProxyImpl constructor - sipContext=" + ((MobicentsSipApplicationSession)request.getSipApplicationSession(false)).getSipContext()); + logger.debug("ProxyImpl constructor - sipContext.getApplicationName()=" + ((MobicentsSipApplicationSession)request.getSipApplicationSession(false)).getSipContext().getApplicationName()); + logger.debug("ProxyImpl constructor - getApplicationName()=" + ((MobicentsSipApplicationSession)request.getSipApplicationSession(false)).getApplicationName()); + logger.debug("ProxyImpl constructor - SipApplicationSession.getId()=" + ((MobicentsSipApplicationSession)request.getSipApplicationSession(false)).getId()); + } + } this.originalRequest = request; this.sipFactoryImpl = sipFactoryImpl; this.proxyBranches = new LinkedHashMap (); @@ -165,7 +181,7 @@ public ProxyImpl(SipServletRequestImpl request, SipFactoryImpl sipFactoryImpl) this.previousNode = extractPreviousNodeFromRequest(request); putTransaction(originalRequest); } - // https://code.google.com/p/sipservlets/issues/detail?id=238 + // https://code.google.com/p/sipservlets/issues/detail?id=238 public void putTransaction(SipServletRequestImpl request) { final String txId = ((ViaHeader) request.getMessage().getHeader(ViaHeader.NAME)).getBranch(); final TransactionApplicationData txData = request.getTransactionApplicationData(); @@ -320,6 +336,10 @@ public List createProxyBranches(List targets) { if(!JainSipUtils.checkScheme(target.toString())) { throw new IllegalArgumentException("Scheme " + target.getScheme() + " is not supported"); } + if(logger.isDebugEnabled()) { + logger.debug("createProxyBranches with proxyTimerService=" + proxyTimerService); + } + ProxyBranchImpl branch = new ProxyBranchImpl(target, this); branch.setRecordRoute(recordRoutingEnabled); branch.setRecurse(recurse); @@ -917,7 +937,9 @@ public void sendFinalResponse(MobicentsSipServletResponse response, proxiedResponse.send(); bestResponseSent = proxiedResponse.getStatus(); proxyBranches.clear(); - originalRequest = null; + //fixes fixes https://github.com/RestComm/sip-servlets/issues/184 + //do not nullify originalReq, otherwise the cleanup logic during + //txtermination will not work completely. // not needed cleanup in the finally clause will do it // bestBranch = null; // bestResponse = null; @@ -964,10 +986,10 @@ public void setOriginalRequest(MobicentsSipServletRequest originalRequest) { // Determine the direction of the request. Either it's from the dialog initiator (the caller) // or from the callee if(storeTerminationInfo) { - if(((MessageExt)originalRequest.getMessage()).getFromHeader().getTag().equals(callerFromTag)) { + if(((MessageExt)originalRequest.getMessage()).getFromHeader().getTag().equals(callerFromTag)) { terminationInfo.setCallerCSeq((((MessageExt)originalRequest.getMessage()).getCSeqHeader().getSeqNumber())); - } else { - // If it's from the callee we should send it in the other direction + } else { + // If it's from the callee we should send it in the other direction terminationInfo.setCalleeCSeq((((MessageExt)originalRequest.getMessage()).getCSeqHeader().getSeqNumber())); } } @@ -1100,6 +1122,10 @@ public Map getTransactionMap() { public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + if(logger.isDebugEnabled()) { + logger.debug("readExternal"); + } + if(ReplicationStrategy.EarlyDialog == StaticServiceHolder.sipStandardService.getReplicationStrategy()) { // Issue 2587 : read only if not null. if(in.readBoolean()) { @@ -1119,12 +1145,18 @@ public void readExternal(ObjectInput in) throws IOException, // tryingSent = in.readBoolean(); finalBranchForSubsequentRequests = (ProxyBranchImpl) in.readObject(); if(finalBranchForSubsequentRequests != null) { + if(logger.isDebugEnabled()) { + logger.debug("readExternal - finalBranchForSubsequentRequests is not null - calling setProxy"); + } finalBranchForSubsequentRequests.setProxy(this); } previousNode = in.readUTF(); callerFromTag = in.readUTF(); storeTerminationInfo = in.readBoolean(); if (storeTerminationInfo) { + if(logger.isDebugEnabled()) { + logger.debug("readExternal - storeTerminationInfo is not null - calling setProxy"); + } terminationInfo = (ProxyTerminationInfo) in.readObject(); terminationInfo.setProxy(this); } @@ -1261,4 +1293,9 @@ public void setRecordRouteURI(SipURI uri) { public boolean isAppSpecifiedRecordRoutingEnabled() { return appSpecifiedRecordRoutingEnabled; } + + public void setProxyTimerService(ProxyTimerService proxyTimerService) { + this.proxyTimerService = proxyTimerService; + } + } diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/proxy/ProxyUtils.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/proxy/ProxyUtils.java index 60b52afad9..257bc7a090 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/proxy/ProxyUtils.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/proxy/ProxyUtils.java @@ -416,6 +416,9 @@ public static Request createProxiedRequest(SipServletRequestImpl originalRequest public static SipServletResponseImpl createProxiedResponse(MobicentsSipServletResponse sipServetResponse, MobicentsProxyBranch proxyBranch) { + if(logger.isDebugEnabled()) { + logger.debug("createProxiedResponse - proxyBranch=" + proxyBranch); + } final Response response = (Response)sipServetResponse.getMessage(); final Response clonedResponse = (Response) response.clone(); ((MessageExt)clonedResponse).setApplicationData(null); diff --git a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/rfc5626/RFC5626Helper.java b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/rfc5626/RFC5626Helper.java index e5a08617ae..1f7108c850 100644 --- a/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/rfc5626/RFC5626Helper.java +++ b/sip-servlets-impl/src/main/java/org/mobicents/servlet/sip/rfc5626/RFC5626Helper.java @@ -81,7 +81,13 @@ public class RFC5626Helper { } public static void checkRequest(ProxyBranchImpl proxyBranch, Request request, SipServletRequestImpl originalRequest) throws IncorrectFlowIdentifierException { + if (logger.isDebugEnabled()){ + logger.debug("checkRequest - proxyBranch=" + proxyBranch + ", request=" + request); + } if(!((ProxyImpl)proxyBranch.getProxy()).getSipOutboundSupport()) { + if (logger.isDebugEnabled()){ + logger.debug("checkRequest - returning immediately"); + } return; } // final Request request = (Request) sipServletRequestImpl.getMessage(); @@ -89,6 +95,10 @@ public static void checkRequest(ProxyBranchImpl proxyBranch, Request request, Si final ProxyImpl proxy = (ProxyImpl) proxyBranch.getProxy(); if(proxyBranch.isAddToPath() && request.getMethod().equalsIgnoreCase(Request.REGISTER)) { + if (logger.isDebugEnabled()){ + logger.debug("checkRequest - RFC 5626 Section 5.1. Processing Register Requests"); + } + //RFC 5626 Section 5.1. Processing Register Requests if(contactHeader != null && contactHeader.getParameter(MessageDispatcher.SIP_OUTBOUND_PARAM_REG_ID) != null) { int nbVias = 0; @@ -114,6 +124,9 @@ public static void checkRequest(ProxyBranchImpl proxyBranch, Request request, Si } } }else { + if (logger.isDebugEnabled()){ + logger.debug("checkRequest - RFC 5626 Section 5.3. Forwarding Non-REGISTER Requests"); + } //RFC 5626 Section 5.3. Forwarding Non-REGISTER Requests RouteHeader poppedRouteHeader = originalRequest.getPoppedRouteHeader(); boolean poppedRouteHasObParam = false; diff --git a/sip-servlets-impl/src/main/resources/org/mobicents/servlet/sip/core/mbeans-descriptors.xml b/sip-servlets-impl/src/main/resources/org/mobicents/servlet/sip/core/mbeans-descriptors.xml index 98f3d5c5d5..ff116ffee1 100644 --- a/sip-servlets-impl/src/main/resources/org/mobicents/servlet/sip/core/mbeans-descriptors.xml +++ b/sip-servlets-impl/src/main/resources/org/mobicents/servlet/sip/core/mbeans-descriptors.xml @@ -153,6 +153,20 @@ + + + + + + + + diff --git a/sip-servlets-impl/src/main/resources/org/mobicents/servlet/sip/core/release.properties b/sip-servlets-impl/src/main/resources/org/mobicents/servlet/sip/core/release.properties index b7fe30b82b..7f44236f1e 100644 --- a/sip-servlets-impl/src/main/resources/org/mobicents/servlet/sip/core/release.properties +++ b/sip-servlets-impl/src/main/resources/org/mobicents/servlet/sip/core/release.properties @@ -5,6 +5,7 @@ release.version=${pom.version} release.revision=r${buildNumber} release.date=${release.timestamp} release.name=${restcomm.name} +statistics.server=${restcomm.statistics.server} release.disclaimer=\n\ ==============================================================================\n\ == ==\n\ diff --git a/sip-servlets-test-suite/applications/annotated-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/AnnotatedServlet.java b/sip-servlets-test-suite/applications/annotated-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/AnnotatedServlet.java index 3b639416b5..386dfbcea0 100644 --- a/sip-servlets-test-suite/applications/annotated-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/AnnotatedServlet.java +++ b/sip-servlets-test-suite/applications/annotated-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/AnnotatedServlet.java @@ -1,167 +1,190 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite; - -import java.io.IOException; -import java.util.Properties; - -import javax.annotation.Resource; -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NamingException; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.sip.SipApplicationSession; -import javax.servlet.sip.SipFactory; -import javax.servlet.sip.SipServlet; -import javax.servlet.sip.SipServletContextEvent; -import javax.servlet.sip.SipServletListener; -import javax.servlet.sip.SipServletRequest; -import javax.servlet.sip.SipServletResponse; -import javax.servlet.sip.SipSessionsUtil; -import javax.servlet.sip.TimerService; -import javax.servlet.sip.annotation.SipApplicationKey; -import javax.servlet.sip.annotation.SipListener; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; - - -@SipListener -@javax.servlet.sip.annotation.SipServlet(loadOnStartup=1) -public class AnnotatedServlet extends SipServlet implements SipServletListener { - private static final long serialVersionUID = 1L; - @Resource - SipFactory sipFactory; - @Resource - SipSessionsUtil sipSessionsUtil; - @Resource - TimerService timerService; - - private static transient Logger logger = Logger.getLogger(AnnotatedServlet.class); - - @Override - public void init(ServletConfig servletConfig) throws ServletException { - super.init(servletConfig); - logger.info("the simple sip servlet has been started"); - logger.info("SipFactory injected resource " + sipFactory); - logger.info("SipSessionsUtil injected resource " + sipSessionsUtil); - logger.info("TimerService injected resource " + timerService); - if(sipFactory == null || sipSessionsUtil == null || timerService == null) { - throw new ServletException("Impossible to get one of the annotated resource"); - } - SipFactory sipFactoryJndi; - SipSessionsUtil sipSessionsUtilJndi; - TimerService timerServiceJndi; - try { - // Getting the Sip factory from the JNDI Context - Properties jndiProps = new Properties(); - Context initCtx = new InitialContext(jndiProps); - Context envCtx = (Context) initCtx.lookup("java:comp/env"); - sipFactoryJndi = (SipFactory) envCtx.lookup("sip/org.mobicents.servlet.sip.testsuite.AnnotatedApplication/SipFactory"); - sipSessionsUtilJndi = (SipSessionsUtil) envCtx.lookup("sip/org.mobicents.servlet.sip.testsuite.AnnotatedApplication/SipSessionsUtil"); - timerServiceJndi = (TimerService) envCtx.lookup("sip/org.mobicents.servlet.sip.testsuite.AnnotatedApplication/TimerService"); - logger.info("SipFactory injected resource" + sipFactory); - logger.info("SipSessionsUtil injected resource" + sipSessionsUtil); - logger.info("TimerService injected resource" + timerService); - logger.info("Sip Factory ref from JNDI : " + sipFactory); - } catch (NamingException e) { - throw new ServletException("Uh oh -- JNDI problem !", e); - } - if(sipFactoryJndi == null || sipSessionsUtilJndi == null || timerServiceJndi == null) { - throw new ServletException("Impossible to get one of the annotated resource"); - } - } - - /** - * {@inheritDoc} - */ - protected void doInvite(SipServletRequest request) throws ServletException, - IOException { - - logger.info("Got request: " - + request.getMethod()); - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_RINGING); - sipServletResponse.send(); - sipServletResponse = request.createResponse(SipServletResponse.SC_OK); - sipServletResponse.send(); - - // End the scenario by sending a message to the Tracker. - logger.info("SipFactory injected resource" + sipFactory); - logger.info("SipSessionsUtil injected resource" + sipSessionsUtil); - logger.info("TimerService injected resource" + timerService); - try { - SipApplicationSession appSession = - sipFactory.createApplicationSession(); // Injected factory - SipServletRequest req = sipFactory.createRequest(appSession, - "INVITE", "sip:from@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070", "sip:to@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5058"); - req.send(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - /** - * {@inheritDoc} - */ - protected void doBye(SipServletRequest request) throws ServletException, - IOException { - - logger.info("Got BYE request: " + request); - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); - sipServletResponse.send(); - } - - // SipErrorListener methods - - public void servletInitialized(SipServletContextEvent ce) { - ConcurrencyControlMode concurrencyControlMode = (ConcurrencyControlMode)ce.getServletContext().getAttribute(ConcurrencyControlMode.class.getCanonicalName()); - logger.info("concurrency control mode set to " + concurrencyControlMode); - if(!ConcurrencyControlMode.SipApplicationSession.equals(concurrencyControlMode)) { - throw new IllegalArgumentException("@ConcurrencyControl annotation badly parsed"); - } - try { - - SipFactory sipFactory = (SipFactory) ce.getServletContext().getAttribute(SIP_FACTORY); - SipApplicationSession appSession = - sipFactory.createApplicationSession(); - SipServletRequest req = sipFactory.createRequest(appSession, - "INVITE", "sip:from@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070", "sip:to@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070"); - req.send(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - @Override - protected void doSuccessResponse(SipServletResponse response) - throws ServletException, IOException { - logger.info("Got response: " + response); - response.createAck().send(); - } - - @SipApplicationKey - public static String key(SipServletRequest request) { - return "working"; - } +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite; + +import java.io.IOException; +import java.util.Properties; + +import javax.annotation.Resource; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.sip.SipApplicationSession; +import javax.servlet.sip.SipFactory; +import javax.servlet.sip.SipServlet; +import javax.servlet.sip.SipServletContextEvent; +import javax.servlet.sip.SipServletListener; +import javax.servlet.sip.SipServletRequest; +import javax.servlet.sip.SipServletResponse; +import javax.servlet.sip.SipSessionsUtil; +import javax.servlet.sip.TimerService; +import javax.servlet.sip.annotation.SipApplicationKey; +import javax.servlet.sip.annotation.SipListener; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; + + +@SipListener +@javax.servlet.sip.annotation.SipServlet(loadOnStartup=1) +public class AnnotatedServlet extends SipServlet implements SipServletListener { + private static final long serialVersionUID = 1L; + @Resource + SipFactory sipFactory; + @Resource + SipSessionsUtil sipSessionsUtil; + @Resource + TimerService timerService; + static ServletContext ctx; + + private static transient Logger logger = Logger.getLogger(AnnotatedServlet.class); + + @Override + public void init(ServletConfig servletConfig) throws ServletException { + super.init(servletConfig); + logger.info("the simple sip servlet has been started"); + ctx = servletConfig.getServletContext(); + logger.info("SipFactory injected resource " + sipFactory); + logger.info("SipSessionsUtil injected resource " + sipSessionsUtil); + logger.info("TimerService injected resource " + timerService); + if(sipFactory == null || sipSessionsUtil == null || timerService == null) { + throw new ServletException("Impossible to get one of the annotated resource"); + } + SipFactory sipFactoryJndi; + SipSessionsUtil sipSessionsUtilJndi; + TimerService timerServiceJndi; + try { + // Getting the Sip factory from the JNDI Context + Properties jndiProps = new Properties(); + Context initCtx = new InitialContext(jndiProps); + Context envCtx = (Context) initCtx.lookup("java:comp/env"); + sipFactoryJndi = (SipFactory) envCtx.lookup("sip/org.mobicents.servlet.sip.testsuite.AnnotatedApplication/SipFactory"); + sipSessionsUtilJndi = (SipSessionsUtil) envCtx.lookup("sip/org.mobicents.servlet.sip.testsuite.AnnotatedApplication/SipSessionsUtil"); + timerServiceJndi = (TimerService) envCtx.lookup("sip/org.mobicents.servlet.sip.testsuite.AnnotatedApplication/TimerService"); + logger.info("SipFactory injected resource" + sipFactory); + logger.info("SipSessionsUtil injected resource" + sipSessionsUtil); + logger.info("TimerService injected resource" + timerService); + logger.info("Sip Factory ref from JNDI : " + sipFactory); + } catch (NamingException e) { + throw new ServletException("Uh oh -- JNDI problem !", e); + } + if(sipFactoryJndi == null || sipSessionsUtilJndi == null || timerServiceJndi == null) { + throw new ServletException("Impossible to get one of the annotated resource"); + } + } + + /** + * {@inheritDoc} + */ + protected void doInvite(SipServletRequest request) throws ServletException, + IOException { + + logger.info("Got request: " + + request.getMethod()); + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_RINGING); + sipServletResponse.send(); + sipServletResponse = request.createResponse(SipServletResponse.SC_OK); + sipServletResponse.send(); + + // End the scenario by sending a message to the Tracker. + logger.info("SipFactory injected resource" + sipFactory); + logger.info("SipSessionsUtil injected resource" + sipSessionsUtil); + logger.info("TimerService injected resource" + timerService); + try { + SipApplicationSession appSession = + sipFactory.createApplicationSession(); // Injected factory + SipServletRequest req = sipFactory.createRequest(appSession, + "INVITE", "sip:from@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getServletContainerPort(ctx), "sip:to@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + req.send(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * {@inheritDoc} + */ + protected void doBye(SipServletRequest request) throws ServletException, + IOException { + + logger.info("Got BYE request: " + request); + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); + sipServletResponse.send(); + } + + // SipErrorListener methods + + public void servletInitialized(SipServletContextEvent ce) { + ConcurrencyControlMode concurrencyControlMode = (ConcurrencyControlMode)ce.getServletContext().getAttribute(ConcurrencyControlMode.class.getCanonicalName()); + logger.info("concurrency control mode set to " + concurrencyControlMode); + if(!ConcurrencyControlMode.SipApplicationSession.equals(concurrencyControlMode)) { + throw new IllegalArgumentException("@ConcurrencyControl annotation badly parsed"); + } + try { + + SipFactory sipFactory = (SipFactory) ce.getServletContext().getAttribute(SIP_FACTORY); + SipApplicationSession appSession = + sipFactory.createApplicationSession(); + SipServletRequest req = sipFactory.createRequest(appSession, + "INVITE", "sip:from@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getServletContainerPort(ctx), "sip:to@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getServletContainerPort(ctx)); + req.send(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + protected void doSuccessResponse(SipServletResponse response) + throws ServletException, IOException { + logger.info("Got response: " + response); + response.createAck().send(); + } + + @SipApplicationKey + public static String key(SipServletRequest request) { + return "working"; + } + + public static Integer getTestPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("testPort"); + logger.info("TestPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5080; + } + } + + public static Integer getServletContainerPort(ServletContext ctx) { + String cPort = ctx.getInitParameter("servletContainerPort"); + logger.info("TestPort at:" + cPort); + if (cPort != null) { + return Integer.valueOf(cPort); + } else { + return 5070; + } + } } \ No newline at end of file diff --git a/sip-servlets-test-suite/applications/appkey-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/AppKeySipServlet.java b/sip-servlets-test-suite/applications/appkey-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/AppKeySipServlet.java index b9cb2294e8..bb612e3995 100644 --- a/sip-servlets-test-suite/applications/appkey-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/AppKeySipServlet.java +++ b/sip-servlets-test-suite/applications/appkey-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/AppKeySipServlet.java @@ -1,137 +1,162 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite; - -import java.io.IOException; - -import javax.annotation.Resource; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.sip.SipApplicationSession; -import javax.servlet.sip.SipFactory; -import javax.servlet.sip.SipServlet; -import javax.servlet.sip.SipServletContextEvent; -import javax.servlet.sip.SipServletListener; -import javax.servlet.sip.SipServletRequest; -import javax.servlet.sip.SipServletResponse; -import javax.servlet.sip.SipSessionsUtil; -import javax.servlet.sip.SipURI; -import javax.servlet.sip.URI; - -import org.apache.log4j.Logger; - -public class AppKeySipServlet - extends SipServlet - implements SipServletListener { - private static final long serialVersionUID = 1L; - private static transient Logger logger = Logger.getLogger(AppKeySipServlet.class); - @Resource - SipFactory sipFactory; - @Resource - SipSessionsUtil sipSessionsUtil; - - public AppKeySipServlet() { - } - - @Override - public void init(ServletConfig servletConfig) throws ServletException { - logger.info("the appkey sip servlet has been started"); - super.init(servletConfig); - } - - @Override - protected void doSuccessResponse(SipServletResponse sipServletResponse) - throws ServletException, IOException { - logger.info("Got : " + sipServletResponse.getStatus() + " " - + sipServletResponse.getMethod()); - int status = sipServletResponse.getStatus(); - if (status == SipServletResponse.SC_OK && "INVITE".equalsIgnoreCase(sipServletResponse.getMethod())) { - SipServletRequest ackRequest = sipServletResponse.createAck(); - ackRequest.send(); -// try { -// Thread.sleep(2000); -// } catch (InterruptedException e) { -// logger.error("unexpected exception", e); -// } -// SipServletRequest sipServletRequest = sipServletResponse.getSession().createRequest("BYE"); -// sipServletRequest.send(); - } - - if (status == SipServletResponse.SC_OK && "REGISTER".equalsIgnoreCase(sipServletResponse.getMethod())) { - URI fromURI = sipFactory.createSipURI("BigGuy", "here.com"); - URI toURI = sipFactory.createSipURI("LittleGuy", "there.com"); - SipServletRequest sipServletRequest = - sipFactory.createRequest(sipServletResponse.getApplicationSession(), "INVITE", fromURI, toURI); - SipURI requestURI = sipFactory.createSipURI("LittleGuy", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - sipServletRequest.setRequestURI(requestURI); - String inviteCallId = sipServletRequest.getHeader("Call-ID"); - String registerCallId = (String) sipServletResponse.getApplicationSession().getAttribute("CallId"); - logger.info("REGISTER Call ID " + registerCallId); - logger.info("INVITE Call ID " + inviteCallId); - if(inviteCallId != null && registerCallId != null && !inviteCallId.equalsIgnoreCase(registerCallId)) { - try { - sipServletRequest.send(); - } catch (IOException e) { - logger.error(e); - } - } else { - throw new ServletException("Call Id for different requests within the same application session whose the key is app generated are the same!"); - } - } - } - - @Override - protected void doBye(SipServletRequest req) throws ServletException, - IOException { - req.createResponse(SipServletResponse.SC_OK).send(); - } - - // SipServletListener methods - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipServletListener#servletInitialized(javax.servlet.sip.SipServletContextEvent) - */ - public void servletInitialized(SipServletContextEvent ce) { - String appKeyName = "appkeytest"; - SipApplicationSession sipApplicationSession = null; - if(ce.getServletContext().getInitParameter("createApplicationSessionByKey") != null) { - sipApplicationSession = sipFactory.createApplicationSessionByKey(appKeyName); - } else { - sipApplicationSession = sipSessionsUtil.getApplicationSessionByKey(appKeyName, true); - } - - URI fromURI = sipFactory.createSipURI("BigGuy", "here.com"); - URI toURI = sipFactory.createSipURI("BigGuy", "there.com"); - SipServletRequest sipServletRequest = - sipFactory.createRequest(sipApplicationSession, "REGISTER", fromURI, toURI); - SipURI requestURI = sipFactory.createSipURI("BigGuy", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - sipServletRequest.setRequestURI(requestURI); - //Storing the Call id for future comparison - sipApplicationSession.setAttribute("CallId", sipServletRequest.getHeader("Call-ID")); - try { - sipServletRequest.send(); - } catch (IOException e) { - logger.error(e); - } - } +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite; + +import java.io.IOException; + +import javax.annotation.Resource; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.sip.SipApplicationSession; +import javax.servlet.sip.SipFactory; +import javax.servlet.sip.SipServlet; +import javax.servlet.sip.SipServletContextEvent; +import javax.servlet.sip.SipServletListener; +import javax.servlet.sip.SipServletRequest; +import javax.servlet.sip.SipServletResponse; +import javax.servlet.sip.SipSessionsUtil; +import javax.servlet.sip.SipURI; +import javax.servlet.sip.URI; + +import org.apache.log4j.Logger; + +public class AppKeySipServlet + extends SipServlet + implements SipServletListener { + private static final long serialVersionUID = 1L; + private static transient Logger logger = Logger.getLogger(AppKeySipServlet.class); + @Resource + SipFactory sipFactory; + @Resource + SipSessionsUtil sipSessionsUtil; + + static ServletContext ctx; + + public AppKeySipServlet() { + } + + @Override + public void init(ServletConfig servletConfig) throws ServletException { + logger.info("the appkey sip servlet has been started"); + super.init(servletConfig); + ctx = servletConfig.getServletContext(); + } + + @Override + protected void doSuccessResponse(SipServletResponse sipServletResponse) + throws ServletException, IOException { + logger.info("Got : " + sipServletResponse.getStatus() + " " + + sipServletResponse.getMethod()); + int status = sipServletResponse.getStatus(); + if (status == SipServletResponse.SC_OK && "INVITE".equalsIgnoreCase(sipServletResponse.getMethod())) { + SipServletRequest ackRequest = sipServletResponse.createAck(); + ackRequest.send(); +// try { +// Thread.sleep(2000); +// } catch (InterruptedException e) { +// logger.error("unexpected exception", e); +// } +// SipServletRequest sipServletRequest = sipServletResponse.getSession().createRequest("BYE"); +// sipServletRequest.send(); + } + + if (status == SipServletResponse.SC_OK && "REGISTER".equalsIgnoreCase(sipServletResponse.getMethod())) { + URI fromURI = sipFactory.createSipURI("BigGuy", "here.com"); + URI toURI = sipFactory.createSipURI("LittleGuy", "there.com"); + SipServletRequest sipServletRequest = + sipFactory.createRequest(sipServletResponse.getApplicationSession(), "INVITE", fromURI, toURI); + SipURI requestURI = sipFactory.createSipURI("LittleGuy", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + sipServletRequest.setRequestURI(requestURI); + String inviteCallId = sipServletRequest.getHeader("Call-ID"); + String registerCallId = (String) sipServletResponse.getApplicationSession().getAttribute("CallId"); + logger.info("REGISTER Call ID " + registerCallId); + logger.info("INVITE Call ID " + inviteCallId); + if(inviteCallId != null && registerCallId != null && !inviteCallId.equalsIgnoreCase(registerCallId)) { + try { + sipServletRequest.send(); + } catch (IOException e) { + logger.error(e); + } + } else { + throw new ServletException("Call Id for different requests within the same application session whose the key is app generated are the same!"); + } + } + } + + @Override + protected void doBye(SipServletRequest req) throws ServletException, + IOException { + req.createResponse(SipServletResponse.SC_OK).send(); + } + + // SipServletListener methods + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipServletListener#servletInitialized(javax.servlet.sip.SipServletContextEvent) + */ + public void servletInitialized(SipServletContextEvent ce) { + String appKeyName = "appkeytest"; + SipApplicationSession sipApplicationSession = null; + if(ce.getServletContext().getInitParameter("createApplicationSessionByKey") != null) { + sipApplicationSession = sipFactory.createApplicationSessionByKey(appKeyName); + } else { + sipApplicationSession = sipSessionsUtil.getApplicationSessionByKey(appKeyName, true); + } + + URI fromURI = sipFactory.createSipURI("BigGuy", "here.com"); + URI toURI = sipFactory.createSipURI("BigGuy", "there.com"); + SipServletRequest sipServletRequest = + sipFactory.createRequest(sipApplicationSession, "REGISTER", fromURI, toURI); + SipURI requestURI = sipFactory.createSipURI("BigGuy", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + sipServletRequest.setRequestURI(requestURI); + //Storing the Call id for future comparison + sipApplicationSession.setAttribute("CallId", sipServletRequest.getHeader("Call-ID")); + try { + sipServletRequest.send(); + } catch (IOException e) { + logger.error(e); + } + } + + public static Integer getTestPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("testPort"); + logger.info("TestPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5059; + } + } + + + public static Integer getServletContainerPort(ServletContext ctx) { + String cPort = ctx.getInitParameter("servletContainerPort"); + logger.info("TestPort at:" + cPort); + if (cPort != null) { + return Integer.valueOf(cPort); + } else { + return 5070; + } + } } \ No newline at end of file diff --git a/sip-servlets-test-suite/applications/b2bua-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/B2BUASipServlet.java b/sip-servlets-test-suite/applications/b2bua-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/B2BUASipServlet.java index 059778cc0e..f2d388004a 100644 --- a/sip-servlets-test-suite/applications/b2bua-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/B2BUASipServlet.java +++ b/sip-servlets-test-suite/applications/b2bua-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/B2BUASipServlet.java @@ -1,190 +1,231 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.servlet.ServletException; -import javax.servlet.sip.B2buaHelper; -import javax.servlet.sip.SipFactory; -import javax.servlet.sip.SipServlet; -import javax.servlet.sip.SipServletRequest; -import javax.servlet.sip.SipServletResponse; -import javax.servlet.sip.SipSession; -import javax.servlet.sip.SipURI; - -import org.apache.log4j.Logger; - -public class B2BUASipServlet extends SipServlet { - private static final long serialVersionUID = 1L; - - private static transient Logger logger = Logger.getLogger(B2BUASipServlet.class); - - @Override - protected void doRegister(SipServletRequest request) throws ServletException, - IOException { - Map> headers=new HashMap>(); - List toHeaderList = new ArrayList(); - toHeaderList.add("sip:aa@sip-servlets.com"); - headers.put("To", toHeaderList); - - B2buaHelper helper = request.getB2buaHelper(); - SipServletRequest forkedRequest = helper.createRequest(request, true, - headers); - - SipFactory sipFactory = (SipFactory) getServletContext().getAttribute( - SIP_FACTORY); - SipURI sipUri = (SipURI) sipFactory.createURI("sip:aa@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5059"); - forkedRequest.setRequestURI(sipUri); - - if (logger.isDebugEnabled()) { - logger.debug("forkedRequest = " + forkedRequest); - } - forkedRequest.getSession().setAttribute("originalRequest", request); - forkedRequest.send(); - } - - @Override - protected void doInvite(SipServletRequest request) throws ServletException, - IOException { - logger.info("Got request:\n" + request); - if(((SipURI)request.getFrom().getURI()).getUser().contains("generateResponses")) { - SipServletResponse ringing = request.createResponse(SipServletResponse.SC_RINGING); - SipServletResponse ok = request.createResponse(SipServletResponse.SC_OK); - ringing.send(); - ok.send(); - } - - Map> headers=new HashMap>(); - List toHeaderList = new ArrayList(); - toHeaderList.add("sip:aa@sip-servlets.com"); - headers.put("To", toHeaderList); - - B2buaHelper helper = request.getB2buaHelper(); - SipServletRequest forkedRequest = helper.createRequest(request, true, - headers); - - SipFactory sipFactory = (SipFactory) getServletContext().getAttribute( - SIP_FACTORY); - SipURI sipUri = (SipURI) sipFactory.createURI("sip:aa@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5059"); - if(request.getTo().toString().contains("cancel-no-response")) { - sipUri = (SipURI) sipFactory.createURI("sip:cancel-no-respo-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":9368"); - } - forkedRequest.setRequestURI(sipUri); - if(request.getTo().toString().contains("cancel-no-response")) { - forkedRequest.send(); - try { - Thread.sleep(4000); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - forkedRequest.createCancel().send(); - return; - } - if (logger.isDebugEnabled()) { - logger.debug("forkedRequest = " + forkedRequest); - } - // Issue 1151 : making sure the contact is present in the B2BUAHelper newly created request - if(forkedRequest.getParameterableHeaders("Contact").hasNext()) { - forkedRequest.getSession().setAttribute("originalRequest", request); - forkedRequest.send(); - } else { - request.createResponse(500, "Contact not present in newly created request").send(); - } - - } - - /** - * {@inheritDoc} - */ - protected void doResponse(SipServletResponse sipServletResponse) - throws ServletException, IOException { - logger.info("Got : " + sipServletResponse.getStatus() + " " - + sipServletResponse.getMethod()); - if (sipServletResponse.getStatus() == SipServletResponse.SC_OK) { - //if this is a response to an INVITE we ack it and forward the OK - if(sipServletResponse.getMethod().equalsIgnoreCase("INVITE")) { - SipServletRequest ackRequest = sipServletResponse.createAck(); - ackRequest.send(); - if(!((SipURI)sipServletResponse.getTo().getURI()).getUser().contains("generateResponses")) { - B2buaHelper helper = sipServletResponse.getRequest().getB2buaHelper(); - //create and sends OK for the first call leg - SipSession originalSession = - helper.getLinkedSession(sipServletResponse.getSession()); - SipServletResponse responseToOriginalRequest = - helper.createResponseToOriginalRequest(originalSession, sipServletResponse.getStatus(), "OK"); - responseToOriginalRequest.send(); - } - } else if (sipServletResponse.getMethod().equalsIgnoreCase("REGISTER")) { - B2buaHelper helper = sipServletResponse.getRequest().getB2buaHelper(); - //create and sends OK for the first call leg - SipSession originalSession = - helper.getLinkedSession(sipServletResponse.getSession()); - SipServletResponse responseToOriginalRequest = - helper.createResponseToOriginalRequest(originalSession, sipServletResponse.getStatus(), "OK"); - responseToOriginalRequest.send(); - } - } else { - super.doResponse(sipServletResponse); - } - } - - /** - * - * {@inheritDoc} - */ - @Override - protected void doBye(SipServletRequest request) throws ServletException, - IOException { - logger.info("Got BYE: " - + request.getMethod()); - SipServletResponse response = request.createResponse(200); - response.send(); - - SipSession session = request.getSession(); - SipSession linkedSession = request.getB2buaHelper().getLinkedSession(session); - SipServletRequest newRequest = linkedSession.createRequest("BYE"); - logger.info(newRequest); - newRequest.send(); - - } - - @Override - protected void doCancel(SipServletRequest request) throws ServletException, - IOException { - logger.info("Got CANCEL: " + request.toString()); - SipSession session = request.getSession(); - B2buaHelper b2buaHelper = request.getB2buaHelper(); - SipSession linkedSession = b2buaHelper.getLinkedSession(session); - SipServletRequest originalRequest = (SipServletRequest)linkedSession.getAttribute("originalRequest"); - SipServletRequest cancelRequest = b2buaHelper.getLinkedSipServletRequest(originalRequest).createCancel(); - logger.info("forkedRequest = " + cancelRequest); - cancelRequest.send(); - } - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; + +import javax.servlet.ServletException; +import javax.servlet.sip.B2buaHelper; +import javax.servlet.sip.SipFactory; +import javax.servlet.sip.SipServlet; +import javax.servlet.sip.SipServletRequest; +import javax.servlet.sip.SipServletResponse; +import javax.servlet.sip.SipSession; +import javax.servlet.sip.SipURI; + +import org.apache.log4j.Logger; + +public class B2BUASipServlet extends SipServlet { + private static final long serialVersionUID = 1L; + + private static transient Logger logger = Logger.getLogger(B2BUASipServlet.class); + + @Override + protected void doRegister(SipServletRequest request) throws ServletException, + IOException { + Map> headers=new HashMap>(); + List toHeaderList = new ArrayList(); + toHeaderList.add("sip:aa@sip-servlets.com"); + headers.put("To", toHeaderList); + + B2buaHelper helper = request.getB2buaHelper(); + SipServletRequest forkedRequest = helper.createRequest(request, true, + headers); + + SipFactory sipFactory = (SipFactory) getServletContext().getAttribute( + SIP_FACTORY); + SipURI sipUri = (SipURI) sipFactory.createURI("sip:aa@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + forkedRequest.setRequestURI(sipUri); + + if (logger.isDebugEnabled()) { + logger.debug("forkedRequest = " + forkedRequest); + } + forkedRequest.getSession().setAttribute("originalRequest", request); + forkedRequest.send(); + } + + @Override + protected void doInvite(SipServletRequest request) throws ServletException, + IOException { + logger.info("Got request:\n" + request); + if(((SipURI)request.getFrom().getURI()).getUser().contains("generateResponses")) { + SipServletResponse ringing = request.createResponse(SipServletResponse.SC_RINGING); + SipServletResponse ok = request.createResponse(SipServletResponse.SC_OK); + ringing.send(); + ok.send(); + } + + Map> headers=new HashMap>(); + List toHeaderList = new ArrayList(); + toHeaderList.add("sip:aa@sip-servlets.com"); + headers.put("To", toHeaderList); + + B2buaHelper helper = request.getB2buaHelper(); + SipServletRequest forkedRequest = helper.createRequest(request, true, + headers); + + SipFactory sipFactory = (SipFactory) getServletContext().getAttribute( + SIP_FACTORY); + SipURI sipUri = (SipURI) sipFactory.createURI("sip:aa@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + if(request.getTo().toString().contains("cancel-no-response")) { + sipUri = (SipURI) sipFactory.createURI("sip:cancel-no-respo-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":9368"); + } + forkedRequest.setRequestURI(sipUri); + if(request.getTo().toString().contains("cancel-no-response")) { + forkedRequest.send(); + try { + Thread.sleep(4000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + forkedRequest.createCancel().send(); + return; + } + if (logger.isDebugEnabled()) { + logger.debug("forkedRequest = " + forkedRequest); + } + // Issue 1151 : making sure the contact is present in the B2BUAHelper newly created request + if(forkedRequest.getParameterableHeaders("Contact").hasNext()) { + forkedRequest.getSession().setAttribute("originalRequest", request); + forkedRequest.send(); + } else { + request.createResponse(500, "Contact not present in newly created request").send(); + } + + } + + /** + * {@inheritDoc} + */ + protected void doResponse(SipServletResponse sipServletResponse) + throws ServletException, IOException { + logger.info("Got : " + sipServletResponse.getStatus() + " " + + sipServletResponse.getMethod()); + if (sipServletResponse.getStatus() == SipServletResponse.SC_OK) { + //if this is a response to an INVITE we ack it and forward the OK + if(sipServletResponse.getMethod().equalsIgnoreCase("INVITE")) { + SipServletRequest ackRequest = sipServletResponse.createAck(); + ackRequest.send(); + if(!((SipURI)sipServletResponse.getTo().getURI()).getUser().contains("generateResponses")) { + B2buaHelper helper = sipServletResponse.getRequest().getB2buaHelper(); + //create and sends OK for the first call leg + SipSession originalSession = + helper.getLinkedSession(sipServletResponse.getSession()); + SipServletResponse responseToOriginalRequest = + helper.createResponseToOriginalRequest(originalSession, sipServletResponse.getStatus(), "OK"); + responseToOriginalRequest.send(); + } + } else if (sipServletResponse.getMethod().equalsIgnoreCase("REGISTER")) { + B2buaHelper helper = sipServletResponse.getRequest().getB2buaHelper(); + //create and sends OK for the first call leg + SipSession originalSession = + helper.getLinkedSession(sipServletResponse.getSession()); + SipServletResponse responseToOriginalRequest = + helper.createResponseToOriginalRequest(originalSession, sipServletResponse.getStatus(), "OK"); + responseToOriginalRequest.send(); + } + } else { + super.doResponse(sipServletResponse); + } + } + + /** + * + * {@inheritDoc} + */ + @Override + protected void doBye(SipServletRequest request) throws ServletException, + IOException { + logger.info("Got BYE: " + + request.getMethod()); + SipServletResponse response = request.createResponse(200); + response.send(); + + SipSession session = request.getSession(); + SipSession linkedSession = request.getB2buaHelper().getLinkedSession(session); + SipServletRequest newRequest = linkedSession.createRequest("BYE"); + logger.info(newRequest); + newRequest.send(); + + } + + @Override + protected void doCancel(SipServletRequest request) throws ServletException, + IOException { + logger.info("Got CANCEL: " + request.toString()); + SipSession session = request.getSession(); + B2buaHelper b2buaHelper = request.getB2buaHelper(); + SipSession linkedSession = b2buaHelper.getLinkedSession(session); + SipServletRequest originalRequest = (SipServletRequest)linkedSession.getAttribute("originalRequest"); + SipServletRequest cancelRequest = b2buaHelper.getLinkedSipServletRequest(originalRequest).createCancel(); + logger.info("forkedRequest = " + cancelRequest); + cancelRequest.send(); + } + + static ServletContext ctx; + + @Override + public void init(ServletConfig servletConfig) throws ServletException { + logger.info("the call forwarding B2BUA sip servlet has been started"); + super.init(servletConfig); + ctx = servletConfig.getServletContext(); + } + + public static Integer getTestPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("testPort"); + logger.info("TestPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5059; + } + } + + public static Integer getSenderPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("senderPort"); + logger.info("SenderPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5080; + } + } + + public static Integer getServletContainerPort(ServletContext ctx) { + String cPort = ctx.getInitParameter("servletContainerPort"); + logger.info("TestPort at:" + cPort); + if (cPort != null) { + return Integer.valueOf(cPort); + } else { + return 5070; + } + } + +} diff --git a/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/b2bua/CallForwardingB2BUASipServlet.java b/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/b2bua/CallForwardingB2BUASipServlet.java index 71747cca29..b005212149 100644 --- a/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/b2bua/CallForwardingB2BUASipServlet.java +++ b/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/b2bua/CallForwardingB2BUASipServlet.java @@ -1,5 +1,5 @@ /* - * TeleStax, Open Source Cloud Communications Copyright 2012. + * TeleStax, Open Source Cloud Communications Copyright 2012. * and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. @@ -33,6 +33,7 @@ import java.util.Set; import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.sip.Address; import javax.servlet.sip.AuthInfo; @@ -61,6 +62,7 @@ import javax.sip.message.Request; import org.apache.log4j.Logger; +import org.mobicents.javax.servlet.sip.SipFactoryExt; import org.mobicents.javax.servlet.sip.SipSessionExt; import org.mobicents.servlet.sip.message.B2buaHelperImpl; @@ -74,65 +76,69 @@ public class CallForwardingB2BUASipServlet extends SipServlet implements SipErro private static final String ACT_AS_UAS = "actAsUas"; private static transient Logger logger = Logger.getLogger(CallForwardingB2BUASipServlet.class); private static Map forwardingUris = null; - - static { + + public void initUris() { forwardingUris = new HashMap(); - forwardingUris.put("sip:forward-sender@sip-servlets.com", - new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090"}); - forwardingUris.put("sip:forward-sender@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070", - new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090"}); - forwardingUris.put("sip:forward-sender-auth-early-dialog@sip-servlets.com", - new String[]{"sip:forward-receiver-auth-early-dialog@sip-servlets.com", "sip:forward-receiver-auth-early-dialog@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090"}); - forwardingUris.put("sip:forward-sender-forking-pending@sip-servlets.com", - new String[]{"sip:forward-receiver-forking-pending@sip-servlets.com", "sip:forward-receiver-forking-pending@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070"}); - forwardingUris.put("sip:forward-sender-factory-same-callID@sip-servlets.com", - new String[]{"sip:forward-receiver-factory-same-callID@sip-servlets.com", "sip:forward-receiver-factory-same-callID@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090"}); - forwardingUris.put("sip:forward-sender-factory-same-callID-kill-original-session@sip-servlets.com", - new String[]{"sip:forward-receiver-factory-same-callID-kill-original-session@sip-servlets.com", "sip:forward-receiver-factory-same-callI-kill-original-sessionD@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090"}); - forwardingUris.put("sip:forward-sender-408@sip-servlets.com", - new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090"}); - forwardingUris.put("sip:forward-sender-408-new-thread@sip-servlets.com", - new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090"}); - forwardingUris.put("sip:factory-sender@sip-servlets.com", - new String[]{"sip:factory-receiver@sip-servlets.com", "sip:factory-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090"}); - forwardingUris.put("sip:forward-pending-sender@sip-servlets.com", - new String[]{"sip:forward-pending-receiver@sip-servlets.com", "sip:forward-pending-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090"}); - forwardingUris.put("sip:blocked-sender@sip-servlets.com", - new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090"}); - forwardingUris.put("sip:forward-sender@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", - new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090"}); - forwardingUris.put("sip:blocked-sender@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", - new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090"}); - forwardingUris.put("sip:forward-tcp-sender@sip-servlets.com", - new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090;transport=tcp"}); - forwardingUris.put("sip:forward-udp-sender@sip-servlets.com", - new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"}); - forwardingUris.put("sip:forward-udp-sender-tcp-sender@sip-servlets.com", - new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"}); - forwardingUris.put("sip:forward-sender@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090", - new String[]{"sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090", "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090"}); - forwardingUris.put("sip:composition@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090", - new String[]{"sip:forward-composition@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070", "sip:forward-composition@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070"}); - forwardingUris.put("sip:composition@sip-servlets.com", - new String[]{"sip:forward-composition@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070", "sip:forward-composition@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070"}); - forwardingUris.put("sip:sender@sip-servlets.com", - new String[]{"sip:fromB2BUA@sip-servlets.com", "sip:fromB2BUA@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090"}); - forwardingUris.put("sip:samesipsession@sip-servlets.com", - new String[]{"sip:forward-samesipsession@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070", "sip:forward-samesipsession@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070"}); - forwardingUris.put("sip:cancel-samesipsession@sip-servlets.com", - new String[]{"sip:cancel-forward-samesipsession@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070", "sip:cancel-forward-samesipsession@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070"}); - forwardingUris.put("sip:error-samesipsession@sip-servlets.com", - new String[]{"sip:error-forward-samesipsession@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070", "sip:error-forward-samesipsession@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070"}); - forwardingUris.put("sip:forward-myself@sip-servlets.com", - new String[]{"sip:forward-sender@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070", "sip:forward-sender@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070"}); - forwardingUris.put("sip:forward-sender-3rd-leg@sip-servlets.com", - new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090"}); - forwardingUris.put("sip:forward-sender-3rd-leg@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070", - new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090"}); - forwardingUris.put("sip:forward-sender-3rd-leg-factory@sip-servlets.com", - new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090"}); - forwardingUris.put("sip:forward-sender-3rd-leg-factory@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070", - new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090"}); + forwardingUris.put("sip:forward-sender@sip-servlets.com", + new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)}); + forwardingUris.put("sip:forward-sender@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getServletContainerPort(ctx), + new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)}); + forwardingUris.put("sip:forward-sender-auth-early-dialog@sip-servlets.com", + new String[]{"sip:forward-receiver-auth-early-dialog@sip-servlets.com", "sip:forward-receiver-auth-early-dialog@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)}); + forwardingUris.put("sip:forward-sender-forking-pending@sip-servlets.com", + new String[]{"sip:forward-receiver-forking-pending@sip-servlets.com", "sip:forward-receiver-forking-pending@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getServletContainerPort(ctx)}); + forwardingUris.put("sip:forward-sender-factory-same-callID@sip-servlets.com", + new String[]{"sip:forward-receiver-factory-same-callID@sip-servlets.com", "sip:forward-receiver-factory-same-callID@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)}); + forwardingUris.put("sip:forward-sender-factory-same-callID-kill-original-session@sip-servlets.com", + new String[]{"sip:forward-receiver-factory-same-callID-kill-original-session@sip-servlets.com", "sip:forward-receiver-factory-same-callI-kill-original-sessionD@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)}); + forwardingUris.put("sip:forward-sender-408@sip-servlets.com", + new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)}); + forwardingUris.put("sip:forward-sender-408-new-thread@sip-servlets.com", + new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)}); + forwardingUris.put("sip:factory-sender@sip-servlets.com", + new String[]{"sip:factory-receiver@sip-servlets.com", "sip:factory-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)}); + forwardingUris.put("sip:forward-pending-sender@sip-servlets.com", + new String[]{"sip:forward-pending-receiver@sip-servlets.com", "sip:forward-pending-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)}); + forwardingUris.put("sip:forward-pending-changeFromTo-sender@sip-servlets.com", + new String[]{"sip:forward-pending-changeFromTo-receiver@sip-servlets.com", "sip:forward-pending-changeFromTo-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)}); + forwardingUris.put("sip:blocked-sender@sip-servlets.com", + new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)}); + forwardingUris.put("sip:forward-sender@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", + new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)}); + forwardingUris.put("sip:blocked-sender@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", + new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)}); + forwardingUris.put("sip:forward-tcp-sender@sip-servlets.com", + new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx) + ";transport=tcp"}); + forwardingUris.put("sip:forward-tcp-sender-factory@sip-servlets.com", + new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx) + ";transport=tcp"}); + forwardingUris.put("sip:forward-udp-sender@sip-servlets.com", + new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getSenderPort(ctx)}); + forwardingUris.put("sip:forward-udp-sender-tcp-sender@sip-servlets.com", + new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getSenderPort(ctx)}); + forwardingUris.put("sip:forward-sender@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx), + new String[]{"sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx), "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)}); + forwardingUris.put("sip:composition@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx), + new String[]{"sip:forward-composition@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getServletContainerPort(ctx), "sip:forward-composition@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getServletContainerPort(ctx)}); + forwardingUris.put("sip:composition@sip-servlets.com", + new String[]{"sip:forward-composition@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getServletContainerPort(ctx), "sip:forward-composition@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getServletContainerPort(ctx)}); + forwardingUris.put("sip:sender@sip-servlets.com", + new String[]{"sip:fromB2BUA@sip-servlets.com", "sip:fromB2BUA@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)}); + forwardingUris.put("sip:samesipsession@sip-servlets.com", + new String[]{"sip:forward-samesipsession@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getServletContainerPort(ctx), "sip:forward-samesipsession@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getServletContainerPort(ctx)}); + forwardingUris.put("sip:cancel-samesipsession@sip-servlets.com", + new String[]{"sip:cancel-forward-samesipsession@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getServletContainerPort(ctx), "sip:cancel-forward-samesipsession@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getServletContainerPort(ctx)}); + forwardingUris.put("sip:error-samesipsession@sip-servlets.com", + new String[]{"sip:error-forward-samesipsession@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getServletContainerPort(ctx), "sip:error-forward-samesipsession@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getServletContainerPort(ctx)}); + forwardingUris.put("sip:forward-myself@sip-servlets.com", + new String[]{"sip:forward-sender@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getServletContainerPort(ctx), "sip:forward-sender@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getServletContainerPort(ctx)}); + forwardingUris.put("sip:forward-sender-3rd-leg@sip-servlets.com", + new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)}); + forwardingUris.put("sip:forward-sender-3rd-leg@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getServletContainerPort(ctx), + new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)}); + forwardingUris.put("sip:forward-sender-3rd-leg-factory@sip-servlets.com", + new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)}); + forwardingUris.put("sip:forward-sender-3rd-leg-factory@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getServletContainerPort(ctx), + new String[]{"sip:forward-receiver@sip-servlets.com", "sip:forward-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)}); } SipSession incomingSession; @@ -141,13 +147,17 @@ public class CallForwardingB2BUASipServlet extends SipServlet implements SipErro SipURI aliceContact; SipURI incomingInterface; - + + static ServletContext ctx; + @Override public void init(ServletConfig servletConfig) throws ServletException { logger.info("the call forwarding B2BUA sip servlet has been started"); - super.init(servletConfig); + super.init(servletConfig); + ctx = servletConfig.getServletContext(); + initUris(); } - + @Override protected void doRequest(SipServletRequest request) throws ServletException, IOException { @@ -175,7 +185,7 @@ protected void doRequest(SipServletRequest request) throws ServletException, } else { // when any request from bob is received, let's try to send an INVITE to Alice SipSession session = request.getSession(); - // setting the outbound interface to make sure the container pick the correct connector + // setting the outbound interface to make sure the container pick the correct connector SipServletRequest out = session.createRequest("INVITE"); out.setRequestURI(aliceContact); SipSession inviteSession = out.getSession(); @@ -190,10 +200,10 @@ protected void doRequest(SipServletRequest request) throws ServletException, } super.doRequest(request); } - + @Override protected void doAck(SipServletRequest request) throws ServletException, - IOException { + IOException { logger.info("Got : " + request.toString()); SipSession session = request.getSession(); if(request.getTo().toString().contains("b2bua@sip-servlet")) { @@ -215,7 +225,7 @@ protected void doAck(SipServletRequest request) throws ServletException, e.printStackTrace(); } } - if(request.getFrom().getURI().toString().contains("pending") || + if(request.getFrom().getURI().toString().contains("pending") || request.getFrom().getURI().toString().contains("factory")) { B2buaHelper helper = request.getB2buaHelper(); SipSession peerSession = helper.getLinkedSession(request.getSession()); @@ -230,13 +240,13 @@ protected void doAck(SipServletRequest request) throws ServletException, } } invitePendingResponse.createAck().send(); - } + } // SipSession linkedSession = helper.getLinkedSession(session); // SipServletRequest forkedRequest = linkedSession.createRequest("ACK"); // forkedRequest.setContentLength(request.getContentLength()); // forkedRequest.setContent(request.getContent(), request.getContentType()); // logger.info("forkedRequest = " + forkedRequest); -// +// // forkedRequest.send(); } @@ -261,13 +271,13 @@ protected void doInvite(SipServletRequest request) throws ServletException, } if(request.getTo().getURI().toString().contains(TEST_USE_LINKED_REQUEST)) { request.getApplicationSession().setAttribute(TEST_USE_LINKED_REQUEST, Boolean.TRUE); - } + } if(request.getTo().getURI().toString().contains(CHECK_CONTACT)) { Address contactAddress = request.getAddressHeader("Contact"); Set> params = contactAddress.getParameters(); Entry entry = params.iterator().next(); String paramValue = entry.getValue(); - logger.info("checkcontact address " + contactAddress.toString()); + logger.info("checkcontact address " + contactAddress.toString()); logger.info("checkcontact param value " + paramValue); // http://code.google.com/p/mobicents/issues/detail?id=1477 // Address parameters become un-quoted @@ -297,8 +307,8 @@ protected void doInvite(SipServletRequest request) throws ServletException, } return ; } - - + + if(forwardingUri != null && forwardingUri.length > 0) { if(((SipURI)request.getFrom().getURI()).getUser().contains("factory")) { forwardInviteUsingSipFactory(request, forwardingUri); @@ -338,52 +348,69 @@ protected void doInvite(SipServletRequest request) throws ServletException, Map> headers=new HashMap>(); List contactHeaderList = new ArrayList(); if(request.getHeader(ContactHeader.NAME).contains("transport=tcp")) { - contactHeaderList.add("\"callforwardingB2BUA\" ;test"); + contactHeaderList.add("\"callforwardingB2BUA\" ;test"); } else { - contactHeaderList.add("\"callforwardingB2BUA\" ;test"); + contactHeaderList.add("\"callforwardingB2BUA\" ;test"); } headers.put("Contact", contactHeaderList); SipServletRequest forkedRequest = b2buaHelper.createRequest(origSession, request, headers); - forkedRequest.getAddressHeader("From").setDisplayName("display name set correctly"); + forkedRequest.getAddressHeader("From").setDisplayName("display name set correctly"); String method = request.getHeader("Method"); if(method != null) { forkedRequest.getSession().setAttribute("method", method); } + if(request.getFrom().getURI().toString().contains("forward-pending-changeFromTo-sender") || + request.getFrom().getURI().toString().contains("forward-pending-changeFromTo-sender") || + request.getFrom().getURI().toString().contains("fromchanged") || + request.getTo().getURI().toString().contains("tochanged")) { + SipFactory sipFactory = (SipFactory) getServletContext().getAttribute( + SIP_FACTORY); + forkedRequest.getAddressHeader("From").setDisplayName("B2BUA From changed correctly"); + forkedRequest.getAddressHeader("To").setDisplayName("B2BUA To changed correctly"); + forkedRequest.getAddressHeader("From").setURI(sipFactory.createURI("sip:fromchanged@sip-servlets.com")); + forkedRequest.getAddressHeader("To").setURI(sipFactory.createURI("sip:tochanged@sip-servlets.com")); + } forkedRequest.send(); } - } - + } + @Override protected void doRegister(SipServletRequest request) throws ServletException, IOException { String[] forwardingUri = forwardingUris.get(request.getFrom().getURI().toString()); - + if(forwardingUri != null && forwardingUri.length > 0) { forwardRequestUsingB2BUAHelper(request, forwardingUri); } else { logger.info("REGISTER has not been forwarded."); } } - + private void forwardRequestUsingB2BUAHelper(SipServletRequest request, String[] forwardingUri) throws IOException, IllegalArgumentException, TooManyHopsException, ServletParseException { - B2buaHelper helper = request.getB2buaHelper(); - + B2buaHelper helper = request.getB2buaHelper(); + helper.createResponseToOriginalRequest(request.getSession(), SipServletResponse.SC_TRYING, "").send(); - + SipFactory sipFactory = (SipFactory) getServletContext().getAttribute( SIP_FACTORY); - + Map> headers=new HashMap>(); - + List toHeaderList = new ArrayList(); toHeaderList.add(forwardingUri[0]); headers.put("To", toHeaderList); - + + if (request.getHeader("P-SetCallId") != null) { + List callIdHeaderList = new ArrayList(); + callIdHeaderList.add(request.getHeader("P-SetCallId")); + headers.put("Call-ID", callIdHeaderList); + } + List userAgentHeaderList = new ArrayList(); userAgentHeaderList.add("CallForwardingB2BUASipServlet"); headers.put("User-Agent", userAgentHeaderList); - + if(((SipURI)request.getFrom().getURI()).getUser().contains("tcp-sender")) { if(request.getHeader(ContactHeader.NAME).contains("transport=tcp")) { List contactHeaderList = new ArrayList(); @@ -395,18 +422,18 @@ private void forwardRequestUsingB2BUAHelper(SipServletRequest request, headers.put("Contact", contactHeaderList); } } - + List extensionsHeaderList = new ArrayList(); extensionsHeaderList.add("extension-header-value1"); extensionsHeaderList.add("extension-header-value2"); headers.put("extension-header", extensionsHeaderList); - + SipServletRequest forkedRequest = helper.createRequest(request, true, headers); forkedRequest.getAddressHeader("From").setDisplayName("display name set correctly"); SipURI sipUri = (SipURI) sipFactory.createURI(forwardingUri[1]); - forkedRequest.setRequestURI(sipUri); - + forkedRequest.setRequestURI(sipUri); + logger.info("forkedRequest = " + forkedRequest); outgoingSession = forkedRequest.getSession(); forkedRequest.getSession().setAttribute("originalRequest", request); @@ -417,12 +444,12 @@ private void forwardRequestUsingB2BUAHelper(SipServletRequest request, if(request.getFrom().getURI().toString().contains("myself")) { ((SipURI)forkedRequest.getAddressHeader("From").getURI()).setUser("forward-sender"); } - + forkedRequest.send(); } private void forwardInviteUsingSipFactory(SipServletRequest origReq, String[] forwardingUri) throws ServletParseException, UnsupportedEncodingException, IOException { - SipFactory sipFactory = (SipFactory) getServletContext().getAttribute( + SipFactoryExt sipFactory = (SipFactoryExt) getServletContext().getAttribute( SIP_FACTORY); B2buaHelper b2buaHelper = origReq.getB2buaHelper(); URI from = origReq.getTo().getURI(); @@ -432,59 +459,68 @@ private void forwardInviteUsingSipFactory(SipServletRequest origReq, String[] fo if(((SipURI)origReq.getFrom().getURI()).getUser().contains("same-callID")) { if(((SipURI)origReq.getFrom().getURI()).getUser().contains("kill-original-session")) { origReq.createResponse(SipServletResponse.SC_BUSY_HERE).send(); - origReq.getSession().invalidate(); + origReq.getSession().invalidate(); } - newRequest = sipFactory.createRequest(origReq, true); + newRequest = sipFactory.createRequest(origReq, true); newRequest.setRequestURI(to); } else { - newRequest = sipFactory.createRequest(appSession, "INVITE", from, to); + if (origReq.getHeader("P-SetCallId") != null) { + newRequest = sipFactory.createRequestWithCallID(appSession, "INVITE", from, to,origReq.getHeader("P-SetCallId")); + //rewrite req uri because transport param is removed + newRequest.setRequestURI(sipFactory.createURI(forwardingUri[1])); + } else { + newRequest = sipFactory.createRequest(appSession, "INVITE", from, to); + } + } + if (origReq.getHeader("P-SetCallId") != null) { + newRequest.setHeader("Call-ID", origReq.getHeader("P-SetCallId")); } if(origReq.getContent() != null) { newRequest.setContent(origReq.getContent(), origReq.getContentType()); } newRequest.setHeader("Allow", "INVITE, ACK, CANCEL, BYE, REFER, UPDATE, INFO"); if(!((SipURI)origReq.getFrom().getURI()).getUser().contains("kill-original-session")) { - b2buaHelper.linkSipSessions(origReq.getSession(), newRequest.getSession()); //Linking sessions! + b2buaHelper.linkSipSessions(origReq.getSession(), newRequest.getSession()); //Linking sessions! origReq.getSession().setAttribute("originalRequest", origReq); } - logger.info("forkedRequest = " + newRequest); + logger.info("forkedRequest = " + newRequest); if(!((SipURI)origReq.getFrom().getURI()).getUser().contains("kill-original-session")) { newRequest.getSession().setAttribute("originalRequest", origReq); newRequest.getB2buaHelper().linkSipSessions(origReq.getSession(), newRequest.getSession()); //Linking sessions! } outgoingSession = newRequest.getSession(); - + // https://github.com/Mobicents/sip-servlets/issues/56 if(newRequest.getSession().isValid()) newRequest.getSession().setAttribute("b2buaHelper", newRequest.getB2buaHelper()); if(origReq.getSession().isValid()) origReq.getSession().setAttribute("b2buaHelper", origReq.getB2buaHelper()); - + if(origReq.getFrom().getURI().toString().contains("myself")) { ((SipURI)newRequest.getAddressHeader("From").getURI()).setUser("forward-sender"); } - - newRequest.send(); + + newRequest.send(); } @Override protected void doBye(SipServletRequest request) throws ServletException, - IOException { - logger.info("Got BYE: " + request.toString()); - + IOException { + logger.info("Got BYE: " + request.toString()); + if(request.getFrom().toString().contains("408")) { SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); sipServletResponse.send(); return; } - + if(request.getSession().getAttribute(ACT_AS_UAS) == null) { if(getServletContext().getInitParameter("checkOriginalRequestMapSize") != null && ((B2buaHelperImpl)request.getB2buaHelper()).getOriginalRequestMap().size() != 0) { logger.error("originalRequestMap size is wrong " + ((B2buaHelperImpl)request.getB2buaHelper()).getOriginalRequestMap().size()); return; } //we forward the BYE - SipSession session = request.getSession(); + SipSession session = request.getSession(); SipSession linkedSession = request.getB2buaHelper().getLinkedSession(session); logger.info("Incoming side session state : " + request.getSession().getState()); logger.info("outgoing side session state : " + linkedSession.getState()); @@ -493,50 +529,50 @@ protected void doBye(SipServletRequest request) throws ServletException, return; } Map> headers=new HashMap>(); - + List userAgentHeaderList = new ArrayList(); userAgentHeaderList.add("CallForwardingB2BUASipServlet"); headers.put("User-Agent", userAgentHeaderList); - + List contactHeaderList = new ArrayList(); - contactHeaderList.add("\"callforwardingB2BUA\" "); + contactHeaderList.add("\"callforwardingB2BUA\" "); headers.put("Contact", contactHeaderList); - + List extensionsHeaderList = new ArrayList(); extensionsHeaderList.add("extension-header-value1"); extensionsHeaderList.add("extension-header-value2"); headers.put("extension-header", extensionsHeaderList); - + SipServletRequest forkedRequest = request.getB2buaHelper().createRequest(linkedSession, request, headers); -// SipServletRequest forkedRequest = linkedSession.createRequest("BYE"); - logger.info("forkedRequest = " + forkedRequest); +// SipServletRequest forkedRequest = linkedSession.createRequest("BYE"); + logger.info("forkedRequest = " + forkedRequest); forkedRequest.send(); - } + } //we send the OK to the first call leg after as sending the response may trigger session invalidation SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); sipServletResponse.send(); - } - + } + @Override protected void doCancel(SipServletRequest request) throws ServletException, IOException { logger.info("Got CANCEL: " + request.toString()); - if(!((SipURI)request.getTo().getURI()).getUser().equals("cancel-forward-samesipsession")) { + if(!((SipURI)request.getTo().getURI()).getUser().equals("cancel-forward-samesipsession")) { SipSession session = request.getSession(); B2buaHelper b2buaHelper = request.getB2buaHelper(); SipSession linkedSession = b2buaHelper.getLinkedSession(session); // SipServletRequest originalRequest = (SipServletRequest)linkedSession.getAttribute("originalRequest"); // if(originalRequest != null) { -// SipServletRequest cancelRequest = b2buaHelper.getLinkedSipServletRequest(originalRequest).createCancel(); +// SipServletRequest cancelRequest = b2buaHelper.getLinkedSipServletRequest(originalRequest).createCancel(); SipServletRequest cancelRequest = b2buaHelper.createCancel(linkedSession); - logger.info("forkedRequest = " + cancelRequest); + logger.info("forkedRequest = " + cancelRequest); cancelRequest.send(); // } else { // logger.info("no invite to cancel, it hasn't been forwarded"); // } } } - + @Override protected void doUpdate(SipServletRequest request) throws ServletException, IOException { @@ -548,11 +584,11 @@ protected void doUpdate(SipServletRequest request) throws ServletException, SipServletRequest update = helper.createRequest(peerSession, request, null); update.send(); } - + @Override protected void doPrack(SipServletRequest req) throws ServletException, IOException { - + B2buaHelper helper = req.getB2buaHelper(); SipSession peerSession = helper.getLinkedSession(req.getSession()); List pendingMessages = helper.getPendingMessages(peerSession, UAMode.UAC); @@ -571,14 +607,14 @@ protected void doPrack(SipServletRequest req) throws ServletException, SipFactory sipFactory = (SipFactory) getServletContext().getAttribute( SIP_FACTORY); SipURI sipUri = (SipURI) sipFactory.createURI(forwardingUri[1]); - prack.setRequestURI(sipUri); + prack.setRequestURI(sipUri); prack.send(); - + if(logger.isTraceEnabled()) { logger.trace("[Send " + prack.getMethod() + " Request]:" + prack); } } - + @Override protected void doSuccessResponse(SipServletResponse sipServletResponse) throws ServletException, IOException { @@ -591,25 +627,25 @@ protected void doSuccessResponse(SipServletResponse sipServletResponse) ackRequest.send(); return; } - + String cSeqValue = sipServletResponse.getHeader("CSeq"); - B2buaHelper b2buaHelper = sipServletResponse.getRequest().getB2buaHelper(); + B2buaHelper b2buaHelper = sipServletResponse.getRequest().getB2buaHelper(); if (cSeqValue.indexOf("INVITE") != -1 && (sipServletResponse.getFrom().getURI().toString().contains("auth-early-dialog") || sipServletResponse.getFrom().getURI().toString().contains("auth-early-dialog"))) { - SipServletRequest clientRequest = b2buaHelper.createRequest(sipServletResponse.getRequest(), - true, null); + SipServletRequest clientRequest = b2buaHelper.createRequest(sipServletResponse.getRequest(), + true, null); } - - SipSession originalSession = + + SipSession originalSession = sipServletResponse.getRequest().getB2buaHelper().getLinkedSession(sipServletResponse.getSession()); - + if(((SipURI)sipServletResponse.getFrom().getURI()).getUser().contains("same-callID-kill-original-session")) { sipServletResponse.getSession().setAttribute(ACT_AS_UAS, true); SipServletRequest ackRequest = sipServletResponse.createAck(); logger.info("Sending " + ackRequest); ackRequest.send(); } - + if(sipServletResponse.getApplicationSession().getAttribute(TEST_USE_LINKED_REQUEST) != null) { if(getServletContext().getInitParameter("checkOriginalRequestMapSize") != null && ((B2buaHelperImpl)b2buaHelper).getOriginalRequestMap().size() != 2 && cSeqValue.indexOf("INVITE") != -1) { logger.error("originalRequestMap size is wrong " + ((B2buaHelperImpl)b2buaHelper).getOriginalRequestMap().size()); @@ -622,7 +658,7 @@ protected void doSuccessResponse(SipServletResponse sipServletResponse) if (logger.isDebugEnabled()) { logger.debug("testing pending messages so not sending ACK"); } - } + } if(sendAck && cSeqValue.indexOf("INVITE") != -1) { // we send the ACK directly only in non PRACK scenario SipServletRequest ackRequest = sipServletResponse.createAck(); @@ -634,14 +670,14 @@ protected void doSuccessResponse(SipServletResponse sipServletResponse) SipServletResponse other = otherReq.createResponse(sipServletResponse.getStatus(), sipServletResponse.getReasonPhrase()); other.send(); } else { - - if ("PRACK".equals(sipServletResponse.getMethod()) || "UPDATE".equals(sipServletResponse.getMethod())) { + + if ("PRACK".equals(sipServletResponse.getMethod()) || "UPDATE".equals(sipServletResponse.getMethod())) { List pendingMessages = sipServletResponse.getRequest().getB2buaHelper().getPendingMessages(originalSession, UAMode.UAS); - SipServletRequest prackPendingMessage =null; + SipServletRequest prackPendingMessage =null; logger.info("pending messages : "); for(SipServletMessage pendingMessage : pendingMessages) { logger.info("\t pending message : " + pendingMessage); - if(((SipServletRequest) pendingMessage).getMethod().equals("PRACK") || + if(((SipServletRequest) pendingMessage).getMethod().equals("PRACK") || ((SipServletRequest) pendingMessage).getMethod().equals("UPDATE")) { prackPendingMessage = (SipServletRequest) pendingMessage; break; @@ -649,10 +685,10 @@ protected void doSuccessResponse(SipServletResponse sipServletResponse) } prackPendingMessage.createResponse(sipServletResponse.getStatus()).send(); return; - } - if(originalSession!= null && cSeqValue.indexOf("REGISTER") != -1) { + } + if(originalSession!= null && cSeqValue.indexOf("REGISTER") != -1) { SipSession peerSession = sipServletResponse.getRequest().getB2buaHelper().getLinkedSession(sipServletResponse.getSession()); - try { + try { SipServletResponse responseToOriginalRequest = sipServletResponse.getRequest().getB2buaHelper().createResponseToOriginalRequest(peerSession, sipServletResponse.getStatus(), sipServletResponse.getReasonPhrase()); logger.info("Created response " + responseToOriginalRequest + " to original request " + sipServletResponse.getRequest()); responseToOriginalRequest.send(); @@ -663,9 +699,9 @@ protected void doSuccessResponse(SipServletResponse sipServletResponse) sipServletResponse.getSession().createRequest("BYE").send(); } } - //if this is a response to an INVITE we ack it and forward the OK - if(originalSession!= null && cSeqValue.indexOf("INVITE") != -1) { - //create and sends OK for the first call leg + //if this is a response to an INVITE we ack it and forward the OK + if(originalSession!= null && cSeqValue.indexOf("INVITE") != -1) { + //create and sends OK for the first call leg SipServletRequest originalRequest = (SipServletRequest) sipServletResponse.getSession().getAttribute("originalRequest"); boolean sendAck = true; String fromURI = sipServletResponse.getFrom().getURI().toString(); @@ -676,7 +712,7 @@ protected void doSuccessResponse(SipServletResponse sipServletResponse) if (logger.isDebugEnabled()) { logger.debug("testing pending messages so not sending ACK"); } - } + } if(originalRequest.getHeader("Require") == null) { if(sendAck) { // we send the ACK directly only in non PRACK scenario @@ -686,24 +722,24 @@ protected void doSuccessResponse(SipServletResponse sipServletResponse) } if(!originalRequest.isCommitted() && !fromURI.contains("forking") && !toURI.contains("forking")) { SipServletResponse responseToOriginalRequest = originalRequest.createResponse(sipServletResponse.getStatus()); - logger.info("Sending OK on 1st call leg" + responseToOriginalRequest); + logger.info("Sending OK on 1st call leg" + responseToOriginalRequest); responseToOriginalRequest.setContentLength(sipServletResponse.getContentLength()); //responseToOriginalRequest.setContent(sipServletResponse.getContent(), sipServletResponse.getContentType()); responseToOriginalRequest.send(); } else { - try { + try { SipServletResponse responseToOriginalRequest = sipServletResponse.getRequest().getB2buaHelper().createResponseToOriginalRequest(originalSession, sipServletResponse.getStatus(), sipServletResponse.getReasonPhrase()); logger.info("Forking case Created response " + responseToOriginalRequest + " to original request " + sipServletResponse.getRequest()); responseToOriginalRequest.send(); }catch (IllegalStateException e) { - logger.warn("200 OK already forwarded to the other side from a different leg so acking and bye-ing this session"); + logger.warn("200 OK already forwarded to the other side from a different leg so acking and bye-ing this session", e); sipServletResponse.createAck().send(); sipServletResponse.getSession().createRequest("BYE").send(); } } } else { SipSession peerSession = sipServletResponse.getRequest().getB2buaHelper().getLinkedSession(sipServletResponse.getSession()); - try { + try { logger.info("Creating response to original request " + sipServletResponse.getRequest()); SipServletResponse responseToOriginalRequest = sipServletResponse.getRequest().getB2buaHelper().createResponseToOriginalRequest(peerSession, sipServletResponse.getStatus(), sipServletResponse.getReasonPhrase()); logger.info("Created response " + responseToOriginalRequest + " to original request " + sipServletResponse.getRequest()); @@ -720,35 +756,35 @@ protected void doSuccessResponse(SipServletResponse sipServletResponse) ackRequest.send(); } } - } + } } } - + @Override protected void doErrorResponse(SipServletResponse sipServletResponse) throws ServletException, IOException { logger.info("Got : " + sipServletResponse.getStatus() + " " - + sipServletResponse.getReasonPhrase()); - + + sipServletResponse.getReasonPhrase()); + if(sipServletResponse.getStatus() == 487) { sipServletResponse.getSession().invalidate(); return; } //create and sends the error response for the first call leg - if(sipServletResponse.getStatus() == SipServletResponse.SC_UNAUTHORIZED || + if(sipServletResponse.getStatus() == SipServletResponse.SC_UNAUTHORIZED || sipServletResponse.getStatus() == SipServletResponse.SC_PROXY_AUTHENTICATION_REQUIRED) { - + // Avoid re-sending if the auth repeatedly fails. if(!"true".equals(getServletContext().getAttribute("FirstResponseRecieved"))) { getServletContext().setAttribute("FirstResponseRecieved", "true"); SipFactory sipFactory = (SipFactory) getServletContext().getAttribute( SIP_FACTORY); - AuthInfo authInfo = sipFactory.createAuthInfo(); + AuthInfo authInfo = sipFactory.createAuthInfo(); authInfo.addAuthInfo(sipServletResponse.getStatus(), "sip-servlets-realm", "user", "pass"); SipServletRequest req2 = sipServletResponse.getRequest(); B2buaHelper helper = req2.getB2buaHelper(); - SipServletRequest req1 = helper.getLinkedSipServletRequest(req2); + SipServletRequest req1 = helper.getLinkedSipServletRequest(req2); SipServletRequest challengeRequest = helper.createRequest(sipServletResponse.getSession(), req2, null); challengeRequest.addAuthHeader(sipServletResponse, authInfo); @@ -757,7 +793,7 @@ protected void doErrorResponse(SipServletResponse sipServletResponse) } } else { if(sipServletResponse.getStatus() == SipServletResponse.SC_REQUEST_TIMEOUT) { - if(sipServletResponse.getFrom().toString().contains("new-thread")) { + if(sipServletResponse.getFrom().toString().contains("new-thread")) { ((TimerService)getServletContext().getAttribute(TIMER_SERVICE)).createTimer(sipServletResponse.getApplicationSession(), 35000, false, (Serializable)sipServletResponse.getSession()); } else { sendSubsequentRequestTo408(sipServletResponse.getSession(), "BYE"); @@ -769,10 +805,10 @@ protected void doErrorResponse(SipServletResponse sipServletResponse) SipServletResponse responseToOriginalRequest = originalRequest.createResponse(sipServletResponse.getStatus(), sipServletResponse.getReasonPhrase()); logger.info("Sending on the first call leg " + responseToOriginalRequest.toString()); responseToOriginalRequest.send(); - } + } } } - + @Override protected void doProvisionalResponse(SipServletResponse sipServletResponse) throws ServletException, IOException { @@ -783,13 +819,13 @@ protected void doProvisionalResponse(SipServletResponse sipServletResponse) SipServletRequest originalRequest = (SipServletRequest) sipServletResponse.getSession().getAttribute("originalRequest"); String fromURI = sipServletResponse.getFrom().getURI().toString(); String toURI = sipServletResponse.getTo().getURI().toString(); - + if(sipServletResponse.getStatus() == 183) { logger.info("Sending back cancel on original request"); sipServletResponse.getRequest().createCancel().send(); return; } - + if(!originalRequest.isCommitted() && !fromURI.contains("forking") && !toURI.contains("forking")) { SipServletResponse responseToOriginalRequest = originalRequest.createResponse(sipServletResponse.getStatus()); if(logger.isInfoEnabled()) { @@ -808,10 +844,10 @@ protected void doProvisionalResponse(SipServletResponse sipServletResponse) responseToOriginalRequest.send(); } } else if(!originalRequest.isCommitted()) { - SipSession originalSession = + SipSession originalSession = sipServletResponse.getRequest().getB2buaHelper().getLinkedSession(sipServletResponse.getSession()); checkForkedSession(originalSession, sipServletResponse); - try { + try { SipServletResponse responseToOriginalRequest = sipServletResponse.getRequest().getB2buaHelper().createResponseToOriginalRequest(originalSession, sipServletResponse.getStatus(), sipServletResponse.getReasonPhrase()); logger.info("Forking case Created response " + responseToOriginalRequest + " to original request " + sipServletResponse.getRequest()); responseToOriginalRequest.send(); @@ -819,14 +855,14 @@ protected void doProvisionalResponse(SipServletResponse sipServletResponse) logger.error("problem while trying to create response to original request ", e); } } - } - + } + // SipErrorListener methods /** * {@inheritDoc} */ public void noAckReceived(SipErrorEvent ee) { - logger.error("noAckReceived."); + logger.error("noAckReceived."); } /** @@ -838,17 +874,17 @@ public void noPrackReceived(SipErrorEvent ee) { public void sessionCreated(SipApplicationSessionEvent ev) { // TODO Auto-generated method stub - + } public void sessionDestroyed(SipApplicationSessionEvent ev) { // TODO Auto-generated method stub - + } public void sessionExpired(SipApplicationSessionEvent ev) { // TODO Auto-generated method stub - + } public void sessionReadyToInvalidate(SipApplicationSessionEvent ev) { @@ -886,7 +922,7 @@ public void sessionReadyToInvalidate(SipApplicationSessionEvent ev) { sendMessage(ev.getApplicationSession(), (SipFactory) getServletContext().getAttribute(SIP_FACTORY), "sipApplicationSessionReadyToBeInvalidated"); } } - + /** * @param sipApplicationSession * @param sipFactory @@ -895,11 +931,11 @@ private void sendMessage(SipApplicationSession sipApplicationSession, SipFactory sipFactory, String content) { try { SipServletRequest sipServletRequest = sipFactory.createRequest( - sipApplicationSession, - "MESSAGE", - "sip:sender@sip-servlets.com", + sipApplicationSession, + "MESSAGE", + "sip:sender@sip-servlets.com", "sip:receiver@sip-servlets.com"); - SipURI sipUri=sipFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); + SipURI sipUri=sipFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getSenderPort(ctx)); sipServletRequest.setRequestURI(sipUri); sipServletRequest.setContentLength(content.length()); sipServletRequest.setContent(content, CONTENT_TYPE); @@ -907,7 +943,7 @@ private void sendMessage(SipApplicationSession sipApplicationSession, } catch (ServletParseException e) { logger.error("Exception occured while parsing the addresses",e); } catch (IOException e) { - logger.error("Exception occured while sending the request",e); + logger.error("Exception occured while sending the request",e); } } @@ -915,10 +951,10 @@ public void timeout(ServletTimer timer) { SipSession sipSession = (SipSession)timer.getInfo(); sendSubsequentRequestTo408(sipSession, (String)sipSession.getAttribute("method")); } - + public void sendSubsequentRequestTo408(SipSession sipSession, String method) { try { - sipSession.createRequest(method).send(); + sipSession.createRequest(method).send(); SipServletRequest originalRequest = (SipServletRequest) sipSession.getAttribute("originalRequest"); originalRequest.createResponse(200).send(); } catch (IOException e) { @@ -932,7 +968,7 @@ public void sendSubsequentRequestTo408(SipSession sipSession, String method) { } } } - + void checkForkedSession(SipSession originalSession, SipServletResponse sipServletResponse) { SipSession responseSession = sipServletResponse.getSession(); okReceived++; @@ -943,7 +979,7 @@ void checkForkedSession(SipSession originalSession, SipServletResponse sipServle logger.info("Outgoing Session " + outgoingSession); // checks for Issue http://code.google.com/p/mobicents/issues/detail?id=2365 // making sure the forked sessions are not equals to the non forked sessions - if(okReceived == 1) { + if(okReceived == 1) { if(!originalSession.equals(incomingSession)) { throw new IllegalStateException("original Session is not equals to the incoming session"); } @@ -961,8 +997,39 @@ void checkForkedSession(SipSession originalSession, SipServletResponse sipServle SipSession originalForkedSession = sipServletResponse.getRequest().getApplicationSession().getSipSession(originalSession.getId()); if(!originalSession.equals(originalForkedSession)) { throw new IllegalStateException("forked original Session retrieved through the application session is not equals to the original session"); - } - } + } + } } - + + + public static Integer getTestPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("testPort"); + logger.info("TestPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5090; + } + } + + public static Integer getSenderPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("senderPort"); + logger.info("SenderPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5080; + } + } + + public static Integer getServletContainerPort(ServletContext ctx) { + String cPort = ctx.getInitParameter("servletContainerPort"); + logger.info("TestPort at:" + cPort); + if (cPort != null) { + return Integer.valueOf(cPort); + } else { + return 5070; + } + } + } diff --git a/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp/WEB-INF/sip.xml b/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp/WEB-INF/sip.xml index 95630ee89e..0f2e049847 100644 --- a/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp/WEB-INF/sip.xml +++ b/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp/WEB-INF/sip.xml @@ -1,29 +1,36 @@ - - - - org.mobicents.servlet.sip.testsuite.CallForwardingB2BUAApplication - Call Forwarding B2BUA Sip Servlet - Call Forwarding B2BUA Sip Servlet - - - - CallForwardingB2BUASipServlet - - - - - CallForwardingB2BUASipServlet - CallForwardingB2BUASipServlet - Call Forwarding B2BUA Sip Servlet - - org.mobicents.servlet.sip.testsuite.b2bua.CallForwardingB2BUASipServlet - - 1 - - - - - org.mobicents.servlet.sip.testsuite.b2bua.CallForwardingB2BUASipServlet - - - + + + + org.mobicents.servlet.sip.testsuite.CallForwardingB2BUAApplication + Call Forwarding B2BUA Sip Servlet + Call Forwarding B2BUA Sip Servlet + + + + CallForwardingB2BUASipServlet + + + + org.restcomm.servlets.sip.REQUEST_TERMINATED_REASON + 487 request terminated reason + + + CallForwardingB2BUASipServlet + CallForwardingB2BUASipServlet + Call Forwarding B2BUA Sip Servlet + + org.mobicents.servlet.sip.testsuite.b2bua.CallForwardingB2BUASipServlet + + 1 + + + org.restcomm.servlets.sip.OVERRIDE_SYSTEM_HEADER_MODIFICATION + Modifiable + + + + + org.mobicents.servlet.sip.testsuite.b2bua.CallForwardingB2BUASipServlet + + + diff --git a/sip-servlets-test-suite/applications/call-forwarding-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/CallForwardingSipServlet.java b/sip-servlets-test-suite/applications/call-forwarding-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/CallForwardingSipServlet.java index 38fd1fab82..b5af05e5c2 100644 --- a/sip-servlets-test-suite/applications/call-forwarding-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/CallForwardingSipServlet.java +++ b/sip-servlets-test-suite/applications/call-forwarding-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/CallForwardingSipServlet.java @@ -1,93 +1,127 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite; - -import java.io.IOException; - -import javax.servlet.Servlet; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.sip.SipErrorEvent; -import javax.servlet.sip.SipErrorListener; -import javax.servlet.sip.SipFactory; -import javax.servlet.sip.SipServlet; -import javax.servlet.sip.SipServletRequest; -import javax.servlet.sip.SipServletResponse; -import javax.servlet.sip.SipURI; - -import org.apache.log4j.Logger; - - -public class CallForwardingSipServlet extends SipServlet implements SipErrorListener { - private static final long serialVersionUID = 1L; - private static transient Logger logger = Logger.getLogger(CallForwardingSipServlet.class); - - - /** Creates a new instance of CallForwardingSipServlet */ - public CallForwardingSipServlet() { - } - - @Override - public void init(ServletConfig servletConfig) throws ServletException { - logger.info("the call forwarding sip servlet has been started"); - super.init(servletConfig); - } - - @Override - protected void doAck(SipServletRequest request) throws ServletException, - IOException { - logger.info("Got ACK: " - + request.getMethod()); - } - - @Override - protected void doInvite(SipServletRequest request) throws ServletException, - IOException { - - logger.info("Got request: " - + request.getMethod()); - if(request.getFrom().getURI().toString().indexOf("sip:forward-sender@sip-servlets.com") != -1) { - SipFactory sipFactory = (SipFactory)getServletContext().getAttribute(SIP_FACTORY); - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_MOVED_TEMPORARILY); - SipURI sipUri= sipFactory.createSipURI("forward-receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090"); - sipServletResponse.addHeader("Contact", sipUri.toString()); - sipServletResponse.send(); - } - } - - // SipErrorListener methods - /** - * {@inheritDoc} - */ - public void noAckReceived(SipErrorEvent ee) { - logger.error("noAckReceived."); - } - - /** - * {@inheritDoc} - */ - public void noPrackReceived(SipErrorEvent ee) { - logger.error("noPrackReceived."); - } - +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite; + +import java.io.IOException; + +import javax.servlet.Servlet; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.sip.SipErrorEvent; +import javax.servlet.sip.SipErrorListener; +import javax.servlet.sip.SipFactory; +import javax.servlet.sip.SipServlet; +import javax.servlet.sip.SipServletRequest; +import javax.servlet.sip.SipServletResponse; +import javax.servlet.sip.SipURI; + +import org.apache.log4j.Logger; + + +public class CallForwardingSipServlet extends SipServlet implements SipErrorListener { + private static final long serialVersionUID = 1L; + private static transient Logger logger = Logger.getLogger(CallForwardingSipServlet.class); + + + /** Creates a new instance of CallForwardingSipServlet */ + public CallForwardingSipServlet() { + } + + static ServletContext ctx; + + @Override + public void init(ServletConfig servletConfig) throws ServletException { + logger.info("the call forwarding sip servlet has been started"); + super.init(servletConfig); + ctx = servletConfig.getServletContext(); + } + + @Override + protected void doAck(SipServletRequest request) throws ServletException, + IOException { + logger.info("Got ACK: " + + request.getMethod()); + } + + @Override + protected void doInvite(SipServletRequest request) throws ServletException, + IOException { + + logger.info("Got request: " + + request.getMethod()); + if(request.getFrom().getURI().toString().indexOf("sip:forward-sender@sip-servlets.com") != -1) { + SipFactory sipFactory = (SipFactory)getServletContext().getAttribute(SIP_FACTORY); + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_MOVED_TEMPORARILY); + SipURI sipUri= sipFactory.createSipURI("forward-receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + sipServletResponse.addHeader("Contact", sipUri.toString()); + sipServletResponse.send(); + } + } + + // SipErrorListener methods + /** + * {@inheritDoc} + */ + public void noAckReceived(SipErrorEvent ee) { + logger.error("noAckReceived."); + } + + /** + * {@inheritDoc} + */ + public void noPrackReceived(SipErrorEvent ee) { + logger.error("noPrackReceived."); + } + + public static Integer getTestPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("testPort"); + logger.info("TestPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5090; + } + } + + public static Integer getSenderPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("senderPort"); + logger.info("SenderPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5080; + } + } + + public static Integer getServletContainerPort(ServletContext ctx) { + String cPort = ctx.getInitParameter("servletContainerPort"); + logger.info("TestPort at:" + cPort); + if (cPort != null) { + return Integer.valueOf(cPort); + } else { + return 5070; + } + } + } \ No newline at end of file diff --git a/sip-servlets-test-suite/applications/click-to-call-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/Click2DialSipServlet.java b/sip-servlets-test-suite/applications/click-to-call-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/Click2DialSipServlet.java index 9ca780ae65..21b20afd74 100644 --- a/sip-servlets-test-suite/applications/click-to-call-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/Click2DialSipServlet.java +++ b/sip-servlets-test-suite/applications/click-to-call-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/Click2DialSipServlet.java @@ -1,324 +1,355 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite; - -import java.io.IOException; -import java.util.Properties; - -import javax.annotation.Resource; -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NamingException; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.http.HttpSession; -import javax.servlet.sip.Address; -import javax.servlet.sip.ServletParseException; -import javax.servlet.sip.SipApplicationSession; -import javax.servlet.sip.SipApplicationSessionEvent; -import javax.servlet.sip.SipApplicationSessionListener; -import javax.servlet.sip.SipFactory; -import javax.servlet.sip.SipServlet; -import javax.servlet.sip.SipServletRequest; -import javax.servlet.sip.SipServletResponse; -import javax.servlet.sip.SipSession; -import javax.servlet.sip.SipURI; -import javax.servlet.sip.SipApplicationSession.Protocol; - -import org.apache.log4j.Logger; - -public class Click2DialSipServlet extends SipServlet implements SipApplicationSessionListener { - private static final long serialVersionUID = 1L; - private static transient Logger logger = Logger.getLogger(Click2DialSipServlet.class); - private static final String SIP_APP_SESSION_DESTROYED = "sipAppSessionDestroyed"; - private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; - @Resource - private SipFactory sipFactory; - - public Click2DialSipServlet() { - } - - @Override - public void init(ServletConfig servletConfig) throws ServletException { - super.init(servletConfig); - logger.info("the click to dial servlet has been started"); - SipFactory contextFactory = (SipFactory) servletConfig.getServletContext().getAttribute(SipServlet.SIP_FACTORY); - if(contextFactory == null) { - throw new IllegalStateException("The Sip Factory should be available in init method"); - } else { - logger.info("Sip Factory ref from Servlet Context : " + contextFactory); - } - try { - // Getting the Sip factory from the JNDI Context - Properties jndiProps = new Properties(); - Context initCtx = new InitialContext(jndiProps); - Context envCtx = (Context) initCtx.lookup("java:comp/env"); - SipFactory jndiSipFactory = (SipFactory) envCtx.lookup("sip/org.mobicents.servlet.sip.testsuite.Click2DialApplication/SipFactory"); - if(jndiSipFactory == null) { - throw new IllegalStateException("The Sip Factory from JNDI should be available in init method"); - } else { - logger.info("Sip Factory ref from JNDI : " + jndiSipFactory); - } - } catch (NamingException e) { - throw new ServletException("Uh oh -- JNDI problem !", e); - } - if(sipFactory == null) { - throw new IllegalStateException("The Sip Factory from Annotations should be available in init method"); - } else { - logger.info("Sip Factory ref from Annotations : " + sipFactory); - } - } - - @Override - protected void doInvite(SipServletRequest req) throws ServletException, - IOException { - if(!req.getFrom().getURI().toString().contains("asyncWork")) { - logger.info("Click2Dial don't handle INVITE. Here's the one we got : " + req.toString()); - } else { - // Expected to receive INVITE for for Async work tests - SipServletResponse response = req.createResponse(SipServletResponse.SC_OK); - response.setContent(req.getApplicationSession().getId(), "text/plain;charset=UTF-8"); - response.send(); - } - } - - @Override - protected void doOptions(SipServletRequest req) throws ServletException, - IOException { - logger.info("Got : " + req.toString()); - if(!req.getFrom().getURI().toString().contains("asyncWork")) { - req.createResponse(SipServletResponse.SC_OK).send(); - } else { - String mode = req.getFrom().getURI().getParameter("mode"); - if(mode.equalsIgnoreCase("SipSession")) { - String content = (String) req.getContent(); - req.getSession().setAttribute("mutable", content); - logger.info("doOptions beforeSleep " + content); - try { - Thread.sleep(5000); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - String mutableAttr = (String) req.getSession().getAttribute("mutable"); - logger.info("doOptions afterSleep " + mutableAttr + " vs " + content); - int response = SipServletResponse.SC_OK; - if(!content.equals(mutableAttr)) - response = SipServletResponse.SC_SERVER_INTERNAL_ERROR; - - req.getSession().setAttribute("mutable", content); - logger.info("doOptions afterSleep set " + content); - - SipServletResponse resp = req.createResponse(response); - resp.send(); - } else{ - String content = (String) req.getContent(); - req.getSession().getApplicationSession().setAttribute("mutable", content); - logger.info("doOptions beforeSleep " + content); - try { - Thread.sleep(5000); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - String mutableAttr = (String) req.getSession().getApplicationSession().getAttribute("mutable"); - logger.info("doOptions afterSleep " + mutableAttr + " vs " + content); - int response = SipServletResponse.SC_OK; - if(!content.equals(mutableAttr)) - response = SipServletResponse.SC_SERVER_INTERNAL_ERROR; - - req.getSession().getApplicationSession().setAttribute("mutable", content); - logger.info("doOptions afterSleep set " + content); - - SipServletResponse resp = req.createResponse(response); - resp.send(); - } - } - } - - @Override - protected void doSuccessResponse(SipServletResponse resp) - throws ServletException, IOException { - logger.info("Got OK"); - - if (resp.getStatus() == SipServletResponse.SC_OK && resp.getMethod().equals("INVITE")) { - if(resp.getFrom().toString().contains("sipAppTest")) { - resp.createAck().send(); - } else { - SipSession session = resp.getSession(); - Boolean inviteSent = (Boolean) session.getAttribute("InviteSent"); - if (inviteSent != null && inviteSent.booleanValue()) { - return; - } - Address secondPartyAddress = (Address) resp.getSession() - .getAttribute("SecondPartyAddress"); - if (secondPartyAddress != null) { - - SipServletRequest invite = sipFactory.createRequest(resp - .getApplicationSession(), "INVITE", session - .getRemoteParty(), secondPartyAddress); - - logger.info("Found second party -- sending INVITE to " - + secondPartyAddress); - - String contentType = resp.getContentType(); - if (contentType != null && contentType.trim().equals("application/sdp")) { - invite.setContent(resp.getContent(), "application/sdp"); - } - - session.setAttribute("LinkedSession", invite.getSession()); - invite.getSession().setAttribute("LinkedSession", session); - - SipServletRequest ack = resp.createAck(); - invite.getSession().setAttribute("FirstPartyAck", ack); - - invite.send(); - - session.setAttribute("InviteSent", Boolean.TRUE); - } else { - String cSeqValue = resp.getHeader("CSeq"); - if(cSeqValue.indexOf("INVITE") != -1) { - logger.info("Got OK from second party -- sending ACK"); - - SipServletRequest secondPartyAck = resp.createAck(); - SipServletRequest firstPartyAck = (SipServletRequest) resp - .getSession().getAttribute("FirstPartyAck"); - - if (resp.getContentType() != null && resp.getContentType().equals("application/sdp")) { - firstPartyAck.setContent(resp.getContent(), - "application/sdp"); - secondPartyAck.setContent(resp.getContent(), - "application/sdp"); - } - - firstPartyAck.send(); - secondPartyAck.send(); - } - } - } - } - if(resp.getStatus() == SipServletResponse.SC_OK && resp.getMethod().equals("MESSAGE") && resp.getApplicationSession().getAttribute("testThread") != null) { - sendMessage(sipFactory.createApplicationSession(), sipFactory, "OK"); - } - } - - @Override - protected void doBye(SipServletRequest request) throws ServletException, - IOException { - logger.info("Got bye"); - SipSession session = request.getSession(); - SipServletResponse ok = request - .createResponse(SipServletResponse.SC_OK); - ok.send(); - if(!request.getTo().toString().contains("sipAppTest")) { - SipSession linkedSession = (SipSession) session - .getAttribute("LinkedSession"); - if (linkedSession != null) { - SipServletRequest bye = linkedSession.createRequest("BYE"); - logger.info("Sending bye to " + linkedSession.getRemoteParty()); - bye.send(); - } - } else { - if(session.isValid() && session.isReadyToInvalidate()) { - String httpSessionId = (String) session.getAttribute("invalidateHttpSession"); - if(httpSessionId != null) { - HttpSession httpSession = (HttpSession) session.getApplicationSession().getSession(httpSessionId, Protocol.HTTP); - httpSession.invalidate(); - } - session.invalidate(); - } - } - } - - - protected void doRegister(SipServletRequest req) - throws ServletException, IOException - { - logger.info("Received register request: " + req.getTo()); - int response = SipServletResponse.SC_OK; - SipServletResponse resp = req.createResponse(response); - resp.send(); - } - - public void sessionCreated(SipApplicationSessionEvent ev) { - // TODO Auto-generated method stub - - } - - public void sessionDestroyed(SipApplicationSessionEvent ev) { - logger.info("sip application session destroyed " + ev.getApplicationSession()); -// SipFactory storedFactory = (SipFactory)ev.getApplicationSession().getAttribute("sipFactory"); - if(sipFactory != null) { - SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); - try { - SipServletRequest sipServletRequest = sipFactory .createRequest( - sipApplicationSession, - "MESSAGE", - "sip:sender@sip-servlets.com", - "sip:receiver@sip-servlets.com"); - SipURI sipUri=sipFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5057"); - sipServletRequest.setRequestURI(sipUri); - sipServletRequest.setContentLength(SIP_APP_SESSION_DESTROYED.length()); - sipServletRequest.setContent(SIP_APP_SESSION_DESTROYED, CONTENT_TYPE); - sipServletRequest.send(); - } catch (ServletParseException e) { - logger.error("Exception occured while parsing the addresses",e); - } catch (IOException e) { - logger.error("Exception occured while sending the request",e); - } - } - } - - public void sessionExpired(SipApplicationSessionEvent ev) { - // TODO Auto-generated method stub - - } - - public void sessionReadyToInvalidate(SipApplicationSessionEvent ev) { - - } - - /** - * @param sipApplicationSession - * @param storedFactory - */ - private static void sendMessage(SipApplicationSession sipApplicationSession, - SipFactory storedFactory, String content) { - try { - SipServletRequest sipServletRequest = storedFactory.createRequest( - sipApplicationSession, - "MESSAGE", - "sip:sender@sip-servlets.com", - "sip:receiver@sip-servlets.com"); - SipURI sipUri=storedFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - sipServletRequest.setRequestURI(sipUri); - sipServletRequest.setContentLength(content.length()); - sipServletRequest.setContent(content, CONTENT_TYPE); - sipServletRequest.send(); - } catch (ServletParseException e) { - logger.error("Exception occured while parsing the addresses",e); - } catch (IOException e) { - logger.error("Exception occured while sending the request",e); - } - } +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite; + +import java.io.IOException; +import java.util.Properties; + +import javax.annotation.Resource; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.http.HttpSession; +import javax.servlet.sip.Address; +import javax.servlet.sip.ServletParseException; +import javax.servlet.sip.SipApplicationSession; +import javax.servlet.sip.SipApplicationSessionEvent; +import javax.servlet.sip.SipApplicationSessionListener; +import javax.servlet.sip.SipFactory; +import javax.servlet.sip.SipServlet; +import javax.servlet.sip.SipServletRequest; +import javax.servlet.sip.SipServletResponse; +import javax.servlet.sip.SipSession; +import javax.servlet.sip.SipURI; +import javax.servlet.sip.SipApplicationSession.Protocol; + +import org.apache.log4j.Logger; + +public class Click2DialSipServlet extends SipServlet implements SipApplicationSessionListener { + private static final long serialVersionUID = 1L; + private static transient Logger logger = Logger.getLogger(Click2DialSipServlet.class); + private static final String SIP_APP_SESSION_DESTROYED = "sipAppSessionDestroyed"; + private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; + @Resource + private SipFactory sipFactory; + private boolean notification = true; + + public Click2DialSipServlet() { + } + + static ServletContext ctx; + + @Override + public void init(ServletConfig servletConfig) throws ServletException { + super.init(servletConfig); + logger.info("the click to dial servlet has been started"); + ctx = servletConfig.getServletContext(); + SipFactory contextFactory = (SipFactory) servletConfig.getServletContext().getAttribute(SipServlet.SIP_FACTORY); + if(contextFactory == null) { + throw new IllegalStateException("The Sip Factory should be available in init method"); + } else { + logger.info("Sip Factory ref from Servlet Context : " + contextFactory); + } + try { + // Getting the Sip factory from the JNDI Context + Properties jndiProps = new Properties(); + Context initCtx = new InitialContext(jndiProps); + Context envCtx = (Context) initCtx.lookup("java:comp/env"); + SipFactory jndiSipFactory = (SipFactory) envCtx.lookup("sip/org.mobicents.servlet.sip.testsuite.Click2DialApplication/SipFactory"); + if(jndiSipFactory == null) { + throw new IllegalStateException("The Sip Factory from JNDI should be available in init method"); + } else { + logger.info("Sip Factory ref from JNDI : " + jndiSipFactory); + } + } catch (NamingException e) { + throw new ServletException("Uh oh -- JNDI problem !", e); + } + if(sipFactory == null) { + throw new IllegalStateException("The Sip Factory from Annotations should be available in init method"); + } else { + logger.info("Sip Factory ref from Annotations : " + sipFactory); + } + } + + @Override + protected void doInvite(SipServletRequest req) throws ServletException, + IOException { + if(!req.getFrom().getURI().toString().contains("asyncWork")) { + logger.info("Click2Dial don't handle INVITE. Here's the one we got : " + req.toString()); + } else { + // Expected to receive INVITE for for Async work tests + SipServletResponse response = req.createResponse(SipServletResponse.SC_OK); + response.setContent(req.getApplicationSession().getId(), "text/plain;charset=UTF-8"); + response.send(); + } + } + + @Override + protected void doOptions(SipServletRequest req) throws ServletException, + IOException { + logger.info("Got : " + req.toString()); + if(!req.getFrom().getURI().toString().contains("asyncWork")) { + req.createResponse(SipServletResponse.SC_OK).send(); + } else { + String mode = req.getFrom().getURI().getParameter("mode"); + if(mode.equalsIgnoreCase("SipSession")) { + String content = (String) req.getContent(); + req.getSession().setAttribute("mutable", content); + logger.info("doOptions beforeSleep " + content); + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + String mutableAttr = (String) req.getSession().getAttribute("mutable"); + logger.info("doOptions afterSleep " + mutableAttr + " vs " + content); + int response = SipServletResponse.SC_OK; + if(!content.equals(mutableAttr)) + response = SipServletResponse.SC_SERVER_INTERNAL_ERROR; + + req.getSession().setAttribute("mutable", content); + logger.info("doOptions afterSleep set " + content); + + SipServletResponse resp = req.createResponse(response); + resp.send(); + } else{ + String content = (String) req.getContent(); + req.getSession().getApplicationSession().setAttribute("mutable", content); + logger.info("doOptions beforeSleep " + content); + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + String mutableAttr = (String) req.getSession().getApplicationSession().getAttribute("mutable"); + logger.info("doOptions afterSleep " + mutableAttr + " vs " + content); + int response = SipServletResponse.SC_OK; + if(!content.equals(mutableAttr)) + response = SipServletResponse.SC_SERVER_INTERNAL_ERROR; + + req.getSession().getApplicationSession().setAttribute("mutable", content); + logger.info("doOptions afterSleep set " + content); + + SipServletResponse resp = req.createResponse(response); + resp.send(); + } + } + } + + @Override + protected void doSuccessResponse(SipServletResponse resp) + throws ServletException, IOException { + logger.info("Got OK"); + + if (resp.getStatus() == SipServletResponse.SC_OK && resp.getMethod().equals("INVITE")) { + if(resp.getFrom().toString().contains("sipAppTest")) { + resp.createAck().send(); + } else { + SipSession session = resp.getSession(); + Boolean inviteSent = (Boolean) session.getAttribute("InviteSent"); + if (inviteSent != null && inviteSent.booleanValue()) { + return; + } + Address secondPartyAddress = (Address) resp.getSession() + .getAttribute("SecondPartyAddress"); + if (secondPartyAddress != null) { + + SipServletRequest invite = sipFactory.createRequest(resp + .getApplicationSession(), "INVITE", session + .getRemoteParty(), secondPartyAddress); + + logger.info("Found second party -- sending INVITE to " + + secondPartyAddress); + + String contentType = resp.getContentType(); + if (contentType != null && contentType.trim().equals("application/sdp")) { + invite.setContent(resp.getContent(), "application/sdp"); + } + + session.setAttribute("LinkedSession", invite.getSession()); + invite.getSession().setAttribute("LinkedSession", session); + + SipServletRequest ack = resp.createAck(); + invite.getSession().setAttribute("FirstPartyAck", ack); + + invite.send(); + + session.setAttribute("InviteSent", Boolean.TRUE); + } else { + String cSeqValue = resp.getHeader("CSeq"); + if(cSeqValue.indexOf("INVITE") != -1) { + logger.info("Got OK from second party -- sending ACK"); + + SipServletRequest secondPartyAck = resp.createAck(); + SipServletRequest firstPartyAck = (SipServletRequest) resp + .getSession().getAttribute("FirstPartyAck"); + + if (resp.getContentType() != null && resp.getContentType().equals("application/sdp")) { + firstPartyAck.setContent(resp.getContent(), + "application/sdp"); + secondPartyAck.setContent(resp.getContent(), + "application/sdp"); + } + + firstPartyAck.send(); + secondPartyAck.send(); + } + } + } + } + if(resp.getStatus() == SipServletResponse.SC_OK && resp.getMethod().equals("MESSAGE") && resp.getApplicationSession().getAttribute("testThread") != null) { + sendMessage(sipFactory.createApplicationSession(), sipFactory, "OK"); + } + } + + @Override + protected void doBye(SipServletRequest request) throws ServletException, + IOException { + logger.info("Got bye"); + SipSession session = request.getSession(); + SipServletResponse ok = request + .createResponse(SipServletResponse.SC_OK); + ok.send(); + if(!request.getTo().toString().contains("sipAppTest")) { + SipSession linkedSession = (SipSession) session + .getAttribute("LinkedSession"); + if (linkedSession != null) { + SipServletRequest bye = linkedSession.createRequest("BYE"); + logger.info("Sending bye to " + linkedSession.getRemoteParty()); + bye.send(); + } + } else { + if(session.isValid() && session.isReadyToInvalidate()) { + String httpSessionId = (String) session.getAttribute("invalidateHttpSession"); + if(httpSessionId != null) { + HttpSession httpSession = (HttpSession) session.getApplicationSession().getSession(httpSessionId, Protocol.HTTP); + httpSession.invalidate(); + } + session.invalidate(); + } + } + } + + + protected void doRegister(SipServletRequest req) + throws ServletException, IOException + { + logger.info("Received register request: " + req.getTo()); + int response = SipServletResponse.SC_OK; + SipServletResponse resp = req.createResponse(response); + resp.send(); + } + + public void sessionCreated(SipApplicationSessionEvent ev) { + // TODO Auto-generated method stub + + } + + public void sessionDestroyed(SipApplicationSessionEvent ev) { + logger.info("sip application session destroyed " + ev.getApplicationSession() + " notification " + notification); +// SipFactory storedFactory = (SipFactory)ev.getApplicationSession().getAttribute("sipFactory"); + if(sipFactory != null && notification) { + SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); + try { + SipServletRequest sipServletRequest = sipFactory .createRequest( + sipApplicationSession, + "MESSAGE", + "sip:sender@sip-servlets.com", + "sip:receiver@sip-servlets.com"); + SipURI sipUri=sipFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + sipServletRequest.setRequestURI(sipUri); + sipServletRequest.setContentLength(SIP_APP_SESSION_DESTROYED.length()); + sipServletRequest.setContent(SIP_APP_SESSION_DESTROYED, CONTENT_TYPE); + sipServletRequest.send(); + } catch (ServletParseException e) { + logger.error("Exception occured while parsing the addresses",e); + } catch (IOException e) { + logger.error("Exception occured while sending the request",e); + } + } + } + + public void sessionExpired(SipApplicationSessionEvent ev) { + logger.info("sip application session about to be destroyed " + ev.getApplicationSession() + " notification " + ev.getApplicationSession().getAttribute("notification")); + if(ev.getApplicationSession().getAttribute("notification") != null) { + notification = false; + } + } + + public void sessionReadyToInvalidate(SipApplicationSessionEvent ev) { + logger.info("sip application session about to be destroyed " + ev.getApplicationSession() + " notification " + ev.getApplicationSession().getAttribute("notification")); + if(ev.getApplicationSession().getAttribute("notification") != null) { + notification = false; + } + } + + /** + * @param sipApplicationSession + * @param storedFactory + */ + private static void sendMessage(SipApplicationSession sipApplicationSession, + SipFactory storedFactory, String content) { + try { + SipServletRequest sipServletRequest = storedFactory.createRequest( + sipApplicationSession, + "MESSAGE", + "sip:sender@sip-servlets.com", + "sip:receiver@sip-servlets.com"); + SipURI sipUri=storedFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + sipServletRequest.setRequestURI(sipUri); + sipServletRequest.setContentLength(content.length()); + sipServletRequest.setContent(content, CONTENT_TYPE); + sipServletRequest.send(); + } catch (ServletParseException e) { + logger.error("Exception occured while parsing the addresses",e); + } catch (IOException e) { + logger.error("Exception occured while sending the request",e); + } + } + + public static Integer getTestPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("testPort"); + logger.info("TestPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5080; + } + } + + public static Integer getServletContainerPort(ServletContext ctx) { + String cPort = ctx.getInitParameter("servletContainerPort"); + logger.info("TestPort at:" + cPort); + if (cPort != null) { + return Integer.valueOf(cPort); + } else { + return 5070; + } + } + } \ No newline at end of file diff --git a/sip-servlets-test-suite/applications/click-to-call-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/SimpleWebServlet.java b/sip-servlets-test-suite/applications/click-to-call-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/SimpleWebServlet.java index 60205f9eb8..d16c2f5bbd 100644 --- a/sip-servlets-test-suite/applications/click-to-call-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/SimpleWebServlet.java +++ b/sip-servlets-test-suite/applications/click-to-call-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/SimpleWebServlet.java @@ -1,263 +1,290 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite; - -import gov.nist.core.ServerLogger; -import gov.nist.javax.sip.message.SIPMessage; -import gov.nist.javax.sip.stack.RawMessageChannel; - -import java.io.IOException; -import java.io.PrintWriter; -import java.util.Iterator; -import java.util.Properties; -import java.util.concurrent.Executors; -import java.util.concurrent.ThreadPoolExecutor; - -import javax.annotation.Resource; -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NamingException; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.sip.ConvergedHttpSession; -import javax.servlet.sip.ServletParseException; -import javax.servlet.sip.SipApplicationSession; -import javax.servlet.sip.SipFactory; -import javax.servlet.sip.SipServlet; -import javax.servlet.sip.SipServletRequest; -import javax.servlet.sip.SipSession; -import javax.servlet.sip.SipSessionsUtil; -import javax.servlet.sip.SipURI; -import javax.servlet.sip.URI; -import javax.servlet.sip.SipApplicationSession.Protocol; - -import org.apache.log4j.Logger; -import org.mobicents.javax.servlet.sip.SipApplicationSessionAsynchronousWork; -import org.mobicents.javax.servlet.sip.SipApplicationSessionExt; -import org.mobicents.javax.servlet.sip.SipSessionAsynchronousWork; -import org.mobicents.javax.servlet.sip.SipSessionExt; -import org.mobicents.javax.servlet.sip.SipSessionsUtilExt; - -public class SimpleWebServlet extends HttpServlet { - private static final long serialVersionUID = 1L; - private static transient Logger logger = Logger.getLogger(SimpleWebServlet.class); - private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; - - @Resource - private SipFactory sipFactory; - @Resource - private SipSessionsUtil sipSessionsUtil; - - @Override - public void init(ServletConfig config) throws ServletException { - super.init(config); - logger.info("the SimpleWebServlet has been started"); - try { - SipFactory contextFactory = (SipFactory) config.getServletContext().getAttribute(SipServlet.SIP_FACTORY); - if(contextFactory == null) { - throw new IllegalStateException("The Sip Factory should be available in init method"); - } else { - logger.info("Sip Factory ref from Servlet Context : " + contextFactory); - } - // Getting the Sip factory from the JNDI Context - Properties jndiProps = new Properties(); - Context initCtx = new InitialContext(jndiProps); - Context envCtx = (Context) initCtx.lookup("java:comp/env"); - SipFactory jndiSipFactory = (SipFactory) envCtx.lookup("sip/org.mobicents.servlet.sip.testsuite.Click2DialApplication/SipFactory"); - if(jndiSipFactory == null) { - throw new IllegalStateException("The Sip Factory from JNDI should be available in init method"); - } else { - logger.info("Sip Factory ref from JNDI : " + jndiSipFactory); - } - } catch (NamingException e) { - throw new ServletException("Uh oh -- JNDI problem !", e); - } - if(sipFactory == null) { - throw new IllegalStateException("The Sip Factory from Annotations should be available in init method"); - } else { - logger.info("Sip Factory ref from Annotations : " + sipFactory); - } - } - /** - * Handle the HTTP GET method by building a simple web page. - */ - public void doGet (HttpServletRequest request, - HttpServletResponse response) - throws ServletException, IOException - { - - if(request.getParameter("expirationTime") != null) { - PrintWriter out; - response.setContentType("text/html"); - out = response.getWriter(); - out.println("" + ((javax.servlet.sip.ConvergedHttpSession)request.getSession()).getApplicationSession().getExpirationTime() ); - out.close(); - return; - } - - String toAddr = request.getParameter("to"); - String fromAddr = request.getParameter("from"); - String invalidateHttpSession = request.getParameter("invalidateHttpSession"); - String asyncWorkMode = request.getParameter("asyncWorkMode"); - String asyncWorkSasId = request.getParameter("asyncWorkSasId"); - if(asyncWorkMode != null && asyncWorkSasId != null) { - doAsyncWork(asyncWorkMode, asyncWorkSasId, response); - return; - } - - URI to = sipFactory.createAddress(toAddr).getURI(); - URI from = sipFactory.createAddress(fromAddr).getURI(); - - // Create app session and request - SipApplicationSession appSession = - ((ConvergedHttpSession)request.getSession()).getApplicationSession(); -// SipApplicationSession appSession = -// sipFactory.createApplicationSession(); - if(!appSession.getSessions("HTTP").hasNext()) { - response.sendError(HttpServletResponse.SC_EXPECTATION_FAILED); - return; - } - SipServletRequest req = sipFactory.createRequest(appSession, "INVITE", from, to); - // Set some attribute - req.getSession().setAttribute("SecondPartyAddress", sipFactory.createAddress(fromAddr)); - if(invalidateHttpSession != null) { - req.getSession().setAttribute("invalidateHttpSession", request.getSession().getId()); - } - logger.info("Sending request" + req); - // Send the INVITE request - req.send(); - - // This hsould be at the end otherwise the response will have been committed and - // the session can't be accessed anymore - // Write some web page content - PrintWriter out; - response.setContentType("text/html"); - out = response.getWriter(); - out.println(""); - out.println("Click to call - converger sip servlet"); - out.println(""); - out.println("

Click To Call Converged Demo Sip Servlet

"); - out.println("

Calling from " + fromAddr + " to " + toAddr + "..."); - out.println(""); - out.close(); - } - private void doAsyncWork(String asyncWorkMode, String asyncWorkSasId, HttpServletResponse response) throws IOException { - if(asyncWorkMode.equals("Thread")) { - Runnable processMessageTask = new Runnable() { - public void run() { - SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); - String response = "testThread"; - sipApplicationSession.setAttribute(response, "true"); - sendMessage(sipApplicationSession, sipFactory, response); - } - }; - Executors.newFixedThreadPool(4).execute(processMessageTask); - } else if(asyncWorkMode.equals("SipSession")) { - final SipApplicationSession sipApplicationSession = sipSessionsUtil.getApplicationSessionById(asyncWorkSasId); - Iterator sipSessionIterator = (Iterator) sipApplicationSession.getSessions(Protocol.SIP.toString()); - SipSession sipSession = sipSessionIterator.next(); - ((SipSessionsUtilExt)sipSessionsUtil).scheduleAsynchronousWork(sipSession.getId(), new SipSessionAsynchronousWork() { - private static final long serialVersionUID = 1L; - - public void doAsynchronousWork(SipSession sipSession) { - String content = "web"; - sipSession.setAttribute("mutable", content); - logger.info("doAsynchronousWork beforeSleep " + content); - try { - Thread.sleep(5000); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - String mutableAttr = (String) sipSession.getAttribute("mutable"); - logger.info("doAsyncWork afterSleep " + mutableAttr + " vs " + content); - String response = "OK"; - if(!content.equals(mutableAttr)) - response = "KO"; - - sendMessage(sipApplicationSession, sipFactory, response); - } - }); - - } else { - ((SipSessionsUtilExt)sipSessionsUtil).scheduleAsynchronousWork(asyncWorkSasId, new SipApplicationSessionAsynchronousWork() { - private static final long serialVersionUID = 1L; - - public void doAsynchronousWork(SipApplicationSession sipApplicationSession) { - String content = "web"; - sipApplicationSession.setAttribute("mutable", content); - logger.info("doAsynchronousWork beforeSleep " + content); - try { - Thread.sleep(5000); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - String mutableAttr = (String) sipApplicationSession.getAttribute("mutable"); - logger.info("doAsyncWork afterSleep " + mutableAttr + " vs " + content); - String response = "OK"; - if(!content.equals(mutableAttr)) - response = "KO"; - - sendMessage(sipApplicationSession, sipFactory, response); - } - }); - } - PrintWriter out; - response.setContentType("text/html"); - out = response.getWriter(); - out.println(""); - out.println("Click to call - converger sip servlet"); - out.println(""); - out.println("OK"); - out.println(""); - out.close(); - } - - /** - * @param sipApplicationSession - * @param storedFactory - */ - private static void sendMessage(SipApplicationSession sipApplicationSession, - SipFactory storedFactory, String content) { - try { - SipServletRequest sipServletRequest = storedFactory.createRequest( - sipApplicationSession, - "MESSAGE", - "sip:sender@sip-servlets.com", - "sip:receiver@sip-servlets.com"); - SipURI sipUri=storedFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - sipServletRequest.setRequestURI(sipUri); - sipServletRequest.setContentLength(content.length()); - sipServletRequest.setContent(content, CONTENT_TYPE); - sipServletRequest.send(); - } catch (ServletParseException e) { - logger.error("Exception occured while parsing the addresses",e); - } catch (IOException e) { - logger.error("Exception occured while sending the request",e); - } - } -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Iterator; +import java.util.Properties; +import java.util.concurrent.Executors; + +import javax.annotation.Resource; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.sip.ConvergedHttpSession; +import javax.servlet.sip.ServletParseException; +import javax.servlet.sip.SipApplicationSession; +import javax.servlet.sip.SipApplicationSession.Protocol; +import javax.servlet.sip.SipFactory; +import javax.servlet.sip.SipServlet; +import javax.servlet.sip.SipServletRequest; +import javax.servlet.sip.SipSession; +import javax.servlet.sip.SipSessionsUtil; +import javax.servlet.sip.SipURI; +import javax.servlet.sip.URI; + +import org.apache.log4j.Logger; +import org.mobicents.javax.servlet.sip.SipApplicationSessionAsynchronousWork; +import org.mobicents.javax.servlet.sip.SipApplicationSessionExt; +import org.mobicents.javax.servlet.sip.SipSessionAsynchronousWork; +import org.mobicents.javax.servlet.sip.SipSessionExt; +import org.mobicents.javax.servlet.sip.SipSessionsUtilExt; + +public class SimpleWebServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + private static transient Logger logger = Logger.getLogger(SimpleWebServlet.class); + private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; + + @Resource + private SipFactory sipFactory; + @Resource + private SipSessionsUtil sipSessionsUtil; + + static ServletContext ctx; + + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + logger.info("the SimpleWebServlet has been started"); + ctx = config.getServletContext(); + try { + SipFactory contextFactory = (SipFactory) config.getServletContext().getAttribute(SipServlet.SIP_FACTORY); + if(contextFactory == null) { + throw new IllegalStateException("The Sip Factory should be available in init method"); + } else { + logger.info("Sip Factory ref from Servlet Context : " + contextFactory); + } + // Getting the Sip factory from the JNDI Context + Properties jndiProps = new Properties(); + Context initCtx = new InitialContext(jndiProps); + Context envCtx = (Context) initCtx.lookup("java:comp/env"); + SipFactory jndiSipFactory = (SipFactory) envCtx.lookup("sip/org.mobicents.servlet.sip.testsuite.Click2DialApplication/SipFactory"); + if(jndiSipFactory == null) { + throw new IllegalStateException("The Sip Factory from JNDI should be available in init method"); + } else { + logger.info("Sip Factory ref from JNDI : " + jndiSipFactory); + } + } catch (NamingException e) { + throw new ServletException("Uh oh -- JNDI problem !", e); + } + if(sipFactory == null) { + throw new IllegalStateException("The Sip Factory from Annotations should be available in init method"); + } else { + logger.info("Sip Factory ref from Annotations : " + sipFactory); + } + } + /** + * Handle the HTTP GET method by building a simple web page. + */ + public void doGet (HttpServletRequest request, + HttpServletResponse response) + throws ServletException, IOException + { + + if(request.getParameter("expirationTime") != null) { + PrintWriter out; + response.setContentType("text/html"); + out = response.getWriter(); + out.println("" + ((javax.servlet.sip.ConvergedHttpSession)request.getSession()).getApplicationSession().getExpirationTime() ); + out.close(); + return; + } + + String toAddr = request.getParameter("to"); + String fromAddr = request.getParameter("from"); + String invalidateHttpSession = request.getParameter("invalidateHttpSession"); + String asyncWorkMode = request.getParameter("asyncWorkMode"); + String asyncWorkSasId = request.getParameter("asyncWorkSasId"); + String notification = request.getParameter("notification"); + if(asyncWorkMode != null && asyncWorkSasId != null) { + doAsyncWork(asyncWorkMode, asyncWorkSasId, response); + return; + } + + URI to = sipFactory.createAddress(toAddr).getURI(); + URI from = sipFactory.createAddress(fromAddr).getURI(); + + // Create app session and request + SipApplicationSession appSession = + ((ConvergedHttpSession)request.getSession()).getApplicationSession(); + +// SipApplicationSession appSession = +// sipFactory.createApplicationSession(); + if(!appSession.getSessions("HTTP").hasNext()) { + response.sendError(HttpServletResponse.SC_EXPECTATION_FAILED); + return; + } + SipServletRequest req = sipFactory.createRequest(appSession, "INVITE", from, to); + +// if (notification != null) { +// req.getApplicationSession().setAttribute("notification", notification); +// } +// req.getApplicationSession().setInvalidateWhenReady(true); +// logger.info("sip application session created " + req.getApplicationSession() + " notification " + notification); + // Set some attribute + req.getSession().setAttribute("SecondPartyAddress", sipFactory.createAddress(fromAddr)); + if(invalidateHttpSession != null) { + req.getSession().setAttribute("invalidateHttpSession", request.getSession().getId()); + } + logger.info("Sending request" + req); + // Send the INVITE request + req.send(); + + // This hsould be at the end otherwise the response will have been committed and + // the session can't be accessed anymore + // Write some web page content + PrintWriter out; + response.setContentType("text/html"); + out = response.getWriter(); + out.println(""); + out.println("Click to call - converger sip servlet"); + out.println(""); + out.println("

Click To Call Converged Demo Sip Servlet

"); + out.println("

Calling from " + fromAddr + " to " + toAddr + "..."); + out.println(""); + out.close(); + } + private void doAsyncWork(String asyncWorkMode, String asyncWorkSasId, HttpServletResponse response) throws IOException { + if(asyncWorkMode.equals("Thread")) { + Runnable processMessageTask = new Runnable() { + public void run() { + SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); + String response = "testThread"; + sipApplicationSession.setAttribute(response, "true"); + sendMessage(sipApplicationSession, sipFactory, response); + } + }; + Executors.newFixedThreadPool(4).execute(processMessageTask); + } else if(asyncWorkMode.equals("SipSession")) { + final SipApplicationSession sipApplicationSession = sipSessionsUtil.getApplicationSessionById(asyncWorkSasId); + Iterator sipSessionIterator = (Iterator) sipApplicationSession.getSessions(Protocol.SIP.toString()); + SipSession sipSession = sipSessionIterator.next(); + ((SipSessionsUtilExt)sipSessionsUtil).scheduleAsynchronousWork(sipSession.getId(), new SipSessionAsynchronousWork() { + private static final long serialVersionUID = 1L; + + public void doAsynchronousWork(SipSession sipSession) { + String content = "web"; + sipSession.setAttribute("mutable", content); + logger.info("doAsynchronousWork beforeSleep " + content); + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + String mutableAttr = (String) sipSession.getAttribute("mutable"); + logger.info("doAsyncWork afterSleep " + mutableAttr + " vs " + content); + String response = "OK"; + if(!content.equals(mutableAttr)) + response = "KO"; + + sendMessage(sipApplicationSession, sipFactory, response); + } + }); + + } else { + ((SipSessionsUtilExt)sipSessionsUtil).scheduleAsynchronousWork(asyncWorkSasId, new SipApplicationSessionAsynchronousWork() { + private static final long serialVersionUID = 1L; + + public void doAsynchronousWork(SipApplicationSession sipApplicationSession) { + String content = "web"; + sipApplicationSession.setAttribute("mutable", content); + logger.info("doAsynchronousWork beforeSleep " + content); + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + String mutableAttr = (String) sipApplicationSession.getAttribute("mutable"); + logger.info("doAsyncWork afterSleep " + mutableAttr + " vs " + content); + String response = "OK"; + if(!content.equals(mutableAttr)) + response = "KO"; + + sendMessage(sipApplicationSession, sipFactory, response); + } + }); + } + PrintWriter out; + response.setContentType("text/html"); + out = response.getWriter(); + out.println(""); + out.println("Click to call - converger sip servlet"); + out.println(""); + out.println("OK"); + out.println(""); + out.close(); + } + + /** + * @param sipApplicationSession + * @param storedFactory + */ + private static void sendMessage(SipApplicationSession sipApplicationSession, + SipFactory storedFactory, String content) { + try { + SipServletRequest sipServletRequest = storedFactory.createRequest( + sipApplicationSession, + "MESSAGE", + "sip:sender@sip-servlets.com", + "sip:receiver@sip-servlets.com"); + SipURI sipUri=storedFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + sipServletRequest.setRequestURI(sipUri); + sipServletRequest.setContentLength(content.length()); + sipServletRequest.setContent(content, CONTENT_TYPE); + sipServletRequest.send(); + } catch (ServletParseException e) { + logger.error("Exception occured while parsing the addresses",e); + } catch (IOException e) { + logger.error("Exception occured while sending the request",e); + } + } + + public static Integer getTestPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("testPort"); + logger.info("TestPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5080; + } + } + + public static Integer getServletContainerPort(ServletContext ctx) { + String cPort = ctx.getInitParameter("servletContainerPort"); + logger.info("TestPort at:" + cPort); + if (cPort != null) { + return Integer.valueOf(cPort); + } else { + return 5070; + } + } +} diff --git a/sip-servlets-test-suite/applications/distributable-servlet/src/main/sipapp/WEB-INF/web.xml b/sip-servlets-test-suite/applications/distributable-servlet/src/main/sipapp/WEB-INF/web.xml new file mode 100644 index 0000000000..08ff71e6e3 --- /dev/null +++ b/sip-servlets-test-suite/applications/distributable-servlet/src/main/sipapp/WEB-INF/web.xml @@ -0,0 +1,16 @@ + + + + DistributableServletTestApplication + + + + + DistributableSipServlet + DistributableSipServlet + Distributable SIP servlet + + org.mobicents.servlet.sip.testsuite.DistributableSipServlet + + + \ No newline at end of file diff --git a/sip-servlets-test-suite/applications/join-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/JoinReceiverSipServlet.java b/sip-servlets-test-suite/applications/join-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/JoinReceiverSipServlet.java index 19718f38a0..da0caf1010 100644 --- a/sip-servlets-test-suite/applications/join-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/JoinReceiverSipServlet.java +++ b/sip-servlets-test-suite/applications/join-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/JoinReceiverSipServlet.java @@ -1,122 +1,170 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite; - -import java.io.IOException; - -import javax.annotation.Resource; -import javax.servlet.ServletException; -import javax.servlet.sip.SipApplicationSession; -import javax.servlet.sip.SipFactory; -import javax.servlet.sip.SipServlet; -import javax.servlet.sip.SipServletRequest; -import javax.servlet.sip.SipServletResponse; -import javax.servlet.sip.SipSession; -import javax.servlet.sip.SipSessionsUtil; -import javax.servlet.sip.SipURI; - -import org.apache.log4j.Logger; - - -public class JoinReceiverSipServlet extends SipServlet { - private static final long serialVersionUID = 1L; - private static transient Logger logger = Logger.getLogger(JoinReceiverSipServlet.class); - private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; - - @Resource - private SipFactory sipFactory; - @Resource - private SipSessionsUtil sipSessionsUtil; - - /** Creates a new instance of JoinSenderSipServlet */ - public JoinReceiverSipServlet() { - } - - @Override - protected void doInvite(SipServletRequest request) throws ServletException, - IOException { - logger.info("Got request:\n" + request.toString()); - SipServletResponse sipServletResponse = - request.createResponse(SipServletResponse.SC_OK); - if("receiver".equalsIgnoreCase(((SipURI)request.getFrom().getURI()).getUser()) && request.getHeader("Join") == null) { - sipServletResponse = - request.createResponse(SipServletResponse.SC_DECLINE); - } else if("receiver".equalsIgnoreCase(((SipURI)request.getFrom().getURI()).getUser()) && request.getHeader("Join") != null) { - SipSession sipSession = sipSessionsUtil.getCorrespondingSipSession(request.getSession(), "join"); - if(sipSession == null) { - sipServletResponse = - request.createResponse(SipServletResponse.SC_DECLINE); - } - request.getSession().setAttribute("JoinInviteReceived", Boolean.TRUE); - } - sipServletResponse.send(); - } - - @Override - protected void doAck(SipServletRequest request) throws ServletException, - IOException { - if(request.getSession().getAttribute("JoinInviteReceived") == null) { - //building the Join content - String callId = request.getHeader("Call-ID"); - String fromTag = request.getFrom().getParameter("tag"); - String toTag = request.getTo().getParameter("tag"); - String messageContent = "Join : " + callId + "; from-tag=" + fromTag + "; to-tag=" + toTag; - - SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); - SipURI fromURI = sipFactory.createSipURI("receiver", "sip-servlets.com"); - SipURI requestURI = sipFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090"); - SipServletRequest sipServletRequest = sipFactory.createRequest(sipApplicationSession, "MESSAGE", fromURI, request.getFrom().getURI()); - sipServletRequest.setContentLength(messageContent.length()); - sipServletRequest.setContent(messageContent, CONTENT_TYPE); - sipServletRequest.setRequestURI(requestURI); - sipServletRequest.send(); - } else { - SipSession sipSession = request.getSession(); - sipSession.createRequest("BYE").send(); - SipSession joinedSession = sipSessionsUtil.getCorrespondingSipSession(sipSession, "join"); - joinedSession.createRequest("BYE").send(); - } - } - - @Override - protected void doSuccessResponse(SipServletResponse resp) - throws ServletException, IOException { - logger.info("Got Success Response : " + resp); - if(!"BYE".equalsIgnoreCase(resp.getMethod())) { - resp.createAck().send(); - } - } - - /** - * {@inheritDoc} - */ - protected void doBye(SipServletRequest request) throws ServletException, - IOException { - - if(request.getSession().getAttribute("joinInvite") != null) { - logger.info("Got BYE request: " + request); - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); - sipServletResponse.send(); - } - } -} \ No newline at end of file +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import javax.annotation.Resource; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.sip.SipApplicationSession; +import javax.servlet.sip.SipFactory; +import javax.servlet.sip.SipServlet; +import static javax.servlet.sip.SipServlet.SIP_FACTORY; +import javax.servlet.sip.SipServletRequest; +import javax.servlet.sip.SipServletResponse; +import javax.servlet.sip.SipSession; +import javax.servlet.sip.SipSessionsUtil; +import javax.servlet.sip.SipURI; +import javax.servlet.sip.URI; + +import org.apache.log4j.Logger; +import static org.mobicents.servlet.sip.testsuite.JoinSenderSipServlet.getServletContainerPort; + +public class JoinReceiverSipServlet extends SipServlet { + + private static final long serialVersionUID = 1L; + private static transient Logger logger = Logger.getLogger(JoinReceiverSipServlet.class); + private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; + + @Resource + private SipFactory sipFactory; + @Resource + private SipSessionsUtil sipSessionsUtil; + + /** + * Creates a new instance of JoinSenderSipServlet + */ + public JoinReceiverSipServlet() { + } + + @Override + protected void doInvite(SipServletRequest request) throws ServletException, + IOException { + logger.info("Got request:\n" + request.toString()); + SipServletResponse sipServletResponse + = request.createResponse(SipServletResponse.SC_OK); + if ("receiver".equalsIgnoreCase(((SipURI) request.getFrom().getURI()).getUser()) && request.getHeader("Join") == null) { + sipServletResponse + = request.createResponse(SipServletResponse.SC_DECLINE); + } else if ("receiver".equalsIgnoreCase(((SipURI) request.getFrom().getURI()).getUser()) && request.getHeader("Join") != null) { + SipSession sipSession = sipSessionsUtil.getCorrespondingSipSession(request.getSession(), "join"); + if (sipSession == null) { + sipServletResponse + = request.createResponse(SipServletResponse.SC_DECLINE); + } + request.getSession().setAttribute("JoinInviteReceived", Boolean.TRUE); + } + sipServletResponse.send(); + } + + @Override + protected void doAck(SipServletRequest request) throws ServletException, + IOException { + if (request.getSession().getAttribute("JoinInviteReceived") == null) { + //building the Join content + String callId = request.getHeader("Call-ID"); + String fromTag = request.getFrom().getParameter("tag"); + String toTag = request.getTo().getParameter("tag"); + String messageContent = "Join : " + callId + "; from-tag=" + fromTag + "; to-tag=" + toTag; + + SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); + SipURI fromURI = sipFactory.createSipURI("receiver", "sip-servlets.com"); + SipURI requestURI = sipFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + SipServletRequest sipServletRequest = sipFactory.createRequest(sipApplicationSession, "MESSAGE", fromURI, request.getFrom().getURI()); + sipServletRequest.setContentLength(messageContent.length()); + sipServletRequest.setContent(messageContent, CONTENT_TYPE); + sipServletRequest.setRequestURI(requestURI); + sipServletRequest.send(); + } else { + SipSession sipSession = request.getSession(); + sipSession.createRequest("BYE").send(); + SipSession joinedSession = sipSessionsUtil.getCorrespondingSipSession(sipSession, "join"); + joinedSession.createRequest("BYE").send(); + } + } + + @Override + protected void doSuccessResponse(SipServletResponse resp) + throws ServletException, IOException { + logger.info("Got Success Response : " + resp); + if (!"BYE".equalsIgnoreCase(resp.getMethod())) { + resp.createAck().send(); + } + } + + /** + * {@inheritDoc} + */ + protected void doBye(SipServletRequest request) throws ServletException, + IOException { + + if (request.getSession().getAttribute("joinInvite") != null) { + logger.info("Got BYE request: " + request); + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); + sipServletResponse.send(); + } + } + + static ServletContext ctx; + + @Override + public void init(ServletConfig servletConfig) throws ServletException { + logger.info("the join sip servlet has been started"); + super.init(servletConfig); + ctx = servletConfig.getServletContext(); + } + + public static Integer getTestPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("testPort"); + logger.info("TestPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5090; + } + } + + public static Integer getSenderPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("senderPort"); + logger.info("SenderPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5080; + } + } + + public static Integer getServletContainerPort(ServletContext ctx) { + String cPort = ctx.getInitParameter("servletContainerPort"); + logger.info("TestPort at:" + cPort); + if (cPort != null) { + return Integer.valueOf(cPort); + } else { + return 5070; + } + } +} diff --git a/sip-servlets-test-suite/applications/join-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/JoinSenderSipServlet.java b/sip-servlets-test-suite/applications/join-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/JoinSenderSipServlet.java index 91f936e2a2..29f4fa9c88 100644 --- a/sip-servlets-test-suite/applications/join-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/JoinSenderSipServlet.java +++ b/sip-servlets-test-suite/applications/join-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/JoinSenderSipServlet.java @@ -1,133 +1,168 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.annotation.Resource; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.sip.Proxy; -import javax.servlet.sip.SipApplicationSession; -import javax.servlet.sip.SipFactory; -import javax.servlet.sip.SipServlet; -import javax.servlet.sip.SipServletRequest; -import javax.servlet.sip.SipServletResponse; -import javax.servlet.sip.SipURI; -import javax.servlet.sip.URI; - -import org.apache.log4j.Logger; - - -public class JoinSenderSipServlet extends SipServlet { - private static final long serialVersionUID = 1L; - private static transient Logger logger = Logger.getLogger(JoinSenderSipServlet.class); - Map> registeredUsers = null; - - @Resource - private SipFactory sipFactory; - - /** Creates a new instance of JoinSenderSipServlet */ - public JoinSenderSipServlet() { - } - - @Override - public void init(ServletConfig servletConfig) throws ServletException { - logger.info("the join sip servlet has been started"); - super.init(servletConfig); - SipFactory sipFactory = (SipFactory)getServletContext().getAttribute(SIP_FACTORY); - registeredUsers = new HashMap>(); - List uriList = new ArrayList(); - uriList.add(sipFactory.createURI("sip:join@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090")); - registeredUsers.put("sip:join@sip-servlets.com", uriList); - registeredUsers.put("sip:join@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070;transport=udp", uriList); - } - - /** - * {@inheritDoc} - */ - protected void doMessage(SipServletRequest request) throws ServletException, - IOException { - logger.info("Got request: " - + request.getMethod()); - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); - sipServletResponse.send(); - - SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); - SipURI fromURI = sipFactory.createSipURI("joiner", "sip-servlets.com"); - SipURI requestURI = sipFactory.createSipURI("joiner", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090"); - SipServletRequest sipServletRequest = sipFactory.createRequest(sipApplicationSession, "INVITE", fromURI, request.getFrom().getURI()); - sipServletRequest.addHeader("Join", ((String)request.getContent()).substring("Join : ".length())); - sipServletRequest.setRequestURI(requestURI); - sipServletRequest.getSession().setAttribute("joinInvite", Boolean.TRUE); - sipServletRequest.send(); - } - - @Override - protected void doInvite(SipServletRequest request) throws ServletException, - IOException { - - logger.info("Got request:\n" + request.toString()); - - List contactAddresses = registeredUsers.get(request.getRequestURI().toString()); - if(contactAddresses != null && contactAddresses.size() > 0) { - Proxy proxy = request.getProxy(); - proxy.setProxyTimeout(3); - proxy.setRecordRoute(true); - proxy.setParallel(true); - proxy.setSupervised(true); - proxy.proxyTo(contactAddresses); - } else { - logger.info(request.getRequestURI().toString() + " is not currently registered"); - SipServletResponse sipServletResponse = - request.createResponse(SipServletResponse.SC_MOVED_PERMANENTLY, "Moved Permanently"); - sipServletResponse.send(); - } - } - - @Override - protected void doSuccessResponse(SipServletResponse resp) - throws ServletException, IOException { - if(!"BYE".equalsIgnoreCase(resp.getMethod()) && resp.getSession().getAttribute("joinInvite") != null) { - resp.createAck().send(); -// resp.getSession(false).createRequest("BYE").send(); - } - } - - /** - * {@inheritDoc} - */ - protected void doBye(SipServletRequest request) throws ServletException, - IOException { - - if(request.getSession().getAttribute("joinInvite") != null) { - logger.info("Got BYE request: " + request); - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); - sipServletResponse.send(); - } - } +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.sip.Proxy; +import javax.servlet.sip.SipApplicationSession; +import javax.servlet.sip.SipFactory; +import javax.servlet.sip.SipServlet; +import javax.servlet.sip.SipServletRequest; +import javax.servlet.sip.SipServletResponse; +import javax.servlet.sip.SipURI; +import javax.servlet.sip.URI; + +import org.apache.log4j.Logger; + + +public class JoinSenderSipServlet extends SipServlet { + private static final long serialVersionUID = 1L; + private static transient Logger logger = Logger.getLogger(JoinSenderSipServlet.class); + Map> registeredUsers = null; + + @Resource + private SipFactory sipFactory; + + + /** Creates a new instance of JoinSenderSipServlet */ + public JoinSenderSipServlet() { + } + + static ServletContext ctx; + + @Override + public void init(ServletConfig servletConfig) throws ServletException { + logger.info("the join sip servlet has been started"); + super.init(servletConfig); + ctx = servletConfig.getServletContext(); + SipFactory sipFactory = (SipFactory)getServletContext().getAttribute(SIP_FACTORY); + registeredUsers = new HashMap>(); + List uriList = new ArrayList(); + uriList.add(sipFactory.createURI("sip:join@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx))); + registeredUsers.put("sip:join@sip-servlets.com", uriList); + registeredUsers.put("sip:join@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getServletContainerPort(ctx) +";transport=udp", uriList); + } + + /** + * {@inheritDoc} + */ + protected void doMessage(SipServletRequest request) throws ServletException, + IOException { + logger.info("Got request: " + + request.getMethod()); + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); + sipServletResponse.send(); + + SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); + SipURI fromURI = sipFactory.createSipURI("joiner", "sip-servlets.com"); + SipURI requestURI = sipFactory.createSipURI("joiner", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + SipServletRequest sipServletRequest = sipFactory.createRequest(sipApplicationSession, "INVITE", fromURI, request.getFrom().getURI()); + sipServletRequest.addHeader("Join", ((String)request.getContent()).substring("Join : ".length())); + sipServletRequest.setRequestURI(requestURI); + sipServletRequest.getSession().setAttribute("joinInvite", Boolean.TRUE); + sipServletRequest.send(); + } + + @Override + protected void doInvite(SipServletRequest request) throws ServletException, + IOException { + + logger.info("Got request:\n" + request.toString()); + + List contactAddresses = registeredUsers.get(request.getRequestURI().toString()); + if(contactAddresses != null && contactAddresses.size() > 0) { + Proxy proxy = request.getProxy(); + proxy.setProxyTimeout(3); + proxy.setRecordRoute(true); + proxy.setParallel(true); + proxy.setSupervised(true); + proxy.proxyTo(contactAddresses); + } else { + logger.info(request.getRequestURI().toString() + " is not currently registered"); + SipServletResponse sipServletResponse = + request.createResponse(SipServletResponse.SC_MOVED_PERMANENTLY, "Moved Permanently"); + sipServletResponse.send(); + } + } + + @Override + protected void doSuccessResponse(SipServletResponse resp) + throws ServletException, IOException { + if(!"BYE".equalsIgnoreCase(resp.getMethod()) && resp.getSession().getAttribute("joinInvite") != null) { + resp.createAck().send(); +// resp.getSession(false).createRequest("BYE").send(); + } + } + + /** + * {@inheritDoc} + */ + protected void doBye(SipServletRequest request) throws ServletException, + IOException { + + if(request.getSession().getAttribute("joinInvite") != null) { + logger.info("Got BYE request: " + request); + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); + sipServletResponse.send(); + } + } + + public static Integer getTestPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("testPort"); + logger.info("TestPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5090; + } + } + + public static Integer getSenderPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("senderPort"); + logger.info("SenderPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5080; + } + } + + public static Integer getServletContainerPort(ServletContext ctx) { + String cPort = ctx.getInitParameter("servletContainerPort"); + logger.info("TestPort at:" + cPort); + if (cPort != null) { + return Integer.valueOf(cPort); + } else { + return 5070; + } + } } \ No newline at end of file diff --git a/sip-servlets-test-suite/applications/listeners-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ListenersSipServlet.java b/sip-servlets-test-suite/applications/listeners-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ListenersSipServlet.java index 8e2d001467..a4c41a2934 100644 --- a/sip-servlets-test-suite/applications/listeners-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ListenersSipServlet.java +++ b/sip-servlets-test-suite/applications/listeners-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ListenersSipServlet.java @@ -1,742 +1,766 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.util.Iterator; -import java.util.Properties; - -import javax.annotation.Resource; -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NamingException; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.sip.ServletParseException; -import javax.servlet.sip.ServletTimer; -import javax.servlet.sip.SipApplicationSession; -import javax.servlet.sip.SipApplicationSessionActivationListener; -import javax.servlet.sip.SipApplicationSessionAttributeListener; -import javax.servlet.sip.SipApplicationSessionBindingEvent; -import javax.servlet.sip.SipApplicationSessionBindingListener; -import javax.servlet.sip.SipApplicationSessionEvent; -import javax.servlet.sip.SipApplicationSessionListener; -import javax.servlet.sip.SipErrorEvent; -import javax.servlet.sip.SipErrorListener; -import javax.servlet.sip.SipFactory; -import javax.servlet.sip.SipServlet; -import javax.servlet.sip.SipServletContextEvent; -import javax.servlet.sip.SipServletListener; -import javax.servlet.sip.SipServletRequest; -import javax.servlet.sip.SipServletResponse; -import javax.servlet.sip.SipSession; -import javax.servlet.sip.SipSessionActivationListener; -import javax.servlet.sip.SipSessionAttributeListener; -import javax.servlet.sip.SipSessionBindingEvent; -import javax.servlet.sip.SipSessionBindingListener; -import javax.servlet.sip.SipSessionEvent; -import javax.servlet.sip.SipSessionListener; -import javax.servlet.sip.SipURI; -import javax.servlet.sip.TimerListener; -import javax.servlet.sip.TimerService; - -import org.apache.log4j.Logger; - - -public class ListenersSipServlet - extends SipServlet - implements SipErrorListener, SipServletListener, - SipSessionListener, SipSessionActivationListener, SipSessionBindingListener, - SipApplicationSessionListener, SipApplicationSessionActivationListener, SipApplicationSessionBindingListener, - SipSessionAttributeListener, SipApplicationSessionAttributeListener, TimerListener { - private static final long serialVersionUID = 1L; - private static transient Logger logger = Logger.getLogger(ListenersSipServlet.class); - - private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; - - private static final String OK = "OK"; - private static final String KO = "KO"; - - private static final String ATTRIBUTE = "attribute"; - private static final String VALUE = "value"; - private static final String NEW_VALUE = "new_value"; - - private static final String NO_ACK_RECEIVED = "noAckReceived"; - private static final String NO_PRACK_RECEIVED = "noPrackReceived"; - private static final String SIP_SERVLET_INITIALIZED = "sipServletInitialized"; - private static final String SIP_SESSION_CREATED = "sipSessionCreated"; - private static final String SIP_SESSION_DESTROYED = "sipSessionDestroyed"; - private static final String SIP_APP_SESSION_VALUE_UNBOUND = "sipAppSessionValueUnbound"; - private static final String SIP_APP_SESSION_VALUE_BOUND = "sipAppSessionValueBound"; - private static final String SIP_APP_SESSION_ATTRIBUTE_REPLACED = "sipAppSessionAttributeReplaced"; - private static final String SIP_APP_SESSION_ATTRIBUTE_REMOVED = "sipAppSessionAttributeRemoved"; - private static final String SIP_APP_SESSION_ATTRIBUTE_ADDED = "sipAppSessionAttributeAdded"; - private static final String SIP_APP_SESSION_PASSIVATED = "sipAppSessionPassivated"; - private static final String SIP_APP_SESSION_ACTIVATED = "sipAppSessionActivated"; - private static final String SIP_APP_SESSION_EXPIRED = "sipAppSessionExpired"; - private static final String SIP_APP_SESSION_DESTROYED = "sipAppSessionDestroyed"; - private static final String SIP_APP_SESSION_CREATED = "sipAppSessionCreated"; - private static final String SIP_SESSION_VALUE_UNBOUND = "sipSessionValueUnbound"; - private static final String SIP_SESSION_VALUE_BOUND = "sipSessionValueBound"; - private static final String SIP_SESSION_ATTRIBUTE_REPLACED = "sipSessionAttributeReplaced"; - private static final String SIP_SESSION_ATTRIBUTE_REMOVED = "sipSessionAttributeRemoved"; - private static final String SIP_SESSION_ATTRIBUTE_ADDED = "sipSessionAttributeAdded"; - private static final String SIP_SESSION_PASSIVATED = "sipSessionPassivated"; - private static final String SIP_SESSION_ACTIVATED = "sipSessionActivated"; - - @Resource - private SipFactory sipFactory; - - - /** Creates a new instance of ListenersSipServlet */ - public ListenersSipServlet() { - } - - @Override - public void init(ServletConfig servletConfig) throws ServletException { - super.init(servletConfig); - logger.info("the listeners test sip servlet has been started"); - try { - // Getting the Sip factory from the JNDI Context - Properties jndiProps = new Properties(); - Context initCtx = new InitialContext(jndiProps); - Context envCtx = (Context) initCtx.lookup("java:comp/env"); - sipFactory = (SipFactory) envCtx.lookup("sip/org.mobicents.servlet.sip.testsuite.ListenersApplication/SipFactory"); - logger.info("Sip Factory ref from JNDI : " + sipFactory); - } catch (NamingException e) { - throw new ServletException("Uh oh -- JNDI problem !", e); - } - } - - /** - * {@inheritDoc} - */ - protected void doInvite(SipServletRequest request) throws ServletException, - IOException { - - logger.info("Got request: " - + request.getMethod()); - SipServletResponse ringingResponse = request.createResponse(SipServletResponse.SC_RINGING); - ringingResponse.send(); - SipServletResponse okResponse = request.createResponse(SipServletResponse.SC_OK); - okResponse.send(); - } - - /** - * {@inheritDoc} - */ - protected void doBye(SipServletRequest request) throws ServletException, - IOException { - - logger.info("Got BYE request: " + request); - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); - sipServletResponse.send(); - //create a timer to invalidate the sessions - request.getSession().setAttribute("sipFactory", sipFactory); -// request.getSession().getApplicationSession().setAttribute("sipFactory", sipFactory); - TimerService timerService = (TimerService) getServletContext().getAttribute(TIMER_SERVICE); - timerService.createTimer(request.getApplicationSession(), 5000, false, null); - } - - @Override - protected void doMessage(SipServletRequest request) throws ServletException, - IOException { - - logger.info("Got request: " - + request.getMethod()); - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); - sipServletResponse.send(); - processMessage(request); - } - - /** - * - * @param request - */ - private void processMessage(SipServletRequest request) { - try { - String message = (String)request.getContent(); - if(message != null && message.length() > 0) { - SipServletRequest responseMessage = request.getSession().createRequest("MESSAGE"); - responseMessage.setContentLength(2); - responseMessage.setContent(KO, CONTENT_TYPE); - if (hasListenerBeenCalled(request, message)) { - responseMessage.setContent(OK, CONTENT_TYPE); - } - responseMessage.send(); - } - } catch (UnsupportedEncodingException e) { - logger.error("the encoding is not supported", e); - } catch (IOException e) { - logger.error("an IO exception occured", e); - } - } - - /** - * Check if a particular listener has been called - * @param request the request the message has been received on - * @param message the message containing the listener to check - * @return true if the listener has been called, flase otherwise - */ - private boolean hasListenerBeenCalled(SipServletRequest request, String message) { - if(SIP_SESSION_CREATED.equals(message) - && request.getSession().getAttribute(message) != null) { - return true; - } else if (SIP_SESSION_DESTROYED.equals(message)) { - request.getSession().invalidate(); - if(request.getSession().getAttribute(message) != null) { - return true; - } else { - return false; - } - } if(SIP_APP_SESSION_CREATED.equals(message) - && request.getApplicationSession().getAttribute(message) != null) { - return true; - } else if (SIP_APP_SESSION_DESTROYED.equals(message)) { - request.getApplicationSession().invalidate(); - if(request.getApplicationSession().getAttribute(message) != null) { - return true; - } else { - return false; - } - } else if (SIP_SESSION_ATTRIBUTE_ADDED.equals(message) || - SIP_SESSION_VALUE_BOUND.equals(message)) { - request.getSession().setAttribute(ATTRIBUTE, VALUE); - if(request.getSession().getAttribute(message) != null) { - return true; - } else { - return false; - } - }else if (SIP_SESSION_ATTRIBUTE_REMOVED.equals(message) || - SIP_SESSION_VALUE_UNBOUND.equals(message)) { - request.getSession().setAttribute(ATTRIBUTE, VALUE); - request.getSession().removeAttribute(ATTRIBUTE); - if(request.getSession().getAttribute(message) != null) { - return true; - } else { - return false; - } - } else if (SIP_SESSION_ATTRIBUTE_REPLACED.equals(message)) { - request.getSession().setAttribute(ATTRIBUTE, VALUE); - request.getSession().setAttribute(ATTRIBUTE, NEW_VALUE); - if(request.getSession().getAttribute(message) != null) { - return true; - } else { - return false; - } - } else if (SIP_APP_SESSION_ATTRIBUTE_ADDED.equals(message) || - SIP_APP_SESSION_VALUE_BOUND.equals(message)) { - request.getApplicationSession().setAttribute(ATTRIBUTE, VALUE); - if(request.getApplicationSession().getAttribute(message) != null) { - return true; - } else { - return false; - } - }else if (SIP_APP_SESSION_ATTRIBUTE_REMOVED.equals(message) || - SIP_APP_SESSION_VALUE_UNBOUND.equals(message)) { - request.getApplicationSession().setAttribute(ATTRIBUTE, VALUE); - request.getApplicationSession().removeAttribute(ATTRIBUTE); - if(request.getApplicationSession().getAttribute(message) != null) { - return true; - } else { - return false; - } - } else if (SIP_APP_SESSION_ATTRIBUTE_REPLACED.equals(message)) { - request.getApplicationSession().setAttribute(ATTRIBUTE, VALUE); - request.getApplicationSession().setAttribute(ATTRIBUTE, NEW_VALUE); - if(request.getApplicationSession().getAttribute(message) != null) { - return true; - } else { - return false; - } - } else if (SIP_SERVLET_INITIALIZED.equals(message) - && getServletContext().getAttribute(message) != null) { - return true; - } - return false; - } - - @Override - protected void doRequest(SipServletRequest req) throws ServletException, - IOException { - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - super.doRequest(req); - } - - @Override - protected void doResponse(SipServletResponse resp) throws ServletException, - IOException { - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - super.doResponse(resp); - } - - // Listeners methods - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipErrorListener#noAckReceived(javax.servlet.sip.SipErrorEvent) - */ - public void noAckReceived(SipErrorEvent ee) { - logger.error("noAckReceived."); - ee.getRequest().getSession().setAttribute(NO_ACK_RECEIVED, OK); - } - - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipErrorListener#noPrackReceived(javax.servlet.sip.SipErrorEvent) - */ - public void noPrackReceived(SipErrorEvent ee) { - logger.info("noPrackReceived."); - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - ee.getRequest().getSession().setAttribute(NO_PRACK_RECEIVED, OK); - } - - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipServletListener#servletInitialized(javax.servlet.sip.SipServletContextEvent) - */ - public void servletInitialized(SipServletContextEvent ce) { - logger.info("servlet initialized "); - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - ce.getServletContext().setAttribute(SIP_SERVLET_INITIALIZED, OK); - } - - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipSessionListener#sessionCreated(javax.servlet.sip.SipSessionEvent) - */ - public void sessionCreated(SipSessionEvent se) { - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - logger.info("sip session created " + se.getSession()); - se.getSession().setAttribute(SIP_SESSION_CREATED, OK); - } - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipSessionListener#sessionDestroyed(javax.servlet.sip.SipSessionEvent) - */ - public void sessionDestroyed(SipSessionEvent se) { - logger.info("sip session destroyed " + se.getSession()); - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } -// SipFactory storedFactory = (SipFactory)se.getSession().getApplicationSession().getAttribute("sipFactory"); - SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); - try { - SipServletRequest sipServletRequest = sipFactory.createRequest( - sipApplicationSession, - "MESSAGE", - "sip:sender@sip-servlets.com", - "sip:receiver@sip-servlets.com"); - SipURI sipUri=sipFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - sipServletRequest.setRequestURI(sipUri); - sipServletRequest.setContentLength(SIP_SESSION_DESTROYED.length()); - sipServletRequest.setContent(SIP_SESSION_DESTROYED, CONTENT_TYPE); - sipServletRequest.send(); - } catch (ServletParseException e) { - logger.error("Exception occured while parsing the addresses",e); - } catch (IOException e) { - logger.error("Exception occured while sending the request",e); - } - } - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipSessionActivationListener#sessionDidActivate(javax.servlet.sip.SipSessionEvent) - */ - public void sessionDidActivate(SipSessionEvent se) { - logger.info("sip session activated " + se.getSession()); - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - if(se.getSession().isValid()){ - se.getSession().setAttribute(SIP_SESSION_ACTIVATED, OK); - } - } - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipSessionActivationListener#sessionWillPassivate(javax.servlet.sip.SipSessionEvent) - */ - public void sessionWillPassivate(SipSessionEvent se) { - logger.info("sip session passivated " + se.getSession()); - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - if(se.getSession().isValid()){ - se.getSession().setAttribute(SIP_SESSION_PASSIVATED, OK); - } - - } - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipSessionAttributeListener#attributeAdded(javax.servlet.sip.SipSessionBindingEvent) - */ - public void attributeAdded(SipSessionBindingEvent ev) { - logger.info("sip session attribute added " + ev.getName()); - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - if(!SIP_SESSION_ATTRIBUTE_ADDED.equals(ev.getName()) && - !SIP_SESSION_VALUE_BOUND.equals(ev.getName()) && - !SIP_SESSION_ATTRIBUTE_REPLACED.equals(ev.getName())) { - if(ev.getSession().isValid()){ - ev.getSession().setAttribute(SIP_SESSION_ATTRIBUTE_ADDED, OK); - } - } - } - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipSessionAttributeListener#attributeRemoved(javax.servlet.sip.SipSessionBindingEvent) - */ - public void attributeRemoved(SipSessionBindingEvent ev) { - logger.info("sip session attribute removed " + ev.getName()); - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - if(!SIP_SESSION_ATTRIBUTE_REMOVED.equals(ev.getName()) && - !SIP_SESSION_VALUE_UNBOUND.equals(ev.getName()) && - !SIP_SESSION_ATTRIBUTE_REPLACED.equals(ev.getName())) { - if(ev.getSession().isValid()){ - ev.getSession().setAttribute(SIP_SESSION_ATTRIBUTE_REMOVED, OK); - } - } - } - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipSessionAttributeListener#attributeReplaced(javax.servlet.sip.SipSessionBindingEvent) - */ - public void attributeReplaced(SipSessionBindingEvent ev) { - logger.info("sip session attribute removed " + ev.getName()); - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - if(!SIP_SESSION_ATTRIBUTE_REPLACED.equals(ev.getName())) { - if(ev.getSession().isValid()){ - ev.getSession().setAttribute(SIP_SESSION_ATTRIBUTE_REPLACED, OK); - } - } - } - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipSessionBindingListener#valueBound(javax.servlet.sip.SipSessionBindingEvent) - */ - public void valueBound(SipSessionBindingEvent event) { - logger.info("sip session attribute bound " + event.getName()); - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - if(!SIP_SESSION_VALUE_BOUND.equals(event.getName()) && - !SIP_SESSION_ATTRIBUTE_ADDED.equals(event.getName()) && - !SIP_SESSION_ATTRIBUTE_REPLACED.equals(event.getName())) { - if(event.getSession().isValid()){ - event.getSession().setAttribute(SIP_SESSION_VALUE_BOUND, OK); - } - } - } - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipSessionBindingListener#valueUnbound(javax.servlet.sip.SipSessionBindingEvent) - */ - public void valueUnbound(SipSessionBindingEvent event) { - logger.info("sip session attribute unbound " + event.getName()); - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - if(!SIP_SESSION_VALUE_UNBOUND.equals(event.getName()) && - !SIP_SESSION_ATTRIBUTE_REMOVED.equals(event.getName()) && - !SIP_SESSION_ATTRIBUTE_REPLACED.equals(event.getName())) { - event.getSession().setAttribute(SIP_SESSION_VALUE_UNBOUND, OK); - } - } - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipApplicationSessionListener#sessionCreated(javax.servlet.sip.SipApplicationSessionEvent) - */ - public void sessionCreated(SipApplicationSessionEvent ev) { - logger.info("sip application session created " + ev.getApplicationSession()); - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - if(ev.getApplicationSession().isValid()){ - ev.getApplicationSession().setAttribute(SIP_APP_SESSION_CREATED, OK); - } - } - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipApplicationSessionListener#sessionDestroyed(javax.servlet.sip.SipApplicationSessionEvent) - */ - public void sessionDestroyed(SipApplicationSessionEvent ev) { - logger.info("sip application session destroyed " + ev.getApplicationSession()); - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } -// SipFactory storedFactory = (SipFactory)ev.getApplicationSession().getAttribute("sipFactory"); - if(sipFactory != null) { - SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); - try { - SipServletRequest sipServletRequest = sipFactory .createRequest( - sipApplicationSession, - "MESSAGE", - "sip:sender@sip-servlets.com", - "sip:receiver@sip-servlets.com"); - SipURI sipUri=sipFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - sipServletRequest.setRequestURI(sipUri); - sipServletRequest.setContentLength(SIP_APP_SESSION_DESTROYED.length()); - sipServletRequest.setContent(SIP_APP_SESSION_DESTROYED, CONTENT_TYPE); - sipServletRequest.send(); - } catch (ServletParseException e) { - logger.error("Exception occured while parsing the addresses",e); - } catch (IOException e) { - logger.error("Exception occured while sending the request",e); - } - } - } - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipApplicationSessionListener#sessionExpired(javax.servlet.sip.SipApplicationSessionEvent) - */ - public void sessionExpired(SipApplicationSessionEvent ev) { - logger.info("sip application session expired " + ev.getApplicationSession()); - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - if(ev.getApplicationSession().isValid()){ - ev.getApplicationSession().setAttribute(SIP_APP_SESSION_EXPIRED, OK); - } - } - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipApplicationSessionActivationListener#sessionDidActivate(javax.servlet.sip.SipApplicationSessionEvent) - */ - public void sessionDidActivate(SipApplicationSessionEvent se) { - logger.info("sip application session activated " + se.getApplicationSession()); - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - if(se.getApplicationSession().isValid()){ - se.getApplicationSession().setAttribute(SIP_APP_SESSION_ACTIVATED, OK); - } - } - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipApplicationSessionActivationListener#sessionWillPassivate(javax.servlet.sip.SipApplicationSessionEvent) - */ - public void sessionWillPassivate(SipApplicationSessionEvent se) { - logger.info("sip application session passivated " + se.getApplicationSession()); - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - if(se.getApplicationSession().isValid()){ - se.getApplicationSession().setAttribute(SIP_APP_SESSION_PASSIVATED, OK); - } - } - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipApplicationSessionAttributeListener#attributeAdded(javax.servlet.sip.SipApplicationSessionBindingEvent) - */ - public void attributeAdded(SipApplicationSessionBindingEvent ev) { - logger.info("sip application session attribute added " + ev.getName()); - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - if(!SIP_APP_SESSION_ATTRIBUTE_ADDED.equals(ev.getName()) && - !SIP_APP_SESSION_VALUE_BOUND.equals(ev.getName()) && - !SIP_APP_SESSION_ATTRIBUTE_REPLACED.equals(ev.getName())) { - if(ev.getApplicationSession().isValid()){ - ev.getApplicationSession().setAttribute(SIP_APP_SESSION_ATTRIBUTE_ADDED, OK); - } - } - } - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipApplicationSessionAttributeListener#attributeRemoved(javax.servlet.sip.SipApplicationSessionBindingEvent) - */ - public void attributeRemoved(SipApplicationSessionBindingEvent ev) { - logger.info("sip application session attribute removed " + ev.getName()); - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - if(!SIP_APP_SESSION_ATTRIBUTE_REMOVED.equals(ev.getName()) && - !SIP_APP_SESSION_VALUE_UNBOUND.equals(ev.getName()) && - !SIP_APP_SESSION_ATTRIBUTE_REPLACED.equals(ev.getName())) { - if(ev.getApplicationSession().isValid()){ - ev.getApplicationSession().setAttribute(SIP_APP_SESSION_ATTRIBUTE_REMOVED, OK); - } - } - } - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipApplicationSessionAttributeListener#attributeReplaced(javax.servlet.sip.SipApplicationSessionBindingEvent) - */ - public void attributeReplaced(SipApplicationSessionBindingEvent ev) { - logger.info("sip application session attribute replaced " + ev.getName()); - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - if(!SIP_APP_SESSION_ATTRIBUTE_REMOVED.equals(ev.getName()) && - !SIP_APP_SESSION_VALUE_UNBOUND.equals(ev.getName()) && - !SIP_APP_SESSION_ATTRIBUTE_REPLACED.equals(ev.getName())) { - if(ev.getApplicationSession().isValid()){ - ev.getApplicationSession().setAttribute(SIP_APP_SESSION_ATTRIBUTE_REPLACED, OK); - } - } - } - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipApplicationSessionBindingListener#valueBound(javax.servlet.sip.SipApplicationSessionBindingEvent) - */ - public void valueBound(SipApplicationSessionBindingEvent event) { - logger.info("sip application session value bound " + event.getName()); - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - if(!SIP_APP_SESSION_VALUE_BOUND.equals(event.getName()) && - !SIP_APP_SESSION_ATTRIBUTE_ADDED.equals(event.getName()) && - !SIP_APP_SESSION_ATTRIBUTE_REPLACED.equals(event.getName())) { - if(event.getApplicationSession().isValid()){ - event.getApplicationSession().setAttribute(SIP_APP_SESSION_VALUE_BOUND, OK); - } - } - } - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipApplicationSessionBindingListener#valueUnbound(javax.servlet.sip.SipApplicationSessionBindingEvent) - */ - public void valueUnbound(SipApplicationSessionBindingEvent event) { - logger.info("sip application session value unbound " + event.getName()); - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - if(!SIP_APP_SESSION_VALUE_UNBOUND.equals(event.getName()) && - !SIP_APP_SESSION_ATTRIBUTE_REMOVED.equals(event.getName()) && - !SIP_APP_SESSION_ATTRIBUTE_REPLACED.equals(event.getName())) { - if(event.getApplicationSession().isValid()){ - event.getApplicationSession().setAttribute(SIP_APP_SESSION_VALUE_UNBOUND, OK); - } - } - } - - /* - * (non-Javadoc) - * @see javax.servlet.sip.TimerListener#timeout(javax.servlet.sip.ServletTimer) - */ - @SuppressWarnings("unchecked") - public void timeout(ServletTimer timer) { - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - SipApplicationSession sipApplicationSession = timer.getApplicationSession(); - Iterator sipSessions = (Iterator) - sipApplicationSession.getSessions("SIP"); - int nbSipSessions = 0; - while (sipSessions.hasNext()) { - sipSessions.next(); - nbSipSessions++; - } - logger.info("Number of sip sessions contained in the sip application " + - "session to invalidate " + nbSipSessions); - sipSessions = (Iterator) - sipApplicationSession.getSessions("SIP"); - while (sipSessions.hasNext()) { - SipSession sipSession = (SipSession) sipSessions.next(); - if(sipSession.isValid()) { - sipSession.invalidate(); - } - } - if(sipApplicationSession.isValid()) { - sipApplicationSession.invalidate(); - } - } - - public void sessionReadyToInvalidate(SipSessionEvent se) { - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - } - - public void sessionReadyToInvalidate(SipApplicationSessionEvent ev) { - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - } -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.Iterator; +import java.util.Properties; + +import javax.annotation.Resource; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.sip.ServletParseException; +import javax.servlet.sip.ServletTimer; +import javax.servlet.sip.SipApplicationSession; +import javax.servlet.sip.SipApplicationSessionActivationListener; +import javax.servlet.sip.SipApplicationSessionAttributeListener; +import javax.servlet.sip.SipApplicationSessionBindingEvent; +import javax.servlet.sip.SipApplicationSessionBindingListener; +import javax.servlet.sip.SipApplicationSessionEvent; +import javax.servlet.sip.SipApplicationSessionListener; +import javax.servlet.sip.SipErrorEvent; +import javax.servlet.sip.SipErrorListener; +import javax.servlet.sip.SipFactory; +import javax.servlet.sip.SipServlet; +import javax.servlet.sip.SipServletContextEvent; +import javax.servlet.sip.SipServletListener; +import javax.servlet.sip.SipServletRequest; +import javax.servlet.sip.SipServletResponse; +import javax.servlet.sip.SipSession; +import javax.servlet.sip.SipSessionActivationListener; +import javax.servlet.sip.SipSessionAttributeListener; +import javax.servlet.sip.SipSessionBindingEvent; +import javax.servlet.sip.SipSessionBindingListener; +import javax.servlet.sip.SipSessionEvent; +import javax.servlet.sip.SipSessionListener; +import javax.servlet.sip.SipURI; +import javax.servlet.sip.TimerListener; +import javax.servlet.sip.TimerService; + +import org.apache.log4j.Logger; + + +public class ListenersSipServlet + extends SipServlet + implements SipErrorListener, SipServletListener, + SipSessionListener, SipSessionActivationListener, SipSessionBindingListener, + SipApplicationSessionListener, SipApplicationSessionActivationListener, SipApplicationSessionBindingListener, + SipSessionAttributeListener, SipApplicationSessionAttributeListener, TimerListener { + private static final long serialVersionUID = 1L; + private static transient Logger logger = Logger.getLogger(ListenersSipServlet.class); + + private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; + + private static final String OK = "OK"; + private static final String KO = "KO"; + + private static final String ATTRIBUTE = "attribute"; + private static final String VALUE = "value"; + private static final String NEW_VALUE = "new_value"; + + private static final String NO_ACK_RECEIVED = "noAckReceived"; + private static final String NO_PRACK_RECEIVED = "noPrackReceived"; + private static final String SIP_SERVLET_INITIALIZED = "sipServletInitialized"; + private static final String SIP_SESSION_CREATED = "sipSessionCreated"; + private static final String SIP_SESSION_DESTROYED = "sipSessionDestroyed"; + private static final String SIP_APP_SESSION_VALUE_UNBOUND = "sipAppSessionValueUnbound"; + private static final String SIP_APP_SESSION_VALUE_BOUND = "sipAppSessionValueBound"; + private static final String SIP_APP_SESSION_ATTRIBUTE_REPLACED = "sipAppSessionAttributeReplaced"; + private static final String SIP_APP_SESSION_ATTRIBUTE_REMOVED = "sipAppSessionAttributeRemoved"; + private static final String SIP_APP_SESSION_ATTRIBUTE_ADDED = "sipAppSessionAttributeAdded"; + private static final String SIP_APP_SESSION_PASSIVATED = "sipAppSessionPassivated"; + private static final String SIP_APP_SESSION_ACTIVATED = "sipAppSessionActivated"; + private static final String SIP_APP_SESSION_EXPIRED = "sipAppSessionExpired"; + private static final String SIP_APP_SESSION_DESTROYED = "sipAppSessionDestroyed"; + private static final String SIP_APP_SESSION_CREATED = "sipAppSessionCreated"; + private static final String SIP_SESSION_VALUE_UNBOUND = "sipSessionValueUnbound"; + private static final String SIP_SESSION_VALUE_BOUND = "sipSessionValueBound"; + private static final String SIP_SESSION_ATTRIBUTE_REPLACED = "sipSessionAttributeReplaced"; + private static final String SIP_SESSION_ATTRIBUTE_REMOVED = "sipSessionAttributeRemoved"; + private static final String SIP_SESSION_ATTRIBUTE_ADDED = "sipSessionAttributeAdded"; + private static final String SIP_SESSION_PASSIVATED = "sipSessionPassivated"; + private static final String SIP_SESSION_ACTIVATED = "sipSessionActivated"; + + @Resource + private SipFactory sipFactory; + + static ServletContext ctx; + + + /** Creates a new instance of ListenersSipServlet */ + public ListenersSipServlet() { + } + + @Override + public void init(ServletConfig servletConfig) throws ServletException { + super.init(servletConfig); + logger.info("the listeners test sip servlet has been started"); + ctx = servletConfig.getServletContext(); + try { + // Getting the Sip factory from the JNDI Context + Properties jndiProps = new Properties(); + Context initCtx = new InitialContext(jndiProps); + Context envCtx = (Context) initCtx.lookup("java:comp/env"); + sipFactory = (SipFactory) envCtx.lookup("sip/org.mobicents.servlet.sip.testsuite.ListenersApplication/SipFactory"); + logger.info("Sip Factory ref from JNDI : " + sipFactory); + } catch (NamingException e) { + throw new ServletException("Uh oh -- JNDI problem !", e); + } + } + + /** + * {@inheritDoc} + */ + protected void doInvite(SipServletRequest request) throws ServletException, + IOException { + + logger.info("Got request: " + + request.getMethod()); + SipServletResponse ringingResponse = request.createResponse(SipServletResponse.SC_RINGING); + ringingResponse.send(); + SipServletResponse okResponse = request.createResponse(SipServletResponse.SC_OK); + okResponse.send(); + } + + /** + * {@inheritDoc} + */ + protected void doBye(SipServletRequest request) throws ServletException, + IOException { + + logger.info("Got BYE request: " + request); + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); + sipServletResponse.send(); + //create a timer to invalidate the sessions + request.getSession().setAttribute("sipFactory", sipFactory); +// request.getSession().getApplicationSession().setAttribute("sipFactory", sipFactory); + TimerService timerService = (TimerService) getServletContext().getAttribute(TIMER_SERVICE); + timerService.createTimer(request.getApplicationSession(), 5000, false, null); + } + + @Override + protected void doMessage(SipServletRequest request) throws ServletException, + IOException { + + logger.info("Got request: " + + request.getMethod()); + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); + sipServletResponse.send(); + processMessage(request); + } + + /** + * + * @param request + */ + private void processMessage(SipServletRequest request) { + try { + String message = (String)request.getContent(); + if(message != null && message.length() > 0) { + SipServletRequest responseMessage = request.getSession().createRequest("MESSAGE"); + responseMessage.setContentLength(2); + responseMessage.setContent(KO, CONTENT_TYPE); + if (hasListenerBeenCalled(request, message)) { + responseMessage.setContent(OK, CONTENT_TYPE); + } + responseMessage.send(); + } + } catch (UnsupportedEncodingException e) { + logger.error("the encoding is not supported", e); + } catch (IOException e) { + logger.error("an IO exception occured", e); + } + } + + /** + * Check if a particular listener has been called + * @param request the request the message has been received on + * @param message the message containing the listener to check + * @return true if the listener has been called, flase otherwise + */ + private boolean hasListenerBeenCalled(SipServletRequest request, String message) { + if(SIP_SESSION_CREATED.equals(message) + && request.getSession().getAttribute(message) != null) { + return true; + } else if (SIP_SESSION_DESTROYED.equals(message)) { + request.getSession().invalidate(); + if(request.getSession().getAttribute(message) != null) { + return true; + } else { + return false; + } + } if(SIP_APP_SESSION_CREATED.equals(message) + && request.getApplicationSession().getAttribute(message) != null) { + return true; + } else if (SIP_APP_SESSION_DESTROYED.equals(message)) { + request.getApplicationSession().invalidate(); + if(request.getApplicationSession().getAttribute(message) != null) { + return true; + } else { + return false; + } + } else if (SIP_SESSION_ATTRIBUTE_ADDED.equals(message) || + SIP_SESSION_VALUE_BOUND.equals(message)) { + request.getSession().setAttribute(ATTRIBUTE, VALUE); + if(request.getSession().getAttribute(message) != null) { + return true; + } else { + return false; + } + }else if (SIP_SESSION_ATTRIBUTE_REMOVED.equals(message) || + SIP_SESSION_VALUE_UNBOUND.equals(message)) { + request.getSession().setAttribute(ATTRIBUTE, VALUE); + request.getSession().removeAttribute(ATTRIBUTE); + if(request.getSession().getAttribute(message) != null) { + return true; + } else { + return false; + } + } else if (SIP_SESSION_ATTRIBUTE_REPLACED.equals(message)) { + request.getSession().setAttribute(ATTRIBUTE, VALUE); + request.getSession().setAttribute(ATTRIBUTE, NEW_VALUE); + if(request.getSession().getAttribute(message) != null) { + return true; + } else { + return false; + } + } else if (SIP_APP_SESSION_ATTRIBUTE_ADDED.equals(message) || + SIP_APP_SESSION_VALUE_BOUND.equals(message)) { + request.getApplicationSession().setAttribute(ATTRIBUTE, VALUE); + if(request.getApplicationSession().getAttribute(message) != null) { + return true; + } else { + return false; + } + }else if (SIP_APP_SESSION_ATTRIBUTE_REMOVED.equals(message) || + SIP_APP_SESSION_VALUE_UNBOUND.equals(message)) { + request.getApplicationSession().setAttribute(ATTRIBUTE, VALUE); + request.getApplicationSession().removeAttribute(ATTRIBUTE); + if(request.getApplicationSession().getAttribute(message) != null) { + return true; + } else { + return false; + } + } else if (SIP_APP_SESSION_ATTRIBUTE_REPLACED.equals(message)) { + request.getApplicationSession().setAttribute(ATTRIBUTE, VALUE); + request.getApplicationSession().setAttribute(ATTRIBUTE, NEW_VALUE); + if(request.getApplicationSession().getAttribute(message) != null) { + return true; + } else { + return false; + } + } else if (SIP_SERVLET_INITIALIZED.equals(message) + && getServletContext().getAttribute(message) != null) { + return true; + } + return false; + } + + @Override + protected void doRequest(SipServletRequest req) throws ServletException, + IOException { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + super.doRequest(req); + } + + @Override + protected void doResponse(SipServletResponse resp) throws ServletException, + IOException { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + super.doResponse(resp); + } + + // Listeners methods + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipErrorListener#noAckReceived(javax.servlet.sip.SipErrorEvent) + */ + public void noAckReceived(SipErrorEvent ee) { + logger.error("noAckReceived."); + ee.getRequest().getSession().setAttribute(NO_ACK_RECEIVED, OK); + } + + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipErrorListener#noPrackReceived(javax.servlet.sip.SipErrorEvent) + */ + public void noPrackReceived(SipErrorEvent ee) { + logger.info("noPrackReceived."); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + ee.getRequest().getSession().setAttribute(NO_PRACK_RECEIVED, OK); + } + + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipServletListener#servletInitialized(javax.servlet.sip.SipServletContextEvent) + */ + public void servletInitialized(SipServletContextEvent ce) { + logger.info("servlet initialized "); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + ce.getServletContext().setAttribute(SIP_SERVLET_INITIALIZED, OK); + } + + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipSessionListener#sessionCreated(javax.servlet.sip.SipSessionEvent) + */ + public void sessionCreated(SipSessionEvent se) { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + logger.info("sip session created " + se.getSession()); + se.getSession().setAttribute(SIP_SESSION_CREATED, OK); + } + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipSessionListener#sessionDestroyed(javax.servlet.sip.SipSessionEvent) + */ + public void sessionDestroyed(SipSessionEvent se) { + logger.info("sip session destroyed " + se.getSession()); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } +// SipFactory storedFactory = (SipFactory)se.getSession().getApplicationSession().getAttribute("sipFactory"); + SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); + try { + SipServletRequest sipServletRequest = sipFactory.createRequest( + sipApplicationSession, + "MESSAGE", + "sip:sender@sip-servlets.com", + "sip:receiver@sip-servlets.com"); + SipURI sipUri=sipFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + sipServletRequest.setRequestURI(sipUri); + sipServletRequest.setContentLength(SIP_SESSION_DESTROYED.length()); + sipServletRequest.setContent(SIP_SESSION_DESTROYED, CONTENT_TYPE); + sipServletRequest.send(); + } catch (ServletParseException e) { + logger.error("Exception occured while parsing the addresses",e); + } catch (IOException e) { + logger.error("Exception occured while sending the request",e); + } + } + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipSessionActivationListener#sessionDidActivate(javax.servlet.sip.SipSessionEvent) + */ + public void sessionDidActivate(SipSessionEvent se) { + logger.info("sip session activated " + se.getSession()); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + if(se.getSession().isValid()){ + se.getSession().setAttribute(SIP_SESSION_ACTIVATED, OK); + } + } + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipSessionActivationListener#sessionWillPassivate(javax.servlet.sip.SipSessionEvent) + */ + public void sessionWillPassivate(SipSessionEvent se) { + logger.info("sip session passivated " + se.getSession()); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + if(se.getSession().isValid()){ + se.getSession().setAttribute(SIP_SESSION_PASSIVATED, OK); + } + + } + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipSessionAttributeListener#attributeAdded(javax.servlet.sip.SipSessionBindingEvent) + */ + public void attributeAdded(SipSessionBindingEvent ev) { + logger.info("sip session attribute added " + ev.getName()); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + if(!SIP_SESSION_ATTRIBUTE_ADDED.equals(ev.getName()) && + !SIP_SESSION_VALUE_BOUND.equals(ev.getName()) && + !SIP_SESSION_ATTRIBUTE_REPLACED.equals(ev.getName())) { + if(ev.getSession().isValid()){ + ev.getSession().setAttribute(SIP_SESSION_ATTRIBUTE_ADDED, OK); + } + } + } + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipSessionAttributeListener#attributeRemoved(javax.servlet.sip.SipSessionBindingEvent) + */ + public void attributeRemoved(SipSessionBindingEvent ev) { + logger.info("sip session attribute removed " + ev.getName()); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + if(!SIP_SESSION_ATTRIBUTE_REMOVED.equals(ev.getName()) && + !SIP_SESSION_VALUE_UNBOUND.equals(ev.getName()) && + !SIP_SESSION_ATTRIBUTE_REPLACED.equals(ev.getName())) { + if(ev.getSession().isValid()){ + ev.getSession().setAttribute(SIP_SESSION_ATTRIBUTE_REMOVED, OK); + } + } + } + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipSessionAttributeListener#attributeReplaced(javax.servlet.sip.SipSessionBindingEvent) + */ + public void attributeReplaced(SipSessionBindingEvent ev) { + logger.info("sip session attribute removed " + ev.getName()); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + if(!SIP_SESSION_ATTRIBUTE_REPLACED.equals(ev.getName())) { + if(ev.getSession().isValid()){ + ev.getSession().setAttribute(SIP_SESSION_ATTRIBUTE_REPLACED, OK); + } + } + } + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipSessionBindingListener#valueBound(javax.servlet.sip.SipSessionBindingEvent) + */ + public void valueBound(SipSessionBindingEvent event) { + logger.info("sip session attribute bound " + event.getName()); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + if(!SIP_SESSION_VALUE_BOUND.equals(event.getName()) && + !SIP_SESSION_ATTRIBUTE_ADDED.equals(event.getName()) && + !SIP_SESSION_ATTRIBUTE_REPLACED.equals(event.getName())) { + if(event.getSession().isValid()){ + event.getSession().setAttribute(SIP_SESSION_VALUE_BOUND, OK); + } + } + } + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipSessionBindingListener#valueUnbound(javax.servlet.sip.SipSessionBindingEvent) + */ + public void valueUnbound(SipSessionBindingEvent event) { + logger.info("sip session attribute unbound " + event.getName()); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + if(!SIP_SESSION_VALUE_UNBOUND.equals(event.getName()) && + !SIP_SESSION_ATTRIBUTE_REMOVED.equals(event.getName()) && + !SIP_SESSION_ATTRIBUTE_REPLACED.equals(event.getName())) { + event.getSession().setAttribute(SIP_SESSION_VALUE_UNBOUND, OK); + } + } + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipApplicationSessionListener#sessionCreated(javax.servlet.sip.SipApplicationSessionEvent) + */ + public void sessionCreated(SipApplicationSessionEvent ev) { + logger.info("sip application session created " + ev.getApplicationSession()); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + if(ev.getApplicationSession().isValid()){ + ev.getApplicationSession().setAttribute(SIP_APP_SESSION_CREATED, OK); + } + } + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipApplicationSessionListener#sessionDestroyed(javax.servlet.sip.SipApplicationSessionEvent) + */ + public void sessionDestroyed(SipApplicationSessionEvent ev) { + logger.info("sip application session destroyed " + ev.getApplicationSession()); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } +// SipFactory storedFactory = (SipFactory)ev.getApplicationSession().getAttribute("sipFactory"); + if(sipFactory != null) { + SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); + try { + SipServletRequest sipServletRequest = sipFactory .createRequest( + sipApplicationSession, + "MESSAGE", + "sip:sender@sip-servlets.com", + "sip:receiver@sip-servlets.com"); + SipURI sipUri=sipFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + sipServletRequest.setRequestURI(sipUri); + sipServletRequest.setContentLength(SIP_APP_SESSION_DESTROYED.length()); + sipServletRequest.setContent(SIP_APP_SESSION_DESTROYED, CONTENT_TYPE); + sipServletRequest.send(); + } catch (ServletParseException e) { + logger.error("Exception occured while parsing the addresses",e); + } catch (IOException e) { + logger.error("Exception occured while sending the request",e); + } + } + } + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipApplicationSessionListener#sessionExpired(javax.servlet.sip.SipApplicationSessionEvent) + */ + public void sessionExpired(SipApplicationSessionEvent ev) { + logger.info("sip application session expired " + ev.getApplicationSession()); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + if(ev.getApplicationSession().isValid()){ + ev.getApplicationSession().setAttribute(SIP_APP_SESSION_EXPIRED, OK); + } + } + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipApplicationSessionActivationListener#sessionDidActivate(javax.servlet.sip.SipApplicationSessionEvent) + */ + public void sessionDidActivate(SipApplicationSessionEvent se) { + logger.info("sip application session activated " + se.getApplicationSession()); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + if(se.getApplicationSession().isValid()){ + se.getApplicationSession().setAttribute(SIP_APP_SESSION_ACTIVATED, OK); + } + } + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipApplicationSessionActivationListener#sessionWillPassivate(javax.servlet.sip.SipApplicationSessionEvent) + */ + public void sessionWillPassivate(SipApplicationSessionEvent se) { + logger.info("sip application session passivated " + se.getApplicationSession()); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + if(se.getApplicationSession().isValid()){ + se.getApplicationSession().setAttribute(SIP_APP_SESSION_PASSIVATED, OK); + } + } + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipApplicationSessionAttributeListener#attributeAdded(javax.servlet.sip.SipApplicationSessionBindingEvent) + */ + public void attributeAdded(SipApplicationSessionBindingEvent ev) { + logger.info("sip application session attribute added " + ev.getName()); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + if(!SIP_APP_SESSION_ATTRIBUTE_ADDED.equals(ev.getName()) && + !SIP_APP_SESSION_VALUE_BOUND.equals(ev.getName()) && + !SIP_APP_SESSION_ATTRIBUTE_REPLACED.equals(ev.getName())) { + if(ev.getApplicationSession().isValid()){ + ev.getApplicationSession().setAttribute(SIP_APP_SESSION_ATTRIBUTE_ADDED, OK); + } + } + } + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipApplicationSessionAttributeListener#attributeRemoved(javax.servlet.sip.SipApplicationSessionBindingEvent) + */ + public void attributeRemoved(SipApplicationSessionBindingEvent ev) { + logger.info("sip application session attribute removed " + ev.getName()); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + if(!SIP_APP_SESSION_ATTRIBUTE_REMOVED.equals(ev.getName()) && + !SIP_APP_SESSION_VALUE_UNBOUND.equals(ev.getName()) && + !SIP_APP_SESSION_ATTRIBUTE_REPLACED.equals(ev.getName())) { + if(ev.getApplicationSession().isValid()){ + ev.getApplicationSession().setAttribute(SIP_APP_SESSION_ATTRIBUTE_REMOVED, OK); + } + } + } + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipApplicationSessionAttributeListener#attributeReplaced(javax.servlet.sip.SipApplicationSessionBindingEvent) + */ + public void attributeReplaced(SipApplicationSessionBindingEvent ev) { + logger.info("sip application session attribute replaced " + ev.getName()); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + if(!SIP_APP_SESSION_ATTRIBUTE_REMOVED.equals(ev.getName()) && + !SIP_APP_SESSION_VALUE_UNBOUND.equals(ev.getName()) && + !SIP_APP_SESSION_ATTRIBUTE_REPLACED.equals(ev.getName())) { + if(ev.getApplicationSession().isValid()){ + ev.getApplicationSession().setAttribute(SIP_APP_SESSION_ATTRIBUTE_REPLACED, OK); + } + } + } + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipApplicationSessionBindingListener#valueBound(javax.servlet.sip.SipApplicationSessionBindingEvent) + */ + public void valueBound(SipApplicationSessionBindingEvent event) { + logger.info("sip application session value bound " + event.getName()); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + if(!SIP_APP_SESSION_VALUE_BOUND.equals(event.getName()) && + !SIP_APP_SESSION_ATTRIBUTE_ADDED.equals(event.getName()) && + !SIP_APP_SESSION_ATTRIBUTE_REPLACED.equals(event.getName())) { + if(event.getApplicationSession().isValid()){ + event.getApplicationSession().setAttribute(SIP_APP_SESSION_VALUE_BOUND, OK); + } + } + } + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipApplicationSessionBindingListener#valueUnbound(javax.servlet.sip.SipApplicationSessionBindingEvent) + */ + public void valueUnbound(SipApplicationSessionBindingEvent event) { + logger.info("sip application session value unbound " + event.getName()); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + if(!SIP_APP_SESSION_VALUE_UNBOUND.equals(event.getName()) && + !SIP_APP_SESSION_ATTRIBUTE_REMOVED.equals(event.getName()) && + !SIP_APP_SESSION_ATTRIBUTE_REPLACED.equals(event.getName())) { + if(event.getApplicationSession().isValid()){ + event.getApplicationSession().setAttribute(SIP_APP_SESSION_VALUE_UNBOUND, OK); + } + } + } + + /* + * (non-Javadoc) + * @see javax.servlet.sip.TimerListener#timeout(javax.servlet.sip.ServletTimer) + */ + @SuppressWarnings("unchecked") + public void timeout(ServletTimer timer) { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + SipApplicationSession sipApplicationSession = timer.getApplicationSession(); + Iterator sipSessions = (Iterator) + sipApplicationSession.getSessions("SIP"); + int nbSipSessions = 0; + while (sipSessions.hasNext()) { + sipSessions.next(); + nbSipSessions++; + } + logger.info("Number of sip sessions contained in the sip application " + + "session to invalidate " + nbSipSessions); + sipSessions = (Iterator) + sipApplicationSession.getSessions("SIP"); + while (sipSessions.hasNext()) { + SipSession sipSession = (SipSession) sipSessions.next(); + if(sipSession.isValid()) { + sipSession.invalidate(); + } + } + if(sipApplicationSession.isValid()) { + sipApplicationSession.invalidate(); + } + } + + public void sessionReadyToInvalidate(SipSessionEvent se) { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + } + + public void sessionReadyToInvalidate(SipApplicationSessionEvent ev) { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + } + + public static Integer getTestPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("testPort"); + logger.info("TestPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5080; + } + } + + public static Integer getServletContainerPort(ServletContext ctx) { + String cPort = ctx.getInitParameter("servletContainerPort"); + logger.info("TestPort at:" + cPort); + if (cPort != null) { + return Integer.valueOf(cPort); + } else { + return 5070; + } + } +} diff --git a/sip-servlets-test-suite/applications/location-service-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/LocationServiceSipServlet.java b/sip-servlets-test-suite/applications/location-service-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/LocationServiceSipServlet.java index 855dc2a82f..16a3927aa4 100644 --- a/sip-servlets-test-suite/applications/location-service-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/LocationServiceSipServlet.java +++ b/sip-servlets-test-suite/applications/location-service-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/LocationServiceSipServlet.java @@ -1,240 +1,343 @@ -/* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2014, Telestax Inc and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - * - * This file incorporates work covered by the following copyright contributed under the GNU LGPL : Copyright 2007-2011 Red Hat. - */ - -package org.mobicents.servlet.sip.testsuite; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.UUID; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.sip.Address; -import javax.servlet.sip.Proxy; -import javax.servlet.sip.SipFactory; -import javax.servlet.sip.SipServlet; -import javax.servlet.sip.SipServletRequest; -import javax.servlet.sip.SipServletResponse; -import javax.servlet.sip.SipURI; -import javax.servlet.sip.URI; - -import org.apache.log4j.Logger; - - -public class LocationServiceSipServlet extends SipServlet { - private static final long serialVersionUID = 1L; - private static transient Logger logger = Logger.getLogger(LocationServiceSipServlet.class); - - private static final String LOCAL_TRANSPORT = "udp"; - private static final int LOCAL_PORT = 5070; - private static final String LOCAL_LOCALHOST_ADDR = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; - - private static final String REMOTE_TRANSPORT = "udp"; - private static final int REMOTE_PORT = 5090; - private static final String REMOTE_LOCALHOST_ADDR = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; - - private static final String INITIAL_REMOTE_TRANSPORT = "udp"; - private static final int INITIAL_REMOTE_PORT = 5070; - private static final String INITIAL_REMOTE_LOCALHOST_ADDR = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; - - private static final String TEST_USER_REMOTE = "remote"; - - Map> registeredUsers = null; - - /** Creates a new instance of SpeedDialSipServlet */ - public LocationServiceSipServlet() {} - - @Override - public void init(ServletConfig servletConfig) throws ServletException { - logger.info("the location service sip servlet has been started"); - super.init(servletConfig); - SipFactory sipFactory = (SipFactory)getServletContext().getAttribute(SIP_FACTORY); - registeredUsers = new HashMap>(); - List uriList = new ArrayList(); - uriList.add(sipFactory.createURI("sip:receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090")); - uriList.add(sipFactory.createURI("sip:receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":6090")); - registeredUsers.put("sip:receiver@sip-servlets.com", uriList); - // https://code.google.com/p/sipservlets/issues/detail?id=273 - uriList = new ArrayList(); - uriList.add(sipFactory.createURI("sip:receiver-prack@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090")); - registeredUsers.put("sip:receiver-prack@sip-servlets.com", uriList); - uriList = new ArrayList(); - uriList.add(sipFactory.createURI("sip:receiver-prack@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090")); - registeredUsers.put("sip:receiver-prack@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090", uriList); - - uriList = new ArrayList(); - uriList.add(sipFactory.createURI("sip:cancel-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090")); - registeredUsers.put("sip:cancel-receiver@sip-servlets.com", uriList); - uriList = new ArrayList(); - uriList.add(sipFactory.createURI("sip:cancel-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090")); - uriList.add(sipFactory.createURI("sip:cancel-receiver2@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5091")); - registeredUsers.put("sip:cancel-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090", uriList); - - - uriList = new ArrayList(); - uriList.add(sipFactory.createURI("sip:receiver-failover@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090")); - registeredUsers.put("sip:receiver-failover@sip-servlets.com", uriList); - registeredUsers.put("sip:receiver-failover@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090", uriList); - uriList = new ArrayList(); - uriList.add(sipFactory.createURI("sip:receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070")); - registeredUsers.put("sip:proxy-b2bua@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070", uriList); - - } - - @Override - protected void doInvite(SipServletRequest request) throws ServletException, - IOException { - - logger.info("Got request:\n" + request.toString()); - - if(((SipURI)request.getFrom().getURI()).getUser().equalsIgnoreCase(TEST_USER_REMOTE)) { - if(request.getRemoteAddr().equals(LOCAL_LOCALHOST_ADDR) && request.getRemotePort() == LOCAL_PORT && request.getTransport().equalsIgnoreCase(LOCAL_TRANSPORT)) { - logger.info("remote information is correct"); - } else { - logger.error("remote information is incorrect"); - logger.error("remote addr " + request.getRemoteAddr()); - logger.error("remote port " + request.getRemotePort()); - logger.error("remote transport " + request.getTransport()); - SipServletResponse sipServletResponse = - request.createResponse(SipServletResponse.SC_SERVER_INTERNAL_ERROR, "Incorrect remote information"); - sipServletResponse.send(); - return; - } - if(request.getInitialRemoteAddr().equals(INITIAL_REMOTE_LOCALHOST_ADDR) && request.getInitialRemotePort() == INITIAL_REMOTE_PORT && request.getInitialTransport().equalsIgnoreCase(INITIAL_REMOTE_TRANSPORT)) { - logger.info("Initial remote information is correct"); - } else { - logger.error("Initial remote information is incorrect"); - logger.error("Initial remote addr " + request.getInitialRemoteAddr()); - logger.error("Initial remote port " + request.getInitialRemotePort()); - logger.error("Initial remote transport " + request.getInitialTransport()); - throw new IllegalArgumentException("initial remote information is incorrect"); - } - if(request.getLocalAddr().equals(LOCAL_LOCALHOST_ADDR) && request.getLocalPort() == LOCAL_PORT && request.getTransport().equalsIgnoreCase(LOCAL_TRANSPORT)) { - logger.info("local information is correct"); - } else { - logger.error("local information is incorrect"); - logger.error("local addr " + request.getLocalAddr()); - logger.error("local port " + request.getLocalPort()); - logger.error("local transport " + request.getTransport()); - throw new IllegalArgumentException("local information is incorrect"); - } - } - - if(request.isInitial()) { - List contactAddresses = registeredUsers.get(request.getRequestURI().toString()); - if(contactAddresses != null && contactAddresses.size() > 0) { - Proxy proxy = request.getProxy(); - proxy.setProxyTimeout(3); - proxy.setRecordRoute(true); - proxy.setParallel(true); - proxy.setSupervised(true); - for (URI uri : contactAddresses) { - logger.info("proxying to " + uri); - } - proxy.proxyTo(contactAddresses); - } else { - logger.info(request.getRequestURI().toString() + " is not currently registered"); - SipServletResponse sipServletResponse = - request.createResponse(SipServletResponse.SC_MOVED_PERMANENTLY, "Moved Permanently"); - sipServletResponse.send(); - } - } - } - - @Override - protected void doPrack(SipServletRequest req) throws ServletException, - IOException { - req.addHeader("X-Seen", "" + UUID.randomUUID()); - } - - @Override - protected void doErrorResponse(SipServletResponse resp) - throws ServletException, IOException { - logger.info("Got response " + resp); - } - - protected void doSuccessResponse(SipServletResponse resp) - throws ServletException, IOException { - logger.info("Got response " + resp); - if(((SipURI)resp.getFrom().getURI()).getUser().equalsIgnoreCase(TEST_USER_REMOTE)) { - String npecause = resp.getTransport(); - npecause = resp.getInitialTransport(); - if(resp.getRemoteAddr().equals(REMOTE_LOCALHOST_ADDR) && resp.getRemotePort() == REMOTE_PORT && resp.getTransport().equalsIgnoreCase(REMOTE_TRANSPORT)) { - logger.info("remote information is correct"); - } else { - logger.error("remote information is incorrect"); - logger.error("remote addr " + resp.getRemoteAddr()); - logger.error("remote port " + resp.getRemotePort()); - logger.error("remote transport " + resp.getTransport()); - throw new IllegalArgumentException("remote information is incorrect"); - } - if(resp.getInitialRemoteAddr().equals(REMOTE_LOCALHOST_ADDR) && resp.getInitialRemotePort() == REMOTE_PORT && resp.getInitialTransport().equalsIgnoreCase(REMOTE_TRANSPORT)) { - logger.info("Initial remote information is correct"); - } else { - logger.error("Initial remote information is incorrect"); - logger.error("Initial remote addr " + resp.getInitialRemoteAddr()); - logger.error("Initial remote port " + resp.getInitialRemotePort()); - logger.error("Initial remote transport " + resp.getInitialTransport()); - throw new IllegalArgumentException("initial remote information is incorrect"); - } - if(resp.getLocalAddr().equals(LOCAL_LOCALHOST_ADDR) && resp.getLocalPort() == LOCAL_PORT && resp.getTransport().equalsIgnoreCase(LOCAL_TRANSPORT)) { - logger.info("local information is correct"); - } else { - logger.error("local information is incorrect"); - logger.error("local addr " + resp.getLocalAddr()); - logger.error("local port " + resp.getLocalPort()); - logger.error("local transport " + resp.getTransport()); - throw new IllegalArgumentException("local information is incorrect"); - } - } - } - - @Override - protected void doRegister(SipServletRequest req) throws ServletException, - IOException { - logger.info("Received register request: " + req.getTo()); - - //Storing the registration - Address toAddress = req.getTo(); - ListIterator

contactAddresses = req.getAddressHeaders("Contact"); - List contactUris = new ArrayList(); - while (contactAddresses.hasNext()) { - Address contactAddress = contactAddresses.next(); - contactUris.add(contactAddress.getURI()); - } - //FIXME handle the expires to add or remove the user - registeredUsers.put(toAddress.toString(), contactUris); - //answering OK to REGISTER - int response = SipServletResponse.SC_OK; - SipServletResponse resp = req.createResponse(response); - resp.send(); - } - - @Override - protected void doCancel(SipServletRequest req) throws ServletException, - IOException { - logger.error("CANCEL seen at proxy " + req); - } -} +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2014, Telestax Inc and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * + * This file incorporates work covered by the following copyright contributed under the GNU LGPL : Copyright 2007-2011 Red Hat. + */ + +package org.mobicents.servlet.sip.testsuite; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.UUID; + +import javax.annotation.Resource; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.sip.Address; +import javax.servlet.sip.Proxy; +import javax.servlet.sip.ProxyBranch; +import javax.servlet.sip.ServletParseException; +import javax.servlet.sip.ServletTimer; +import javax.servlet.sip.SipApplicationSession; +import javax.servlet.sip.SipFactory; +import javax.servlet.sip.SipServlet; +import javax.servlet.sip.SipServletContextEvent; +import javax.servlet.sip.SipServletListener; +import javax.servlet.sip.SipServletRequest; +import javax.servlet.sip.SipServletResponse; +import javax.servlet.sip.SipURI; +import javax.servlet.sip.TimerListener; +import javax.servlet.sip.TimerService; +import javax.servlet.sip.URI; +import javax.servlet.sip.annotation.SipListener; +import javax.servlet.sip.ar.SipApplicationRoutingDirective; + +import org.apache.log4j.Logger; + +@SipListener +public class LocationServiceSipServlet extends SipServlet implements SipServletListener, TimerListener { + private static final long serialVersionUID = 1L; + private static transient Logger logger = Logger.getLogger(LocationServiceSipServlet.class); + + private static final String LOCAL_TRANSPORT = "udp"; + private static final String LOCAL_LOCALHOST_ADDR = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; + + private static final String REMOTE_TRANSPORT = "udp"; + private static final String REMOTE_LOCALHOST_ADDR = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; + + private static final String INITIAL_REMOTE_TRANSPORT = "udp"; + private static final String INITIAL_REMOTE_LOCALHOST_ADDR = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; + + private static final String TEST_USER_REMOTE = "remote"; + + Map> registeredUsers = null; + + @Resource + SipFactory sipFactory; + @Resource + TimerService timerService; + ServletTimer timerTask; + static ServletContext ctx; + + /** Creates a new instance of SpeedDialSipServlet */ + public LocationServiceSipServlet() {} + + @Override + public void init(ServletConfig servletConfig) throws ServletException { + logger.info("the location service sip servlet has been started"); + super.init(servletConfig); + ctx = servletConfig.getServletContext(); + SipFactory sipFactory = (SipFactory)getServletContext().getAttribute(SIP_FACTORY); + registeredUsers = new HashMap>(); + List uriList = new ArrayList(); + uriList.add(sipFactory.createURI("sip:receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx))); + uriList.add(sipFactory.createURI("sip:receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":6090")); + registeredUsers.put("sip:receiver@sip-servlets.com", uriList); + // https://code.google.com/p/sipservlets/issues/detail?id=273 + uriList = new ArrayList(); + uriList.add(sipFactory.createURI("sip:receiver-prack@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx))); + registeredUsers.put("sip:receiver-prack@sip-servlets.com", uriList); + uriList = new ArrayList(); + uriList.add(sipFactory.createURI("sip:receiver-prack@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx))); + registeredUsers.put("sip:receiver-prack@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx), uriList); + + uriList = new ArrayList(); + uriList.add(sipFactory.createURI("sip:cancel-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx))); + registeredUsers.put("sip:cancel-receiver@sip-servlets.com", uriList); + uriList = new ArrayList(); + uriList.add(sipFactory.createURI("sip:cancel-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx))); + uriList.add(sipFactory.createURI("sip:cancel-receiver2@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getReceiver2Port(ctx))); + registeredUsers.put("sip:cancel-receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx), uriList); + + + uriList = new ArrayList(); + uriList.add(sipFactory.createURI("sip:receiver-failover@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx))); + registeredUsers.put("sip:receiver-failover@sip-servlets.com", uriList); + registeredUsers.put("sip:receiver-failover@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx), uriList); + uriList = new ArrayList(); + uriList.add(sipFactory.createURI("sip:receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getServletContainerPort(ctx))); + registeredUsers.put("sip:proxy-b2bua@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getServletContainerPort(ctx), uriList); + + } + + @Override + protected void doInvite(SipServletRequest request) throws ServletException, + IOException { + + logger.info("Got request:\n" + request.toString()); + if(!request.getRequestURI().toString().contains("act-as-uac") && timerTask != null) { + timerTask.cancel(); + } + if(((SipURI)request.getFrom().getURI()).getUser().equalsIgnoreCase(TEST_USER_REMOTE)) { + if(request.getRemoteAddr().equals(LOCAL_LOCALHOST_ADDR) && request.getRemotePort() == getServletContainerPort(ctx) && request.getTransport().equalsIgnoreCase(LOCAL_TRANSPORT)) { + logger.info("remote information is correct"); + } else { + logger.error("remote information is incorrect"); + logger.error("remote addr " + request.getRemoteAddr()); + logger.error("remote port " + request.getRemotePort()); + logger.error("remote transport " + request.getTransport()); + SipServletResponse sipServletResponse = + request.createResponse(SipServletResponse.SC_SERVER_INTERNAL_ERROR, "Incorrect remote information"); + sipServletResponse.send(); + return; + } + if(request.getInitialRemoteAddr().equals(INITIAL_REMOTE_LOCALHOST_ADDR) && + request.getInitialRemotePort() == getServletContainerPort(ctx) && + request.getInitialTransport().equalsIgnoreCase(INITIAL_REMOTE_TRANSPORT)) { + logger.info("Initial remote information is correct"); + } else { + logger.error("Initial remote information is incorrect"); + logger.error("Initial remote addr " + request.getInitialRemoteAddr()); + logger.error("Initial remote port " + request.getInitialRemotePort()); + logger.error("Initial remote transport " + request.getInitialTransport()); + throw new IllegalArgumentException("initial remote information is incorrect"); + } + if(request.getLocalAddr().equals(LOCAL_LOCALHOST_ADDR) && request.getLocalPort() == getServletContainerPort(ctx) && request.getTransport().equalsIgnoreCase(LOCAL_TRANSPORT)) { + logger.info("local information is correct"); + } else { + logger.error("local information is incorrect"); + logger.error("local addr " + request.getLocalAddr()); + logger.error("local port " + request.getLocalPort()); + logger.error("local transport " + request.getTransport()); + throw new IllegalArgumentException("local information is incorrect"); + } + } + + String count = null; + if(request.getHeader("X-Count") != null) { + count = request.getHeader("X-Count"); + } + if(request.isInitial()) { + if(count != null && count.equalsIgnoreCase("0")) { + Proxy proxy = request.getProxy(); + proxy.setRecordRoute(true); + proxy.setParallel(true); + proxy.setSupervised(true); + ArrayList uris = new ArrayList(); + uris.add(sipFactory.createURI("sip:receiver@sip-servlets.com")); + List proxyBranches = proxy.createProxyBranches(uris); + for(ProxyBranch proxyBranch : proxyBranches) { + proxyBranch.getRequest().setHeader("X-Count", "1"); + } + logger.info("proxying to " + request.getRequestURI()); + proxy.startProxy(); + return; + } + List contactAddresses = registeredUsers.get(request.getRequestURI().toString()); + if(contactAddresses != null && contactAddresses.size() > 0) { + Proxy proxy = request.getProxy(); + proxy.setProxyTimeout(3); + proxy.setRecordRoute(true); + proxy.setParallel(true); + proxy.setSupervised(true); + for (URI uri : contactAddresses) { + logger.info("proxying to " + uri); + } + proxy.proxyTo(contactAddresses); + } else { + logger.info(request.getRequestURI().toString() + " is not currently registered"); + SipServletResponse sipServletResponse = + request.createResponse(SipServletResponse.SC_MOVED_PERMANENTLY, "Moved Permanently"); + sipServletResponse.send(); + } + } + } + + @Override + protected void doPrack(SipServletRequest req) throws ServletException, + IOException { + req.addHeader("X-Seen", "" + UUID.randomUUID()); + } + + @Override + protected void doErrorResponse(SipServletResponse resp) + throws ServletException, IOException { + logger.info("Got response " + resp); + } + + protected void doSuccessResponse(SipServletResponse resp) + throws ServletException, IOException { + logger.info("Got response " + resp); + if(((SipURI)resp.getFrom().getURI()).getUser().equalsIgnoreCase(TEST_USER_REMOTE)) { + String npecause = resp.getTransport(); + npecause = resp.getInitialTransport(); + if(resp.getRemoteAddr().equals(REMOTE_LOCALHOST_ADDR) && resp.getRemotePort() == getTestPort(ctx) && resp.getTransport().equalsIgnoreCase(REMOTE_TRANSPORT)) { + logger.info("remote information is correct"); + } else { + logger.error("remote information is incorrect"); + logger.error("remote addr " + resp.getRemoteAddr()); + logger.error("remote port " + resp.getRemotePort()); + logger.error("remote transport " + resp.getTransport()); + throw new IllegalArgumentException("remote information is incorrect"); + } + if(resp.getInitialRemoteAddr().equals(REMOTE_LOCALHOST_ADDR) && resp.getInitialRemotePort() == getTestPort(ctx) && resp.getInitialTransport().equalsIgnoreCase(REMOTE_TRANSPORT)) { + logger.info("Initial remote information is correct"); + } else { + logger.error("Initial remote information is incorrect"); + logger.error("Initial remote addr " + resp.getInitialRemoteAddr()); + logger.error("Initial remote port " + resp.getInitialRemotePort()); + logger.error("Initial remote transport " + resp.getInitialTransport()); + throw new IllegalArgumentException("initial remote information is incorrect"); + } + if(resp.getLocalAddr().equals(LOCAL_LOCALHOST_ADDR) && resp.getLocalPort() == getServletContainerPort(ctx) && resp.getTransport().equalsIgnoreCase(LOCAL_TRANSPORT)) { + logger.info("local information is correct"); + } else { + logger.error("local information is incorrect"); + logger.error("local addr " + resp.getLocalAddr()); + logger.error("local port " + resp.getLocalPort()); + logger.error("local transport " + resp.getTransport()); + throw new IllegalArgumentException("local information is incorrect"); + } + } + } + + @Override + protected void doRegister(SipServletRequest req) throws ServletException, + IOException { + logger.info("Received register request: " + req.getTo()); + + //Storing the registration + Address toAddress = req.getTo(); + ListIterator
contactAddresses = req.getAddressHeaders("Contact"); + List contactUris = new ArrayList(); + while (contactAddresses.hasNext()) { + Address contactAddress = contactAddresses.next(); + contactUris.add(contactAddress.getURI()); + } + //FIXME handle the expires to add or remove the user + registeredUsers.put(toAddress.toString(), contactUris); + //answering OK to REGISTER + int response = SipServletResponse.SC_OK; + SipServletResponse resp = req.createResponse(response); + resp.send(); + } + + @Override + protected void doCancel(SipServletRequest req) throws ServletException, + IOException { + logger.error("CANCEL seen at proxy " + req); + } + + @Override + public void servletInitialized(SipServletContextEvent ce) { + SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); + timerTask = timerService.createTimer(sipApplicationSession, 2000, false, null); + } + + @Override + public void timeout(ServletTimer timer) { + try { + SipServletRequest newRequest = sipFactory.createRequest( + timer.getApplicationSession(), + "INVITE", + "sip:uac@" + System.getProperty("org.mobicents.testsuite.testhostaddr"), + "sip:receiver@sip-servlets.com"); + newRequest.addHeader("X-Count", "0"); + newRequest.send(); + } catch (Exception e) { + logger.error("an error occured sending the UAC INVITE ", e); + } + } + + + public static Integer getTestPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("testPort"); + logger.info("TestPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5090; + } + } + + public static Integer getSenderPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("senderPort"); + logger.info("SenderPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5080; + } + } + + public static Integer getReceiver2Port(ServletContext ctx) { + String tPort = ctx.getInitParameter("receiver2Port"); + logger.info("Receiver2Port at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5091; + } + } + + public static Integer getServletContainerPort(ServletContext ctx) { + String cPort = ctx.getInitParameter("servletContainerPort"); + logger.info("TestPort at:" + cPort); + if (cPort != null) { + return Integer.valueOf(cPort); + } else { + return 5070; + } + } + +} diff --git a/sip-servlets-test-suite/applications/notifier-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/NotifierSipServlet.java b/sip-servlets-test-suite/applications/notifier-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/NotifierSipServlet.java index 16647a28bf..89cca6a768 100644 --- a/sip-servlets-test-suite/applications/notifier-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/NotifierSipServlet.java +++ b/sip-servlets-test-suite/applications/notifier-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/NotifierSipServlet.java @@ -1,196 +1,220 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite; - -import java.io.IOException; - -import javax.annotation.Resource; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.sip.SipApplicationSession; -import javax.servlet.sip.SipFactory; -import javax.servlet.sip.SipServlet; -import javax.servlet.sip.SipServletContextEvent; -import javax.servlet.sip.SipServletListener; -import javax.servlet.sip.SipServletRequest; -import javax.servlet.sip.SipServletResponse; -import javax.servlet.sip.SipSessionEvent; -import javax.servlet.sip.SipSessionListener; -import javax.servlet.sip.SipURI; -import javax.servlet.sip.URI; - -import org.apache.log4j.Logger; - -/** - * - * @author Jean Deruelle - * - */ -public class NotifierSipServlet extends SipServlet implements SipSessionListener, SipServletListener { - private static final long serialVersionUID = 1L; - private static transient Logger logger = Logger.getLogger(NotifierSipServlet.class); - private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; - private static final String SIP_SESSION_READY_TO_BE_INVALIDATED = "sipSessionReadyToBeInvalidated"; - - @Resource - SipFactory sipFactory; - - /** Creates a new instance of SimpleProxyServlet */ - public NotifierSipServlet() { - } - - @Override - public void init(ServletConfig servletConfig) throws ServletException { - logger.info("the notifier sip servlet has been started"); - super.init(servletConfig); - } - - /** - * {@inheritDoc} - */ - protected void doInvite(SipServletRequest request) throws ServletException, - IOException { - logger.info("from : " + request.getFrom()); - logger.info("Got request: " - + request.getMethod()); - - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_RINGING); - sipServletResponse.send(); - request.getSession().setAttribute("inviteReceived", "true"); - try { - Thread.sleep(2000); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - sipServletResponse = request.createResponse(SipServletResponse.SC_OK); - sipServletResponse.send(); - } - - @Override - protected void doErrorResponse(SipServletResponse resp) - throws ServletException, IOException { - logger.info("Got response: " - + resp); - if(!resp.getMethod().equalsIgnoreCase("BYE")) { - resp.getSession().createRequest("BYE").send(); - } - } - - /** - * {@inheritDoc} - */ - protected void doBye(SipServletRequest request) throws ServletException, - IOException { - - logger.info("Got BYE request: " + request); - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); - sipServletResponse.send(); - } - - /** - * {@inheritDoc} - */ - protected void doSubscribe(SipServletRequest request) throws ServletException, - IOException { - - logger.info("Got Subscribe: " - + request.getMethod()); - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); - request.getApplicationSession().setAttribute("sendMessage", "true"); - sipServletResponse.addHeader("Expires", request.getHeader("Expires")); - sipServletResponse.addHeader("Event", request.getHeader("Event")); - sipServletResponse.send(); - // send notify - SipServletRequest notifyRequest = request.getSession().createRequest("NOTIFY"); - if(request.isInitial() || request.getSession().getAttribute("inviteReceived") != null) { - request.getSession().removeAttribute("inviteReceived"); - notifyRequest.addHeader("Subscription-State", "pending"); - notifyRequest.addHeader("Event", "reg"); - notifyRequest.send(); - notifyRequest = request.getSession().createRequest("NOTIFY"); - } - if(request.getHeader("Expires").trim().equals("0")) { - notifyRequest.addHeader("Subscription-State", "terminated"); - } else { - notifyRequest.addHeader("Subscription-State", "active"); - } - notifyRequest.addHeader("Event", "reg"); - notifyRequest.send(); - } - - public void sessionCreated(SipSessionEvent se) { - // TODO Auto-generated method stub - - } - - public void sessionDestroyed(SipSessionEvent se) { - // TODO Auto-generated method stub - - } - - public void sessionReadyToInvalidate(SipSessionEvent se) { - logger.info("sip session ready To Invalidate " + se.getSession()); - - if(se.getSession().getApplicationSession().getAttribute("sendMessage") != null) { - try { - SipServletRequest sipServletRequest = sipFactory.createRequest( - sipFactory.createApplicationSession(), - "MESSAGE", - se.getSession().getLocalParty(), - se.getSession().getRemoteParty()); - SipURI sipUri=sipFactory.createSipURI("LittleGuy", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - sipServletRequest.setRequestURI(sipUri); - sipServletRequest.setContentLength(SIP_SESSION_READY_TO_BE_INVALIDATED.length()); - sipServletRequest.setContent(SIP_SESSION_READY_TO_BE_INVALIDATED, CONTENT_TYPE); - sipServletRequest.send(); - } catch (IOException e) { - logger.error("Exception occured while sending the request",e); - } - } - } - - public void servletInitialized(SipServletContextEvent ce) { - if(ce.getServletContext().getInitParameter("sendUnsollictedNotify") != null) { - SipFactory sipFactory = (SipFactory)ce.getServletContext().getAttribute(SIP_FACTORY); - SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); - - URI fromURI = sipFactory.createSipURI("UnsollictedNotify", "here.com"); - URI toURI = sipFactory.createSipURI("LittleGuy", "there.com"); - SipServletRequest sipServletRequest = - sipFactory.createRequest(sipApplicationSession, "NOTIFY", fromURI, toURI); - SipURI requestURI = sipFactory.createSipURI("LittleGuy", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - sipServletRequest.addHeader("Event", "aastra-xml"); - sipServletRequest.addHeader("Subscription-State", "pending"); - try { - sipServletRequest.setContent("", "application/xml"); - sipServletRequest.setRequestURI(requestURI); - sipServletRequest.getSession().setAttribute("sendUnsollictedNotify", Boolean.TRUE); - logger.info("session id " + sipServletRequest.getSession().getId()); - sipServletRequest.send(); - } catch (IOException e) { - logger.error("Unexpected exception while sending the request " + sipServletRequest, e); - } - } - } +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite; + +import java.io.IOException; + +import javax.annotation.Resource; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.sip.SipApplicationSession; +import javax.servlet.sip.SipFactory; +import javax.servlet.sip.SipServlet; +import javax.servlet.sip.SipServletContextEvent; +import javax.servlet.sip.SipServletListener; +import javax.servlet.sip.SipServletRequest; +import javax.servlet.sip.SipServletResponse; +import javax.servlet.sip.SipSessionEvent; +import javax.servlet.sip.SipSessionListener; +import javax.servlet.sip.SipURI; +import javax.servlet.sip.URI; + +import org.apache.log4j.Logger; + +/** + * + * @author Jean Deruelle + * + */ +public class NotifierSipServlet extends SipServlet implements SipSessionListener, SipServletListener { + private static final long serialVersionUID = 1L; + private static transient Logger logger = Logger.getLogger(NotifierSipServlet.class); + private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; + private static final String SIP_SESSION_READY_TO_BE_INVALIDATED = "sipSessionReadyToBeInvalidated"; + + @Resource + SipFactory sipFactory; + + static ServletContext ctx; + + /** Creates a new instance of SimpleProxyServlet */ + public NotifierSipServlet() { + } + + @Override + public void init(ServletConfig servletConfig) throws ServletException { + logger.info("the notifier sip servlet has been started"); + super.init(servletConfig); + ctx = servletConfig.getServletContext(); + } + + /** + * {@inheritDoc} + */ + protected void doInvite(SipServletRequest request) throws ServletException, + IOException { + logger.info("from : " + request.getFrom()); + logger.info("Got request: " + + request.getMethod()); + + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_RINGING); + sipServletResponse.send(); + request.getSession().setAttribute("inviteReceived", "true"); + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + sipServletResponse = request.createResponse(SipServletResponse.SC_OK); + sipServletResponse.send(); + } + + @Override + protected void doErrorResponse(SipServletResponse resp) + throws ServletException, IOException { + logger.info("Got response: " + + resp); + if(!resp.getMethod().equalsIgnoreCase("BYE")) { + resp.getSession().createRequest("BYE").send(); + } + } + + /** + * {@inheritDoc} + */ + protected void doBye(SipServletRequest request) throws ServletException, + IOException { + + logger.info("Got BYE request: " + request); + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); + sipServletResponse.send(); + } + + /** + * {@inheritDoc} + */ + protected void doSubscribe(SipServletRequest request) throws ServletException, + IOException { + + logger.info("Got Subscribe: " + + request.getMethod()); + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); + request.getApplicationSession().setAttribute("sendMessage", "true"); + sipServletResponse.addHeader("Expires", request.getHeader("Expires")); + sipServletResponse.addHeader("Event", request.getHeader("Event")); + sipServletResponse.send(); + // send notify + SipServletRequest notifyRequest = request.getSession().createRequest("NOTIFY"); + if(request.isInitial() || request.getSession().getAttribute("inviteReceived") != null) { + request.getSession().removeAttribute("inviteReceived"); + notifyRequest.addHeader("Subscription-State", "pending"); + notifyRequest.addHeader("Event", "reg"); + notifyRequest.send(); + notifyRequest = request.getSession().createRequest("NOTIFY"); + } + if(request.getHeader("Expires").trim().equals("0")) { + notifyRequest.addHeader("Subscription-State", "terminated"); + } else { + notifyRequest.addHeader("Subscription-State", "active"); + } + notifyRequest.addHeader("Event", "reg"); + notifyRequest.send(); + } + + public void sessionCreated(SipSessionEvent se) { + // TODO Auto-generated method stub + + } + + public void sessionDestroyed(SipSessionEvent se) { + // TODO Auto-generated method stub + + } + + public void sessionReadyToInvalidate(SipSessionEvent se) { + logger.info("sip session ready To Invalidate " + se.getSession()); + + if(se.getSession().getApplicationSession().getAttribute("sendMessage") != null) { + try { + SipServletRequest sipServletRequest = sipFactory.createRequest( + sipFactory.createApplicationSession(), + "MESSAGE", + se.getSession().getLocalParty(), + se.getSession().getRemoteParty()); + SipURI sipUri=sipFactory.createSipURI("LittleGuy", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + sipServletRequest.setRequestURI(sipUri); + sipServletRequest.setContentLength(SIP_SESSION_READY_TO_BE_INVALIDATED.length()); + sipServletRequest.setContent(SIP_SESSION_READY_TO_BE_INVALIDATED, CONTENT_TYPE); + sipServletRequest.send(); + } catch (IOException e) { + logger.error("Exception occured while sending the request",e); + } + } + } + + public void servletInitialized(SipServletContextEvent ce) { + if(ce.getServletContext().getInitParameter("sendUnsollictedNotify") != null) { + SipFactory sipFactory = (SipFactory)ce.getServletContext().getAttribute(SIP_FACTORY); + SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); + + URI fromURI = sipFactory.createSipURI("UnsollictedNotify", "here.com"); + URI toURI = sipFactory.createSipURI("LittleGuy", "there.com"); + SipServletRequest sipServletRequest = + sipFactory.createRequest(sipApplicationSession, "NOTIFY", fromURI, toURI); + SipURI requestURI = sipFactory.createSipURI("LittleGuy", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + sipServletRequest.addHeader("Event", "aastra-xml"); + sipServletRequest.addHeader("Subscription-State", "pending"); + try { + sipServletRequest.setContent("", "application/xml"); + sipServletRequest.setRequestURI(requestURI); + sipServletRequest.getSession().setAttribute("sendUnsollictedNotify", Boolean.TRUE); + logger.info("session id " + sipServletRequest.getSession().getId()); + sipServletRequest.send(); + } catch (IOException e) { + logger.error("Unexpected exception while sending the request " + sipServletRequest, e); + } + } + } + + public static Integer getTestPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("testPort"); + logger.info("TestPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5080; + } + } + + public static Integer getServletContainerPort(ServletContext ctx) { + String cPort = ctx.getInitParameter("servletContainerPort"); + logger.info("TestPort at:" + cPort); + if (cPort != null) { + return Integer.valueOf(cPort); + } else { + return 5070; + } + } } \ No newline at end of file diff --git a/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ProxySipServlet.java b/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ProxySipServlet.java index 2ad64d5bd8..a438e432e9 100644 --- a/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ProxySipServlet.java +++ b/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ProxySipServlet.java @@ -1,762 +1,826 @@ -/* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2014, Telestax Inc and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - * - * This file incorporates work covered by the following copyright contributed under the GNU LGPL : Copyright 2007-2011 Red Hat. - */ - -package org.mobicents.servlet.sip.testsuite; - -import java.io.IOException; -import java.io.Serializable; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import javax.annotation.Resource; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.sip.Address; -import javax.servlet.sip.Proxy; -import javax.servlet.sip.ProxyBranch; -import javax.servlet.sip.ServletParseException; -import javax.servlet.sip.ServletTimer; -import javax.servlet.sip.SipApplicationSession; -import javax.servlet.sip.SipApplicationSessionEvent; -import javax.servlet.sip.SipApplicationSessionListener; -import javax.servlet.sip.SipErrorEvent; -import javax.servlet.sip.SipErrorListener; -import javax.servlet.sip.SipFactory; -import javax.servlet.sip.SipServlet; -import javax.servlet.sip.SipServletRequest; -import javax.servlet.sip.SipServletResponse; -import javax.servlet.sip.SipSession; -import javax.servlet.sip.SipSessionEvent; -import javax.servlet.sip.SipSessionListener; -import javax.servlet.sip.SipURI; -import javax.servlet.sip.TimerListener; -import javax.servlet.sip.TimerService; -import javax.servlet.sip.TooManyHopsException; -import javax.servlet.sip.URI; - -import org.apache.log4j.Logger; -import org.mobicents.javax.servlet.sip.ProxyBranchListener; -import org.mobicents.javax.servlet.sip.ProxyExt; -import org.mobicents.javax.servlet.sip.ResponseType; -import org.mobicents.javax.servlet.sip.SipFactoryExt; -import org.mobicents.javax.servlet.sip.SipServletRequestExt; -import org.mobicents.javax.servlet.sip.SipServletResponseExt; -import org.mobicents.javax.servlet.sip.dns.DNSResolver; -import org.mobicents.servlet.sip.proxy.ProxyImpl; - -public class ProxySipServlet extends SipServlet implements SipErrorListener, ProxyBranchListener, SipSessionListener, SipApplicationSessionListener, TimerListener { - private static final String ERROR = "ERROR"; - private static final String SIP_APPLICATION_SESSION_TIMEOUT = "sipApplicationSessionTimeout"; - private static final long serialVersionUID = 1L; - private static transient Logger logger = Logger.getLogger(ProxySipServlet.class); - String host = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; - private static String USE_HOSTNAME = "useHostName"; - private static String CHECK_URI = "check_uri"; - private static String TEST_2_TRYING = "test_2_trying"; - private static String CHECK_READY_TO_INVALIDATE = "check_rti"; - private static String NON_RECORD_ROUTING = "nonRecordRouting"; - private static String RECORD_ROUTING = "recordRouting"; - private static String TEST_CREATE_SUBSEQUENT_REQUEST = "test_create_subsequent_request"; - private static String TEST_TERMINATION = "test_termination"; - private static String REGISTER_OUTBOUND = "register-outbound"; - private static String INVITE_INBOUND = "invite-inbound"; - private static final String BRANCHES = "branches"; - private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; - - @Resource TimerService timerService; - - @Override - public void init(ServletConfig servletConfig) throws ServletException { - logger.info("the proxy sip servlet has been started"); - super.init(servletConfig); - } - - @Override - protected void doRegister(SipServletRequest req) throws ServletException, - IOException { - SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); - req.getProxy().setAddToPath(true); - URI uri1 = sipFactory.createAddress("sip:receiver@" + host + ":5057").getURI(); - ((ProxyExt)req.getProxy()).setSipOutboundSupport(true); - req.getProxy().proxyTo(uri1); - } - - /** - * {@inheritDoc} - */ - @Override - protected void doInvite(SipServletRequest request) throws ServletException, - IOException { - - SipApplicationSession sas = request.getApplicationSession(); - logger.info("Got request:\n" + request.getMethod()); - SipServletRequestExt req = (SipServletRequestExt)request; - if(req.isOrphan() && !req.isInitial()) { - req.getSession().setAttribute("h", "hhh"); - return; - } - if(request.getFrom().toString().contains("popped-route-uri")) { - if (request.getPoppedRoute()== null || !request.getPoppedRoute().getURI().toString().contains("test.mobicents.org")) { - throw new IllegalArgumentException("We didn't have the expected test.mobicents.org in the following popped route " + request.getPoppedRoute()); - } else { - DNSResolver dnsResolver = (DNSResolver) getServletContext().getAttribute("org.mobicents.servlet.sip.DNS_RESOLVER"); - Set ipAddresses = dnsResolver.resolveHost(((SipURI)request.getPoppedRoute().getURI()).getHost()); - logger.info(ipAddresses.toArray().toString()); - if(!ipAddresses.contains("127.0.0.1")) { - throw new IllegalArgumentException("Couldn't resolve test.mobicents.org to 127.0.0.1"); - } - } - } - if(request.getFrom().toString().contains("proxy-orphan")) { - SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); - SipFactoryExt sipFactoryExt = (SipFactoryExt) sipFactory; - request.getApplicationSession(false); - sipFactoryExt.setRouteOrphanRequests(true); - Object o = getServletContext().getAttribute(javax.servlet.sip.SipServlet. OUTBOUND_INTERFACES); - request.getProxy().setRecordRoute(true); - request.getProxy().proxyTo(sipFactory.createURI("sip:a@127.0.0.1:5090;transport=udp")); - return; - } - if(request.getFrom().toString().contains("proxy-tcp")) { - SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); - Object o = getServletContext().getAttribute(javax.servlet.sip.SipServlet. OUTBOUND_INTERFACES); - request.getProxy().setRecordRoute(true); - request.getProxy().proxyTo(sipFactory.createURI("sip:a@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090;transport=tcp")); - return; - } - - if(request.getFrom().toString().contains("proxy-udp")) { - SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); - Object o = getServletContext().getAttribute(javax.servlet.sip.SipServlet. OUTBOUND_INTERFACES); - request.getProxy().setRecordRoute(true); - request.getProxy().proxyTo(sipFactory.createURI("sip:a@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090;transport=udp")); - return; - } - - if(request.getFrom().toString().contains("proxy-unspecified")) { - SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); - Object o = getServletContext().getAttribute(javax.servlet.sip.SipServlet. OUTBOUND_INTERFACES); - request.getProxy().setRecordRoute(true); - request.getProxy().proxyTo(sipFactory.createURI("sip:a@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090")); - return; - } - - if(request.getFrom().toString().contains("proxy-tls")) { - SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); - Object o = getServletContext().getAttribute(javax.servlet.sip.SipServlet. OUTBOUND_INTERFACES); - request.getProxy().setRecordRoute(true); - request.getProxy().proxyTo(sipFactory.createURI("sips:a@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090;transport=tls")); - return; - } - String error = (String) request.getApplicationSession().getAttribute(ERROR); - if(error != null) { - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_SERVER_INTERNAL_ERROR, error); - sipServletResponse.send(); - return; - } - final String from = request.getFrom().getURI().toString(); - SipURI fromURI = ((SipURI)request.getFrom().getURI()); - logger.info("invalidate when ready " - + request.getApplicationSession().getInvalidateWhenReady()); - if(fromURI.getUser().equals(CHECK_READY_TO_INVALIDATE)) { - if(!request.getApplicationSession().getInvalidateWhenReady()) { - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_SERVER_INTERNAL_ERROR); - sipServletResponse.send(); - return; - } - } - Address contactAddress = request.getAddressHeader("Contact"); - int contactPort = ((SipURI)contactAddress.getURI()).getPort(); - request.getApplicationSession().setAttribute("contactPort", contactPort); - request.getSession().setAttribute("contactPort", contactPort); - if(fromURI.getUser().equals(SIP_APPLICATION_SESSION_TIMEOUT)) { - logger.info("testing session expiration, setting invalidateWhenReady to false"); - request.getApplicationSession().setAttribute(SIP_APPLICATION_SESSION_TIMEOUT, "true"); - } - if(!request.isInitial()){ - if(request.getFrom().toString().contains("final-response-subsequent")) { - // https://code.google.com/p/sipservlets/issues/detail?id=21 - request.createResponse(491).send(); - } - return; - } - - //This is a proxying sample. - SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); - - if(fromURI.getUser().contains(USE_HOSTNAME)) { - host = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; - logger.info("using Host Name for proxy test"); - } - - URI uri1 = sipFactory.createAddress("sip:receiver@" + host + ":5057").getURI(); - URI uri2 = sipFactory.createAddress("sip:cutme@" + host + ":5056").getURI(); - URI uri3 = sipFactory.createAddress("sip:nonexist@" + host + ":5856").getURI(); - String via = request.getHeader("Via"); - String transport = "udp"; - if(via.contains("TCP") || via.contains("tcp")) { - transport = "tcp"; - logger.info("setting transport param to " + transport); - ((SipURI)uri1).setTransportParam(transport); - ((SipURI)uri2).setTransportParam(transport); - ((SipURI)uri3).setTransportParam(transport); - request.getApplicationSession().setAttribute("transport", transport); - request.getSession().setAttribute("transport", transport); - } else { - request.getApplicationSession().setAttribute("transport", transport); - request.getSession().setAttribute("transport", transport); - } - - if(from.contains("forward-sender-downstream-proxy")) { - URI uri = sipFactory.createAddress("sip:receiver@" + host + ":5070").getURI(); - Proxy proxy = request.getProxy(); - proxy.setParallel(false); - proxy.setRecordRoute(true); - proxy.setProxyTimeout(5); - logger.info("proxying to downstream proxy" + uri); - proxy.proxyTo(uri); - return; - } - - if(from.contains("unique-location-urn")) { - Proxy proxy = request.getProxy(); - proxy.setParallel(false); - proxy.setRecordRoute(true); - proxy.setProxyTimeout(5); - logger.info("proxying to downstream proxy" + request.getRequestURI()); - if(from.contains("push-route-app-server")) { - logger.info("Max Forwards " + request.getHeader("Max-Forwards")); - if(request.getHeader("Max-Forwards").equalsIgnoreCase("70")) { - logger.info("proxying to downstream app server on port 5069"); - // only the first hop proxy to the second server or the second server will endlessly route to itself - URI uriAppServer = sipFactory.createAddress("sip:receiver@" + host + ":5069").getURI(); - request.pushRoute((SipURI)uriAppServer); - proxy.proxyTo(request.getRequestURI()); - return; - } - } else if(from.contains("route")) { - request.pushRoute((SipURI)uri1); - } - if(from.contains("uri1")) { - proxy.proxyTo(uri1); - } else { - proxy.proxyTo(request.getRequestURI()); - } - return; - } - - if(from.contains("sequential")) { - Proxy proxy = request.getProxy(); - proxy.setParallel(false); - proxy.setProxyTimeout(5); - if(from.contains("1xxResponseTimeout")) { - ((ProxyExt)proxy).setProxy1xxTimeout(1); - } - if(from.contains("finalResponseTimeout")) { - proxy.setProxyTimeout(2); - } - proxy.setRecordRoute(true); - ArrayList uris = new ArrayList(); - if(from.contains("sequential-reverse")) { - uris.add(uri1); - if(!from.contains("sequential-reverse-one")) { - uris.add(uri2); - } - } else if(from.contains("sequential-three")) { - uris.add(uri3); - uris.add(uri2); - uris.add(uri1); - } else if(from.contains("sequential-cut")) { - uris.add(uri2); - } else if(from.contains("nonexist-1xx")) { - uris.add(uri3); - proxy.setProxyTimeout(40); - ((ProxyExt)proxy).setProxy1xxTimeout(1); - } else if(from.contains("nonexist")) { - uris.add(uri3); - proxy.setProxyTimeout(40); - } else if(from.contains("cancel-480-sequential-2-locations")) { - uris.add(uri1); - proxy.setProxyTimeout(140); - } else { - uris.add(uri2); - uris.add(uri1); - } - - proxy.proxyTo(uris); - } else { - Proxy proxy = request.getProxy(); - ArrayList uris = new ArrayList(); - uris.add(uri1); - if(!fromURI.getUser().contains("unique-location") && !fromURI.getUser().contains("prack") && !fromURI.getUser().contains(REGISTER_OUTBOUND)) { - uris.add(uri2); - } - if(fromURI.getUser().contains(REGISTER_OUTBOUND)) { - ((ProxyExt)proxy).setSipOutboundSupport(true); - } - if(fromURI.getUser().contains(INVITE_INBOUND)) { - ((ProxyExt)proxy).setSipOutboundSupport(true); - uris.clear(); - SipURI sipURI = sipFactory.createSipURI("receiver", host ); - sipURI.setPort(5080); - if(via.contains("TCP") || via.contains("tcp")) { - sipURI.setTransportParam("tcp"); - uris.add(sipURI); - } else { - uris.add(sipURI); - } - } - List outboundInterfaces = (List)getServletContext().getAttribute(OUTBOUND_INTERFACES); - - if(outboundInterfaces == null) throw new NullPointerException("Outbound interfaces should not be null"); - - SipURI obi = null; - - for(SipURI uri:outboundInterfaces) { - logger.info("Outbound interface : " + uri); - if(uri.toString().indexOf("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "")>0 && uri.getTransportParam().equalsIgnoreCase(transport)) { - - // pick the lo interface, since its universal on all machines - proxy.setOutboundInterface(new InetSocketAddress(InetAddress.getByName(uri.getHost()),uri.getPort())); - obi = uri; - break; - } - if(System.getProperty("org.mobicents.testsuite.testhostaddr").contains("::1")) { - if(uri.toString().contains(":1")) { - obi = uri;break; - } - } - } - - if(obi == null) throw new NullPointerException("No loopback interface found."); - - boolean recordRoute = true; - if(fromURI.getUser().contains(NON_RECORD_ROUTING)) { - recordRoute = false; - logger.info("not record routing"); - } - if(fromURI.getUser().contains(TEST_TERMINATION)) { - ((ProxyExt)proxy).storeTerminationInformation(true); - logger.info("testing termination"); - } - //proxy.setOutboundInterface((SipURI)sipFactory.createAddress("sip:proxy@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070").getURI()); - proxy.setRecordRoute(recordRoute); - proxy.setSupervised(true); - if(recordRoute) { - if(fromURI.getUser().contains("record-route-uri")) { - ((ProxyExt)proxy).setRecordRouteURI(sipFactory.createSipURI(null, "localhost")); - } - proxy.getRecordRouteURI().setParameter("testparamname", "TESTVALUE"); - if((via.contains("TCP") || via.contains("tcp")) && fromURI.getUser().contains("tcp-record-route-tcp")) { - proxy.getRecordRouteURI().setTransportParam("TCP"); - uri1.removeParameter("transport"); - } - } - proxy.setParallel(true); - if(CHECK_URI.equals(fromURI.getUser())) { - Address routeAddress = sipFactory.createAddress("sip:" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5057"); - request.pushRoute(routeAddress); - Address ra = request.getAddressHeader("Route"); - logger.info("doInvite: ra = " + ra); - URI uri = ra.getURI(); // this causes NPE - logger.info("doInvite: uri = " + uri); - proxy.setParallel(false); - } - if (from.contains("update") || from.contains("prack") || from.contains("redirect") || from.contains("cancel")){ - proxy.setProxyTimeout(40); - } else { - proxy.setProxyTimeout(4); - } - if(TEST_2_TRYING.equals(fromURI.getUser())) { - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - if(fromURI.getUser().contains(BRANCHES)) { - List proxyBranches = proxy.createProxyBranches(uris); - for(ProxyBranch proxyBranch : proxyBranches) { - proxyBranch.getRequest().setContent("test", CONTENT_TYPE); - } - proxy.startProxy(); - } else { - proxy.proxyTo(uris); - } - } - } - - @Override - protected void doAck(SipServletRequest request) throws ServletException, - IOException { - logger.info("Got request:\n" + request); - - SipURI fromURI = ((SipURI)request.getFrom().getURI()); - String from = fromURI.toString(); - if(request.getFrom().toString().contains("proxy-orphan")) { - request.getSession().invalidate(); - request.getApplicationSession().invalidate(); - return; - } - if(from.contains("unique-location-urn-route")) { - SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); - URI uri1 = sipFactory.createAddress("sip:receiver@" + host + ":5057").getURI(); - if(from.contains("tcp")) { - ((SipURI)uri1).setTransportParam("tcp"); - } - request.pushRoute((SipURI)uri1); - } - - if(from.contains("unique-location-ack-seen-by-app") && request.getHeader("CSeq").contains("2")) { - sendMessage("ack-seen-by-app", 5080, "udp"); - } - - if(from.contains(TEST_TERMINATION)) { - timerService.createTimer(request.getApplicationSession(), 10000, false, (Serializable) request); - } - } - - /** - * {@inheritDoc} - */ - protected void doBye(SipServletRequest request) throws ServletException, - IOException { - if(fail) { - request.createResponse(500).send(); - throw new ServletException("Failed because of double response"); - } - logger.info("Got BYE request:\n" + request); - SipURI fromURI = ((SipURI)request.getFrom().getURI()); - String from = fromURI.toString(); - SipServletRequestExt sipServletRequestExt = (SipServletRequestExt) request; - if(sipServletRequestExt.isOrphan()) return; - if(from.contains("unique-location-urn-route")) { - SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); - URI uri1 = sipFactory.createAddress("sip:receiver@" + host + ":5057").getURI(); - if(from.contains("tcp")) { - ((SipURI)uri1).setTransportParam("tcp"); - } - request.pushRoute((SipURI)uri1); - } - - if(fromURI.toString().contains(TEST_CREATE_SUBSEQUENT_REQUEST)) { - try { - request.getSession().createRequest("BYE"); - } catch(IllegalStateException ise) { - logger.error("Got expected IllegalStateException on trying to create a subsequent request on a proxy session", ise); - throw ise; - } - } - - SipServletResponse sipServletResponse = request.createResponse(200); - - // If the branchResponse callback was called we are good otherwise fail by - // not delivering OK to BYE - String doBranchRespValue = (String) request.getApplicationSession().getAttribute("branchResponseReceived"); - if("true".equals(doBranchRespValue)) -// sipServletResponse.send(); - - - logger.info("invalidate when ready " - + request.getApplicationSession().getInvalidateWhenReady()); - if(fromURI.getUser().equals(CHECK_READY_TO_INVALIDATE)) { - request.getApplicationSession().setExpires(1); - } - } - - long lastOKstamp=0; - SipServletResponse oldResp; - boolean fail; - - /** - * {@inheritDoc} - */ - protected void doResponse(SipServletResponse response) - throws ServletException, IOException { - - logger.info("Got response: " + response); - logger.info("Sip Session is :" + response.getSession(false)); - if(response.getApplicationSession(false) != null) { - Iterator it = (Iterator) response.getApplicationSession(false).getSessions("SIP"); - logger.debug("dumping sip session list"); - int i = 0; - while (it.hasNext()) { - SipSession sipSession = it.next(); - logger.debug("sip session " + sipSession.getId()); - i++; - } - logger.debug("Number of SIP Sessions is :" + i); - } - SipServletResponseExt sipServletResponseExt = (SipServletResponseExt) response; - SipApplicationSession sas = response.getApplicationSession(); - SipServletRequest re = response.getRequest(); -// re.getCallId(); - if(sipServletResponseExt.isOrphan()) { - sipServletResponseExt.getApplicationSession(false); - return; - } - SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); - SipFactoryExt ext = (SipFactoryExt)sipFactory; - if(!ext.isRouteOrphanRequests()) { // not to break the orphan test - long delta = Math.abs(System.currentTimeMillis() - lastOKstamp); - if(response.getStatus() == 200) { - if(delta < 20 & oldResp != null && response != null && oldResp.getCallId().equals(response.getCallId())) { - fail = true; - throw new ServletException("Problem with double response delta=" + delta + "\n1:" + oldResp + "\n2:" - + response); - // This means we receive two responses within 20ms which can't be a retransmission but an indication of a bug delivering responses twice http://code.google.com/p/mobicents/issues/detail?id=2821 - } - lastOKstamp = System.currentTimeMillis(); - oldResp = response; - } - } - - - if(!"PRACK".equals(response.getMethod()) && response.getProxy() != null && response.getProxy().getOriginalRequest() != null) { - logger.info("Original Sip Session is :" + response.getProxy().getOriginalRequest().getSession(false)); - } - if(response.getFrom().getURI().toString().contains("sequential-retransmission")) { - if(response.getMethod().equals("INVITE")) { - if(response.getStatus() == 200) { - String lastOK = (String) response.getSession().getAttribute("lastOK"); - if(lastOK != null) { - if(!response.toString().equals(lastOK)) { - // We expect to see the retransmissions. Fail the whole test in an ugly way otherwise. - System.out.print("ERROR ERROR ERROR : // We expect to see the retransmissions. Fail the whole test in an ugly way otherwise.\nERROR\ndsfdsf\n\n\n\n\n\n\nERROR'n"); - System.exit(0); - } - } - response.getSession().setAttribute("lastOK", response.toString()); - } - } - } - response.toString(); - if(response.getMethod().equalsIgnoreCase("BYE")) { - response.addHeader("X-Proxy-Transactions", "" + ((ProxyImpl)response.getProxy()).getTransactionMap().size()); - } - super.doResponse(response); - } - - @Override - protected void doSuccessResponse(SipServletResponse response) - throws ServletException, IOException { - if(response.getFrom().getURI().toString().contains("modify-SDP")) { - if(response.getMethod().equals("INVITE")) { - if(response.getStatus() == 200) { - response.setContentType(CONTENT_TYPE); - response.setContent("SDP modified successfully".getBytes("UTF-8"),CONTENT_TYPE); - } - } - } - } - - @Override - protected void doBranchResponse(SipServletResponse response) - throws ServletException, IOException { - - logger.info("doBranchResponse callback was called " + response); - response.getApplicationSession().setAttribute("branchResponseReceived", "true"); - if(response.getStatus() == 408) { - sendMessage("doBranchTimeoutReceived", 5080, "udp"); - } - if(response.getStatus() == 480) { - // https://code.google.com/p/sipservlets/issues/detail?id=266 - SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); - ArrayList uris = new ArrayList(); - // This URi completes and need to be canceled before answering - uris.add(sipFactory.createAddress("sip:neutral@" + host + ":5058").getURI()); - List branches = response.getProxy().createProxyBranches(uris); - for (ProxyBranch proxyBranch : branches) { - if(response.getFrom().getURI().toString().contains("change-to-user")) { - // https://code.google.com/p/sipservlets/issues/detail?id=154 - Address toHeader = proxyBranch.getRequest().getAddressHeader("To"); - SipURI toSipURI = (SipURI) toHeader.getURI(); - toSipURI.setUser("newuser"); - } - } - response.getProxy().startProxy(); - } - } - - // SipErrorListener methods - - /** - * {@inheritDoc} - */ - public void noAckReceived(SipErrorEvent ee) { - logger.error("noAckReceived."); - } - - /** - * {@inheritDoc} - */ - public void noPrackReceived(SipErrorEvent ee) { - logger.error("noPrackReceived."); - } - - @Override - protected void doSubscribe(SipServletRequest req) throws ServletException, IOException - { - if(req.isInitial()) { - SipURI uri = (SipURI)req.getRequestURI().clone(); - uri.setPort(5057); - req.pushRoute(uri); - Proxy proxy = req.getProxy(true); - final String from = req.getFrom().getURI().toString(); - if(from.contains(RECORD_ROUTING)) { - proxy.setRecordRoute(true); - } - proxy.proxyTo(req.getRequestURI()); - } - } - - @Override - protected void doPublish(SipServletRequest req) throws ServletException, IOException - { - SipURI uri = (SipURI)req.getRequestURI().clone(); - uri.setPort(5057); - req.pushRoute(uri); - req.getProxy(true).proxyTo(req.getRequestURI()); - } - - @Override - protected void doCancel(SipServletRequest req) throws ServletException, - IOException { - logger.error("CANCEL seen at proxy " + req); - } - /* - * (non-Javadoc) - * @see org.mobicents.javax.servlet.sip.ProxyBranchListener#onProxyBranchResponseTimeout(org.mobicents.javax.servlet.sip.ResponseType, javax.servlet.sip.ProxyBranch) - */ - public void onProxyBranchResponseTimeout(ResponseType responseType, - ProxyBranch proxyBranch) { - logger.info("onProxyBranchResponseTimeout callback was called. responseType = " + responseType + " , branch = " + proxyBranch + ", request " + proxyBranch.getRequest() + ", response " + proxyBranch.getResponse()); - if(proxyBranch.getRequest() != null && (proxyBranch.getRequest().getFrom().getURI().toString().contains("ResponseTimeout") || proxyBranch.getRequest().getFrom().getURI().toString().contains("unique-location"))) { - sendMessage(responseType.toString(), 5080, "udp"); - } - } - - /** - * @param sipApplicationSession - * @param storedFactory - */ - private void sendMessage(String content, int port, String transport) { - try { - SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); - SipServletRequest sipServletRequest = sipFactory.createRequest( - sipFactory.createApplicationSession(), - "MESSAGE", - "sip:sender@sip-servlets.com", - "sip:receiver@sip-servlets.com"); - SipURI sipUri = sipFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":"+ port); - sipUri.setTransportParam(transport); - sipServletRequest.setRequestURI(sipUri); - sipServletRequest.setContentLength(content.length()); - sipServletRequest.setContent(content, CONTENT_TYPE); - sipServletRequest.send(); - } catch (ServletParseException e) { - logger.error("Exception occured while parsing the addresses",e); - } catch (IOException e) { - logger.error("Exception occured while sending the request",e); - } - } - - public void sessionCreated(SipApplicationSessionEvent ev) { - logger.info("sessionCreated " + ev.getApplicationSession().getId()); - String expires = getServletContext().getInitParameter(SIP_APPLICATION_SESSION_TIMEOUT); - if(expires != null) { - logger.info("setting expires to " + expires); - long now = System.currentTimeMillis(); - ev.getApplicationSession().setExpires(Integer.valueOf(expires)); - long expirationTime = ev.getApplicationSession().getExpirationTime(); - logger.info("expirationTime " + expirationTime); - if(expirationTime < (now + (Integer.valueOf(expires) * 60 * 1000L))) { - ev.getApplicationSession().setAttribute(ERROR, "sip App Sesion getExpirationTime() returns incorrect value"); - } - } - } - - public void sessionDestroyed(SipApplicationSessionEvent ev) { - logger.info("sessionDestroyed " + ev.getApplicationSession().getId()); - } - - public void sessionExpired(SipApplicationSessionEvent ev) { - logger.info("sessionExpired " + ev.getApplicationSession().getId()); - if(ev.getApplicationSession().getAttribute(SIP_APPLICATION_SESSION_TIMEOUT) != null) { - sendMessage("sessionExpired", (Integer) ev.getApplicationSession().getAttribute("contactPort"), (String) ev.getApplicationSession().getAttribute("transport")); - } - } - - public void sessionReadyToInvalidate(SipApplicationSessionEvent ev) { - logger.info("sessionReadyToInvalidate " + ev.getApplicationSession().getId()); - if(ev.getApplicationSession().getAttribute("contactPort") != null) { - sendMessage("sessionReadyToInvalidate", (Integer) ev.getApplicationSession().getAttribute("contactPort"), (String) ev.getApplicationSession().getAttribute("transport")); - if(ev.getApplicationSession().getAttribute(SIP_APPLICATION_SESSION_TIMEOUT) != null) { - ev.getApplicationSession().setInvalidateWhenReady(false); - } - } - } - - public void sessionCreated(SipSessionEvent se) { - // TODO Auto-generated method stub - - } - - public void sessionDestroyed(SipSessionEvent se) { - // TODO Auto-generated method stub - - } - - public void sessionReadyToInvalidate(SipSessionEvent se) { - logger.info("sipSessionReadyToInvalidate " + se.getSession().getId()); - if(se.getSession().getAttribute("contactPort") != null) { - sendMessage("sipSessionReadyToInvalidate", (Integer) se.getSession().getAttribute("contactPort"), (String) se.getSession().getAttribute("transport")); - } - } - - @Override - protected void doUpdate(SipServletRequest req) throws ServletException, IOException { - logger.info("Got request:\n "+req); - } - - //@Override - public void timeout(ServletTimer timer) { - SipServletRequest request = (SipServletRequest)timer.getInfo(); - try { - ((ProxyExt)request.getProxy()).terminateSession(request.getSession(), 500, "Testing termination", 500, "Testing Termination"); - } catch (IllegalStateException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (TooManyHopsException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } -} +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2014, Telestax Inc and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * + * This file incorporates work covered by the following copyright contributed under the GNU LGPL : Copyright 2007-2011 Red Hat. + */ + +package org.mobicents.servlet.sip.testsuite; + +import java.io.IOException; +import java.io.Serializable; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import javax.annotation.Resource; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.sip.Address; +import javax.servlet.sip.Proxy; +import javax.servlet.sip.ProxyBranch; +import javax.servlet.sip.ServletParseException; +import javax.servlet.sip.ServletTimer; +import javax.servlet.sip.SipApplicationSession; +import javax.servlet.sip.SipApplicationSessionEvent; +import javax.servlet.sip.SipApplicationSessionListener; +import javax.servlet.sip.SipErrorEvent; +import javax.servlet.sip.SipErrorListener; +import javax.servlet.sip.SipFactory; +import javax.servlet.sip.SipServlet; +import javax.servlet.sip.SipServletRequest; +import javax.servlet.sip.SipServletResponse; +import javax.servlet.sip.SipSession; +import javax.servlet.sip.SipSessionEvent; +import javax.servlet.sip.SipSessionListener; +import javax.servlet.sip.SipURI; +import javax.servlet.sip.TimerListener; +import javax.servlet.sip.TimerService; +import javax.servlet.sip.TooManyHopsException; +import javax.servlet.sip.URI; + +import org.apache.log4j.Logger; +import org.mobicents.javax.servlet.sip.ProxyBranchListener; +import org.mobicents.javax.servlet.sip.ProxyExt; +import org.mobicents.javax.servlet.sip.ResponseType; +import org.mobicents.javax.servlet.sip.SipFactoryExt; +import org.mobicents.javax.servlet.sip.SipServletRequestExt; +import org.mobicents.javax.servlet.sip.SipServletResponseExt; +import org.mobicents.javax.servlet.sip.dns.DNSResolver; +import org.mobicents.servlet.sip.proxy.ProxyImpl; + +public class ProxySipServlet extends SipServlet implements SipErrorListener, ProxyBranchListener, SipSessionListener, SipApplicationSessionListener, TimerListener { + private static final String ERROR = "ERROR"; + private static final String SIP_APPLICATION_SESSION_TIMEOUT = "sipApplicationSessionTimeout"; + private static final long serialVersionUID = 1L; + private static transient Logger logger = Logger.getLogger(ProxySipServlet.class); + String host = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; + private static String USE_HOSTNAME = "useHostName"; + private static String CHECK_URI = "check_uri"; + private static String TEST_2_TRYING = "test_2_trying"; + private static String CHECK_READY_TO_INVALIDATE = "check_rti"; + private static String NON_RECORD_ROUTING = "nonRecordRouting"; + private static String RECORD_ROUTING = "recordRouting"; + private static String TEST_CREATE_SUBSEQUENT_REQUEST = "test_create_subsequent_request"; + private static String TEST_TERMINATION = "test_termination"; + private static String REGISTER_OUTBOUND = "register-outbound"; + private static String INVITE_INBOUND = "invite-inbound"; + private static final String BRANCHES = "branches"; + private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; + + @Resource TimerService timerService; + + static ServletContext ctx; + + @Override + public void init(ServletConfig servletConfig) throws ServletException { + logger.info("the proxy sip servlet has been started"); + super.init(servletConfig); + ctx = servletConfig.getServletContext(); + } + + @Override + protected void doRegister(SipServletRequest req) throws ServletException, + IOException { + SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); + req.getProxy().setAddToPath(true); + URI uri1 = sipFactory.createAddress("sip:receiver@" + host + ":" + getReceiverPort(ctx)).getURI(); + ((ProxyExt)req.getProxy()).setSipOutboundSupport(true); + req.getProxy().proxyTo(uri1); + } + + /** + * {@inheritDoc} + */ + @Override + protected void doInvite(SipServletRequest request) throws ServletException, + IOException { + + SipApplicationSession sas = request.getApplicationSession(); + logger.info("Got request:\n" + request.getMethod()); + SipServletRequestExt req = (SipServletRequestExt)request; + if(req.isOrphan() && !req.isInitial()) { + req.getSession().setAttribute("h", "hhh"); + return; + } + if(request.getFrom().toString().contains("popped-route-uri")) { + if (request.getPoppedRoute()== null || !request.getPoppedRoute().getURI().toString().contains("test.mobicents.org")) { + throw new IllegalArgumentException("We didn't have the expected test.mobicents.org in the following popped route " + request.getPoppedRoute()); + } else { + DNSResolver dnsResolver = (DNSResolver) getServletContext().getAttribute("org.mobicents.servlet.sip.DNS_RESOLVER"); + Set ipAddresses = dnsResolver.resolveHost(((SipURI)request.getPoppedRoute().getURI()).getHost()); + logger.info(ipAddresses.toArray().toString()); + if(!ipAddresses.contains("127.0.0.1")) { + throw new IllegalArgumentException("Couldn't resolve test.mobicents.org to 127.0.0.1"); + } + } + } + if(request.getFrom().toString().contains("proxy-orphan")) { + SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); + SipFactoryExt sipFactoryExt = (SipFactoryExt) sipFactory; + request.getApplicationSession(false); + sipFactoryExt.setRouteOrphanRequests(true); + Object o = getServletContext().getAttribute(javax.servlet.sip.SipServlet. OUTBOUND_INTERFACES); + request.getProxy().setRecordRoute(true); + request.getProxy().proxyTo(sipFactory.createURI("sip:a@127.0.0.1:" + getReceiverPort(ctx) + ";transport=udp")); + return; + } + if(request.getFrom().toString().contains("proxy-tcp")) { + SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); + Object o = getServletContext().getAttribute(javax.servlet.sip.SipServlet. OUTBOUND_INTERFACES); + request.getProxy().setRecordRoute(true); + request.getProxy().proxyTo(sipFactory.createURI("sip:a@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getReceiverPort(ctx) + ";transport=tcp")); + return; + } + + if(request.getFrom().toString().contains("proxy-udp")) { + SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); + Object o = getServletContext().getAttribute(javax.servlet.sip.SipServlet. OUTBOUND_INTERFACES); + request.getProxy().setRecordRoute(true); + request.getProxy().proxyTo(sipFactory.createURI("sip:a@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getReceiverPort(ctx) + ";transport=udp")); + return; + } + + if(request.getFrom().toString().contains("proxy-unspecified")) { + SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); + Object o = getServletContext().getAttribute(javax.servlet.sip.SipServlet. OUTBOUND_INTERFACES); + request.getProxy().setRecordRoute(true); + request.getProxy().proxyTo(sipFactory.createURI("sip:a@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getReceiverPort(ctx))); + return; + } + + if(request.getFrom().toString().contains("proxy-tls")) { + SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); + Object o = getServletContext().getAttribute(javax.servlet.sip.SipServlet. OUTBOUND_INTERFACES); + request.getProxy().setRecordRoute(true); + request.getProxy().proxyTo(sipFactory.createURI("sips:a@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getReceiverPort(ctx) + ";transport=tls")); + return; + } + String error = (String) request.getApplicationSession().getAttribute(ERROR); + if(error != null) { + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_SERVER_INTERNAL_ERROR, error); + sipServletResponse.send(); + return; + } + final String from = request.getFrom().getURI().toString(); + SipURI fromURI = ((SipURI)request.getFrom().getURI()); + logger.info("invalidate when ready " + + request.getApplicationSession().getInvalidateWhenReady()); + if(fromURI.getUser().equals(CHECK_READY_TO_INVALIDATE)) { + if(!request.getApplicationSession().getInvalidateWhenReady()) { + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_SERVER_INTERNAL_ERROR); + sipServletResponse.send(); + return; + } + } + Address contactAddress = request.getAddressHeader("Contact"); + int contactPort = ((SipURI)contactAddress.getURI()).getPort(); + request.getApplicationSession().setAttribute("contactPort", contactPort); + request.getSession().setAttribute("contactPort", contactPort); + if(fromURI.getUser().equals(SIP_APPLICATION_SESSION_TIMEOUT)) { + logger.info("testing session expiration, setting invalidateWhenReady to false"); + request.getApplicationSession().setAttribute(SIP_APPLICATION_SESSION_TIMEOUT, "true"); + } + if(!request.isInitial()){ + if(request.getFrom().toString().contains("final-response-subsequent")) { + // https://code.google.com/p/sipservlets/issues/detail?id=21 + request.createResponse(491).send(); + } + return; + } + + //This is a proxying sample. + SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); + + if(fromURI.getUser().contains(USE_HOSTNAME)) { + host = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; + logger.info("using Host Name for proxy test"); + } + + URI uri1 = sipFactory.createAddress("sip:receiver@" + host + ":" + getReceiverPort(ctx)).getURI(); + URI uri2 = sipFactory.createAddress("sip:cutme@" + host + ":" + getCutmePort(ctx)).getURI(); + URI uri3 = sipFactory.createAddress("sip:nonexist@" + host + ":5856").getURI(); + String via = request.getHeader("Via"); + String transport = "udp"; + if(via.contains("TCP") || via.contains("tcp")) { + transport = "tcp"; + logger.info("setting transport param to " + transport); + ((SipURI)uri1).setTransportParam(transport); + ((SipURI)uri2).setTransportParam(transport); + ((SipURI)uri3).setTransportParam(transport); + request.getApplicationSession().setAttribute("transport", transport); + request.getSession().setAttribute("transport", transport); + } else { + request.getApplicationSession().setAttribute("transport", transport); + request.getSession().setAttribute("transport", transport); + } + + if(from.contains("forward-sender-downstream-proxy")) { + URI uri = sipFactory.createAddress("sip:receiver@" + host + ":" + getReceiverPort(ctx)).getURI(); + Proxy proxy = request.getProxy(); + proxy.setParallel(false); + proxy.setRecordRoute(true); + proxy.setProxyTimeout(5); + logger.info("proxying to downstream proxy" + uri); + proxy.proxyTo(uri); + return; + } + + if(from.contains("unique-location-urn")) { + Proxy proxy = request.getProxy(); + proxy.setParallel(false); + proxy.setRecordRoute(true); + proxy.setProxyTimeout(5); + logger.info("proxying to downstream proxy" + request.getRequestURI()); + if(from.contains("push-route-app-server")) { + logger.info("Max Forwards " + request.getHeader("Max-Forwards")); + if(request.getHeader("Max-Forwards").equalsIgnoreCase("70")) { + logger.info("proxying to downstream app server on port " + getDownstreamContainerPort(ctx)); + // only the first hop proxy to the second server or the second server will endlessly route to itself + URI uriAppServer = sipFactory.createAddress("sip:receiver@" + host + ":" + getDownstreamContainerPort(ctx)).getURI(); + request.pushRoute((SipURI)uriAppServer); + proxy.proxyTo(request.getRequestURI()); + return; + } + } else if(from.contains("route")) { + request.pushRoute((SipURI)uri1); + } + if(from.contains("uri1")) { + proxy.proxyTo(uri1); + } else { + proxy.proxyTo(request.getRequestURI()); + } + return; + } + + if(from.contains("sequential")) { + Proxy proxy = request.getProxy(); + proxy.setParallel(false); + proxy.setProxyTimeout(5); + if(from.contains("1xxResponseTimeout")) { + ((ProxyExt)proxy).setProxy1xxTimeout(1); + } + if(from.contains("finalResponseTimeout")) { + proxy.setProxyTimeout(2); + } + proxy.setRecordRoute(true); + ArrayList uris = new ArrayList(); + if(from.contains("sequential-reverse")) { + uris.add(uri1); + if(!from.contains("sequential-reverse-one")) { + uris.add(uri2); + } + } else if(from.contains("sequential-three")) { + uris.add(uri3); + uris.add(uri2); + uris.add(uri1); + } else if(from.contains("sequential-cut")) { + uris.add(uri2); + } else if(from.contains("nonexist-1xx")) { + uris.add(uri3); + proxy.setProxyTimeout(40); + ((ProxyExt)proxy).setProxy1xxTimeout(1); + } else if(from.contains("nonexist")) { + uris.add(uri3); + proxy.setProxyTimeout(40); + } else if(from.contains("cancel-480-sequential-2-locations")) { + uris.add(uri1); + proxy.setProxyTimeout(140); + } else { + uris.add(uri2); + uris.add(uri1); + } + + proxy.proxyTo(uris); + } else { + Proxy proxy = request.getProxy(); + ArrayList uris = new ArrayList(); + uris.add(uri1); + if(!fromURI.getUser().contains("unique-location") && !fromURI.getUser().contains("prack") && !fromURI.getUser().contains(REGISTER_OUTBOUND)) { + uris.add(uri2); + } + if(fromURI.getUser().contains(REGISTER_OUTBOUND)) { + ((ProxyExt)proxy).setSipOutboundSupport(true); + } + if(fromURI.getUser().contains(INVITE_INBOUND)) { + ((ProxyExt)proxy).setSipOutboundSupport(true); + uris.clear(); + SipURI sipURI = sipFactory.createSipURI("receiver", host ); + sipURI.setPort(getTestPort(ctx)); + if(via.contains("TCP") || via.contains("tcp")) { + sipURI.setTransportParam("tcp"); + uris.add(sipURI); + } else { + uris.add(sipURI); + } + } + List outboundInterfaces = (List)getServletContext().getAttribute(OUTBOUND_INTERFACES); + + if(outboundInterfaces == null) throw new NullPointerException("Outbound interfaces should not be null"); + + SipURI obi = null; + + for(SipURI uri:outboundInterfaces) { + logger.info("Outbound interface : " + uri); + if(uri.toString().indexOf("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "")>0 && uri.getTransportParam().equalsIgnoreCase(transport)) { + + // pick the lo interface, since its universal on all machines + proxy.setOutboundInterface(new InetSocketAddress(InetAddress.getByName(uri.getHost()),uri.getPort())); + obi = uri; + break; + } + if(System.getProperty("org.mobicents.testsuite.testhostaddr").contains("::1")) { + if(uri.toString().contains(":1")) { + obi = uri;break; + } + } + } + + if(obi == null) throw new NullPointerException("No loopback interface found."); + + boolean recordRoute = true; + if(fromURI.getUser().contains(NON_RECORD_ROUTING)) { + recordRoute = false; + logger.info("not record routing"); + } + if(fromURI.getUser().contains(TEST_TERMINATION)) { + ((ProxyExt)proxy).storeTerminationInformation(true); + logger.info("testing termination"); + } + //proxy.setOutboundInterface((SipURI)sipFactory.createAddress("sip:proxy@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" ":" + getServletContainerPort(ctx)).getURI()); + proxy.setRecordRoute(recordRoute); + proxy.setSupervised(true); + if(recordRoute) { + if(fromURI.getUser().contains("record-route-uri")) { + ((ProxyExt)proxy).setRecordRouteURI(sipFactory.createSipURI(null, "localhost")); + } + proxy.getRecordRouteURI().setParameter("testparamname", "TESTVALUE"); + if((via.contains("TCP") || via.contains("tcp")) && fromURI.getUser().contains("tcp-record-route-tcp")) { + proxy.getRecordRouteURI().setTransportParam("TCP"); + uri1.removeParameter("transport"); + } + } + proxy.setParallel(true); + if(CHECK_URI.equals(fromURI.getUser())) { + Address routeAddress = sipFactory.createAddress("sip:" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getReceiverPort(ctx)); + request.pushRoute(routeAddress); + Address ra = request.getAddressHeader("Route"); + logger.info("doInvite: ra = " + ra); + URI uri = ra.getURI(); // this causes NPE + logger.info("doInvite: uri = " + uri); + proxy.setParallel(false); + } + if (from.contains("update") || from.contains("prack") || from.contains("redirect") || from.contains("cancel")){ + proxy.setProxyTimeout(40); + } else { + proxy.setProxyTimeout(4); + } + if(TEST_2_TRYING.equals(fromURI.getUser())) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + if(fromURI.getUser().contains(BRANCHES)) { + List proxyBranches = proxy.createProxyBranches(uris); + for(ProxyBranch proxyBranch : proxyBranches) { + proxyBranch.getRequest().setContent("test", CONTENT_TYPE); + } + proxy.startProxy(); + } else { + proxy.proxyTo(uris); + } + } + } + + @Override + protected void doAck(SipServletRequest request) throws ServletException, + IOException { + logger.info("Got request:\n" + request); + + SipURI fromURI = ((SipURI)request.getFrom().getURI()); + String from = fromURI.toString(); + if(request.getFrom().toString().contains("proxy-orphan")) { + request.getSession().invalidate(); + request.getApplicationSession().invalidate(); + return; + } + if(from.contains("unique-location-urn-route")) { + SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); + URI uri1 = sipFactory.createAddress("sip:receiver@" + host + ":" + getReceiverPort(ctx)).getURI(); + if(from.contains("tcp")) { + ((SipURI)uri1).setTransportParam("tcp"); + } + request.pushRoute((SipURI)uri1); + } + + if(from.contains("unique-location-ack-seen-by-app") && request.getHeader("CSeq").contains("2")) { + sendMessage("ack-seen-by-app", getTestPort(ctx), "udp"); + } + + if(from.contains(TEST_TERMINATION)) { + timerService.createTimer(request.getApplicationSession(), 10000, false, (Serializable) request); + } + } + + /** + * {@inheritDoc} + */ + protected void doBye(SipServletRequest request) throws ServletException, + IOException { + if(fail) { + request.createResponse(500).send(); + throw new ServletException("Failed because of double response"); + } + logger.info("Got BYE request:\n" + request); + SipURI fromURI = ((SipURI)request.getFrom().getURI()); + String from = fromURI.toString(); + SipServletRequestExt sipServletRequestExt = (SipServletRequestExt) request; + if(sipServletRequestExt.isOrphan()) return; + if(from.contains("unique-location-urn-route")) { + SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); + URI uri1 = sipFactory.createAddress("sip:receiver@" + host + ":" + getReceiverPort(ctx)).getURI(); + if(from.contains("tcp")) { + ((SipURI)uri1).setTransportParam("tcp"); + } + request.pushRoute((SipURI)uri1); + } + + if(fromURI.toString().contains(TEST_CREATE_SUBSEQUENT_REQUEST)) { + try { + request.getSession().createRequest("BYE"); + } catch(IllegalStateException ise) { + logger.error("Got expected IllegalStateException on trying to create a subsequent request on a proxy session", ise); + throw ise; + } + } + + SipServletResponse sipServletResponse = request.createResponse(200); + + // If the branchResponse callback was called we are good otherwise fail by + // not delivering OK to BYE + String doBranchRespValue = (String) request.getApplicationSession().getAttribute("branchResponseReceived"); + if("true".equals(doBranchRespValue)) +// sipServletResponse.send(); + + + logger.info("invalidate when ready " + + request.getApplicationSession().getInvalidateWhenReady()); + if(fromURI.getUser().equals(CHECK_READY_TO_INVALIDATE)) { + request.getApplicationSession().setExpires(1); + } + } + + long lastOKstamp=0; + SipServletResponse oldResp; + boolean fail; + + /** + * {@inheritDoc} + */ + protected void doResponse(SipServletResponse response) + throws ServletException, IOException { + + logger.info("Got response: " + response); + logger.info("Sip Session is :" + response.getSession(false)); + if(response.getApplicationSession(false) != null) { + Iterator it = (Iterator) response.getApplicationSession(false).getSessions("SIP"); + logger.debug("dumping sip session list"); + int i = 0; + while (it.hasNext()) { + SipSession sipSession = it.next(); + logger.debug("sip session " + sipSession.getId()); + i++; + } + logger.debug("Number of SIP Sessions is :" + i); + } + SipServletResponseExt sipServletResponseExt = (SipServletResponseExt) response; + SipApplicationSession sas = response.getApplicationSession(); + SipServletRequest re = response.getRequest(); +// re.getCallId(); + if(sipServletResponseExt.isOrphan()) { + sipServletResponseExt.getApplicationSession(false); + return; + } + SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); + SipFactoryExt ext = (SipFactoryExt)sipFactory; + if(!ext.isRouteOrphanRequests()) { // not to break the orphan test + long delta = Math.abs(System.currentTimeMillis() - lastOKstamp); + if(response.getStatus() == 200) { + if(delta < 20 & oldResp != null && response != null && oldResp.getCallId().equals(response.getCallId())) { + fail = true; + throw new ServletException("Problem with double response delta=" + delta + "\n1:" + oldResp + "\n2:" + + response); + // This means we receive two responses within 20ms which can't be a retransmission but an indication of a bug delivering responses twice http://code.google.com/p/mobicents/issues/detail?id=2821 + } + lastOKstamp = System.currentTimeMillis(); + oldResp = response; + } + } + + + if(!"PRACK".equals(response.getMethod()) && response.getProxy() != null && response.getProxy().getOriginalRequest() != null) { + logger.info("Original Sip Session is :" + response.getProxy().getOriginalRequest().getSession(false)); + } + if(response.getFrom().getURI().toString().contains("sequential-retransmission")) { + if(response.getMethod().equals("INVITE")) { + if(response.getStatus() == 200) { + String lastOK = (String) response.getSession().getAttribute("lastOK"); + if(lastOK != null) { + if(!response.toString().equals(lastOK)) { + // We expect to see the retransmissions. Fail the whole test in an ugly way otherwise. + System.out.print("ERROR ERROR ERROR : // We expect to see the retransmissions. Fail the whole test in an ugly way otherwise.\nERROR\ndsfdsf\n\n\n\n\n\n\nERROR'n"); + System.exit(0); + } + } + response.getSession().setAttribute("lastOK", response.toString()); + } + } + } + response.toString(); + if(response.getMethod().equalsIgnoreCase("BYE")) { + response.addHeader("X-Proxy-Transactions", "" + ((ProxyImpl)response.getProxy()).getTransactionMap().size()); + } + super.doResponse(response); + } + + @Override + protected void doSuccessResponse(SipServletResponse response) + throws ServletException, IOException { + if(response.getFrom().getURI().toString().contains("modify-SDP")) { + if(response.getMethod().equals("INVITE")) { + if(response.getStatus() == 200) { + response.setContentType(CONTENT_TYPE); + response.setContent("SDP modified successfully".getBytes("UTF-8"),CONTENT_TYPE); + } + } + } + } + + @Override + protected void doBranchResponse(SipServletResponse response) + throws ServletException, IOException { + + logger.info("doBranchResponse callback was called " + response); + response.getApplicationSession().setAttribute("branchResponseReceived", "true"); + if(response.getStatus() == 408) { + sendMessage("doBranchTimeoutReceived", getTestPort(ctx), "udp"); + } + if(response.getStatus() == 480) { + // https://code.google.com/p/sipservlets/issues/detail?id=266 + SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); + ArrayList uris = new ArrayList(); + // This URi completes and need to be canceled before answering + uris.add(sipFactory.createAddress("sip:neutral@" + host + ":" + getNeutralPort(ctx)).getURI()); + List branches = response.getProxy().createProxyBranches(uris); + for (ProxyBranch proxyBranch : branches) { + if(response.getFrom().getURI().toString().contains("change-to-user")) { + // https://code.google.com/p/sipservlets/issues/detail?id=154 + Address toHeader = proxyBranch.getRequest().getAddressHeader("To"); + SipURI toSipURI = (SipURI) toHeader.getURI(); + toSipURI.setUser("newuser"); + } + } + response.getProxy().startProxy(); + } + } + + // SipErrorListener methods + + /** + * {@inheritDoc} + */ + public void noAckReceived(SipErrorEvent ee) { + logger.error("noAckReceived."); + } + + /** + * {@inheritDoc} + */ + public void noPrackReceived(SipErrorEvent ee) { + logger.error("noPrackReceived."); + } + + @Override + protected void doSubscribe(SipServletRequest req) throws ServletException, IOException + { + if(req.isInitial()) { + SipURI uri = (SipURI)req.getRequestURI().clone(); + uri.setPort(getReceiverPort(ctx)); + req.pushRoute(uri); + Proxy proxy = req.getProxy(true); + final String from = req.getFrom().getURI().toString(); + if(from.contains(RECORD_ROUTING)) { + proxy.setRecordRoute(true); + } + proxy.proxyTo(req.getRequestURI()); + } + } + + @Override + protected void doPublish(SipServletRequest req) throws ServletException, IOException + { + SipURI uri = (SipURI)req.getRequestURI().clone(); + uri.setPort(getReceiverPort(ctx)); + req.pushRoute(uri); + req.getProxy(true).proxyTo(req.getRequestURI()); + } + + @Override + protected void doCancel(SipServletRequest req) throws ServletException, + IOException { + logger.error("CANCEL seen at proxy " + req); + } + /* + * (non-Javadoc) + * @see org.mobicents.javax.servlet.sip.ProxyBranchListener#onProxyBranchResponseTimeout(org.mobicents.javax.servlet.sip.ResponseType, javax.servlet.sip.ProxyBranch) + */ + public void onProxyBranchResponseTimeout(ResponseType responseType, + ProxyBranch proxyBranch) { + logger.info("onProxyBranchResponseTimeout callback was called. responseType = " + responseType + " , branch = " + proxyBranch + ", request " + proxyBranch.getRequest() + ", response " + proxyBranch.getResponse()); + if(proxyBranch.getRequest() != null && (proxyBranch.getRequest().getFrom().getURI().toString().contains("ResponseTimeout") || proxyBranch.getRequest().getFrom().getURI().toString().contains("unique-location"))) { + sendMessage(responseType.toString(), getTestPort(ctx), "udp"); + } + } + + /** + * @param sipApplicationSession + * @param storedFactory + */ + private void sendMessage(String content, int port, String transport) { + try { + SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); + SipServletRequest sipServletRequest = sipFactory.createRequest( + sipFactory.createApplicationSession(), + "MESSAGE", + "sip:sender@sip-servlets.com", + "sip:receiver@sip-servlets.com"); + SipURI sipUri = sipFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":"+ port); + sipUri.setTransportParam(transport); + sipServletRequest.setRequestURI(sipUri); + sipServletRequest.setContentLength(content.length()); + sipServletRequest.setContent(content, CONTENT_TYPE); + sipServletRequest.send(); + } catch (ServletParseException e) { + logger.error("Exception occured while parsing the addresses",e); + } catch (IOException e) { + logger.error("Exception occured while sending the request",e); + } + } + + public void sessionCreated(SipApplicationSessionEvent ev) { + logger.info("sessionCreated " + ev.getApplicationSession().getId()); + String expires = getServletContext().getInitParameter(SIP_APPLICATION_SESSION_TIMEOUT); + if(expires != null) { + logger.info("setting expires to " + expires); + long now = System.currentTimeMillis(); + ev.getApplicationSession().setExpires(Integer.valueOf(expires)); + long expirationTime = ev.getApplicationSession().getExpirationTime(); + logger.info("expirationTime " + expirationTime); + if(expirationTime < (now + (Integer.valueOf(expires) * 60 * 1000L))) { + ev.getApplicationSession().setAttribute(ERROR, "sip App Sesion getExpirationTime() returns incorrect value"); + } + } + } + + public void sessionDestroyed(SipApplicationSessionEvent ev) { + logger.info("sessionDestroyed " + ev.getApplicationSession().getId()); + } + + public void sessionExpired(SipApplicationSessionEvent ev) { + logger.info("sessionExpired " + ev.getApplicationSession().getId()); + if(ev.getApplicationSession().getAttribute(SIP_APPLICATION_SESSION_TIMEOUT) != null) { + sendMessage("sessionExpired", (Integer) ev.getApplicationSession().getAttribute("contactPort"), (String) ev.getApplicationSession().getAttribute("transport")); + } + } + + public void sessionReadyToInvalidate(SipApplicationSessionEvent ev) { + logger.info("sessionReadyToInvalidate " + ev.getApplicationSession().getId()); + if(ev.getApplicationSession().getAttribute("contactPort") != null) { + sendMessage("sessionReadyToInvalidate", (Integer) ev.getApplicationSession().getAttribute("contactPort"), (String) ev.getApplicationSession().getAttribute("transport")); + if(ev.getApplicationSession().getAttribute(SIP_APPLICATION_SESSION_TIMEOUT) != null) { + ev.getApplicationSession().setInvalidateWhenReady(false); + } + } + } + + public void sessionCreated(SipSessionEvent se) { + // TODO Auto-generated method stub + + } + + public void sessionDestroyed(SipSessionEvent se) { + // TODO Auto-generated method stub + + } + + public void sessionReadyToInvalidate(SipSessionEvent se) { + logger.info("sipSessionReadyToInvalidate " + se.getSession().getId()); + if(se.getSession().getAttribute("contactPort") != null) { + sendMessage("sipSessionReadyToInvalidate", (Integer) se.getSession().getAttribute("contactPort"), (String) se.getSession().getAttribute("transport")); + } + } + + @Override + protected void doUpdate(SipServletRequest req) throws ServletException, IOException { + logger.info("Got request:\n "+req); + } + + //@Override + public void timeout(ServletTimer timer) { + SipServletRequest request = (SipServletRequest)timer.getInfo(); + try { + ((ProxyExt)request.getProxy()).terminateSession(request.getSession(), 500, "Testing termination", 500, "Testing Termination"); + } catch (IllegalStateException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (TooManyHopsException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + public static Integer getTestPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("testPort"); + logger.info("TestPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5080; + } + } + + public static Integer getReceiverPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("receiverPort"); + logger.info("ReceiverPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5057; + } + } + + public static Integer getNeutralPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("neutralPort"); + logger.info("NeutralPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5058; + } + } + + public static Integer getCutmePort(ServletContext ctx) { + String tPort = ctx.getInitParameter("cutmePort"); + logger.info("CutmePort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5056; + } + } + + public static Integer getServletContainerPort(ServletContext ctx) { + String cPort = ctx.getInitParameter("servletContainerPort"); + logger.info("TestPort at:" + cPort); + if (cPort != null) { + return Integer.valueOf(cPort); + } else { + return 5070; + } + } + + public static Integer getDownstreamContainerPort(ServletContext ctx) { + String cPort = ctx.getInitParameter("downstreamContainerPort"); + logger.info("DownstramContainerPort at:" + cPort); + if (cPort != null) { + return Integer.valueOf(cPort); + } else { + return 5069; + } + } +} \ No newline at end of file diff --git a/sip-servlets-test-suite/applications/publish-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/PublishSipServlet.java b/sip-servlets-test-suite/applications/publish-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/PublishSipServlet.java index 44af9c318c..ac53eb64d4 100644 --- a/sip-servlets-test-suite/applications/publish-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/PublishSipServlet.java +++ b/sip-servlets-test-suite/applications/publish-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/PublishSipServlet.java @@ -1,204 +1,227 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.Random; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.sip.ServletTimer; -import javax.servlet.sip.SipApplicationSession; -import javax.servlet.sip.SipFactory; -import javax.servlet.sip.SipServlet; -import javax.servlet.sip.SipServletContextEvent; -import javax.servlet.sip.SipServletListener; -import javax.servlet.sip.SipServletRequest; -import javax.servlet.sip.SipServletResponse; -import javax.servlet.sip.SipSession; -import javax.servlet.sip.SipURI; -import javax.servlet.sip.TimerListener; -import javax.servlet.sip.TimerService; -import javax.servlet.sip.URI; - -import org.apache.log4j.Logger; - -/** - * - * @author Jean Deruelle - * - */ -public class PublishSipServlet extends SipServlet implements SipServletListener, TimerListener { - private static final long serialVersionUID = 1L; - private static final String SUBSCRIBER_SESSIONS = "subscriberSessions"; - private static final String PUBLISH_SIP_ETAGS = "publishSIP-ETag_s"; - private static transient Logger logger = Logger.getLogger(PublishSipServlet.class); - - - /** Creates a new instance of PublishSipServlet */ - public PublishSipServlet() { - } - - @Override - public void init(ServletConfig servletConfig) throws ServletException { - logger.info("the publish sip servlet has been started"); - super.init(servletConfig); - getServletContext().setAttribute(SUBSCRIBER_SESSIONS, new HashMap()); - getServletContext().setAttribute(PUBLISH_SIP_ETAGS, new HashMap()); - } - - @Override - protected void doSuccessResponse(SipServletResponse resp) - throws ServletException, IOException { - if("PUBLISH".equals(resp.getMethod()) && !"Modify".equals(getServletContext().getAttribute("publishStateSent"))) { - SipFactory sipFactory = (SipFactory)getServletContext().getAttribute(SIP_FACTORY); - SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); - SipURI fromURI = sipFactory.createSipURI("presentity", "example.com"); - SipURI toURI = sipFactory.createSipURI("presentity", "example.com"); - SipServletRequest sipServletRequest = - sipFactory.createRequest(sipApplicationSession, "PUBLISH", fromURI, toURI); - SipURI requestURI = sipFactory.createSipURI("presentity", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - sipServletRequest.setRequestURI(requestURI); - sipServletRequest.setExpires(3600); - sipServletRequest.setHeader("Event", "presence"); - sipServletRequest.setHeader("SIP-If-Match", resp.getHeader("Sip-ETag")); - - try { - if(getServletContext().getAttribute("publishStateSent") != null) { - sipServletRequest.setContent("Modify", "application/pidf+xml"); - getServletContext().setAttribute("publishStateSent", "Modify"); - } else { - getServletContext().setAttribute("publishStateSent", "Refresh"); - } - sipServletRequest.send(); - } catch (IOException e) { - logger.error(e); - } - } - } - - /** - * {@inheritDoc} - */ - protected void doSubscribe(SipServletRequest request) throws ServletException, - IOException { - //If we receive a SUBSCRIBE, we cancel the timer to avoid acting as UAC and sending PUBLISH - ServletTimer servletTimer = (ServletTimer)getServletContext().getAttribute("servletTimer"); - servletTimer.cancel(); - - logger.info("Got Subscribe: " - + request.getMethod()); - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); - sipServletResponse.addHeader("Expires", request.getHeader("Expires")); - sipServletResponse.addHeader("Event", request.getHeader("Event")); - sipServletResponse.send(); - Map subscriberSessions = (Map) - getServletContext().getAttribute(SUBSCRIBER_SESSIONS); - subscriberSessions.put(request.getRequestURI(), request.getSession()); - - // send notify - SipServletRequest notifyRequest = request.getSession().createRequest("NOTIFY"); - notifyRequest.addHeader("Subscription-State", "active"); - notifyRequest.addHeader("Event", "presence"); - notifyRequest.send(); - } - - @Override - protected void doPublish(SipServletRequest request) throws ServletException, - IOException { - Map subscriberSessions = (Map) - getServletContext().getAttribute(SUBSCRIBER_SESSIONS); - Map sipETags = (Map) - getServletContext().getAttribute(PUBLISH_SIP_ETAGS); - - SipSession subscriberSession = subscriberSessions.get(request.getRequestURI()); - boolean sipIfMatchFound = true; - String sipIfMatch = request.getHeader("SIP-If-Match"); - if(sipIfMatch != null && !sipIfMatch.equalsIgnoreCase(sipETags.get(request.getRequestURI()))) { - sipIfMatchFound = false; - } - if(subscriberSession != null && sipIfMatchFound) { - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); - sipServletResponse.addHeader("Expires", request.getHeader("Expires")); - String sipETag = Integer.toString(new Random().nextInt(10000000)); - sipETags.put(request.getRequestURI(), sipETag); - sipServletResponse.addHeader("SIP-ETag", sipETag); - sipServletResponse.send(); - - if(request.getRawContent() != null) { - String content = new String(request.getRawContent()); - if(content.length() > 0) { - if(logger.isDebugEnabled()) { - logger.debug("Content : "+content); - } - SipServletRequest notifyRequest = subscriberSession.createRequest("NOTIFY"); - notifyRequest.addHeader("Subscription-State", "active"); - notifyRequest.addHeader("Event", "presence"); - notifyRequest.send(); - } - } - } else { - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_SERVER_INTERNAL_ERROR); - sipServletResponse.send(); - } - } - - // Listener methods - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipServletListener#servletInitialized(javax.servlet.sip.SipServletContextEvent) - */ - public void servletInitialized(SipServletContextEvent ce) { - SipFactory sipFactory = (SipFactory)ce.getServletContext().getAttribute(SIP_FACTORY); - SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); - TimerService timerService = (TimerService)ce.getServletContext().getAttribute(TIMER_SERVICE); - sipApplicationSession.setAttribute("sipFactory", sipFactory); - ServletTimer servletTimer = timerService.createTimer(sipApplicationSession, 2000, false, null); - ce.getServletContext().setAttribute("servletTimer", servletTimer); - } - - /* - * (non-Javadoc) - * @see javax.servlet.sip.TimerListener#timeout(javax.servlet.sip.ServletTimer) - */ - public void timeout(ServletTimer timer) { - SipFactory sipFactory = (SipFactory) timer.getApplicationSession().getAttribute("sipFactory"); - SipURI fromURI = sipFactory.createSipURI("presentity", "example.com"); - SipURI toURI = sipFactory.createSipURI("presentity", "example.com"); - SipServletRequest sipServletRequest = - sipFactory.createRequest(timer.getApplicationSession(), "PUBLISH", fromURI, toURI); - SipURI requestURI = sipFactory.createSipURI("presentity", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - sipServletRequest.setRequestURI(requestURI); - sipServletRequest.setExpires(3600); - sipServletRequest.setHeader("Event", "presence"); - - try { - sipServletRequest.setContent("Initial", "application/pidf+xml"); - sipServletRequest.send(); - } catch (IOException e) { - logger.error(e); - } - } +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.sip.ServletTimer; +import javax.servlet.sip.SipApplicationSession; +import javax.servlet.sip.SipFactory; +import javax.servlet.sip.SipServlet; +import javax.servlet.sip.SipServletContextEvent; +import javax.servlet.sip.SipServletListener; +import javax.servlet.sip.SipServletRequest; +import javax.servlet.sip.SipServletResponse; +import javax.servlet.sip.SipSession; +import javax.servlet.sip.SipURI; +import javax.servlet.sip.TimerListener; +import javax.servlet.sip.TimerService; +import javax.servlet.sip.URI; + +import org.apache.log4j.Logger; + +/** + * + * @author Jean Deruelle + * + */ +public class PublishSipServlet extends SipServlet implements SipServletListener, TimerListener { + private static final long serialVersionUID = 1L; + private static final String SUBSCRIBER_SESSIONS = "subscriberSessions"; + private static final String PUBLISH_SIP_ETAGS = "publishSIP-ETag_s"; + private static transient Logger logger = Logger.getLogger(PublishSipServlet.class); + + static ServletContext ctx; + + /** Creates a new instance of PublishSipServlet */ + public PublishSipServlet() { + } + + @Override + public void init(ServletConfig servletConfig) throws ServletException { + logger.info("the publish sip servlet has been started"); + super.init(servletConfig); + ctx = servletConfig.getServletContext(); + getServletContext().setAttribute(SUBSCRIBER_SESSIONS, new HashMap()); + getServletContext().setAttribute(PUBLISH_SIP_ETAGS, new HashMap()); + } + + @Override + protected void doSuccessResponse(SipServletResponse resp) + throws ServletException, IOException { + if("PUBLISH".equals(resp.getMethod()) && !"Modify".equals(getServletContext().getAttribute("publishStateSent"))) { + SipFactory sipFactory = (SipFactory)getServletContext().getAttribute(SIP_FACTORY); + SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); + SipURI fromURI = sipFactory.createSipURI("presentity", "example.com"); + SipURI toURI = sipFactory.createSipURI("presentity", "example.com"); + SipServletRequest sipServletRequest = + sipFactory.createRequest(sipApplicationSession, "PUBLISH", fromURI, toURI); + SipURI requestURI = sipFactory.createSipURI("presentity", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + sipServletRequest.setRequestURI(requestURI); + sipServletRequest.setExpires(3600); + sipServletRequest.setHeader("Event", "presence"); + sipServletRequest.setHeader("SIP-If-Match", resp.getHeader("Sip-ETag")); + + try { + if(getServletContext().getAttribute("publishStateSent") != null) { + sipServletRequest.setContent("Modify", "application/pidf+xml"); + getServletContext().setAttribute("publishStateSent", "Modify"); + } else { + getServletContext().setAttribute("publishStateSent", "Refresh"); + } + sipServletRequest.send(); + } catch (IOException e) { + logger.error(e); + } + } + } + + /** + * {@inheritDoc} + */ + protected void doSubscribe(SipServletRequest request) throws ServletException, + IOException { + //If we receive a SUBSCRIBE, we cancel the timer to avoid acting as UAC and sending PUBLISH + ServletTimer servletTimer = (ServletTimer)getServletContext().getAttribute("servletTimer"); + servletTimer.cancel(); + + logger.info("Got Subscribe: " + + request.getMethod()); + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); + sipServletResponse.addHeader("Expires", request.getHeader("Expires")); + sipServletResponse.addHeader("Event", request.getHeader("Event")); + sipServletResponse.send(); + Map subscriberSessions = (Map) + getServletContext().getAttribute(SUBSCRIBER_SESSIONS); + subscriberSessions.put(request.getRequestURI(), request.getSession()); + + // send notify + SipServletRequest notifyRequest = request.getSession().createRequest("NOTIFY"); + notifyRequest.addHeader("Subscription-State", "active"); + notifyRequest.addHeader("Event", "presence"); + notifyRequest.send(); + } + + @Override + protected void doPublish(SipServletRequest request) throws ServletException, + IOException { + Map subscriberSessions = (Map) + getServletContext().getAttribute(SUBSCRIBER_SESSIONS); + Map sipETags = (Map) + getServletContext().getAttribute(PUBLISH_SIP_ETAGS); + + SipSession subscriberSession = subscriberSessions.get(request.getRequestURI()); + boolean sipIfMatchFound = true; + String sipIfMatch = request.getHeader("SIP-If-Match"); + if(sipIfMatch != null && !sipIfMatch.equalsIgnoreCase(sipETags.get(request.getRequestURI()))) { + sipIfMatchFound = false; + } + if(subscriberSession != null && sipIfMatchFound) { + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); + sipServletResponse.addHeader("Expires", request.getHeader("Expires")); + String sipETag = Integer.toString(new Random().nextInt(10000000)); + sipETags.put(request.getRequestURI(), sipETag); + sipServletResponse.addHeader("SIP-ETag", sipETag); + sipServletResponse.send(); + + if(request.getRawContent() != null) { + String content = new String(request.getRawContent()); + if(content.length() > 0) { + if(logger.isDebugEnabled()) { + logger.debug("Content : "+content); + } + SipServletRequest notifyRequest = subscriberSession.createRequest("NOTIFY"); + notifyRequest.addHeader("Subscription-State", "active"); + notifyRequest.addHeader("Event", "presence"); + notifyRequest.send(); + } + } + } else { + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_SERVER_INTERNAL_ERROR); + sipServletResponse.send(); + } + } + + // Listener methods + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipServletListener#servletInitialized(javax.servlet.sip.SipServletContextEvent) + */ + public void servletInitialized(SipServletContextEvent ce) { + SipFactory sipFactory = (SipFactory)ce.getServletContext().getAttribute(SIP_FACTORY); + SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); + TimerService timerService = (TimerService)ce.getServletContext().getAttribute(TIMER_SERVICE); + sipApplicationSession.setAttribute("sipFactory", sipFactory); + ServletTimer servletTimer = timerService.createTimer(sipApplicationSession, 2000, false, null); + ce.getServletContext().setAttribute("servletTimer", servletTimer); + } + + /* + * (non-Javadoc) + * @see javax.servlet.sip.TimerListener#timeout(javax.servlet.sip.ServletTimer) + */ + public void timeout(ServletTimer timer) { + SipFactory sipFactory = (SipFactory) timer.getApplicationSession().getAttribute("sipFactory"); + SipURI fromURI = sipFactory.createSipURI("presentity", "example.com"); + SipURI toURI = sipFactory.createSipURI("presentity", "example.com"); + SipServletRequest sipServletRequest = + sipFactory.createRequest(timer.getApplicationSession(), "PUBLISH", fromURI, toURI); + SipURI requestURI = sipFactory.createSipURI("presentity", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + sipServletRequest.setRequestURI(requestURI); + sipServletRequest.setExpires(3600); + sipServletRequest.setHeader("Event", "presence"); + + try { + sipServletRequest.setContent("Initial", "application/pidf+xml"); + sipServletRequest.send(); + } catch (IOException e) { + logger.error(e); + } + } + + public static Integer getTestPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("testPort"); + logger.info("TestPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5080; + } + } + + public static Integer getServletContainerPort(ServletContext ctx) { + String cPort = ctx.getInitParameter("servletContainerPort"); + logger.info("TestPort at:" + cPort); + if (cPort != null) { + return Integer.valueOf(cPort); + } else { + return 5070; + } + } } \ No newline at end of file diff --git a/sip-servlets-test-suite/applications/refer-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ReferSipServlet.java b/sip-servlets-test-suite/applications/refer-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ReferSipServlet.java index db8f71bc87..c38d7a1fc6 100644 --- a/sip-servlets-test-suite/applications/refer-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ReferSipServlet.java +++ b/sip-servlets-test-suite/applications/refer-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ReferSipServlet.java @@ -1,259 +1,293 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite; - -import java.io.IOException; - -import javax.annotation.Resource; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.sip.ServletTimer; -import javax.servlet.sip.SipApplicationSession; -import javax.servlet.sip.SipFactory; -import javax.servlet.sip.SipServlet; -import javax.servlet.sip.SipServletContextEvent; -import javax.servlet.sip.SipServletListener; -import javax.servlet.sip.SipServletRequest; -import javax.servlet.sip.SipServletResponse; -import javax.servlet.sip.SipSession; -import javax.servlet.sip.SipSessionEvent; -import javax.servlet.sip.SipSessionListener; -import javax.servlet.sip.SipURI; -import javax.servlet.sip.TimerListener; -import javax.servlet.sip.TimerService; -import javax.servlet.sip.URI; - -import org.apache.log4j.Logger; - -/** - * - * @author Jean Deruelle - * - */ -public class ReferSipServlet extends SipServlet implements SipServletListener, TimerListener, SipSessionListener { - private static final long serialVersionUID = 1L; - private static final String REFER_SESSION = "referSession"; - private static transient Logger logger = Logger.getLogger(ReferSipServlet.class); - private final static String TRYING_CONTENT = "SIP/2.0 100 Trying"; - private final static String OK_CONTENT = "SIP/2.0 200 OK"; - private final static String SUBSEQUENT_CONTENT = "SIP/2.0 100 Subsequent"; - private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; - private static final String SIP_SESSION_READY_TO_BE_INVALIDATED = "sipSessionReadyToBeInvalidated"; - - @Resource - SipFactory sipFactory; - - /** Creates a new instance of ReferSipServlet */ - public ReferSipServlet() { - } - - @Override - public void init(ServletConfig servletConfig) throws ServletException { - logger.info("the refer sip servlet has been started"); - super.init(servletConfig); - } - - /** - * {@inheritDoc} - */ - protected void doInvite(SipServletRequest request) throws ServletException, - IOException { - logger.info("from : " + request.getFrom()); - logger.info("Got request: " - + request.getMethod()); - - //If we receive an INVITE, we cancel the timer to avoid acting as UAC and sending REFER - ServletTimer servletTimer = (ServletTimer)getServletContext().getAttribute("servletTimer"); - servletTimer.cancel(); - - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_RINGING); - sipServletResponse.send(); - request.getSession().setAttribute("inviteReceived", "true"); - try { - Thread.sleep(2000); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - sipServletResponse = request.createResponse(SipServletResponse.SC_OK); - sipServletResponse.send(); - } - - /** - * {@inheritDoc} - */ - protected void doRefer(SipServletRequest request) throws ServletException, - IOException { - - logger.info("Got REFER: " - + request); - //If we receive a Refer, we cancel the timer to avoid acting as UAC and sending REFER - ServletTimer servletTimer = (ServletTimer)getServletContext().getAttribute("servletTimer"); - servletTimer.cancel(); - - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_ACCEPTED); - sipServletResponse.send(); - // send notify - SipServletRequest notifyRequest = request.getSession().createRequest("NOTIFY"); - notifyRequest.addHeader("Subscription-State", "active;expires=3600"); - notifyRequest.addHeader("Event", "refer"); - if(request.isInitial() || request.getSession().getAttribute("inviteReceived") != null) { - notifyRequest.setContentLength(TRYING_CONTENT.length()); - notifyRequest.setContent(TRYING_CONTENT, "message/sipfrag;version=2.0"); - } else { - notifyRequest.setContentLength(TRYING_CONTENT.length()); - notifyRequest.setContent(SUBSEQUENT_CONTENT, "message/sipfrag;version=2.0"); - } - notifyRequest.send(); - - if(request.isInitial() || request.getSession().getAttribute("inviteReceived") != null) { - request.getSession().removeAttribute("inviteReceived"); - SipFactory sipFactory = (SipFactory)getServletContext().getAttribute(SIP_FACTORY); - SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); - sipApplicationSession.setAttribute(REFER_SESSION, request.getSession()); - String inviteUri = request.getHeader("Refer-To"); - SipURI fromURI = sipFactory.createSipURI("receiver", "example.com"); - URI toURI = sipFactory.createURI(inviteUri.substring(1,inviteUri.length()-1)); - SipURI requestURI = sipFactory.createSipURI(((SipURI)toURI).getUser(), "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090"); - SipServletRequest inviteRequest = sipFactory.createRequest(sipApplicationSession, "INVITE", fromURI, toURI); - inviteRequest.setRequestURI(requestURI); - inviteRequest.setHeader("Referred-By", request.getFrom().getURI().toString()); - try { - inviteRequest.send(); - } catch (IOException e) { - logger.error(e); - } - } - } - - @Override - protected void doSuccessResponse(SipServletResponse resp) - throws ServletException, IOException { - if("INVITE".equals(resp.getMethod())) { - resp.createAck().send(); - SipSession referSession = (SipSession) resp.getApplicationSession().getAttribute(REFER_SESSION); - if(referSession != null) { - SipServletRequest notifyRequest = referSession.createRequest("NOTIFY"); - notifyRequest.addHeader("Subscription-State", "terminated;reason=noresource"); - notifyRequest.addHeader("Event", "refer"); - notifyRequest.setContentLength(OK_CONTENT.length()); - notifyRequest.setContent(OK_CONTENT, "message/sipfrag;version=2.0"); - notifyRequest.send(); - } - } - } - - @Override - protected void doBye(SipServletRequest req) throws ServletException, - IOException { - req.createResponse(SipServletResponse.SC_OK).send(); - } - - @Override - protected void doNotify(SipServletRequest req) throws ServletException, - IOException { - req.createResponse(SipServletResponse.SC_OK).send(); - - if(req.getRawContent() != null) { - String content = new String(req.getRawContent()); - if("SIP/2.0 200 OK".equals(content) && req.getHeader("Out-Of-Dialog") == null) { - SipServletRequest sipServletRequest = req.getSession().createRequest("REFER"); - SipFactory sipFactory = (SipFactory)getServletContext().getAttribute(SIP_FACTORY); - SipURI requestURI = sipFactory.createSipURI("sender", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - sipServletRequest.setRequestURI(requestURI); - sipServletRequest.addHeader("Refer-To", "sip:refer-to@nist.gov"); - sipServletRequest.send(); - } else if ("SIP/2.0 100 Subsequent".equals(content)) { - SipServletRequest messageRequest = req.getSession().createRequest("MESSAGE"); - SipFactory sipFactory = (SipFactory)getServletContext().getAttribute(SIP_FACTORY); - SipURI requestURI = sipFactory.createSipURI("sender", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - messageRequest.setRequestURI(requestURI); - messageRequest.setContentLength(req.getContentLength()); - messageRequest.setContent("SIP/2.0 100 Subsequent", "text/plain;charset=UTF-8"); - messageRequest.send(); - } - } - } - // Listener methods - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipServletListener#servletInitialized(javax.servlet.sip.SipServletContextEvent) - */ - public void servletInitialized(SipServletContextEvent ce) { - SipFactory sipFactory = (SipFactory)ce.getServletContext().getAttribute(SIP_FACTORY); - SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); - TimerService timerService = (TimerService)ce.getServletContext().getAttribute(TIMER_SERVICE); - sipApplicationSession.setAttribute("sipFactory", sipFactory); - ServletTimer servletTimer = timerService.createTimer(sipApplicationSession, 2000, false, null); - ce.getServletContext().setAttribute("servletTimer", servletTimer); - } - - /* - * (non-Javadoc) - * @see javax.servlet.sip.TimerListener#timeout(javax.servlet.sip.ServletTimer) - */ - public void timeout(ServletTimer timer) { - SipFactory sipFactory = (SipFactory) timer.getApplicationSession().getAttribute("sipFactory"); - SipURI fromURI = sipFactory.createSipURI("receiver", "nist.gov"); - SipURI toURI = sipFactory.createSipURI("sender", "nist.gov"); - SipServletRequest sipServletRequest = - sipFactory.createRequest(timer.getApplicationSession(), "REFER", fromURI, toURI); - SipURI requestURI = sipFactory.createSipURI("sender", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - sipServletRequest.setRequestURI(requestURI); - sipServletRequest.addHeader("Refer-To", "sip:refer-to@nist.gov"); - try { - sipServletRequest.send(); - } catch (IOException e) { - logger.error(e); - } - } - - public void sessionCreated(SipSessionEvent se) { - // TODO Auto-generated method stub - - } - - public void sessionDestroyed(SipSessionEvent se) { - // TODO Auto-generated method stub - - } - - public void sessionReadyToInvalidate(SipSessionEvent se) { - logger.info("sip session expired " + se.getSession()); - - try { - SipServletRequest sipServletRequest = sipFactory.createRequest( - sipFactory.createApplicationSession(), - "MESSAGE", - se.getSession().getLocalParty(), - se.getSession().getRemoteParty()); - SipURI sipUri=sipFactory.createSipURI("LittleGuy", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - sipServletRequest.setRequestURI(sipUri); - sipServletRequest.setContentLength(SIP_SESSION_READY_TO_BE_INVALIDATED.length()); - sipServletRequest.setContent(SIP_SESSION_READY_TO_BE_INVALIDATED, CONTENT_TYPE); - sipServletRequest.send(); - } catch (IOException e) { - logger.error("Exception occured while sending the request",e); - } - } +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite; + +import java.io.IOException; + +import javax.annotation.Resource; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.sip.ServletTimer; +import javax.servlet.sip.SipApplicationSession; +import javax.servlet.sip.SipFactory; +import javax.servlet.sip.SipServlet; +import javax.servlet.sip.SipServletContextEvent; +import javax.servlet.sip.SipServletListener; +import javax.servlet.sip.SipServletRequest; +import javax.servlet.sip.SipServletResponse; +import javax.servlet.sip.SipSession; +import javax.servlet.sip.SipSessionEvent; +import javax.servlet.sip.SipSessionListener; +import javax.servlet.sip.SipURI; +import javax.servlet.sip.TimerListener; +import javax.servlet.sip.TimerService; +import javax.servlet.sip.URI; + +import org.apache.log4j.Logger; + +/** + * + * @author Jean Deruelle + * + */ +public class ReferSipServlet extends SipServlet implements SipServletListener, TimerListener, SipSessionListener { + private static final long serialVersionUID = 1L; + private static final String REFER_SESSION = "referSession"; + private static transient Logger logger = Logger.getLogger(ReferSipServlet.class); + private final static String TRYING_CONTENT = "SIP/2.0 100 Trying"; + private final static String OK_CONTENT = "SIP/2.0 200 OK"; + private final static String SUBSEQUENT_CONTENT = "SIP/2.0 100 Subsequent"; + private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; + private static final String SIP_SESSION_READY_TO_BE_INVALIDATED = "sipSessionReadyToBeInvalidated"; + + @Resource + SipFactory sipFactory; + + static ServletContext ctx; + + /** Creates a new instance of ReferSipServlet */ + public ReferSipServlet() { + } + + @Override + public void init(ServletConfig servletConfig) throws ServletException { + logger.info("the refer sip servlet has been started"); + super.init(servletConfig); + ctx = servletConfig.getServletContext(); + } + + /** + * {@inheritDoc} + */ + protected void doInvite(SipServletRequest request) throws ServletException, + IOException { + logger.info("from : " + request.getFrom()); + logger.info("Got request: " + + request.getMethod()); + + //If we receive an INVITE, we cancel the timer to avoid acting as UAC and sending REFER + ServletTimer servletTimer = (ServletTimer)getServletContext().getAttribute("servletTimer"); + servletTimer.cancel(); + + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_RINGING); + sipServletResponse.send(); + request.getSession().setAttribute("inviteReceived", "true"); + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + sipServletResponse = request.createResponse(SipServletResponse.SC_OK); + sipServletResponse.send(); + } + + /** + * {@inheritDoc} + */ + protected void doRefer(SipServletRequest request) throws ServletException, + IOException { + + logger.info("Got REFER: " + + request); + //If we receive a Refer, we cancel the timer to avoid acting as UAC and sending REFER + ServletTimer servletTimer = (ServletTimer)getServletContext().getAttribute("servletTimer"); + servletTimer.cancel(); + + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_ACCEPTED); + sipServletResponse.send(); + // send notify + SipServletRequest notifyRequest = request.getSession().createRequest("NOTIFY"); + notifyRequest.addHeader("Subscription-State", "active;expires=3600"); + notifyRequest.addHeader("Event", "refer"); + if(request.isInitial() || request.getSession().getAttribute("inviteReceived") != null) { + notifyRequest.setContentLength(TRYING_CONTENT.length()); + notifyRequest.setContent(TRYING_CONTENT, "message/sipfrag;version=2.0"); + } else { + notifyRequest.setContentLength(TRYING_CONTENT.length()); + notifyRequest.setContent(SUBSEQUENT_CONTENT, "message/sipfrag;version=2.0"); + } + notifyRequest.send(); + + if(request.isInitial() || request.getSession().getAttribute("inviteReceived") != null) { + request.getSession().removeAttribute("inviteReceived"); + SipFactory sipFactory = (SipFactory)getServletContext().getAttribute(SIP_FACTORY); + SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); + sipApplicationSession.setAttribute(REFER_SESSION, request.getSession()); + String inviteUri = request.getHeader("Refer-To"); + SipURI fromURI = sipFactory.createSipURI("receiver", "example.com"); + URI toURI = sipFactory.createURI(inviteUri.substring(1,inviteUri.length()-1)); + SipURI requestURI = sipFactory.createSipURI(((SipURI)toURI).getUser(), "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getReferPort(ctx)); + SipServletRequest inviteRequest = sipFactory.createRequest(sipApplicationSession, "INVITE", fromURI, toURI); + inviteRequest.setRequestURI(requestURI); + inviteRequest.setHeader("Referred-By", request.getFrom().getURI().toString()); + try { + inviteRequest.send(); + } catch (IOException e) { + logger.error(e); + } + } + } + + @Override + protected void doSuccessResponse(SipServletResponse resp) + throws ServletException, IOException { + if("INVITE".equals(resp.getMethod())) { + resp.createAck().send(); + SipSession referSession = (SipSession) resp.getApplicationSession().getAttribute(REFER_SESSION); + if(referSession != null) { + SipServletRequest notifyRequest = referSession.createRequest("NOTIFY"); + notifyRequest.addHeader("Subscription-State", "terminated;reason=noresource"); + notifyRequest.addHeader("Event", "refer"); + notifyRequest.setContentLength(OK_CONTENT.length()); + notifyRequest.setContent(OK_CONTENT, "message/sipfrag;version=2.0"); + notifyRequest.send(); + } + } + } + + @Override + protected void doBye(SipServletRequest req) throws ServletException, + IOException { + req.createResponse(SipServletResponse.SC_OK).send(); + } + + @Override + protected void doNotify(SipServletRequest req) throws ServletException, + IOException { + req.createResponse(SipServletResponse.SC_OK).send(); + + if(req.getRawContent() != null) { + String content = new String(req.getRawContent()); + if("SIP/2.0 200 OK".equals(content) && req.getHeader("Out-Of-Dialog") == null) { + SipServletRequest sipServletRequest = req.getSession().createRequest("REFER"); + SipFactory sipFactory = (SipFactory)getServletContext().getAttribute(SIP_FACTORY); + SipURI requestURI = sipFactory.createSipURI("sender", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + sipServletRequest.setRequestURI(requestURI); + sipServletRequest.addHeader("Refer-To", "sip:refer-to@nist.gov"); + sipServletRequest.send(); + } else if ("SIP/2.0 100 Subsequent".equals(content)) { + SipServletRequest messageRequest = req.getSession().createRequest("MESSAGE"); + SipFactory sipFactory = (SipFactory)getServletContext().getAttribute(SIP_FACTORY); + SipURI requestURI = sipFactory.createSipURI("sender", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + messageRequest.setRequestURI(requestURI); + messageRequest.setContentLength(req.getContentLength()); + messageRequest.setContent("SIP/2.0 100 Subsequent", "text/plain;charset=UTF-8"); + messageRequest.send(); + } + } + } + // Listener methods + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipServletListener#servletInitialized(javax.servlet.sip.SipServletContextEvent) + */ + public void servletInitialized(SipServletContextEvent ce) { + SipFactory sipFactory = (SipFactory)ce.getServletContext().getAttribute(SIP_FACTORY); + SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); + TimerService timerService = (TimerService)ce.getServletContext().getAttribute(TIMER_SERVICE); + sipApplicationSession.setAttribute("sipFactory", sipFactory); + ServletTimer servletTimer = timerService.createTimer(sipApplicationSession, 2000, false, null); + ce.getServletContext().setAttribute("servletTimer", servletTimer); + } + + /* + * (non-Javadoc) + * @see javax.servlet.sip.TimerListener#timeout(javax.servlet.sip.ServletTimer) + */ + public void timeout(ServletTimer timer) { + SipFactory sipFactory = (SipFactory) timer.getApplicationSession().getAttribute("sipFactory"); + SipURI fromURI = sipFactory.createSipURI("receiver", "nist.gov"); + SipURI toURI = sipFactory.createSipURI("sender", "nist.gov"); + SipServletRequest sipServletRequest = + sipFactory.createRequest(timer.getApplicationSession(), "REFER", fromURI, toURI); + SipURI requestURI = sipFactory.createSipURI("sender", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + sipServletRequest.setRequestURI(requestURI); + sipServletRequest.addHeader("Refer-To", "sip:refer-to@nist.gov"); + try { + sipServletRequest.send(); + } catch (IOException e) { + logger.error(e); + } + } + + public void sessionCreated(SipSessionEvent se) { + // TODO Auto-generated method stub + + } + + public void sessionDestroyed(SipSessionEvent se) { + // TODO Auto-generated method stub + + } + + public void sessionReadyToInvalidate(SipSessionEvent se) { + logger.info("sip session expired " + se.getSession()); + + try { + SipServletRequest sipServletRequest = sipFactory.createRequest( + sipFactory.createApplicationSession(), + "MESSAGE", + se.getSession().getLocalParty(), + se.getSession().getRemoteParty()); + SipURI sipUri=sipFactory.createSipURI("LittleGuy", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + sipServletRequest.setRequestURI(sipUri); + sipServletRequest.setContentLength(SIP_SESSION_READY_TO_BE_INVALIDATED.length()); + sipServletRequest.setContent(SIP_SESSION_READY_TO_BE_INVALIDATED, CONTENT_TYPE); + sipServletRequest.send(); + } catch (IOException e) { + logger.error("Exception occured while sending the request",e); + } + } + + public static Integer getTestPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("testPort"); + logger.info("TestPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5080; + } + } + + public static Integer getReferPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("referPort"); + logger.info("referPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5090; + } + } + + public static Integer getServletContainerPort(ServletContext ctx) { + String cPort = ctx.getInitParameter("servletContainerPort"); + logger.info("TestPort at:" + cPort); + if (cPort != null) { + return Integer.valueOf(cPort); + } else { + return 5070; + } + } } \ No newline at end of file diff --git a/sip-servlets-test-suite/applications/replaces-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ReplacesReceiverSipServlet.java b/sip-servlets-test-suite/applications/replaces-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ReplacesReceiverSipServlet.java index a52760ae73..4524a11eb9 100644 --- a/sip-servlets-test-suite/applications/replaces-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ReplacesReceiverSipServlet.java +++ b/sip-servlets-test-suite/applications/replaces-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ReplacesReceiverSipServlet.java @@ -1,123 +1,169 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite; - -import java.io.IOException; - -import javax.annotation.Resource; -import javax.servlet.ServletException; -import javax.servlet.sip.SipApplicationSession; -import javax.servlet.sip.SipFactory; -import javax.servlet.sip.SipServlet; -import javax.servlet.sip.SipServletRequest; -import javax.servlet.sip.SipServletResponse; -import javax.servlet.sip.SipSession; -import javax.servlet.sip.SipSessionsUtil; -import javax.servlet.sip.SipURI; - -import org.apache.log4j.Logger; - - -public class ReplacesReceiverSipServlet extends SipServlet { - private static final long serialVersionUID = 1L; - private static final String REPLACES = "Replaces"; - private static transient Logger logger = Logger.getLogger(ReplacesReceiverSipServlet.class); - private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; - - @Resource - private SipFactory sipFactory; - @Resource - private SipSessionsUtil sipSessionsUtil; - - /** Creates a new instance of ReplacesSenderSipServlet */ - public ReplacesReceiverSipServlet() { - } - - @Override - protected void doInvite(SipServletRequest request) throws ServletException, - IOException { - logger.info("Got request:\n" + request.toString()); - SipServletResponse sipServletResponse = - request.createResponse(SipServletResponse.SC_OK); - if("receiver".equalsIgnoreCase(((SipURI)request.getFrom().getURI()).getUser()) && request.getHeader(REPLACES) == null) { - sipServletResponse = - request.createResponse(SipServletResponse.SC_DECLINE); - } else if("receiver".equalsIgnoreCase(((SipURI)request.getFrom().getURI()).getUser()) && request.getHeader(REPLACES) != null) { - SipSession sipSession = sipSessionsUtil.getCorrespondingSipSession(request.getSession(), REPLACES); - if(sipSession == null) { - sipServletResponse = - request.createResponse(SipServletResponse.SC_DECLINE); - } - request.getSession().setAttribute("ReplacesInviteReceived", Boolean.TRUE); - } - sipServletResponse.send(); - } - - @Override - protected void doAck(SipServletRequest request) throws ServletException, - IOException { - if(request.getSession().getAttribute("ReplacesInviteReceived") == null) { - //building the Replaces content - String callId = request.getHeader("Call-ID"); - String fromTag = request.getFrom().getParameter("tag"); - String toTag = request.getTo().getParameter("tag"); - String messageContent = "Replaces : " + callId + "; from-tag=" + fromTag + "; to-tag=" + toTag; - - SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); - SipURI fromURI = sipFactory.createSipURI("receiver", "sip-servlets.com"); - SipURI requestURI = sipFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090"); - SipServletRequest sipServletRequest = sipFactory.createRequest(sipApplicationSession, "MESSAGE", fromURI, request.getFrom().getURI()); - sipServletRequest.setContentLength(messageContent.length()); - sipServletRequest.setContent(messageContent, CONTENT_TYPE); - sipServletRequest.setRequestURI(requestURI); - sipServletRequest.send(); - } else { - SipSession sipSession = request.getSession(); - sipSession.createRequest("BYE").send(); - SipSession replacedSession = sipSessionsUtil.getCorrespondingSipSession(sipSession, REPLACES); - replacedSession.createRequest("BYE").send(); - } - } - - @Override - protected void doSuccessResponse(SipServletResponse resp) - throws ServletException, IOException { - logger.info("Got Success Response : " + resp); - if(!"BYE".equalsIgnoreCase(resp.getMethod())) { - resp.createAck().send(); - } - } - - /** - * {@inheritDoc} - */ - protected void doBye(SipServletRequest request) throws ServletException, - IOException { - - if(request.getSession().getAttribute("replacesInvite") != null) { - logger.info("Got BYE request: " + request); - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); - sipServletResponse.send(); - } - } +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import javax.annotation.Resource; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.sip.SipApplicationSession; +import javax.servlet.sip.SipFactory; +import javax.servlet.sip.SipServlet; +import javax.servlet.sip.SipServletRequest; +import javax.servlet.sip.SipServletResponse; +import javax.servlet.sip.SipSession; +import javax.servlet.sip.SipSessionsUtil; +import javax.servlet.sip.SipURI; +import javax.servlet.sip.URI; + +import org.apache.log4j.Logger; +import static org.mobicents.servlet.sip.testsuite.ReplacesSenderSipServlet.ctx; + + +public class ReplacesReceiverSipServlet extends SipServlet { + private static final long serialVersionUID = 1L; + private static final String REPLACES = "Replaces"; + private static transient Logger logger = Logger.getLogger(ReplacesReceiverSipServlet.class); + private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; + + @Resource + private SipFactory sipFactory; + @Resource + private SipSessionsUtil sipSessionsUtil; + + /** Creates a new instance of ReplacesSenderSipServlet */ + public ReplacesReceiverSipServlet() { + } + + @Override + protected void doInvite(SipServletRequest request) throws ServletException, + IOException { + logger.info("Got request:\n" + request.toString()); + SipServletResponse sipServletResponse = + request.createResponse(SipServletResponse.SC_OK); + if("receiver".equalsIgnoreCase(((SipURI)request.getFrom().getURI()).getUser()) && request.getHeader(REPLACES) == null) { + sipServletResponse = + request.createResponse(SipServletResponse.SC_DECLINE); + } else if("receiver".equalsIgnoreCase(((SipURI)request.getFrom().getURI()).getUser()) && request.getHeader(REPLACES) != null) { + SipSession sipSession = sipSessionsUtil.getCorrespondingSipSession(request.getSession(), REPLACES); + if(sipSession == null) { + sipServletResponse = + request.createResponse(SipServletResponse.SC_DECLINE); + } + request.getSession().setAttribute("ReplacesInviteReceived", Boolean.TRUE); + } + sipServletResponse.send(); + } + + @Override + protected void doAck(SipServletRequest request) throws ServletException, + IOException { + if(request.getSession().getAttribute("ReplacesInviteReceived") == null) { + //building the Replaces content + String callId = request.getHeader("Call-ID"); + String fromTag = request.getFrom().getParameter("tag"); + String toTag = request.getTo().getParameter("tag"); + String messageContent = "Replaces : " + callId + "; from-tag=" + fromTag + "; to-tag=" + toTag; + + SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); + SipURI fromURI = sipFactory.createSipURI("receiver", "sip-servlets.com"); + SipURI requestURI = sipFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + SipServletRequest sipServletRequest = sipFactory.createRequest(sipApplicationSession, "MESSAGE", fromURI, request.getFrom().getURI()); + sipServletRequest.setContentLength(messageContent.length()); + sipServletRequest.setContent(messageContent, CONTENT_TYPE); + sipServletRequest.setRequestURI(requestURI); + sipServletRequest.send(); + } else { + SipSession sipSession = request.getSession(); + sipSession.createRequest("BYE").send(); + SipSession replacedSession = sipSessionsUtil.getCorrespondingSipSession(sipSession, REPLACES); + replacedSession.createRequest("BYE").send(); + } + } + + @Override + protected void doSuccessResponse(SipServletResponse resp) + throws ServletException, IOException { + logger.info("Got Success Response : " + resp); + if(!"BYE".equalsIgnoreCase(resp.getMethod())) { + resp.createAck().send(); + } + } + + /** + * {@inheritDoc} + */ + protected void doBye(SipServletRequest request) throws ServletException, + IOException { + + if(request.getSession().getAttribute("replacesInvite") != null) { + logger.info("Got BYE request: " + request); + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); + sipServletResponse.send(); + } + } + + static ServletContext ctx; + + @Override + public void init(ServletConfig servletConfig) throws ServletException { + logger.info("the sip servlet has been started"); + super.init(servletConfig); + ctx = servletConfig.getServletContext(); + } + + public static Integer getTestPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("testPort"); + logger.info("TestPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5090; + } + } + + public static Integer getSenderPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("senderPort"); + logger.info("senderPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5080; + } + } + + public static Integer getServletContainerPort(ServletContext ctx) { + String cPort = ctx.getInitParameter("servletContainerPort"); + logger.info("TestPort at:" + cPort); + if (cPort != null) { + return Integer.valueOf(cPort); + } else { + return 5070; + } + } } \ No newline at end of file diff --git a/sip-servlets-test-suite/applications/replaces-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ReplacesSenderSipServlet.java b/sip-servlets-test-suite/applications/replaces-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ReplacesSenderSipServlet.java index f245c4bcf4..005a227a2a 100644 --- a/sip-servlets-test-suite/applications/replaces-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ReplacesSenderSipServlet.java +++ b/sip-servlets-test-suite/applications/replaces-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ReplacesSenderSipServlet.java @@ -1,133 +1,167 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.annotation.Resource; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.sip.Proxy; -import javax.servlet.sip.SipApplicationSession; -import javax.servlet.sip.SipFactory; -import javax.servlet.sip.SipServlet; -import javax.servlet.sip.SipServletRequest; -import javax.servlet.sip.SipServletResponse; -import javax.servlet.sip.SipURI; -import javax.servlet.sip.URI; - -import org.apache.log4j.Logger; - - -public class ReplacesSenderSipServlet extends SipServlet { - private static final long serialVersionUID = 1L; - private static transient Logger logger = Logger.getLogger(ReplacesSenderSipServlet.class); - Map> registeredUsers = null; - - @Resource - private SipFactory sipFactory; - - /** Creates a new instance of ReplacesSenderSipServlet */ - public ReplacesSenderSipServlet() { - } - - @Override - public void init(ServletConfig servletConfig) throws ServletException { - logger.info("the join sip servlet has been started"); - super.init(servletConfig); - SipFactory sipFactory = (SipFactory)getServletContext().getAttribute(SIP_FACTORY); - registeredUsers = new HashMap>(); - List uriList = new ArrayList(); - uriList.add(sipFactory.createURI("sip:replaces@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090")); - registeredUsers.put("sip:replaces@sip-servlets.com", uriList); - registeredUsers.put("sip:replaces@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070;transport=udp", uriList); - } - - /** - * {@inheritDoc} - */ - protected void doMessage(SipServletRequest request) throws ServletException, - IOException { - logger.info("Got request: " - + request.getMethod()); - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); - sipServletResponse.send(); - - SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); - SipURI fromURI = sipFactory.createSipURI("replacer", "sip-servlets.com"); - SipURI requestURI = sipFactory.createSipURI("replacer", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090"); - SipServletRequest sipServletRequest = sipFactory.createRequest(sipApplicationSession, "INVITE", fromURI, request.getFrom().getURI()); - sipServletRequest.addHeader("Replaces", ((String)request.getContent()).substring("Replaces : ".length())); - sipServletRequest.setRequestURI(requestURI); - sipServletRequest.getSession().setAttribute("replacesInvite", Boolean.TRUE); - sipServletRequest.send(); - } - - @Override - protected void doInvite(SipServletRequest request) throws ServletException, - IOException { - - logger.info("Got request:\n" + request.toString()); - - List contactAddresses = registeredUsers.get(request.getRequestURI().toString()); - if(contactAddresses != null && contactAddresses.size() > 0) { - Proxy proxy = request.getProxy(); - proxy.setProxyTimeout(3); - proxy.setRecordRoute(true); - proxy.setParallel(true); - proxy.setSupervised(true); - proxy.proxyTo(contactAddresses); - } else { - logger.info(request.getRequestURI().toString() + " is not currently registered"); - SipServletResponse sipServletResponse = - request.createResponse(SipServletResponse.SC_MOVED_PERMANENTLY, "Moved Permanently"); - sipServletResponse.send(); - } - } - - @Override - protected void doSuccessResponse(SipServletResponse resp) - throws ServletException, IOException { - if(!"BYE".equalsIgnoreCase(resp.getMethod()) && resp.getSession().getAttribute("replacesInvite") != null) { - resp.createAck().send(); -// resp.getSession(false).createRequest("BYE").send(); - } - } - - /** - * {@inheritDoc} - */ - protected void doBye(SipServletRequest request) throws ServletException, - IOException { - - if(request.getSession().getAttribute("replacesInvite") != null) { - logger.info("Got BYE request: " + request); - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); - sipServletResponse.send(); - } - } +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.sip.Proxy; +import javax.servlet.sip.SipApplicationSession; +import javax.servlet.sip.SipFactory; +import javax.servlet.sip.SipServlet; +import javax.servlet.sip.SipServletRequest; +import javax.servlet.sip.SipServletResponse; +import javax.servlet.sip.SipURI; +import javax.servlet.sip.URI; + +import org.apache.log4j.Logger; + + +public class ReplacesSenderSipServlet extends SipServlet { + private static final long serialVersionUID = 1L; + private static transient Logger logger = Logger.getLogger(ReplacesSenderSipServlet.class); + Map> registeredUsers = null; + + static ServletContext ctx; + + @Resource + private SipFactory sipFactory; + + /** Creates a new instance of ReplacesSenderSipServlet */ + public ReplacesSenderSipServlet() { + } + + @Override + public void init(ServletConfig servletConfig) throws ServletException { + logger.info("the join sip servlet has been started"); + super.init(servletConfig); + ctx = servletConfig.getServletContext(); + SipFactory sipFactory = (SipFactory)getServletContext().getAttribute(SIP_FACTORY); + registeredUsers = new HashMap>(); + List uriList = new ArrayList(); + uriList.add(sipFactory.createURI("sip:replaces@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx))); + registeredUsers.put("sip:replaces@sip-servlets.com", uriList); + registeredUsers.put("sip:replaces@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getServletContainerPort(ctx) + ";transport=udp", uriList); + } + + /** + * {@inheritDoc} + */ + protected void doMessage(SipServletRequest request) throws ServletException, + IOException { + logger.info("Got request: " + + request.getMethod()); + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); + sipServletResponse.send(); + + SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); + SipURI fromURI = sipFactory.createSipURI("replacer", "sip-servlets.com"); + SipURI requestURI = sipFactory.createSipURI("replacer", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + SipServletRequest sipServletRequest = sipFactory.createRequest(sipApplicationSession, "INVITE", fromURI, request.getFrom().getURI()); + sipServletRequest.addHeader("Replaces", ((String)request.getContent()).substring("Replaces : ".length())); + sipServletRequest.setRequestURI(requestURI); + sipServletRequest.getSession().setAttribute("replacesInvite", Boolean.TRUE); + sipServletRequest.send(); + } + + @Override + protected void doInvite(SipServletRequest request) throws ServletException, + IOException { + + logger.info("Got request:\n" + request.toString()); + + List contactAddresses = registeredUsers.get(request.getRequestURI().toString()); + if(contactAddresses != null && contactAddresses.size() > 0) { + Proxy proxy = request.getProxy(); + proxy.setProxyTimeout(3); + proxy.setRecordRoute(true); + proxy.setParallel(true); + proxy.setSupervised(true); + proxy.proxyTo(contactAddresses); + } else { + logger.info(request.getRequestURI().toString() + " is not currently registered"); + SipServletResponse sipServletResponse = + request.createResponse(SipServletResponse.SC_MOVED_PERMANENTLY, "Moved Permanently"); + sipServletResponse.send(); + } + } + + @Override + protected void doSuccessResponse(SipServletResponse resp) + throws ServletException, IOException { + if(!"BYE".equalsIgnoreCase(resp.getMethod()) && resp.getSession().getAttribute("replacesInvite") != null) { + resp.createAck().send(); +// resp.getSession(false).createRequest("BYE").send(); + } + } + + /** + * {@inheritDoc} + */ + protected void doBye(SipServletRequest request) throws ServletException, + IOException { + + if(request.getSession().getAttribute("replacesInvite") != null) { + logger.info("Got BYE request: " + request); + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); + sipServletResponse.send(); + } + } + + public static Integer getTestPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("testPort"); + logger.info("TestPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5090; + } + } + + public static Integer getSenderPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("senderPort"); + logger.info("senderPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5080; + } + } + + public static Integer getServletContainerPort(ServletContext ctx) { + String cPort = ctx.getInitParameter("servletContainerPort"); + logger.info("TestPort at:" + cPort); + if (cPort != null) { + return Integer.valueOf(cPort); + } else { + return 5070; + } + } } \ No newline at end of file diff --git a/sip-servlets-test-suite/applications/same-instance-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/SameInstanceSipServlet.java b/sip-servlets-test-suite/applications/same-instance-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/SameInstanceSipServlet.java index 1ee37f96c9..1ac3103b01 100644 --- a/sip-servlets-test-suite/applications/same-instance-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/SameInstanceSipServlet.java +++ b/sip-servlets-test-suite/applications/same-instance-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/SameInstanceSipServlet.java @@ -30,6 +30,7 @@ import javax.naming.InitialContext; import javax.naming.NamingException; import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.sip.ServletParseException; import javax.servlet.sip.ServletTimer; @@ -62,6 +63,8 @@ public class SameInstanceSipServlet private TimerService timerService; private SipServlet instance; + + static ServletContext ctx; @Override public void init(ServletConfig servletConfig) throws ServletException { @@ -75,6 +78,7 @@ public void init(ServletConfig servletConfig) throws ServletException { Context initCtx = new InitialContext(jndiProps); Context envCtx = (Context) initCtx.lookup("java:comp/env"); SipFactory jndiSipFactory = (SipFactory) envCtx.lookup("sip/SameInstanceServletTestApplication/SipFactory"); + ctx = servletConfig.getServletContext(); logger.info("Sip Factory ref from JNDI : " + jndiSipFactory); } catch (NamingException e) { throw new ServletException("Uh oh -- JNDI problem !", e); @@ -106,7 +110,7 @@ public void sessionCreated(SipApplicationSessionEvent event) { "MESSAGE", "sip:sender@sip-servlets.com", "sip:receiver@sip-servlets.com"); - SipURI sipUri=sipFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); + SipURI sipUri=sipFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); sipServletRequest.setRequestURI(sipUri); sipServletRequest.setContentLength(INSTANCES_DIFFERENT.length()); sipServletRequest.setContent(INSTANCES_DIFFERENT, CONTENT_TYPE); @@ -145,7 +149,7 @@ public void timeout(ServletTimer timer) { "MESSAGE", "sip:sender@sip-servlets.com", "sip:receiver@sip-servlets.com"); - SipURI sipUri=sipFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); + SipURI sipUri=sipFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); sipServletRequest.setRequestURI(sipUri); sipServletRequest.setContentLength(INSTANCES_DIFFERENT.length()); sipServletRequest.setContent(INSTANCES_DIFFERENT, CONTENT_TYPE); @@ -159,5 +163,24 @@ public void timeout(ServletTimer timer) { } } + public static Integer getTestPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("testPort"); + logger.info("TestPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5080; + } + } + + public static Integer getServletContainerPort(ServletContext ctx) { + String cPort = ctx.getInitParameter("servletContainerPort"); + logger.info("TestPort at:" + cPort); + if (cPort != null) { + return Integer.valueOf(cPort); + } else { + return 5070; + } + } } \ No newline at end of file diff --git a/sip-servlets-test-suite/applications/same-instance-servlet/src/main/sipapp/WEB-INF/web.xml b/sip-servlets-test-suite/applications/same-instance-servlet/src/main/sipapp/WEB-INF/web.xml new file mode 100644 index 0000000000..ad5a874273 --- /dev/null +++ b/sip-servlets-test-suite/applications/same-instance-servlet/src/main/sipapp/WEB-INF/web.xml @@ -0,0 +1,19 @@ + + + + SameInstanceServletTestApplication + + SameInstanceSipServlet + SameInstanceSipServlet + SameInstance SIP servlet + + org.mobicents.servlet.sip.testsuite.SameInstanceSipServlet + + + + + + org.mobicents.servlet.sip.testsuite.SameInstanceSipServlet + + + \ No newline at end of file diff --git a/sip-servlets-test-suite/applications/servlet-mapping-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ServletMappingSipServlet.java b/sip-servlets-test-suite/applications/servlet-mapping-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ServletMappingSipServlet.java index 0639228336..46a25699a6 100644 --- a/sip-servlets-test-suite/applications/servlet-mapping-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ServletMappingSipServlet.java +++ b/sip-servlets-test-suite/applications/servlet-mapping-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ServletMappingSipServlet.java @@ -1,115 +1,139 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; - -import javax.annotation.Resource; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.sip.ServletParseException; -import javax.servlet.sip.SipApplicationSession; -import javax.servlet.sip.SipFactory; -import javax.servlet.sip.SipServlet; -import javax.servlet.sip.SipServletContextEvent; -import javax.servlet.sip.SipServletListener; -import javax.servlet.sip.SipServletRequest; -import javax.servlet.sip.SipServletResponse; - -import org.apache.log4j.Logger; - - -public class ServletMappingSipServlet extends SipServlet implements SipServletListener { - private static final long serialVersionUID = 1L; - private static transient Logger logger = Logger.getLogger(ServletMappingSipServlet.class); - - @Resource - private SipFactory factory; - - /** Creates a new instance of ServletMappingSipServlet */ - public ServletMappingSipServlet() { - } - - @Override - public void init(ServletConfig servletConfig) throws ServletException { - logger.info("the servlet mamping sip servlet has been started"); - super.init(servletConfig); - } - - /** - * {@inheritDoc} - */ - protected void doInvite(SipServletRequest request) throws ServletException, - IOException { - - sendMessage("inviteReceived"); - - logger.info("Got request: " - + request.getMethod()); - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_RINGING); - sipServletResponse.send(); - sipServletResponse = request.createResponse(SipServletResponse.SC_OK); - sipServletResponse.send(); - } - - /** - * {@inheritDoc} - */ - protected void doBye(SipServletRequest request) throws ServletException, - IOException { - - logger.info("Got BYE request: " + request); - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); - sipServletResponse.send(); - } - - public void servletInitialized(SipServletContextEvent ce) { - try { - if(ce.getSipServlet().equals(this)) { - sendMessage("servletInitialized"); - } - } catch (Exception e) { - logger.error("unexpected exception while trying to send the invite out", e); - } - } - - /** - * @throws ServletParseException - * @throws UnsupportedEncodingException - * @throws IOException - */ - private void sendMessage(String body) throws ServletParseException, - UnsupportedEncodingException, IOException { - SipApplicationSession appSession = factory.createApplicationSession(); - SipServletRequest request = - factory.createRequest(appSession, "MESSAGE", - "sip:from@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070", "sip:to@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - request.setContentLength(2); - request.setContent(body, "text/plain;charset=UTF-8"); - request.send(); - } - - - +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; + +import javax.annotation.Resource; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.sip.ServletParseException; +import javax.servlet.sip.SipApplicationSession; +import javax.servlet.sip.SipFactory; +import javax.servlet.sip.SipServlet; +import javax.servlet.sip.SipServletContextEvent; +import javax.servlet.sip.SipServletListener; +import javax.servlet.sip.SipServletRequest; +import javax.servlet.sip.SipServletResponse; + +import org.apache.log4j.Logger; + + +public class ServletMappingSipServlet extends SipServlet implements SipServletListener { + private static final long serialVersionUID = 1L; + private static transient Logger logger = Logger.getLogger(ServletMappingSipServlet.class); + + @Resource + private SipFactory factory; + + static ServletContext ctx; + + /** Creates a new instance of ServletMappingSipServlet */ + public ServletMappingSipServlet() { + } + + @Override + public void init(ServletConfig servletConfig) throws ServletException { + logger.info("the servlet mamping sip servlet has been started"); + super.init(servletConfig); + ctx = servletConfig.getServletContext(); + } + + /** + * {@inheritDoc} + */ + protected void doInvite(SipServletRequest request) throws ServletException, + IOException { + + sendMessage("inviteReceived"); + + logger.info("Got request: " + + request.getMethod()); + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_RINGING); + sipServletResponse.send(); + sipServletResponse = request.createResponse(SipServletResponse.SC_OK); + sipServletResponse.send(); + } + + /** + * {@inheritDoc} + */ + protected void doBye(SipServletRequest request) throws ServletException, + IOException { + + logger.info("Got BYE request: " + request); + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); + sipServletResponse.send(); + } + + public void servletInitialized(SipServletContextEvent ce) { + try { + if(ce.getSipServlet().equals(this)) { + sendMessage("servletInitialized"); + } + } catch (Exception e) { + logger.error("unexpected exception while trying to send the invite out", e); + } + } + + /** + * @throws ServletParseException + * @throws UnsupportedEncodingException + * @throws IOException + */ + private void sendMessage(String body) throws ServletParseException, + UnsupportedEncodingException, IOException { + SipApplicationSession appSession = factory.createApplicationSession(); + SipServletRequest request = + factory.createRequest(appSession, "MESSAGE", + "sip:from@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getServletContainerPort(ctx), + "sip:to@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + request.setContentLength(2); + request.setContent(body, "text/plain;charset=UTF-8"); + request.send(); + } + + public static Integer getTestPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("testPort"); + logger.info("TestPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5080; + } + } + + public static Integer getServletContainerPort(ServletContext ctx) { + String cPort = ctx.getInitParameter("servletContainerPort"); + logger.info("TestPort at:" + cPort); + if (cPort != null) { + return Integer.valueOf(cPort); + } else { + return 5070; + } + } + + } \ No newline at end of file diff --git a/sip-servlets-test-suite/applications/session-state-uac/src/main/java/org/mobicents/servlet/sip/testsuite/SessionStateUACSipServlet.java b/sip-servlets-test-suite/applications/session-state-uac/src/main/java/org/mobicents/servlet/sip/testsuite/SessionStateUACSipServlet.java index 817b9d9293..e2489c65e4 100644 --- a/sip-servlets-test-suite/applications/session-state-uac/src/main/java/org/mobicents/servlet/sip/testsuite/SessionStateUACSipServlet.java +++ b/sip-servlets-test-suite/applications/session-state-uac/src/main/java/org/mobicents/servlet/sip/testsuite/SessionStateUACSipServlet.java @@ -1,231 +1,254 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite; - -import java.io.IOException; -import java.util.Properties; - -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NamingException; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.sip.ServletParseException; -import javax.servlet.sip.SipApplicationSession; -import javax.servlet.sip.SipApplicationSessionEvent; -import javax.servlet.sip.SipApplicationSessionListener; -import javax.servlet.sip.SipFactory; -import javax.servlet.sip.SipServlet; -import javax.servlet.sip.SipServletContextEvent; -import javax.servlet.sip.SipServletListener; -import javax.servlet.sip.SipServletRequest; -import javax.servlet.sip.SipServletResponse; -import javax.servlet.sip.SipSessionEvent; -import javax.servlet.sip.SipSessionListener; -import javax.servlet.sip.SipURI; - -import org.apache.log4j.Logger; - - -public class SessionStateUACSipServlet - extends SipServlet - implements SipServletListener, SipApplicationSessionListener, SipSessionListener { - private static final long serialVersionUID = 1L; - private static transient Logger logger = Logger.getLogger(SessionStateUACSipServlet.class); - - private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; - private static final String SEND_1XX_4XX = "send1xx_4xx"; -// private static final String SEND_1XX_2XX = "send1xx_2xx"; -// private static final String SEND_4XX = "send4xx"; -// private static final String SEND_2XX = "send2xx"; -// -// private SipFactory sipFactory; - - /** Creates a new instance of SessionStateUACSipServlet */ - public SessionStateUACSipServlet() { - } - - @Override - public void init(ServletConfig servletConfig) throws ServletException { - super.init(servletConfig); - logger.info("the session state UAC test sip servlet has been started"); - } - - @Override - protected void doResponse(SipServletResponse sipServletResponse) - throws ServletException, IOException { - logger.info("Got : " + sipServletResponse); - if ("INVITE".equalsIgnoreCase(sipServletResponse.getMethod())) { - SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); - sendMessage(sipFactory, sipServletResponse.getSession().getState().toString()); - } - SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); - if(sipServletResponse.getStatus() == 408) { - try { - Properties jndiProps = new Properties(); - Context initCtx = new InitialContext(jndiProps); - Context envCtx = (Context) initCtx.lookup("java:comp/env"); - sipFactory = (SipFactory) envCtx.lookup("sip/org.mobicents.servlet.sip.testsuite.SessionStateUACApplication/SipFactory"); - sendMessage(sipFactory, "408 received"); - } catch (NamingException e) { - throw new ServletException("Uh oh -- JNDI problem !", e); - } - } - if(sipServletResponse.getStatus() == 200 && "INVITE".equalsIgnoreCase(sipServletResponse.getMethod())) { - sipServletResponse.createAck().send(); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - SipServletRequest refer =sipServletResponse.getSession().createRequest("REFER"); - refer.addHeader("Refer-To", "sip:refer-to@nist.gov"); - refer.send(); - } - if(sipServletResponse.getStatus() >= 200 && "REFER".equalsIgnoreCase(sipServletResponse.getMethod())) { - sendMessage(sipFactory, sipServletResponse.getSession().getState().toString()); - } - } - - @Override - protected void doBye(SipServletRequest req) throws ServletException, - IOException { - req.createResponse(200).send(); - SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); - sendMessage(sipFactory, req.getSession().getState().toString()); - } - - // SipServletListener methods - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipServletListener#servletInitialized(javax.servlet.sip.SipServletContextEvent) - */ - public void servletInitialized(SipServletContextEvent ce) { - SipFactory sipFactory = (SipFactory)ce.getServletContext().getAttribute(SIP_FACTORY); - if(getServletContext().getInitParameter("testTimeout") != null) { - sendMessage(sipFactory, "This request must timeout", "sip:timeout@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":4794"); - }else { - SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); - SipURI fromURI = sipFactory.createSipURI("BigGuy", "here.com"); - SipURI toURI = sipFactory.createSipURI("LittleGuy", "there.com"); - SipServletRequest sipServletRequest = - sipFactory.createRequest(sipApplicationSession, "INVITE", fromURI, toURI); - SipURI requestURI = sipFactory.createSipURI("LittleGuy", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - sipServletRequest.setRequestURI(requestURI); - sipServletRequest.setContentLength(SEND_1XX_4XX.length()); - try { - sipServletRequest.setContent(SEND_1XX_4XX, CONTENT_TYPE); - sipServletRequest.send(); - } catch (IOException e) { - logger.error("An Io exception occured while trying to set the content or send the request", e); - } - sendMessage(sipFactory, sipServletRequest.getSession().getState().toString()); - } - } - - /** - * Utility method to send a message out of dialog - * @param messageContent messageContent - */ - public void sendMessage(SipFactory sipFactory, String messageContent) { - try { - SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); - SipServletRequest sipServletRequest = sipFactory.createRequest( - sipApplicationSession, - "MESSAGE", - "sip:sender@sip-servlets.com", - "sip:receiver@sip-servlets.com"); - SipURI sipUri = sipFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - sipServletRequest.setRequestURI(sipUri); - sipServletRequest.setContentLength(messageContent.length()); - sipServletRequest.setContent(messageContent, CONTENT_TYPE); - sipServletRequest.send(); - } catch (ServletParseException e) { - logger.error("Exception occured while parsing the addresses",e); - } catch (IOException e) { - logger.error("Exception occured while sending the request",e); - } - } - - public void sendMessage(SipFactory sipFactory, String messageContent, String addr) { - try { - SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); - SipServletRequest sipServletRequest = sipFactory.createRequest( - sipApplicationSession, - "MESSAGE", - "sip:sender@sip-servlets.com", - "sip:receiver@sip-servlets.com"); - SipURI sipUri = (SipURI) sipFactory.createURI(addr); - sipServletRequest.setRequestURI(sipUri); - sipServletRequest.setContentLength(messageContent.length()); - sipServletRequest.setContent(messageContent, CONTENT_TYPE); - sipServletRequest.send(); - sipApplicationSession.setExpires(1); - } catch (ServletParseException e) { - logger.error("Exception occured while parsing the addresses",e); - } catch (IOException e) { - logger.error("Exception occured while sending the request",e); - } - } - - public void sessionCreated(SipApplicationSessionEvent ev) { - // TODO Auto-generated method stub - - } - - public void sessionDestroyed(SipApplicationSessionEvent ev) { - // TODO Auto-generated method stub - - } - - public void sessionExpired(SipApplicationSessionEvent ev) { - SipFactory sipFactory = (SipFactory)getServletContext().getAttribute(SIP_FACTORY); - sendMessage(sipFactory, "sessionExpired"); - } - - public void sessionReadyToInvalidate(SipApplicationSessionEvent ev) { - SipFactory sipFactory = (SipFactory)getServletContext().getAttribute(SIP_FACTORY); - if(getServletContext().getInitParameter("testTimeout") != null) { - sendMessage(sipFactory, "sipAppSessionReadyToInvalidate"); - } - } - - public void sessionCreated(SipSessionEvent se) { - // TODO Auto-generated method stub - - } - - public void sessionDestroyed(SipSessionEvent se) { - // TODO Auto-generated method stub - - } - - public void sessionReadyToInvalidate(SipSessionEvent se) { - SipFactory sipFactory = (SipFactory)getServletContext().getAttribute(SIP_FACTORY); - if(getServletContext().getInitParameter("testTimeout") != null) { - sendMessage(sipFactory, "sipSessionReadyToInvalidate"); - } - } - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite; + +import java.io.IOException; +import java.util.Properties; + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.sip.ServletParseException; +import javax.servlet.sip.SipApplicationSession; +import javax.servlet.sip.SipApplicationSessionEvent; +import javax.servlet.sip.SipApplicationSessionListener; +import javax.servlet.sip.SipFactory; +import javax.servlet.sip.SipServlet; +import javax.servlet.sip.SipServletContextEvent; +import javax.servlet.sip.SipServletListener; +import javax.servlet.sip.SipServletRequest; +import javax.servlet.sip.SipServletResponse; +import javax.servlet.sip.SipSessionEvent; +import javax.servlet.sip.SipSessionListener; +import javax.servlet.sip.SipURI; + +import org.apache.log4j.Logger; + + +public class SessionStateUACSipServlet + extends SipServlet + implements SipServletListener, SipApplicationSessionListener, SipSessionListener { + private static final long serialVersionUID = 1L; + private static transient Logger logger = Logger.getLogger(SessionStateUACSipServlet.class); + + private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; + private static final String SEND_1XX_4XX = "send1xx_4xx"; +// private static final String SEND_1XX_2XX = "send1xx_2xx"; +// private static final String SEND_4XX = "send4xx"; +// private static final String SEND_2XX = "send2xx"; +// +// private SipFactory sipFactory; + static ServletContext ctx; + + /** Creates a new instance of SessionStateUACSipServlet */ + public SessionStateUACSipServlet() { + } + + @Override + public void init(ServletConfig servletConfig) throws ServletException { + super.init(servletConfig); + logger.info("the session state UAC test sip servlet has been started"); + ctx = servletConfig.getServletContext(); + } + + @Override + protected void doResponse(SipServletResponse sipServletResponse) + throws ServletException, IOException { + logger.info("Got : " + sipServletResponse); + if ("INVITE".equalsIgnoreCase(sipServletResponse.getMethod())) { + SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); + sendMessage(sipFactory, sipServletResponse.getSession().getState().toString()); + } + SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); + if(sipServletResponse.getStatus() == 408) { + try { + Properties jndiProps = new Properties(); + Context initCtx = new InitialContext(jndiProps); + Context envCtx = (Context) initCtx.lookup("java:comp/env"); + sipFactory = (SipFactory) envCtx.lookup("sip/org.mobicents.servlet.sip.testsuite.SessionStateUACApplication/SipFactory"); + sendMessage(sipFactory, "408 received"); + } catch (NamingException e) { + throw new ServletException("Uh oh -- JNDI problem !", e); + } + } + if(sipServletResponse.getStatus() == 200 && "INVITE".equalsIgnoreCase(sipServletResponse.getMethod())) { + sipServletResponse.createAck().send(); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + SipServletRequest refer =sipServletResponse.getSession().createRequest("REFER"); + refer.addHeader("Refer-To", "sip:refer-to@nist.gov"); + refer.send(); + } + if(sipServletResponse.getStatus() >= 200 && "REFER".equalsIgnoreCase(sipServletResponse.getMethod())) { + sendMessage(sipFactory, sipServletResponse.getSession().getState().toString()); + } + } + + @Override + protected void doBye(SipServletRequest req) throws ServletException, + IOException { + req.createResponse(200).send(); + SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); + sendMessage(sipFactory, req.getSession().getState().toString()); + } + + // SipServletListener methods + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipServletListener#servletInitialized(javax.servlet.sip.SipServletContextEvent) + */ + public void servletInitialized(SipServletContextEvent ce) { + SipFactory sipFactory = (SipFactory)ce.getServletContext().getAttribute(SIP_FACTORY); + if(getServletContext().getInitParameter("testTimeout") != null) { + sendMessage(sipFactory, "This request must timeout", "sip:timeout@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":4794"); + }else { + SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); + SipURI fromURI = sipFactory.createSipURI("BigGuy", "here.com"); + SipURI toURI = sipFactory.createSipURI("LittleGuy", "there.com"); + SipServletRequest sipServletRequest = + sipFactory.createRequest(sipApplicationSession, "INVITE", fromURI, toURI); + SipURI requestURI = sipFactory.createSipURI("LittleGuy", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + sipServletRequest.setRequestURI(requestURI); + sipServletRequest.setContentLength(SEND_1XX_4XX.length()); + try { + sipServletRequest.setContent(SEND_1XX_4XX, CONTENT_TYPE); + sipServletRequest.send(); + } catch (IOException e) { + logger.error("An Io exception occured while trying to set the content or send the request", e); + } + sendMessage(sipFactory, sipServletRequest.getSession().getState().toString()); + } + } + + /** + * Utility method to send a message out of dialog + * @param messageContent messageContent + */ + public void sendMessage(SipFactory sipFactory, String messageContent) { + try { + SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); + SipServletRequest sipServletRequest = sipFactory.createRequest( + sipApplicationSession, + "MESSAGE", + "sip:sender@sip-servlets.com", + "sip:receiver@sip-servlets.com"); + SipURI sipUri = sipFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + sipServletRequest.setRequestURI(sipUri); + sipServletRequest.setContentLength(messageContent.length()); + sipServletRequest.setContent(messageContent, CONTENT_TYPE); + sipServletRequest.send(); + } catch (ServletParseException e) { + logger.error("Exception occured while parsing the addresses",e); + } catch (IOException e) { + logger.error("Exception occured while sending the request",e); + } + } + + public void sendMessage(SipFactory sipFactory, String messageContent, String addr) { + try { + SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); + SipServletRequest sipServletRequest = sipFactory.createRequest( + sipApplicationSession, + "MESSAGE", + "sip:sender@sip-servlets.com", + "sip:receiver@sip-servlets.com"); + SipURI sipUri = (SipURI) sipFactory.createURI(addr); + sipServletRequest.setRequestURI(sipUri); + sipServletRequest.setContentLength(messageContent.length()); + sipServletRequest.setContent(messageContent, CONTENT_TYPE); + sipServletRequest.send(); + sipApplicationSession.setExpires(1); + } catch (ServletParseException e) { + logger.error("Exception occured while parsing the addresses",e); + } catch (IOException e) { + logger.error("Exception occured while sending the request",e); + } + } + + public void sessionCreated(SipApplicationSessionEvent ev) { + // TODO Auto-generated method stub + + } + + public void sessionDestroyed(SipApplicationSessionEvent ev) { + // TODO Auto-generated method stub + + } + + public void sessionExpired(SipApplicationSessionEvent ev) { + SipFactory sipFactory = (SipFactory)getServletContext().getAttribute(SIP_FACTORY); + sendMessage(sipFactory, "sessionExpired"); + } + + public void sessionReadyToInvalidate(SipApplicationSessionEvent ev) { + SipFactory sipFactory = (SipFactory)getServletContext().getAttribute(SIP_FACTORY); + if(getServletContext().getInitParameter("testTimeout") != null) { + sendMessage(sipFactory, "sipAppSessionReadyToInvalidate"); + } + } + + public void sessionCreated(SipSessionEvent se) { + // TODO Auto-generated method stub + + } + + public void sessionDestroyed(SipSessionEvent se) { + // TODO Auto-generated method stub + + } + + public void sessionReadyToInvalidate(SipSessionEvent se) { + SipFactory sipFactory = (SipFactory)getServletContext().getAttribute(SIP_FACTORY); + if(getServletContext().getInitParameter("testTimeout") != null) { + sendMessage(sipFactory, "sipSessionReadyToInvalidate"); + } + } + + public static Integer getTestPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("testPort"); + logger.info("TestPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5080; + } + } + + public static Integer getServletContainerPort(ServletContext ctx) { + String cPort = ctx.getInitParameter("servletContainerPort"); + logger.info("TestPort at:" + cPort); + if (cPort != null) { + return Integer.valueOf(cPort); + } else { + return 5070; + } + } + +} diff --git a/sip-servlets-test-suite/applications/session-state-uas/src/main/java/org/mobicents/servlet/sip/testsuite/SessionStateUASSipServlet.java b/sip-servlets-test-suite/applications/session-state-uas/src/main/java/org/mobicents/servlet/sip/testsuite/SessionStateUASSipServlet.java index 428e338631..28d91e7aee 100644 --- a/sip-servlets-test-suite/applications/session-state-uas/src/main/java/org/mobicents/servlet/sip/testsuite/SessionStateUASSipServlet.java +++ b/sip-servlets-test-suite/applications/session-state-uas/src/main/java/org/mobicents/servlet/sip/testsuite/SessionStateUASSipServlet.java @@ -1,219 +1,243 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite; - -import java.io.IOException; -import java.util.Properties; - -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NamingException; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.sip.ServletParseException; -import javax.servlet.sip.SipApplicationSession; -import javax.servlet.sip.SipFactory; -import javax.servlet.sip.SipServlet; -import javax.servlet.sip.SipServletRequest; -import javax.servlet.sip.SipServletResponse; -import javax.servlet.sip.SipURI; -import javax.servlet.sip.SipSession.State; - -import org.apache.log4j.Logger; - - -public class SessionStateUASSipServlet - extends SipServlet { - private static final long serialVersionUID = 1L; - private static transient Logger logger = Logger.getLogger(SessionStateUASSipServlet.class); - - private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; - private static final String SEND_1XX_2XX = "send1xx_2xx"; - private static final String SEND_1XX_4XX = "send1xx_4xx"; - private static final String SEND_4XX = "send4xx"; - private static final String SEND_2XX = "send2xx"; - private static final String TEST_TIMEOUT = "test_timeout"; - private static final String STX_408_RECEIVED = "408 received on STX"; - //TODO externalize in sip.xml and specify it from test if needed - private static final int TIMEOUT = 10000; - - private SipFactory sipFactory; - - - /** Creates a new instance of SessionStateUASSipServlet */ - public SessionStateUASSipServlet() { - } - - @Override - public void init(ServletConfig servletConfig) throws ServletException { - super.init(servletConfig); - logger.info("the session state UAS test sip servlet has been started"); - try { - // Getting the Sip factory from the JNDI Context - Properties jndiProps = new Properties(); - Context initCtx = new InitialContext(jndiProps); - Context envCtx = (Context) initCtx.lookup("java:comp/env"); - sipFactory = (SipFactory) envCtx.lookup("sip/org.mobicents.servlet.sip.testsuite.SessionStateUASApplication/SipFactory"); - logger.info("Sip Factory ref from JNDI : " + sipFactory); - } catch (NamingException e) { - throw new ServletException("Uh oh -- JNDI problem !", e); - } - } - - /** - * {@inheritDoc} - */ - protected void doInvite(SipServletRequest request) throws ServletException, - IOException { - - logger.info("Got request: " - + request.getMethod()); - - String message = (String)request.getContent(); - - //checking state machines for UAS mode, sending session state after each response sent - if(message != null && message.length() > 0) { - if(TEST_TIMEOUT.equals(message)) { - SipServletResponse response = request.createResponse(SipServletResponse.SC_BAD_REQUEST); - response.send(); - - return; - } - // send message precising the current session state - sendMessage(request.getSession().getState().toString()); - - if(SEND_1XX_2XX.equals(message)) { - SipServletResponse ringingResponse = request.createResponse(SipServletResponse.SC_RINGING); - ringingResponse.send(); - - // send message precising the current session state - sendMessage(request.getSession().getState().toString()); - - SipServletResponse okResponse = request.createResponse(SipServletResponse.SC_OK); - okResponse.send(); - - // send message precising the current session state - sendMessage(request.getSession().getState().toString()); - } else if(SEND_1XX_4XX.equals(message)) { - request.getSession().setInvalidateWhenReady(false); - - SipServletResponse ringingResponse = request.createResponse(SipServletResponse.SC_RINGING); - ringingResponse.send(); - - // send message precising the current session state - sendMessage(request.getSession().getState().toString()); - - SipServletResponse forbiddenResponse = request.createResponse(SipServletResponse.SC_FORBIDDEN); - forbiddenResponse.send(); - - try { - Thread.sleep(TIMEOUT); - } catch (InterruptedException e) { - logger.error("unexpected exception while putting the thread to sleep", e); - } - if(request.getSession().isValid()) { - logger.info("the session have not been invalidated by the container since the invalidateWhenReady flag is false"); - // send message precising the current session state - sendMessage(request.getSession().getState().toString()); - request.getSession().invalidate(); - } else { - logger.error("the session should not have been invalidated by the container since the invalidateWhenReady flag is false"); - } - } else if(SEND_2XX.equals(message)) { - SipServletResponse okResponse = request.createResponse(SipServletResponse.SC_OK); - okResponse.send(); - - // send message precising the current session state - sendMessage(request.getSession().getState().toString()); - } else if(SEND_4XX.equals(message)) { - SipServletResponse forbiddenResponse = request.createResponse(SipServletResponse.SC_FORBIDDEN); - forbiddenResponse.send(); - - // send message precising the current session state - if(request.getSession().isValid()) { - sendMessage(request.getSession().getState().toString()); - } else { - sendMessage(State.TERMINATED.toString()); - } - } - } - } - - @Override - protected void doRefer(SipServletRequest request) throws ServletException, - IOException { - SipServletResponse finalResponse = request.createResponse(SipServletResponse.SC_REQUEST_TERMINATED); - finalResponse.send(); - - // send message precising the current session state - sendMessage(request.getSession().getState().toString()); - } - - /** - * {@inheritDoc} - */ - protected void doBye(SipServletRequest request) throws ServletException, - IOException { - - logger.info("Got BYE request: " + request); - - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); - sipServletResponse.send(); - - // send message precising the current session state - sendMessage(request.getSession().getState().toString()); - } - - @Override - protected void doErrorResponse(SipServletResponse resp) - throws ServletException, IOException { - if(resp.getStatus() == 408 && resp.getMethod().equalsIgnoreCase("INVITE")) { - sendMessage(STX_408_RECEIVED); - } - } - - /** - * Utility method to send a message out of dialog - * @param messageContent messageContent - */ - public void sendMessage(String messageContent) { - try { - SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); - SipServletRequest sipServletRequest = sipFactory.createRequest( - sipApplicationSession, - "MESSAGE", - "sip:sender@sip-servlets.com", - "sip:receiver@sip-servlets.com"); - SipURI sipUri = sipFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - sipServletRequest.setRequestURI(sipUri); - sipServletRequest.setContentLength(messageContent.length()); - sipServletRequest.setContent(messageContent, CONTENT_TYPE); - sipServletRequest.send(); - } catch (ServletParseException e) { - logger.error("Exception occured while parsing the addresses",e); - } catch (IOException e) { - logger.error("Exception occured while sending the request",e); - } - } - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite; + +import java.io.IOException; +import java.util.Properties; + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.sip.ServletParseException; +import javax.servlet.sip.SipApplicationSession; +import javax.servlet.sip.SipFactory; +import javax.servlet.sip.SipServlet; +import javax.servlet.sip.SipServletRequest; +import javax.servlet.sip.SipServletResponse; +import javax.servlet.sip.SipURI; +import javax.servlet.sip.SipSession.State; + +import org.apache.log4j.Logger; + + +public class SessionStateUASSipServlet + extends SipServlet { + private static final long serialVersionUID = 1L; + private static transient Logger logger = Logger.getLogger(SessionStateUASSipServlet.class); + + private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; + private static final String SEND_1XX_2XX = "send1xx_2xx"; + private static final String SEND_1XX_4XX = "send1xx_4xx"; + private static final String SEND_4XX = "send4xx"; + private static final String SEND_2XX = "send2xx"; + private static final String TEST_TIMEOUT = "test_timeout"; + private static final String STX_408_RECEIVED = "408 received on STX"; + //TODO externalize in sip.xml and specify it from test if needed + private static final int TIMEOUT = 10000; + + private SipFactory sipFactory; + + static ServletContext ctx; + + + /** Creates a new instance of SessionStateUASSipServlet */ + public SessionStateUASSipServlet() { + } + + @Override + public void init(ServletConfig servletConfig) throws ServletException { + super.init(servletConfig); + logger.info("the session state UAS test sip servlet has been started"); + ctx = servletConfig.getServletContext(); + try { + // Getting the Sip factory from the JNDI Context + Properties jndiProps = new Properties(); + Context initCtx = new InitialContext(jndiProps); + Context envCtx = (Context) initCtx.lookup("java:comp/env"); + sipFactory = (SipFactory) envCtx.lookup("sip/org.mobicents.servlet.sip.testsuite.SessionStateUASApplication/SipFactory"); + logger.info("Sip Factory ref from JNDI : " + sipFactory); + } catch (NamingException e) { + throw new ServletException("Uh oh -- JNDI problem !", e); + } + } + + /** + * {@inheritDoc} + */ + protected void doInvite(SipServletRequest request) throws ServletException, + IOException { + + logger.info("Got request: " + + request.getMethod()); + + String message = (String)request.getContent(); + + //checking state machines for UAS mode, sending session state after each response sent + if(message != null && message.length() > 0) { + if(TEST_TIMEOUT.equals(message)) { + SipServletResponse response = request.createResponse(SipServletResponse.SC_BAD_REQUEST); + response.send(); + + return; + } + // send message precising the current session state + sendMessage(request.getSession().getState().toString()); + + if(SEND_1XX_2XX.equals(message)) { + SipServletResponse ringingResponse = request.createResponse(SipServletResponse.SC_RINGING); + ringingResponse.send(); + + // send message precising the current session state + sendMessage(request.getSession().getState().toString()); + + SipServletResponse okResponse = request.createResponse(SipServletResponse.SC_OK); + okResponse.send(); + + // send message precising the current session state + sendMessage(request.getSession().getState().toString()); + } else if(SEND_1XX_4XX.equals(message)) { + request.getSession().setInvalidateWhenReady(false); + + SipServletResponse ringingResponse = request.createResponse(SipServletResponse.SC_RINGING); + ringingResponse.send(); + + // send message precising the current session state + sendMessage(request.getSession().getState().toString()); + + SipServletResponse forbiddenResponse = request.createResponse(SipServletResponse.SC_FORBIDDEN); + forbiddenResponse.send(); + + try { + Thread.sleep(TIMEOUT); + } catch (InterruptedException e) { + logger.error("unexpected exception while putting the thread to sleep", e); + } + if(request.getSession().isValid()) { + logger.info("the session have not been invalidated by the container since the invalidateWhenReady flag is false"); + // send message precising the current session state + sendMessage(request.getSession().getState().toString()); + request.getSession().invalidate(); + } else { + logger.error("the session should not have been invalidated by the container since the invalidateWhenReady flag is false"); + } + } else if(SEND_2XX.equals(message)) { + SipServletResponse okResponse = request.createResponse(SipServletResponse.SC_OK); + okResponse.send(); + + // send message precising the current session state + sendMessage(request.getSession().getState().toString()); + } else if(SEND_4XX.equals(message)) { + SipServletResponse forbiddenResponse = request.createResponse(SipServletResponse.SC_FORBIDDEN); + forbiddenResponse.send(); + + // send message precising the current session state + if(request.getSession().isValid()) { + sendMessage(request.getSession().getState().toString()); + } else { + sendMessage(State.TERMINATED.toString()); + } + } + } + } + + @Override + protected void doRefer(SipServletRequest request) throws ServletException, + IOException { + SipServletResponse finalResponse = request.createResponse(SipServletResponse.SC_REQUEST_TERMINATED); + finalResponse.send(); + + // send message precising the current session state + sendMessage(request.getSession().getState().toString()); + } + + /** + * {@inheritDoc} + */ + protected void doBye(SipServletRequest request) throws ServletException, + IOException { + + logger.info("Got BYE request: " + request); + + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); + sipServletResponse.send(); + + // send message precising the current session state + sendMessage(request.getSession().getState().toString()); + } + + @Override + protected void doErrorResponse(SipServletResponse resp) + throws ServletException, IOException { + if(resp.getStatus() == 408 && resp.getMethod().equalsIgnoreCase("INVITE")) { + sendMessage(STX_408_RECEIVED); + } + } + + /** + * Utility method to send a message out of dialog + * @param messageContent messageContent + */ + public void sendMessage(String messageContent) { + try { + SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); + SipServletRequest sipServletRequest = sipFactory.createRequest( + sipApplicationSession, + "MESSAGE", + "sip:sender@sip-servlets.com", + "sip:receiver@sip-servlets.com"); + SipURI sipUri = sipFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + sipServletRequest.setRequestURI(sipUri); + sipServletRequest.setContentLength(messageContent.length()); + sipServletRequest.setContent(messageContent, CONTENT_TYPE); + sipServletRequest.send(); + } catch (ServletParseException e) { + logger.error("Exception occured while parsing the addresses",e); + } catch (IOException e) { + logger.error("Exception occured while sending the request",e); + } + } + + public static Integer getTestPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("testPort"); + logger.info("TestPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5080; + } + } + + public static Integer getServletContainerPort(ServletContext ctx) { + String cPort = ctx.getInitParameter("servletContainerPort"); + logger.info("TestPort at:" + cPort); + if (cPort != null) { + return Integer.valueOf(cPort); + } else { + return 5070; + } + } + +} diff --git a/sip-servlets-test-suite/applications/shootist-sip-servlet-auth/src/main/java/org/mobicents/servlet/sip/testsuite/ShootistSipServletAuth.java b/sip-servlets-test-suite/applications/shootist-sip-servlet-auth/src/main/java/org/mobicents/servlet/sip/testsuite/ShootistSipServletAuth.java index 9c3182a008..87a3ced5e0 100644 --- a/sip-servlets-test-suite/applications/shootist-sip-servlet-auth/src/main/java/org/mobicents/servlet/sip/testsuite/ShootistSipServletAuth.java +++ b/sip-servlets-test-suite/applications/shootist-sip-servlet-auth/src/main/java/org/mobicents/servlet/sip/testsuite/ShootistSipServletAuth.java @@ -1,303 +1,327 @@ -/* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2013, Telestax Inc and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - */ - -package org.mobicents.servlet.sip.testsuite; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.sip.AuthInfo; -import javax.servlet.sip.Parameterable; -import javax.servlet.sip.ServletParseException; -import javax.servlet.sip.SipApplicationSession; -import javax.servlet.sip.SipFactory; -import javax.servlet.sip.SipServlet; -import javax.servlet.sip.SipServletContextEvent; -import javax.servlet.sip.SipServletListener; -import javax.servlet.sip.SipServletRequest; -import javax.servlet.sip.SipServletResponse; -import javax.servlet.sip.SipSession; -import javax.servlet.sip.SipSessionEvent; -import javax.servlet.sip.SipSessionListener; -import javax.servlet.sip.SipURI; -import javax.sip.ListeningPoint; -import javax.sip.header.ProxyAuthenticateHeader; - -import org.apache.log4j.Logger; -import org.mobicents.javax.servlet.sip.SipServletRequestExt; - -public class ShootistSipServletAuth - extends SipServlet - implements SipServletListener, SipSessionListener { - private static final long serialVersionUID = 1L; - private static transient Logger logger = Logger.getLogger(ShootistSipServletAuth.class); - private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; - - private String sampleSDP = "v=0" + - "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com" + - "s=" + - "c=IN IP4 host.atlanta.example.com" + - "t=0 0" + - "m=audio 49170 RTP/AVP 0" + - "a=rtpmap:0 PCMU/8000" + - "m=audio 51372 RTP/AVP 97 101" + - "a=rtpmap:97 iLBC/8000" + - "a=rtpmap:101 telephone-event/8000"; - - private String sampleSDP2 = "v=1" + - "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com" + - "s=" + - "c=IN IP4 host.atlanta.example.com" + - "t=0 0" + - "m=audio 49170 RTP/AVP 0" + - "a=rtpmap:0 PCMU/8000" + - "m=audio 51372 RTP/AVP 97 101" + - "a=rtpmap:97 iLBC/8000" + - "a=rtpmap:101 telephone-event/8000"; - - /** Creates a new instance of ShootistSipServletAuth */ - public ShootistSipServletAuth() { - } - - @Override - public void init(ServletConfig servletConfig) throws ServletException { - logger.info("the shootist has been started"); - super.init(servletConfig); - } - - @Override - protected void doErrorResponse(SipServletResponse response) - throws ServletException, IOException { - - SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); - if(response.getStatus() == SipServletResponse.SC_UNAUTHORIZED || - response.getStatus() == SipServletResponse.SC_PROXY_AUTHENTICATION_REQUIRED) { - - // Avoid re-sending if the auth repeatedly fails. - if(!"true".equals(getServletContext().getAttribute("FirstResponseRecieved"))) - { - String fromString = response.getFrom().getURI().toString(); - - getServletContext().setAttribute("FirstResponseRecieved", "true"); - // non regression test for https://code.google.com/p/sipservlets/issues/detail?id=239 - Parameterable proxyAuthHeader = response.getParameterableHeader(ProxyAuthenticateHeader.NAME); - AuthInfo authInfo = sipFactory.createAuthInfo(); - String realm = proxyAuthHeader.getParameter("Digest realm"); - authInfo.addAuthInfo(response.getStatus(), realm, "user", "pass"); - SipServletRequest challengeRequest = response.getSession().createRequest( - response.getRequest().getMethod()); - boolean cacheCredentials = false; - if(fromString.contains("cache-credentials")) { - cacheCredentials = true; - } - logger.info("cache Credentials : " + cacheCredentials); - ((SipServletRequestExt)challengeRequest).addAuthHeader(response, authInfo, cacheCredentials); - challengeRequest.send(); - - if(fromString.contains("cancelChallenge")) { - if(fromString.contains("Before1xx")) { - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - logger.error("unexpected exception", e); - } - challengeRequest.createCancel().send(); - } else { - response.getSession().setAttribute("cancelChallenge", challengeRequest); - } - } - } - } - - logger.info("Got response: " + response); - - } - - @Override - protected void doProvisionalResponse(SipServletResponse resp) - throws ServletException, IOException { - SipServletRequest servletRequest = (SipServletRequest) resp.getSession().getAttribute("cancelChallenge"); - if(servletRequest != null && resp.getStatus() > 100) { - servletRequest.createCancel().send(); - } - } - - @Override - protected void doSuccessResponse(SipServletResponse sipServletResponse) - throws ServletException, IOException { - logger.info("Got : " + sipServletResponse.getStatus() + " " - + sipServletResponse.getMethod()); - int status = sipServletResponse.getStatus(); - String fromString = sipServletResponse.getFrom().getURI().toString(); - if (status == SipServletResponse.SC_OK && "INVITE".equalsIgnoreCase(sipServletResponse.getMethod())) { - SipServletRequest ackRequest = sipServletResponse.createAck(); - ackRequest.send(); - try { - Thread.sleep(2000); - } catch (InterruptedException e) { - logger.error("unexpected exception", e); - } - if(!fromString.contains("reinvite")) { - SipServletRequest sipServletRequest = sipServletResponse.getSession().createRequest("BYE"); - sipServletRequest.send(); - } else if(!sipServletResponse.getHeader("CSeq").contains((String)sipServletResponse.getApplicationSession().getAttribute("nbSubsequentReq"))) { - getServletContext().setAttribute("FirstResponseRecieved", "false"); - SipServletRequest invite = sipServletResponse.getSession().createRequest(sipServletResponse.getMethod()); - try { - invite.setContent(sampleSDP2, "application/sdp"); - } catch (UnsupportedEncodingException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - invite.send(); - } - } - if("REGISTER".equalsIgnoreCase(sipServletResponse.getMethod())) { - try { - Thread.sleep(4000); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - if(!sipServletResponse.getHeader("CSeq").contains((String)sipServletResponse.getApplicationSession().getAttribute("nbSubsequentReq"))) { - getServletContext().setAttribute("FirstResponseRecieved", "false"); - SipServletRequest register = sipServletResponse.getSession().createRequest(sipServletResponse.getMethod()); - register.send(); - } - } - } - - @Override - protected void doInfo(SipServletRequest req) throws ServletException, - IOException { - req.createResponse(200).send(); - SipServletRequest reInvite = req.getSession().createRequest("INVITE"); - reInvite.send(); - - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - logger.error("unexpected exception", e); - } - - reInvite.createCancel().send(); - } - - // SipServletListener methods - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipServletListener#servletInitialized(javax.servlet.sip.SipServletContextEvent) - */ - public void servletInitialized(SipServletContextEvent ce) { - SipFactory sipFactory = (SipFactory)ce.getServletContext().getAttribute(SIP_FACTORY); - String method = ce.getServletContext().getInitParameter("METHOD"); - if(method == null) { - method = "INVITE"; - } - - SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); - String from = ce.getServletContext().getInitParameter("from"); - if(from == null) { - from = "BigGuy"; - } - - String numberOfSubsequentRequests = ce.getServletContext().getInitParameter("nbSubsequentReq"); - if(numberOfSubsequentRequests == null) { - numberOfSubsequentRequests = "10"; - } - SipURI fromURI = sipFactory.createSipURI(from, "here.com"); - SipURI toURI = sipFactory.createSipURI("LittleGuy", "there.com"); - SipServletRequest sipServletRequest = - sipFactory.createRequest(sipApplicationSession, method, fromURI, toURI); - sipApplicationSession.setAttribute("nbSubsequentReq", numberOfSubsequentRequests); - SipURI requestURI = sipFactory.createSipURI("LittleGuy", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - sipServletRequest.setRequestURI(requestURI); - if(method.equalsIgnoreCase("INVITE")) { - try { - sipServletRequest.setContent(sampleSDP, "application/sdp"); - } catch (UnsupportedEncodingException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - try { - sipServletRequest.send(); - } catch (IOException e) { - logger.error(e); - } - } - - public void sessionCreated(SipSessionEvent se) { - final SipSession sipSession = se.getSession(); - Integer nbSessionCreated = (Integer) sipSession.getAttribute("nbSessionCreated"); - if(nbSessionCreated == null) { - sipSession.setAttribute("nbSessionCreated", Integer.valueOf(1)); - } else { - sipSession.setAttribute("nbSessionCreated", Integer.valueOf(nbSessionCreated.intValue() + 1)); - } - logger.info("number of sip sessions created " + sipSession.getAttribute("nbSessionCreated") + " session " + sipSession); - SipFactory sipFactory = (SipFactory)getServletContext().getAttribute(SIP_FACTORY); - if(nbSessionCreated != null && nbSessionCreated > 1) { - sendMessage(sipSession.getApplicationSession(), sipFactory, "" + nbSessionCreated, null); - } - } - - /** - * @param sipApplicationSession - * @param storedFactory - */ - private void sendMessage(SipApplicationSession sipApplicationSession, - SipFactory storedFactory, String content, String transport) { - try { - SipServletRequest sipServletRequest = storedFactory.createRequest( - sipApplicationSession, - "MESSAGE", - "sip:sender@sip-servlets.com", - "sip:receiver@sip-servlets.com"); - sipServletRequest.addHeader("Ext", "Test 1, 2 ,3"); - SipURI sipUri = storedFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - if(transport != null) { - if(transport.equalsIgnoreCase(ListeningPoint.TCP)) { - sipUri = storedFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5081"); - } - sipUri.setTransportParam(transport); - } - sipServletRequest.setRequestURI(sipUri); - sipServletRequest.setContentLength(content.length()); - sipServletRequest.setContent(content, CONTENT_TYPE); - sipServletRequest.send(); - } catch (ServletParseException e) { - logger.error("Exception occured while parsing the addresses",e); - } catch (IOException e) { - logger.error("Exception occured while sending the request",e); - } - } - - public void sessionDestroyed(SipSessionEvent se) { - // TODO Auto-generated method stub - - } - - public void sessionReadyToInvalidate(SipSessionEvent se) { - // TODO Auto-generated method stub - - } +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2013, Telestax Inc and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + */ + +package org.mobicents.servlet.sip.testsuite; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.sip.AuthInfo; +import javax.servlet.sip.Parameterable; +import javax.servlet.sip.ServletParseException; +import javax.servlet.sip.SipApplicationSession; +import javax.servlet.sip.SipFactory; +import javax.servlet.sip.SipServlet; +import javax.servlet.sip.SipServletContextEvent; +import javax.servlet.sip.SipServletListener; +import javax.servlet.sip.SipServletRequest; +import javax.servlet.sip.SipServletResponse; +import javax.servlet.sip.SipSession; +import javax.servlet.sip.SipSessionEvent; +import javax.servlet.sip.SipSessionListener; +import javax.servlet.sip.SipURI; +import javax.sip.ListeningPoint; +import javax.sip.header.ProxyAuthenticateHeader; + +import org.apache.log4j.Logger; +import org.mobicents.javax.servlet.sip.SipServletRequestExt; + +public class ShootistSipServletAuth + extends SipServlet + implements SipServletListener, SipSessionListener { + private static final long serialVersionUID = 1L; + private static transient Logger logger = Logger.getLogger(ShootistSipServletAuth.class); + private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; + + private String sampleSDP = "v=0" + + "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com" + + "s=" + + "c=IN IP4 host.atlanta.example.com" + + "t=0 0" + + "m=audio 49170 RTP/AVP 0" + + "a=rtpmap:0 PCMU/8000" + + "m=audio 51372 RTP/AVP 97 101" + + "a=rtpmap:97 iLBC/8000" + + "a=rtpmap:101 telephone-event/8000"; + + private String sampleSDP2 = "v=1" + + "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com" + + "s=" + + "c=IN IP4 host.atlanta.example.com" + + "t=0 0" + + "m=audio 49170 RTP/AVP 0" + + "a=rtpmap:0 PCMU/8000" + + "m=audio 51372 RTP/AVP 97 101" + + "a=rtpmap:97 iLBC/8000" + + "a=rtpmap:101 telephone-event/8000"; + + static ServletContext ctx; + + /** Creates a new instance of ShootistSipServletAuth */ + public ShootistSipServletAuth() { + } + + @Override + public void init(ServletConfig servletConfig) throws ServletException { + logger.info("the shootist has been started"); + super.init(servletConfig); + ctx = servletConfig.getServletContext(); + } + + @Override + protected void doErrorResponse(SipServletResponse response) + throws ServletException, IOException { + + SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); + if(response.getStatus() == SipServletResponse.SC_UNAUTHORIZED || + response.getStatus() == SipServletResponse.SC_PROXY_AUTHENTICATION_REQUIRED) { + + // Avoid re-sending if the auth repeatedly fails. + if(!"true".equals(getServletContext().getAttribute("FirstResponseRecieved"))) + { + String fromString = response.getFrom().getURI().toString(); + + getServletContext().setAttribute("FirstResponseRecieved", "true"); + // non regression test for https://code.google.com/p/sipservlets/issues/detail?id=239 + Parameterable proxyAuthHeader = response.getParameterableHeader(ProxyAuthenticateHeader.NAME); + AuthInfo authInfo = sipFactory.createAuthInfo(); + String realm = proxyAuthHeader.getParameter("Digest realm"); + authInfo.addAuthInfo(response.getStatus(), realm, "user", "pass"); + SipServletRequest challengeRequest = response.getSession().createRequest( + response.getRequest().getMethod()); + boolean cacheCredentials = false; + if(fromString.contains("cache-credentials")) { + cacheCredentials = true; + } + logger.info("cache Credentials : " + cacheCredentials); + ((SipServletRequestExt)challengeRequest).addAuthHeader(response, authInfo, cacheCredentials); + challengeRequest.send(); + + if(fromString.contains("cancelChallenge")) { + if(fromString.contains("Before1xx")) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + logger.error("unexpected exception", e); + } + challengeRequest.createCancel().send(); + } else { + response.getSession().setAttribute("cancelChallenge", challengeRequest); + } + } + } + } + + logger.info("Got response: " + response); + + } + + @Override + protected void doProvisionalResponse(SipServletResponse resp) + throws ServletException, IOException { + SipServletRequest servletRequest = (SipServletRequest) resp.getSession().getAttribute("cancelChallenge"); + if(servletRequest != null && resp.getStatus() > 100) { + servletRequest.createCancel().send(); + } + } + + @Override + protected void doSuccessResponse(SipServletResponse sipServletResponse) + throws ServletException, IOException { + logger.info("Got : " + sipServletResponse.getStatus() + " " + + sipServletResponse.getMethod()); + int status = sipServletResponse.getStatus(); + String fromString = sipServletResponse.getFrom().getURI().toString(); + if (status == SipServletResponse.SC_OK && "INVITE".equalsIgnoreCase(sipServletResponse.getMethod())) { + SipServletRequest ackRequest = sipServletResponse.createAck(); + ackRequest.send(); + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + logger.error("unexpected exception", e); + } + if(!fromString.contains("reinvite")) { + SipServletRequest sipServletRequest = sipServletResponse.getSession().createRequest("BYE"); + sipServletRequest.send(); + } else if(!sipServletResponse.getHeader("CSeq").contains((String)sipServletResponse.getApplicationSession().getAttribute("nbSubsequentReq"))) { + getServletContext().setAttribute("FirstResponseRecieved", "false"); + SipServletRequest invite = sipServletResponse.getSession().createRequest(sipServletResponse.getMethod()); + try { + invite.setContent(sampleSDP2, "application/sdp"); + } catch (UnsupportedEncodingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + invite.send(); + } + } + if("REGISTER".equalsIgnoreCase(sipServletResponse.getMethod())) { + try { + Thread.sleep(4000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + if(!sipServletResponse.getHeader("CSeq").contains((String)sipServletResponse.getApplicationSession().getAttribute("nbSubsequentReq"))) { + getServletContext().setAttribute("FirstResponseRecieved", "false"); + SipServletRequest register = sipServletResponse.getSession().createRequest(sipServletResponse.getMethod()); + register.send(); + } + } + } + + @Override + protected void doInfo(SipServletRequest req) throws ServletException, + IOException { + req.createResponse(200).send(); + SipServletRequest reInvite = req.getSession().createRequest("INVITE"); + reInvite.send(); + + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + logger.error("unexpected exception", e); + } + + reInvite.createCancel().send(); + } + + // SipServletListener methods + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipServletListener#servletInitialized(javax.servlet.sip.SipServletContextEvent) + */ + public void servletInitialized(SipServletContextEvent ce) { + SipFactory sipFactory = (SipFactory)ce.getServletContext().getAttribute(SIP_FACTORY); + String method = ce.getServletContext().getInitParameter("METHOD"); + if(method == null) { + method = "INVITE"; + } + + SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); + String from = ce.getServletContext().getInitParameter("from"); + if(from == null) { + from = "BigGuy"; + } + + String numberOfSubsequentRequests = ce.getServletContext().getInitParameter("nbSubsequentReq"); + if(numberOfSubsequentRequests == null) { + numberOfSubsequentRequests = "10"; + } + SipURI fromURI = sipFactory.createSipURI(from, "here.com"); + SipURI toURI = sipFactory.createSipURI("LittleGuy", "there.com"); + SipServletRequest sipServletRequest = + sipFactory.createRequest(sipApplicationSession, method, fromURI, toURI); + sipApplicationSession.setAttribute("nbSubsequentReq", numberOfSubsequentRequests); + SipURI requestURI = sipFactory.createSipURI("LittleGuy", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + sipServletRequest.setRequestURI(requestURI); + if(method.equalsIgnoreCase("INVITE")) { + try { + sipServletRequest.setContent(sampleSDP, "application/sdp"); + } catch (UnsupportedEncodingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + try { + sipServletRequest.send(); + } catch (IOException e) { + logger.error(e); + } + } + + public void sessionCreated(SipSessionEvent se) { + final SipSession sipSession = se.getSession(); + Integer nbSessionCreated = (Integer) sipSession.getAttribute("nbSessionCreated"); + if(nbSessionCreated == null) { + sipSession.setAttribute("nbSessionCreated", Integer.valueOf(1)); + } else { + sipSession.setAttribute("nbSessionCreated", Integer.valueOf(nbSessionCreated.intValue() + 1)); + } + logger.info("number of sip sessions created " + sipSession.getAttribute("nbSessionCreated") + " session " + sipSession); + SipFactory sipFactory = (SipFactory)getServletContext().getAttribute(SIP_FACTORY); + if(nbSessionCreated != null && nbSessionCreated > 1) { + sendMessage(sipSession.getApplicationSession(), sipFactory, "" + nbSessionCreated, null); + } + } + + /** + * @param sipApplicationSession + * @param storedFactory + */ + private void sendMessage(SipApplicationSession sipApplicationSession, + SipFactory storedFactory, String content, String transport) { + try { + SipServletRequest sipServletRequest = storedFactory.createRequest( + sipApplicationSession, + "MESSAGE", + "sip:sender@sip-servlets.com", + "sip:receiver@sip-servlets.com"); + sipServletRequest.addHeader("Ext", "Test 1, 2 ,3"); + SipURI sipUri = storedFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + if(transport != null) { + if(transport.equalsIgnoreCase(ListeningPoint.TCP)) { + sipUri = storedFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5081"); + } + sipUri.setTransportParam(transport); + } + sipServletRequest.setRequestURI(sipUri); + sipServletRequest.setContentLength(content.length()); + sipServletRequest.setContent(content, CONTENT_TYPE); + sipServletRequest.send(); + } catch (ServletParseException e) { + logger.error("Exception occured while parsing the addresses",e); + } catch (IOException e) { + logger.error("Exception occured while sending the request",e); + } + } + + public void sessionDestroyed(SipSessionEvent se) { + // TODO Auto-generated method stub + + } + + public void sessionReadyToInvalidate(SipSessionEvent se) { + // TODO Auto-generated method stub + + } + + public static Integer getTestPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("testPort"); + logger.info("TestPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5080; + } + } + + public static Integer getServletContainerPort(ServletContext ctx) { + String cPort = ctx.getInitParameter("servletContainerPort"); + logger.info("TestPort at:" + cPort); + if (cPort != null) { + return Integer.valueOf(cPort); + } else { + return 5070; + } + } } \ No newline at end of file diff --git a/sip-servlets-test-suite/applications/shootist-sip-servlet-auth/src/test/java/shootist/Shootist.java b/sip-servlets-test-suite/applications/shootist-sip-servlet-auth/src/test/java/shootist/Shootist.java index 56885cd8c2..ffd52a385b 100644 --- a/sip-servlets-test-suite/applications/shootist-sip-servlet-auth/src/test/java/shootist/Shootist.java +++ b/sip-servlets-test-suite/applications/shootist-sip-servlet-auth/src/test/java/shootist/Shootist.java @@ -1,428 +1,429 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package shootist; - -import java.text.ParseException; -import java.util.ArrayList; -import java.util.Properties; -import java.util.Timer; -import java.util.TimerTask; - -import javax.sip.DialogTerminatedEvent; -import javax.sip.IOExceptionEvent; -import javax.sip.RequestEvent; -import javax.sip.ResponseEvent; -import javax.sip.SipListener; -import javax.sip.TimeoutEvent; -import javax.sip.TransactionTerminatedEvent; - -import javax.sip.address.*; -import javax.sip.header.*; -import javax.sip.message.*; -import javax.sip.*; - -public class Shootist implements SipListener { - - - private static SipProvider sipProvider; - - private static AddressFactory addressFactory; - - private static MessageFactory messageFactory; - - private static HeaderFactory headerFactory; - - private static SipStack sipStack; - - private ContactHeader contactHeader; - - private ListeningPoint udpListeningPoint; - - private ClientTransaction inviteTid; - - private Dialog dialog; - - private boolean byeTaskRunning; - - private boolean callerSendsBye = true; - - class ByeTask extends TimerTask { - Dialog dialog; - public ByeTask(Dialog dialog) { - this.dialog = dialog; - } - public void run () { - try { - System.out.println("Sending BYE!"); - Request byeRequest = this.dialog.createRequest(Request.BYE); - ClientTransaction ct = sipProvider.getNewClientTransaction(byeRequest); - dialog.sendRequest(ct); - } catch (Exception ex) { - ex.printStackTrace(); - System.exit(0); - } - - } - - } - - private static final String usageString = "java " - + "examples.shootist.Shootist \n" - + ">>>> is your class path set to the root?"; - - private static void usage() { - System.out.println(usageString); - System.exit(0); - - } - - - public void processRequest(RequestEvent requestReceivedEvent) { - Request request = requestReceivedEvent.getRequest(); - ServerTransaction serverTransactionId = requestReceivedEvent - .getServerTransaction(); - - System.out.println("\n\nRequest " + request.getMethod() - + " received at " + sipStack.getStackName() - + " with server transaction id " + serverTransactionId); - - // We are the UAC so the only request we get is the BYE. - if (request.getMethod().equals(Request.BYE)) - processBye(request, serverTransactionId); - else { - try { - serverTransactionId.sendResponse( messageFactory.createResponse(202,request) ); - } catch (SipException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (InvalidArgumentException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (ParseException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - } - - public void processBye(Request request, - ServerTransaction serverTransactionId) { - try { - System.out.println("shootist: got a bye ."); - if (serverTransactionId == null) { - System.out.println("shootist: null TID."); - return; - } - Dialog dialog = serverTransactionId.getDialog(); - System.out.println("Dialog State = " + dialog.getState()); - Response response = messageFactory.createResponse(200, request); - serverTransactionId.sendResponse(response); - System.out.println("shootist: Sending OK."); - System.out.println("Dialog State = " + dialog.getState()); - - } catch (Exception ex) { - ex.printStackTrace(); - System.exit(0); - - } - } - - // Save the created ACK request, to respond to retransmitted 2xx - private Request ackRequest; - - public void processResponse(ResponseEvent responseReceivedEvent) { - System.out.println("Got a response"); - Response response = (Response) responseReceivedEvent.getResponse(); - ClientTransaction tid = responseReceivedEvent.getClientTransaction(); - CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME); - - System.out.println("Response received : Status Code = " - + response.getStatusCode() + " " + cseq); - - - if (tid == null) { - - // RFC3261: MUST respond to every 2xx - if (ackRequest!=null && dialog!=null) { - System.out.println("re-sending ACK"); - try { - dialog.sendAck(ackRequest); - } catch (SipException se) { - se.printStackTrace(); - } - } - return; - } - - System.out.println("transaction state is " + tid.getState()); - System.out.println("Dialog = " + tid.getDialog()); - System.out.println("Dialog State is " + tid.getDialog().getState()); - - try { - if (response.getStatusCode() == Response.OK) { - if (cseq.getMethod().equals(Request.INVITE)) { - ackRequest = dialog.createRequest(Request.ACK); - System.out.println("Sending ACK"); - dialog.sendAck(ackRequest); - // If the caller is supposed to send the bye - if ( callerSendsBye && !byeTaskRunning) { - byeTaskRunning = true; - new Timer().schedule(new ByeTask(dialog), 4000) ; - } - - } else if (cseq.getMethod().equals(Request.CANCEL)) { - if (dialog.getState() == DialogState.CONFIRMED) { - // oops cancel went in too late. Need to hang up the - // dialog. - System.out - .println("Sending BYE -- cancel went in too late !!"); - Request byeRequest = dialog.createRequest(Request.BYE); - ClientTransaction ct = sipProvider - .getNewClientTransaction(byeRequest); - dialog.sendRequest(ct); - - } - - } else if ( cseq.getMethod().equals(Request.BYE)) { - System.out.println("Got OK for the BYE -- tear down the stack"); - this.sipStack.stop(); - } - } - } catch (Exception ex) { - ex.printStackTrace(); - System.exit(0); - } - - } - - public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) { - - ClientTransaction ct = timeoutEvent.getClientTransaction(); - System.out.println("Transaction Time out" + ((ClientTransaction) ct).getRequest().getMethod()); - } - - - - public void init() { - SipFactory sipFactory = null; - sipStack = null; - sipFactory = SipFactory.getInstance(); - sipFactory.setPathName("gov.nist"); - Properties properties = new Properties(); - // If you want to try TCP transport change the following to - String transport = "udp"; - String peerHostPort = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070"; - properties.setProperty("javax.sip.OUTBOUND_PROXY", peerHostPort + "/" - + transport); - // If you want to use UDP then uncomment this. - properties.setProperty("javax.sip.STACK_NAME", "shootist"); - - // The following properties are specific to nist-sip - // and are not necessarily part of any other jain-sip - // implementation. - // You can set a max message size for tcp transport to - // guard against denial of service attack. - properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", - "logs/shootistdebug.txt"); - properties.setProperty("gov.nist.javax.sip.SERVER_LOG", - "logs/shootistlog.txt"); - - // Drop the client connection after we are done with the transaction. - properties.setProperty("gov.nist.javax.sip.CACHE_CLIENT_CONNECTIONS", - "false"); - // Set to 0 (or NONE) in your production code for max speed. - // You need 16 (or TRACE) for logging traces. 32 (or DEBUG) for debug + traces. - // Your code will limp at 32 but it is best for debugging. - properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "TRACE"); - - try { - // Create SipStack object - sipStack = sipFactory.createSipStack(properties); - System.out.println("createSipStack " + sipStack); - } catch (PeerUnavailableException e) { - // could not find - // gov.nist.jain.protocol.ip.sip.SipStackImpl - // in the classpath - e.printStackTrace(); - System.err.println(e.getMessage()); - System.exit(0); - } - - try { - headerFactory = sipFactory.createHeaderFactory(); - addressFactory = sipFactory.createAddressFactory(); - messageFactory = sipFactory.createMessageFactory(); - udpListeningPoint = sipStack.createListeningPoint("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", 5080, "udp"); - sipProvider = sipStack.createSipProvider(udpListeningPoint); - Shootist listener = this; - sipProvider.addSipListener(listener); - - String fromName = "BigGuy"; - String fromSipAddress = "here.com"; - String fromDisplayName = "The Master Blaster"; - - String toSipAddress = "there.com"; - String toUser = "LittleGuy"; - String toDisplayName = "The Little Blister"; - - // create >From Header - SipURI fromAddress = addressFactory.createSipURI(fromName, - fromSipAddress); - - Address fromNameAddress = addressFactory.createAddress(fromAddress); - fromNameAddress.setDisplayName(fromDisplayName); - FromHeader fromHeader = headerFactory.createFromHeader( - fromNameAddress, "12345"); - - // create To Header - SipURI toAddress = addressFactory - .createSipURI(toUser, toSipAddress); - Address toNameAddress = addressFactory.createAddress(toAddress); - toNameAddress.setDisplayName(toDisplayName); - ToHeader toHeader = headerFactory.createToHeader(toNameAddress, - null); - - // create Request URI - SipURI requestURI = addressFactory.createSipURI(toUser, - peerHostPort); - - // Create ViaHeaders - - ArrayList viaHeaders = new ArrayList(); - String ipAddress = udpListeningPoint.getIPAddress(); - ViaHeader viaHeader = headerFactory.createViaHeader(ipAddress, - sipProvider.getListeningPoint(transport).getPort(), - transport, null); - - // add via headers - viaHeaders.add(viaHeader); - - // Create ContentTypeHeader - ContentTypeHeader contentTypeHeader = headerFactory - .createContentTypeHeader("application", "sdp"); - - // Create a new CallId header - CallIdHeader callIdHeader = sipProvider.getNewCallId(); - - // Create a new Cseq header - CSeqHeader cSeqHeader = headerFactory.createCSeqHeader(1L, - Request.INVITE); - - // Create a new MaxForwardsHeader - MaxForwardsHeader maxForwards = headerFactory - .createMaxForwardsHeader(70); - - // Create the request. - Request request = messageFactory.createRequest(requestURI, - Request.INVITE, callIdHeader, cSeqHeader, fromHeader, - toHeader, viaHeaders, maxForwards); - // Create contact headers - String host = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; - - SipURI contactUrl = addressFactory.createSipURI(fromName, host); - contactUrl.setPort(udpListeningPoint.getPort()); - contactUrl.setLrParam(); - - // Create the contact name address. - SipURI contactURI = addressFactory.createSipURI(fromName, host); - contactURI.setPort(sipProvider.getListeningPoint(transport) - .getPort()); - - Address contactAddress = addressFactory.createAddress(contactURI); - - // Add the contact address. - contactAddress.setDisplayName(fromName); - - contactHeader = headerFactory.createContactHeader(contactAddress); - request.addHeader(contactHeader); - - // You can add extension headers of your own making - // to the outgoing SIP request. - // Add the extension header. - Header extensionHeader = headerFactory.createHeader("My-Header", - "my header value"); - request.addHeader(extensionHeader); - - String sdpData = "v=0\r\n" - + "o=4855 13760799956958020 13760799956958020" - + " IN IP4 129.6.55.78\r\n" + "s=mysession session\r\n" - + "p=+46 8 52018010\r\n" + "c=IN IP4 129.6.55.78\r\n" - + "t=0 0\r\n" + "m=audio 6022 RTP/AVP 0 4 18\r\n" - + "a=rtpmap:0 PCMU/8000\r\n" + "a=rtpmap:4 G723/8000\r\n" - + "a=rtpmap:18 G729A/8000\r\n" + "a=ptime:20\r\n"; - byte[] contents = sdpData.getBytes(); - - request.setContent(contents, contentTypeHeader); - // You can add as many extension headers as you - // want. - - extensionHeader = headerFactory.createHeader("My-Other-Header", - "my new header value "); - request.addHeader(extensionHeader); - - Header callInfoHeader = headerFactory.createHeader("Call-Info", - ""); - request.addHeader(callInfoHeader); - - // Create the client transaction. - inviteTid = sipProvider.getNewClientTransaction(request); - - // send the request out. - inviteTid.sendRequest(); - - dialog = inviteTid.getDialog(); - - } catch (Exception ex) { - System.out.println(ex.getMessage()); - ex.printStackTrace(); - usage(); - } - } - - public static void main(String args[]) { - new Shootist().init(); - - } - - public void processIOException(IOExceptionEvent exceptionEvent) { - System.out.println("IOException happened for " - + exceptionEvent.getHost() + " port = " - + exceptionEvent.getPort()); - - } - - public void processTransactionTerminated( - TransactionTerminatedEvent transactionTerminatedEvent) { - System.out.println("Transaction terminated event recieved"); - } - - public void processDialogTerminated( - DialogTerminatedEvent dialogTerminatedEvent) { - System.out.println("dialogTerminatedEvent"); - this.sipStack.stop(); - - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package shootist; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Properties; +import java.util.Timer; +import java.util.TimerTask; +import javax.servlet.ServletContext; + +import javax.sip.DialogTerminatedEvent; +import javax.sip.IOExceptionEvent; +import javax.sip.RequestEvent; +import javax.sip.ResponseEvent; +import javax.sip.SipListener; +import javax.sip.TimeoutEvent; +import javax.sip.TransactionTerminatedEvent; + +import javax.sip.address.*; +import javax.sip.header.*; +import javax.sip.message.*; +import javax.sip.*; + +public class Shootist implements SipListener { + + + private static SipProvider sipProvider; + + private static AddressFactory addressFactory; + + private static MessageFactory messageFactory; + + private static HeaderFactory headerFactory; + + private static SipStack sipStack; + + private ContactHeader contactHeader; + + private ListeningPoint udpListeningPoint; + + private ClientTransaction inviteTid; + + private Dialog dialog; + + private boolean byeTaskRunning; + + private boolean callerSendsBye = true; + + class ByeTask extends TimerTask { + Dialog dialog; + public ByeTask(Dialog dialog) { + this.dialog = dialog; + } + public void run () { + try { + System.out.println("Sending BYE!"); + Request byeRequest = this.dialog.createRequest(Request.BYE); + ClientTransaction ct = sipProvider.getNewClientTransaction(byeRequest); + dialog.sendRequest(ct); + } catch (Exception ex) { + ex.printStackTrace(); + System.exit(0); + } + + } + + } + + private static final String usageString = "java " + + "examples.shootist.Shootist \n" + + ">>>> is your class path set to the root?"; + + private static void usage() { + System.out.println(usageString); + System.exit(0); + + } + + + public void processRequest(RequestEvent requestReceivedEvent) { + Request request = requestReceivedEvent.getRequest(); + ServerTransaction serverTransactionId = requestReceivedEvent + .getServerTransaction(); + + System.out.println("\n\nRequest " + request.getMethod() + + " received at " + sipStack.getStackName() + + " with server transaction id " + serverTransactionId); + + // We are the UAC so the only request we get is the BYE. + if (request.getMethod().equals(Request.BYE)) + processBye(request, serverTransactionId); + else { + try { + serverTransactionId.sendResponse( messageFactory.createResponse(202,request) ); + } catch (SipException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InvalidArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + } + + public void processBye(Request request, + ServerTransaction serverTransactionId) { + try { + System.out.println("shootist: got a bye ."); + if (serverTransactionId == null) { + System.out.println("shootist: null TID."); + return; + } + Dialog dialog = serverTransactionId.getDialog(); + System.out.println("Dialog State = " + dialog.getState()); + Response response = messageFactory.createResponse(200, request); + serverTransactionId.sendResponse(response); + System.out.println("shootist: Sending OK."); + System.out.println("Dialog State = " + dialog.getState()); + + } catch (Exception ex) { + ex.printStackTrace(); + System.exit(0); + + } + } + + // Save the created ACK request, to respond to retransmitted 2xx + private Request ackRequest; + + public void processResponse(ResponseEvent responseReceivedEvent) { + System.out.println("Got a response"); + Response response = (Response) responseReceivedEvent.getResponse(); + ClientTransaction tid = responseReceivedEvent.getClientTransaction(); + CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME); + + System.out.println("Response received : Status Code = " + + response.getStatusCode() + " " + cseq); + + + if (tid == null) { + + // RFC3261: MUST respond to every 2xx + if (ackRequest!=null && dialog!=null) { + System.out.println("re-sending ACK"); + try { + dialog.sendAck(ackRequest); + } catch (SipException se) { + se.printStackTrace(); + } + } + return; + } + + System.out.println("transaction state is " + tid.getState()); + System.out.println("Dialog = " + tid.getDialog()); + System.out.println("Dialog State is " + tid.getDialog().getState()); + + try { + if (response.getStatusCode() == Response.OK) { + if (cseq.getMethod().equals(Request.INVITE)) { + ackRequest = dialog.createRequest(Request.ACK); + System.out.println("Sending ACK"); + dialog.sendAck(ackRequest); + // If the caller is supposed to send the bye + if ( callerSendsBye && !byeTaskRunning) { + byeTaskRunning = true; + new Timer().schedule(new ByeTask(dialog), 4000) ; + } + + } else if (cseq.getMethod().equals(Request.CANCEL)) { + if (dialog.getState() == DialogState.CONFIRMED) { + // oops cancel went in too late. Need to hang up the + // dialog. + System.out + .println("Sending BYE -- cancel went in too late !!"); + Request byeRequest = dialog.createRequest(Request.BYE); + ClientTransaction ct = sipProvider + .getNewClientTransaction(byeRequest); + dialog.sendRequest(ct); + + } + + } else if ( cseq.getMethod().equals(Request.BYE)) { + System.out.println("Got OK for the BYE -- tear down the stack"); + this.sipStack.stop(); + } + } + } catch (Exception ex) { + ex.printStackTrace(); + System.exit(0); + } + + } + + public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) { + + ClientTransaction ct = timeoutEvent.getClientTransaction(); + System.out.println("Transaction Time out" + ((ClientTransaction) ct).getRequest().getMethod()); + } + + + + public void init() { + SipFactory sipFactory = null; + sipStack = null; + sipFactory = SipFactory.getInstance(); + sipFactory.setPathName("gov.nist"); + Properties properties = new Properties(); + // If you want to try TCP transport change the following to + String transport = "udp"; + String peerHostPort = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070"; + properties.setProperty("javax.sip.OUTBOUND_PROXY", peerHostPort + "/" + + transport); + // If you want to use UDP then uncomment this. + properties.setProperty("javax.sip.STACK_NAME", "shootist"); + + // The following properties are specific to nist-sip + // and are not necessarily part of any other jain-sip + // implementation. + // You can set a max message size for tcp transport to + // guard against denial of service attack. + properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", + "logs/shootistdebug.txt"); + properties.setProperty("gov.nist.javax.sip.SERVER_LOG", + "logs/shootistlog.txt"); + + // Drop the client connection after we are done with the transaction. + properties.setProperty("gov.nist.javax.sip.CACHE_CLIENT_CONNECTIONS", + "false"); + // Set to 0 (or NONE) in your production code for max speed. + // You need 16 (or TRACE) for logging traces. 32 (or DEBUG) for debug + traces. + // Your code will limp at 32 but it is best for debugging. + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "TRACE"); + + try { + // Create SipStack object + sipStack = sipFactory.createSipStack(properties); + System.out.println("createSipStack " + sipStack); + } catch (PeerUnavailableException e) { + // could not find + // gov.nist.jain.protocol.ip.sip.SipStackImpl + // in the classpath + e.printStackTrace(); + System.err.println(e.getMessage()); + System.exit(0); + } + + try { + headerFactory = sipFactory.createHeaderFactory(); + addressFactory = sipFactory.createAddressFactory(); + messageFactory = sipFactory.createMessageFactory(); + udpListeningPoint = sipStack.createListeningPoint("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", 5080, "udp"); + sipProvider = sipStack.createSipProvider(udpListeningPoint); + Shootist listener = this; + sipProvider.addSipListener(listener); + + String fromName = "BigGuy"; + String fromSipAddress = "here.com"; + String fromDisplayName = "The Master Blaster"; + + String toSipAddress = "there.com"; + String toUser = "LittleGuy"; + String toDisplayName = "The Little Blister"; + + // create >From Header + SipURI fromAddress = addressFactory.createSipURI(fromName, + fromSipAddress); + + Address fromNameAddress = addressFactory.createAddress(fromAddress); + fromNameAddress.setDisplayName(fromDisplayName); + FromHeader fromHeader = headerFactory.createFromHeader( + fromNameAddress, "12345"); + + // create To Header + SipURI toAddress = addressFactory + .createSipURI(toUser, toSipAddress); + Address toNameAddress = addressFactory.createAddress(toAddress); + toNameAddress.setDisplayName(toDisplayName); + ToHeader toHeader = headerFactory.createToHeader(toNameAddress, + null); + + // create Request URI + SipURI requestURI = addressFactory.createSipURI(toUser, + peerHostPort); + + // Create ViaHeaders + + ArrayList viaHeaders = new ArrayList(); + String ipAddress = udpListeningPoint.getIPAddress(); + ViaHeader viaHeader = headerFactory.createViaHeader(ipAddress, + sipProvider.getListeningPoint(transport).getPort(), + transport, null); + + // add via headers + viaHeaders.add(viaHeader); + + // Create ContentTypeHeader + ContentTypeHeader contentTypeHeader = headerFactory + .createContentTypeHeader("application", "sdp"); + + // Create a new CallId header + CallIdHeader callIdHeader = sipProvider.getNewCallId(); + + // Create a new Cseq header + CSeqHeader cSeqHeader = headerFactory.createCSeqHeader(1L, + Request.INVITE); + + // Create a new MaxForwardsHeader + MaxForwardsHeader maxForwards = headerFactory + .createMaxForwardsHeader(70); + + // Create the request. + Request request = messageFactory.createRequest(requestURI, + Request.INVITE, callIdHeader, cSeqHeader, fromHeader, + toHeader, viaHeaders, maxForwards); + // Create contact headers + String host = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; + + SipURI contactUrl = addressFactory.createSipURI(fromName, host); + contactUrl.setPort(udpListeningPoint.getPort()); + contactUrl.setLrParam(); + + // Create the contact name address. + SipURI contactURI = addressFactory.createSipURI(fromName, host); + contactURI.setPort(sipProvider.getListeningPoint(transport) + .getPort()); + + Address contactAddress = addressFactory.createAddress(contactURI); + + // Add the contact address. + contactAddress.setDisplayName(fromName); + + contactHeader = headerFactory.createContactHeader(contactAddress); + request.addHeader(contactHeader); + + // You can add extension headers of your own making + // to the outgoing SIP request. + // Add the extension header. + Header extensionHeader = headerFactory.createHeader("My-Header", + "my header value"); + request.addHeader(extensionHeader); + + String sdpData = "v=0\r\n" + + "o=4855 13760799956958020 13760799956958020" + + " IN IP4 129.6.55.78\r\n" + "s=mysession session\r\n" + + "p=+46 8 52018010\r\n" + "c=IN IP4 129.6.55.78\r\n" + + "t=0 0\r\n" + "m=audio 6022 RTP/AVP 0 4 18\r\n" + + "a=rtpmap:0 PCMU/8000\r\n" + "a=rtpmap:4 G723/8000\r\n" + + "a=rtpmap:18 G729A/8000\r\n" + "a=ptime:20\r\n"; + byte[] contents = sdpData.getBytes(); + + request.setContent(contents, contentTypeHeader); + // You can add as many extension headers as you + // want. + + extensionHeader = headerFactory.createHeader("My-Other-Header", + "my new header value "); + request.addHeader(extensionHeader); + + Header callInfoHeader = headerFactory.createHeader("Call-Info", + ""); + request.addHeader(callInfoHeader); + + // Create the client transaction. + inviteTid = sipProvider.getNewClientTransaction(request); + + // send the request out. + inviteTid.sendRequest(); + + dialog = inviteTid.getDialog(); + + } catch (Exception ex) { + System.out.println(ex.getMessage()); + ex.printStackTrace(); + usage(); + } + } + + public static void main(String args[]) { + new Shootist().init(); + + } + + public void processIOException(IOExceptionEvent exceptionEvent) { + System.out.println("IOException happened for " + + exceptionEvent.getHost() + " port = " + + exceptionEvent.getPort()); + + } + + public void processTransactionTerminated( + TransactionTerminatedEvent transactionTerminatedEvent) { + System.out.println("Transaction terminated event recieved"); + } + + public void processDialogTerminated( + DialogTerminatedEvent dialogTerminatedEvent) { + System.out.println("dialogTerminatedEvent"); + this.sipStack.stop(); + + } + + +} diff --git a/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ShootistSipServlet.java b/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ShootistSipServlet.java index 0d30af139b..03cb86144a 100644 --- a/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ShootistSipServlet.java +++ b/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/ShootistSipServlet.java @@ -1,862 +1,917 @@ -/* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2014, Telestax Inc and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - */ - -package org.mobicents.servlet.sip.testsuite; - -import java.io.IOException; -import java.io.Serializable; -import java.io.UnsupportedEncodingException; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; - -import javax.annotation.Resource; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.sip.Address; -import javax.servlet.sip.Parameterable; -import javax.servlet.sip.ServletParseException; -import javax.servlet.sip.ServletTimer; -import javax.servlet.sip.SipApplicationSession; -import javax.servlet.sip.SipApplicationSessionEvent; -import javax.servlet.sip.SipApplicationSessionListener; -import javax.servlet.sip.SipFactory; -import javax.servlet.sip.SipServlet; -import javax.servlet.sip.SipServletContextEvent; -import javax.servlet.sip.SipServletListener; -import javax.servlet.sip.SipServletRequest; -import javax.servlet.sip.SipServletResponse; -import javax.servlet.sip.SipSession; -import javax.servlet.sip.SipSessionEvent; -import javax.servlet.sip.SipSessionListener; -import javax.servlet.sip.SipURI; -import javax.servlet.sip.TelURL; -import javax.servlet.sip.TimerListener; -import javax.servlet.sip.TimerService; -import javax.servlet.sip.URI; -import javax.sip.ListeningPoint; - -import org.apache.log4j.Logger; -import org.mobicents.javax.servlet.sip.SipServletRequestExt; -import org.mobicents.javax.servlet.sip.SipSessionExt; -import org.mobicents.javax.servlet.sip.dns.DNSResolver; -import org.mobicents.servlet.sip.SipConnector; -import org.mobicents.servlet.sip.listener.SipConnectorListener; - -public class ShootistSipServlet - extends SipServlet - implements SipServletListener,TimerListener, SipSessionListener, SipApplicationSessionListener, SipConnectorListener { - private static final long serialVersionUID = 1L; - private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; - private static final String ENCODE_URI = "encodedURI"; - private static final String TEST_ERROR_RESPONSE = "testErrorResponse"; - private static final String NO_BYE = "noBye"; - private static transient Logger logger = Logger.getLogger(ShootistSipServlet.class); - - public static AtomicBoolean isAlreadyAccessed = new AtomicBoolean(false); - - int numberOf183Responses = 0; - int numberOf180Responses = 0; - - @Resource - TimerService timerService; - @Resource - SipFactory sipFactory; - - ServletTimer keepAlivetimer; - - /** Creates a new instance of ShootistSipServlet */ - public ShootistSipServlet() { - } - - @Override - public void init(ServletConfig servletConfig) throws ServletException { - logger.info("the shootist has been started"); - super.init(servletConfig); - } - - @Override - protected void doProvisionalResponse(SipServletResponse resp) - throws ServletException, IOException { - try { - access(); - if(resp.getStatus() == 183) numberOf183Responses++; - if(resp.getStatus() == 180) numberOf180Responses++; - if(resp.getHeader("require") != null) { - SipServletRequest prack = resp.createPrack(); - SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); - SipURI requestURI = sipFactory.createSipURI("LittleGuy", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - prack.setRequestURI(requestURI); - prack.send(); - } - if(getServletContext().getInitParameter("cancelOn1xx") != null) { - try { - Thread.sleep(500); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - try { - resp.getRequest().getApplicationSession().setAttribute(TEST_ERROR_RESPONSE, "true"); - resp.getRequest().createCancel().send(); - } catch (IOException e) { - logger.error(e); - } - } - if(resp.getStatus() == 180 && getServletContext().getInitParameter("cancel") != null) { - String timeToWaitString = getServletContext().getInitParameter("servletTimer"); - if(timeToWaitString != null && !timeToWaitString.equals("0")) { - SipServletRequest cancelRequest = resp.getRequest().createCancel(); - timerService.createTimer(resp.getRequest().getApplicationSession(), 500, false, (Serializable) cancelRequest); - } - } - } finally { - release(); - } - } - - @Override - protected void doSuccessResponse(SipServletResponse sipServletResponse) - throws ServletException, IOException { - try { - access(); - logger.info("Got : " + sipServletResponse.getStatus() + " " - + sipServletResponse.getMethod()); - int status = sipServletResponse.getStatus(); - if (status == SipServletResponse.SC_OK && "REGISTER".equalsIgnoreCase(sipServletResponse.getMethod())) { - sipServletResponse.getSession().setInvalidateWhenReady(false); - timerService.createTimer(sipServletResponse.getApplicationSession(), 20000L, false, (Serializable)sipServletResponse.getSession()); - } - if (status == SipServletResponse.SC_OK && "INVITE".equalsIgnoreCase(sipServletResponse.getMethod())) { - SipServletRequest ackRequest = sipServletResponse.createAck(); - ackRequest.send(); - if(System.currentTimeMillis() - sipServletResponse.getSession().getLastAccessedTime() > 500) { - logger.error("lastAccessedTime was not updated => lastAccessedTime " + sipServletResponse.getSession().getLastAccessedTime() + " current Time " + System.currentTimeMillis()); - return; - } - - if(sipServletResponse.getRequest().isInitial() && !(sipServletResponse.getFrom().getURI() instanceof TelURL) && !(sipServletResponse.getTo().getURI() instanceof TelURL) && - ((SipURI)sipServletResponse.getFrom().getURI()).getUser() != null && - (((SipURI)sipServletResponse.getFrom().getURI()).getUser().equals("reinvite") || ((SipURI)sipServletResponse.getTo().getURI()).getUser().equals("reinvite"))) { - SipServletRequest request=sipServletResponse.getSession().createRequest("INVITE"); - request.send(); - } else { - if(sipServletResponse.getApplicationSession().getAttribute(ENCODE_URI) == null && getServletContext().getInitParameter(NO_BYE) == null) { - String timeToWaitForBye = getServletContext().getInitParameter("timeToWaitForBye"); - int delay = 2000; - if(timeToWaitForBye != null) { - delay = Integer.parseInt(timeToWaitForBye); - } - SipServletRequest sipServletRequest = sipServletResponse.getSession().createRequest("BYE"); - ServletTimer timer = timerService.createTimer(sipServletResponse.getApplicationSession(), delay, false, (Serializable)sipServletRequest); - sipServletResponse.getApplicationSession().setAttribute("timer", timer); - } - } - } - if(getServletContext().getInitParameter("closeReliableChannel")!= null) { - timerService.createTimer(sipFactory.createApplicationSession(), Long.valueOf(getServletContext().getInitParameter("timeout")), false, "" + sipServletResponse.getInitialRemotePort()); - } - if(getServletContext().getInitParameter("testKeepAlive") != null && sipServletResponse.getInitialRemotePort() != 5081) { - SipConnector[] sipConnectors = (SipConnector[]) getServletContext().getAttribute("org.mobicents.servlet.sip.SIP_CONNECTORS"); - for (SipConnector sipConnector : sipConnectors) { - if(sipConnector.getIpAddress().equals(sipServletResponse.getLocalAddr()) && sipConnector.getPort() == sipServletResponse.getLocalPort() && sipConnector.getTransport().equals(sipServletResponse.getTransport())) { - sipServletResponse.getApplicationSession().setAttribute("keepAliveAddress", sipServletResponse.getInitialRemoteAddr()); - sipServletResponse.getApplicationSession().setAttribute("keepAlivePort", sipServletResponse.getInitialRemotePort()); - sipServletResponse.getApplicationSession().setAttribute("keepAlivetoSend", Integer.valueOf(getServletContext().getInitParameter("testKeepAlive"))); - keepAlivetimer = timerService.createTimer(sipServletResponse.getApplicationSession(), 0, 2000, false, false, sipConnector); - return; - } - } - } - } finally { - release(); - } - } - - @Override - protected void doRequest(SipServletRequest req) throws ServletException, - IOException { - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - super.doRequest(req); - } - - @Override - protected void doResponse(SipServletResponse resp) throws ServletException, - IOException { - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - super.doResponse(resp); - } - - @Override - protected void doInvite(SipServletRequest req) throws ServletException, - IOException { - try { - access(); - String requestURIStringified = req.getRequestURI().toString(); - logger.info(requestURIStringified); - if(req.getTo().getURI().toString().contains("nonrecordrouteeinvite")) { - req.createResponse(200).send(); - return; - } - if(req.getTo().getURI().toString().contains("recordrouteeinvite")) { - ((SipSessionExt)req.getSession()).setCopyRecordRouteHeadersOnSubsequentResponses(true); - req.createResponse(200).send(); - return; - } - if(!requestURIStringified.startsWith("sip:mss@sip-servlets.com;org.mobicents.servlet.sip.ApplicationSessionKey=") && !requestURIStringified.endsWith("%3Aorg.mobicents.servlet.sip.testsuite.ShootistApplication")) { - req.createResponse(500, "SipURI.toString() does not escape charachters according to RFC2396.").send(); - } - if(((SipURI)req.getFrom().getURI()).getUser().equalsIgnoreCase(ENCODE_URI)) { - if(req.getApplicationSession().getAttribute(ENCODE_URI) != null) { - req.createResponse(200).send(); - } else { - req.createResponse(500, "received a request using the encodeURI mechanism but not the same sip application session").send(); - } - } else { - req.createResponse(500, "received a request using the encodeURI mechanism but not the same sip application session").send(); - } - } finally { - release(); - } - } - - @Override - protected void doErrorResponse(SipServletResponse sipServletResponse) - throws ServletException, IOException { - try { - access(); - logger.info("Got : " + sipServletResponse.getStatus()); - logger.info("remote address : " + sipServletResponse.getRemoteAddr()); - if(sipServletResponse.getRemoteAddr() == null) { - // non regression test for https://github.com/Mobicents/sip-servlets/issues/59 - throw new IllegalArgumentException("remote address shouldn't be null for 408 Timeout generated by the container"); - } - if( getServletContext().getInitParameter("cancel") != null) { - long now = System.currentTimeMillis(); - long timeSent = (Long) sipServletResponse.getApplicationSession().getAttribute("timeSent"); - if(now - timeSent > 30000) { - sendMessage(sipFactory.createApplicationSession(), sipFactory, "30 sec passed"); - } - } - if(sipServletResponse.getStatus() == 408) { - sendMessage(sipFactory.createApplicationSession(), sipFactory, "408 received"); - sipServletResponse.getApplicationSession().invalidate(); - } - if(sipServletResponse.getStatus() == 422) { - try { - Thread.sleep(10000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - sipServletResponse.getSession().createRequest("INVITE").send(); - } - } finally { - release(); - } - } - - @Override - protected void doBye(SipServletRequest req) throws ServletException, - IOException { - try { - access(); - ServletTimer timer = (ServletTimer) req.getApplicationSession().getAttribute("timer"); - if(timer != null) { - timer.cancel(); - } - req.createResponse(SipServletResponse.SC_OK).send(); - } finally { - release(); - } - } - - // SipServletListener methods - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipServletListener#servletInitialized(javax.servlet.sip.SipServletContextEvent) - */ - public void servletInitialized(SipServletContextEvent ce) { - try { - access(); - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - SipFactory sipFactory = (SipFactory)ce.getServletContext().getAttribute(SIP_FACTORY); - SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); - - String testServletListener = ce.getServletContext().getInitParameter("testServletListener"); - if(testServletListener != null) { - logger.error("servlet initialized " + this); - sendMessage(sipApplicationSession, sipFactory, "testServletListener"); - return; - } - String testContentLength = ce.getServletContext().getInitParameter("testContentLength"); - if(testContentLength != null) { - sendMessage(sipApplicationSession, sipFactory, null); - return; - } - - String userName = ce.getServletContext().getInitParameter("username"); - if(userName == null || userName.length() < 1) { - userName = "BigGuy"; - } - if(userName.equalsIgnoreCase("nullTest")) { - userName = ""; - } - URI fromURI = sipFactory.createSipURI(userName, "here.com"); - URI toURI = null; - if(ce.getServletContext().getInitParameter("urlType") != null) { - if(ce.getServletContext().getInitParameter("urlType").equalsIgnoreCase("tel")) { - try { - toURI = sipFactory.createURI("tel:+358-555-1234567"); - } catch (ServletParseException e) { - logger.error("Impossible to create the tel URL", e); - } - if(ce.getServletContext().getInitParameter("flag") != null) { - toURI.setParameter(ce.getServletContext().getInitParameter("flag"), ""); - } - if(ce.getServletContext().getInitParameter("enum") != null) { - DNSResolver dnsResolver = (DNSResolver) getServletContext().getAttribute("org.mobicents.servlet.sip.DNS_RESOLVER"); - toURI = dnsResolver.getSipURI(toURI); - } - } else if(ce.getServletContext().getInitParameter("urlType").equalsIgnoreCase("telAsSip")) { - try { - toURI = sipFactory.createURI("sip:+34666777888@192.168.0.20:5080"); - } catch (ServletParseException e) { - logger.error("Impossible to create the tel URL as SIP", e); - } - - try { - toURI = sipFactory.createAddress("").getURI(); - } catch (ServletParseException e) { - logger.error("Impossible to create the tel URL as SIP", e); - } - } - } else { - toURI = sipFactory.createSipURI("LittleGuy", "there.com"); - } - String toTag = ce.getServletContext().getInitParameter("toTag"); - if(toTag != null) { - toURI.setParameter("tag", toTag); - } - String toParam = ce.getServletContext().getInitParameter("toParam"); - if(toParam != null) { - toURI.setParameter("toParam", toParam); - } - - String method = ce.getServletContext().getInitParameter("method"); - if(method == null) { - method = "INVITE"; - } - SipServletRequest sipServletRequest = null; - if(ce.getServletContext().getInitParameter("useStringFactory") != null) { - try { - sipServletRequest = sipFactory.createRequest(sipApplicationSession, method, "sip:LittleGuy@there.com", userName); - if(!sipServletRequest.getTo().toString().contains(userName)) { - logger.error("To Address and username should match!"); - return; - } - } catch (ServletParseException e) { - logger.error("Impossible to create the " + method + " request ", e); - return; - } - } else { - sipServletRequest = sipFactory.createRequest(sipApplicationSession, method, sipFactory.createAddress(fromURI, "from display"), sipFactory.createAddress(toURI,"to display")); - } - - String authHeader = ce.getServletContext().getInitParameter("auth-header"); - if(authHeader != null) { - // test Issue 1547 : can't add a Proxy-Authorization using SipServletMessage.addHeader - // please note that addAuthHeader is not used here - String headerToAdd = ce.getServletContext().getInitParameter("headerToAdd"); - sipServletRequest.addHeader(headerToAdd, authHeader); - if(headerToAdd.equals("Proxy-Authorization")) { - sipServletRequest.addHeader("Proxy-Authenticate", authHeader); - } - } - - String routeHeader = ce.getServletContext().getInitParameter("route"); - if(routeHeader != null) { - try { - sipServletRequest.pushRoute((SipURI) sipFactory.createURI(routeHeader)); - } catch (ServletParseException e) { - logger.error("Couldn't create Route Header from " + routeHeader); - return; - } - } - - String outboundInterface = ce.getServletContext().getInitParameter("outboundInterface"); - if(outboundInterface != null) { - List outboundInterfaces = (List)getServletContext().getAttribute(OUTBOUND_INTERFACES); - - if(outboundInterfaces == null) throw new NullPointerException("Outbound interfaces should not be null"); - - for(SipURI uri:outboundInterfaces) { - logger.info("checking following outboudinterface" + uri +" against transport" + outboundInterface); - if(uri.toString().contains(outboundInterface)) { - logger.info("using following outboudinterface" + uri); - // pick the lo interface, since its universal on all machines - ((SipSessionExt)sipServletRequest.getSession()).setOutboundInterface(uri); - break; - } - } - } - if(!method.equalsIgnoreCase("REGISTER") && !method.equalsIgnoreCase("OPTIONS") && !method.equalsIgnoreCase("MESSAGE")) { - Address addr = null; - try { - addr = sipServletRequest.getAddressHeader("Contact"); - } catch (ServletParseException e1) { - } - if(addr == null) return; // Fail the test, we need that header - String prack = ce.getServletContext().getInitParameter("prack"); - if(prack != null) { - sipServletRequest.addHeader("Require", "100rel"); - } - addr.setParameter("headerparam1", "headervalue1"); - addr.setParameter("param5", "ffff"); - addr.getURI().setParameter("uriparam", "urivalue"); - } - String dontSetRURI = ce.getServletContext().getInitParameter("dontSetRURI"); - if(dontSetRURI == null) { - String host = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"; - if(ce.getServletContext().getInitParameter("testIOException") != null) { - host = ce.getServletContext().getInitParameter("testIOException"); - } - if(ce.getServletContext().getInitParameter("host") != null) { - host = ce.getServletContext().getInitParameter("host"); - } - SipURI requestURI = sipFactory.createSipURI("LittleGuy", host); - requestURI.setSecure(ce.getServletContext().getInitParameter("secureRURI")!=null); - if(ce.getServletContext().getInitParameter("encodeRequestURI") != null) { - sipApplicationSession.encodeURI(requestURI); - sipApplicationSession.setAttribute(ENCODE_URI, "true"); - } - if(ce.getServletContext().getInitParameter("transportRURI") != null) { - requestURI.setTransportParam(ce.getServletContext().getInitParameter("transportRURI")); - if(method.equalsIgnoreCase("REGISTER")) { - sipServletRequest.addHeader("Contact", "sips:LittleGuy@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - } - } - // http://code.google.com/p/sipservlets/issues/detail?id=156 and http://code.google.com/p/sipservlets/issues/detail?id=172 - if(ce.getServletContext().getInitParameter("setRandomContact") != null) { - if(method.equalsIgnoreCase("REGISTER")) { - sipServletRequest.addHeader("Contact", "sip:random@172.172.172.172:3289"); - } - if(method.equalsIgnoreCase("OPTIONS") || method.equalsIgnoreCase("MESSAGE")) { - try { - sipServletRequest.addHeader("Contact", "sip:random@172.172.172.172:3289"); - logger.error("JSR 289, Section 4.1.3 The Contact Header Field: Contact header is a system header except for the following messages: 4. 200/OPTIONS responses. Container should have thrown an exception"); - throw new IllegalStateException("JSR 289, Section 4.1.3 The Contact Header Field: Contact header is a system header except for the following messages: 4. 200/OPTIONS responses. Container should have thrown an exception"); - } catch(Exception e) { - } - try { - Address contactAddress = sipServletRequest.getAddressHeader("Contact"); - ((SipURI)contactAddress.getURI()).setUser("optionUser"); - ((SipURI)contactAddress.getURI()).setHost("optionHost.com"); - logger.error("JSR 289, Section 4.1.3 The Contact Header Field: Contact header is a system header except for the following messages: 4. 200/OPTIONS responses. Container should have thrown an exception"); - throw new IllegalStateException("JSR 289, Section 4.1.3 The Contact Header Field: Contact header is a system header except for the following messages: 4. 200/OPTIONS responses. Container should have thrown an exception"); - } catch(Exception e) { - } - try { - Parameterable contactHeader = sipServletRequest.getParameterableHeader("Contact"); - contactHeader.setParameter("optionParam", "optionValue"); - } catch (ServletParseException e) { - logger.error("an error occured while getting the contact Header", e); - } - - } - } -// try { - sipServletRequest.setRequestURI(requestURI); -// } catch (ServletParseException e) { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } - if(ce.getServletContext().getInitParameter("enum") != null) { - sipServletRequest.setRequestURI(toURI); - } - } - String testErrorResponse = ce.getServletContext().getInitParameter(TEST_ERROR_RESPONSE); - if(testErrorResponse != null) { - sipServletRequest.getApplicationSession().setAttribute(TEST_ERROR_RESPONSE, "true"); - } - if(sipServletRequest.getTo().getParameter("tag") != null) { - logger.error("the ToTag should be empty, not sending the request"); - return; - } - - String testRemoteAddrAndPort = ce.getServletContext().getInitParameter("testRemoteAddrAndPort"); - if(testRemoteAddrAndPort != null) { - sipServletRequest.getRemoteAddr(); - sipServletRequest.getRemotePort(); - sipServletRequest.getRemoteHost(); - sipServletRequest.getRemoteUser(); - sipServletRequest.getInitialRemoteAddr(); - sipServletRequest.getInitialPoppedRoute(); - sipServletRequest.getInitialRemotePort(); - sipServletRequest.getInitialTransport(); - } - String testMultipleReasonHeaders = ce.getServletContext().getInitParameter("testMultipleReasonHeaders"); - if(testMultipleReasonHeaders != null) { - sipServletRequest.addHeader("Reason", "SIP ;cause=200 ;text=\"Call completed elsewhere\""); - sipServletRequest.addHeader("Reason", "Q.850 ;cause=16 ;text=\"Terminated\""); - } - // test for http://code.google.com/p/sipservlets/issues/detail?id=31 - Parameterable paramVia = null; - try { - String via = sipServletRequest.getHeader("Via"); - paramVia = sipServletRequest.getParameterableHeader("Via"); - - logger.info("Via Header " + via); - logger.info("Param Via Header " + paramVia); - } catch (ServletParseException e) { - logger.error("couln't parse the Via Header ", e); - } - paramVia.setParameter("rport", ""); - boolean gotException = false; - try { - paramVia.setParameter("branch", ""); - } catch (IllegalStateException e) { - gotException = true; - } - if(gotException) { - logger.info("got the expected exception on Via Header branch setting"); - } else { - throw new IllegalStateException("didn't get the expected exception on branch modification of the Via Header"); - } - if(testRemoteAddrAndPort != null) { - sipServletRequest.getRemoteAddr(); - sipServletRequest.getRemotePort(); - sipServletRequest.getRemoteHost(); - sipServletRequest.getRemoteUser(); - sipServletRequest.getInitialRemoteAddr(); - sipServletRequest.getInitialPoppedRoute(); - sipServletRequest.getInitialRemotePort(); - sipServletRequest.getInitialTransport(); - } - if(ce.getServletContext().getInitParameter("testMultipartBytes") != null) { - // https://code.google.com/p/sipservlets/issues/detail?id=169 - try { - sipServletRequest.setContent(new String("test Multipart"), "multipart/unknown"); - } catch (UnsupportedEncodingException e) { - throw new IllegalStateException("couldn't set the content", e); - } - } - if(ce.getServletContext().getInitParameter("testAddressParam") != null) { - // https://code.google.com/p/sipservlets/issues/detail?id=245 - try { - sipServletRequest.getFrom().setDisplayName("Test name"); - sipServletRequest.getFrom().setParameter("epid", "00112233"); - sipServletRequest.getTo().setParameter("epid", "33221100"); - - Address address = sipFactory.createAddress(sipFactory.createURI("sip:test@address.example.com")); - address.setParameter("epid", "bzz"); - sipServletRequest.addAddressHeader("TestAddress", address, true); - - logger.info("testAddressParam Test Address" + address); - logger.info("request " + sipServletRequest); - } catch (ServletParseException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - if(ce.getServletContext().getInitParameter("testGruu") != null) { - logger.info("testGruu Test Address"); - // https://github.com/Mobicents/sip-servlets/issues/51 - try { - // Support for https://tools.ietf.org/html/rfc5627 - Address address = sipFactory.createAddress(""); - sipServletRequest.addAddressHeader("Contact", address, true); - logger.info("request " + sipServletRequest); - sipServletRequest.removeHeader("Contact"); - - // Support for https://tools.ietf.org/html/draft-ietf-sip-gruu-10#section-14.1 for Lync interop - address = sipFactory.createAddress(""); - sipServletRequest.addAddressHeader("Contact", address, true); - logger.info("request " + sipServletRequest); - - } catch (ServletParseException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - try { - sipServletRequest.send(); - } catch (IOException e) { - if(ce.getServletContext().getInitParameter("testIOException") != null) { - logger.info("expected exception thrown" + e); - ((SipURI)sipServletRequest.getRequestURI()).setHost("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); - ((SipURI)sipServletRequest.getRequestURI()).setPort(5080); - ((SipURI)sipServletRequest.getRequestURI()).setTransportParam("udp"); - try { - sipServletRequest.send(); - sendMessage(sipApplicationSession, sipFactory, "IOException thrown"); - } catch (IOException e1) { - logger.error("Unexpected exception while sending the INVITE request",e1); - } - } else { - logger.error("Unexpected exception while sending the INVITE request",e); - } - } - if(ce.getServletContext().getInitParameter("cancel") != null) { - SipServletRequest cancelRequest = sipServletRequest.createCancel(); - sipServletRequest.getApplicationSession().setAttribute(TEST_ERROR_RESPONSE, "true"); - String timeToWaitString = ce.getServletContext().getInitParameter("servletTimer"); - if(timeToWaitString == null) { - try { - Thread.sleep(500); - cancelRequest.send(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } catch (IOException e) { - logger.error(e); - } - } else if(timeToWaitString.equals("0")) { - if(getServletContext().getInitParameter("servletTimer") != null) { - timerService.createTimer(sipServletRequest.getApplicationSession(), 0, false, (Serializable) cancelRequest); - try { - Thread.sleep(2000); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - } - } - } finally { - release(); - } - } - - public void timeout(ServletTimer timer) { - try { - Serializable info = timer.getInfo(); - if (info instanceof String) { - String port = (String)info; - SipConnector[] sipConnectors = (SipConnector[]) getServletContext().getAttribute("org.mobicents.servlet.sip.SIP_CONNECTORS"); - for (SipConnector sipConnector : sipConnectors) { - if(sipConnector.getIpAddress().equals(System.getProperty("org.mobicents.testsuite.testhostaddr")) && sipConnector.getTransport().equalsIgnoreCase("TCP")) { - try { - boolean changed = sipConnector.closeReliableConnection(System.getProperty("org.mobicents.testsuite.testhostaddr"), Integer.valueOf(port)); - logger.info("SipConnector reliable connection killed changed " + System.getProperty("org.mobicents.testsuite.testhostaddr") +":"+ Integer.valueOf(port)+ " changed " + changed); - if(changed) { - keepAlivetimer.cancel(); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - } - return; - } - access(); - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - if(info instanceof SipConnector) { - String remoteAddress = (String) timer.getApplicationSession().getAttribute("keepAliveAddress"); - int remotePort = (Integer) timer.getApplicationSession().getAttribute("keepAlivePort"); - int keepAlivetoSend = (Integer) timer.getApplicationSession().getAttribute("keepAlivetoSend"); - Integer keepAliveSent = (Integer) timer.getApplicationSession().getAttribute("keepAliveSent"); - if(keepAliveSent == null) { - keepAliveSent = 0; - } - logger.info("keepalive sent " + keepAliveSent + " ,keepAliveToSend " + keepAlivetoSend); - if(keepAliveSent < keepAlivetoSend) { - try { - ((SipConnector)info).sendHeartBeat(remoteAddress, remotePort); - } catch (Exception e) { - logger.error("problem sending heartbeat to " + remoteAddress+":"+ remotePort); - timer.cancel(); - } - keepAliveSent = keepAliveSent.intValue() +1; - timer.getApplicationSession().setAttribute("keepAliveSent", new Integer(keepAliveSent)); - if(keepAliveSent >= keepAlivetoSend) { - try { - ((SipConnector)info).setKeepAliveTimeout(remoteAddress, remotePort, -1); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - } - } else if(info instanceof SipSession){ - SipSession sipSession = (SipSession) info; - try { - sipSession.createRequest("REGISTER").send(); - } catch (IOException e) { - logger.error("Unexpected exception while sending the REGISTER request",e); - } - } else { - SipServletRequest sipServletRequest = (SipServletRequest) timer.getInfo(); - sipServletRequest.getApplicationSession().setAttribute("timeSent", Long.valueOf(System.currentTimeMillis())); - try { - // http://code.google.com/p/sipservlets/issues/detail?id=31 - sipServletRequest.getParameterableHeader("Via").setParameter("rport", ""); - sipServletRequest.send(); - } catch (IOException e) { - logger.error("Unexpected exception while sending the BYE request",e); - } catch (ServletParseException e) { - logger.error("Couldn't parse via header for BYE request",e); - } - timer.cancel(); - } - } finally { - release(); - } - } - - public void access() { - if(!isAlreadyAccessed.compareAndSet(false, true)) { - sendMessage(sipFactory.createApplicationSession(), sipFactory, "servlet is already being accessed !", null); - } - } - - public void release() { - isAlreadyAccessed.set(false); - } - - /** - * @param sipApplicationSession - * @param storedFactory - */ - private void sendMessage(SipApplicationSession sipApplicationSession, - SipFactory storedFactory, String content) { - try { - SipServletRequest sipServletRequest = storedFactory.createRequest( - sipApplicationSession, - "MESSAGE", - "sip:sender@sip-servlets.com", - "sip:receiver@sip-servlets.com"); - SipURI sipUri=storedFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - sipServletRequest.setRequestURI(sipUri); - if(content != null) { - sipServletRequest.setContentLength(content.length()); - sipServletRequest.setContent(content, CONTENT_TYPE); - } else { - sipServletRequest.setContentLength(0); - } - sipServletRequest.send(); - } catch (ServletParseException e) { - logger.error("Exception occured while parsing the addresses",e); - } catch (IOException e) { - logger.error("Exception occured while sending the request",e); - } - } - - public void sessionCreated(SipSessionEvent se) { - // TODO Auto-generated method stub - - } - - public void sessionDestroyed(SipSessionEvent se) { - // TODO Auto-generated method stub - - } - - public void sessionReadyToInvalidate(SipSessionEvent se) { - if(se.getSession().getApplicationSession().getAttribute(TEST_ERROR_RESPONSE) != null) { - sendMessage(sipFactory.createApplicationSession(), sipFactory, "sipSessionReadyToInvalidate", null); - } - } - - public void sessionCreated(SipApplicationSessionEvent ev) { - // TODO Auto-generated method stub - - } - - public void sessionDestroyed(SipApplicationSessionEvent ev) { - // TODO Auto-generated method stub - - } - - public void sessionExpired(SipApplicationSessionEvent ev) { - // TODO Auto-generated method stub - - } - - public void sessionReadyToInvalidate(SipApplicationSessionEvent ev) { - if(ev.getApplicationSession().getAttribute(TEST_ERROR_RESPONSE) != null) { - sendMessage(sipFactory.createApplicationSession(), sipFactory, "sipAppSessionReadyToInvalidate", null); - } - } - - /** - * @param sipApplicationSession - * @param storedFactory - */ - private void sendMessage(SipApplicationSession sipApplicationSession, - SipFactory storedFactory, String content, String transport) { - try { - SipServletRequest sipServletRequest = storedFactory.createRequest( - sipApplicationSession, - "MESSAGE", - "sip:sender@sip-servlets.com", - "sip:receiver@sip-servlets.com"); - sipServletRequest.addHeader("Ext", "Test 1, 2 ,3"); - SipURI sipUri = storedFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - if(transport != null) { - if(transport.equalsIgnoreCase(ListeningPoint.TCP)) { - sipUri = storedFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5081"); - } - sipUri.setTransportParam(transport); - } - sipServletRequest.setRequestURI(sipUri); - sipServletRequest.setContentLength(content.length()); - sipServletRequest.setContent(content, CONTENT_TYPE); - sipServletRequest.setHeader("EarlyMediaResponses", new Integer(numberOf183Responses).toString()); - sipServletRequest.setHeader("EarlyMedia180Responses", new Integer(numberOf180Responses).toString()); - - sipServletRequest.send(); - } catch (ServletParseException e) { - logger.error("Exception occured while parsing the addresses",e); - } catch (IOException e) { - logger.error("Exception occured while sending the request",e); - } - } - - - @Override - public void sipConnectorAdded(SipConnector connector) { - - } - - @Override - public void sipConnectorRemoved(SipConnector connector) { - - } - - @Override - public void onKeepAliveTimeout(SipConnector connector, String peerAddress, - int peerPort) { - logger.error("SipConnector " + connector + " remotePeer " + peerAddress +":"+ peerPort); - keepAlivetimer.cancel(); - sendMessage(sipFactory.createApplicationSession(), sipFactory, "shootist onKeepAliveTimeout", "tcp"); - } +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2014, Telestax Inc and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + */ + +package org.mobicents.servlet.sip.testsuite; + +import java.io.IOException; +import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.net.Inet4Address; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +import javax.annotation.Resource; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.sip.Address; +import javax.servlet.sip.Parameterable; +import javax.servlet.sip.ServletParseException; +import javax.servlet.sip.ServletTimer; +import javax.servlet.sip.SipApplicationSession; +import javax.servlet.sip.SipApplicationSessionEvent; +import javax.servlet.sip.SipApplicationSessionListener; +import javax.servlet.sip.SipFactory; +import javax.servlet.sip.SipServlet; +import javax.servlet.sip.SipServletContextEvent; +import javax.servlet.sip.SipServletListener; +import javax.servlet.sip.SipServletRequest; +import javax.servlet.sip.SipServletResponse; +import javax.servlet.sip.SipSession; +import javax.servlet.sip.SipSessionEvent; +import javax.servlet.sip.SipSessionListener; +import javax.servlet.sip.SipURI; +import javax.servlet.sip.TelURL; +import javax.servlet.sip.TimerListener; +import javax.servlet.sip.TimerService; +import javax.servlet.sip.URI; +import javax.sip.ListeningPoint; + +import org.apache.log4j.Logger; +import org.mobicents.javax.servlet.sip.SipSessionExt; +import org.mobicents.javax.servlet.sip.dns.DNSResolver; +import org.mobicents.servlet.sip.SipConnector; +import org.mobicents.servlet.sip.listener.SipConnectorListener; + +public class ShootistSipServlet + extends SipServlet + implements SipServletListener,TimerListener, SipSessionListener, SipApplicationSessionListener, SipConnectorListener { + private static final long serialVersionUID = 1L; + private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; + private static final String ENCODE_URI = "encodedURI"; + private static final String TEST_ERROR_RESPONSE = "testErrorResponse"; + private static final String NO_BYE = "noBye"; + private static transient Logger logger = Logger.getLogger(ShootistSipServlet.class); + + public static AtomicBoolean isAlreadyAccessed = new AtomicBoolean(false); + + int numberOf183Responses = 0; + int numberOf180Responses = 0; + + @Resource + TimerService timerService; + @Resource + SipFactory sipFactory; + + ServletTimer keepAlivetimer; + + static ServletContext ctx; + + /** Creates a new instance of ShootistSipServlet */ + public ShootistSipServlet() { + } + + @Override + public void init(ServletConfig servletConfig) throws ServletException { + logger.info("the shootist has been started"); + super.init(servletConfig); + ctx = servletConfig.getServletContext(); + } + + @Override + protected void doProvisionalResponse(SipServletResponse resp) + throws ServletException, IOException { + try { + access(); + if(resp.getStatus() == 183) numberOf183Responses++; + if(resp.getStatus() == 180) numberOf180Responses++; + if(resp.getHeader("require") != null) { + SipServletRequest prack = resp.createPrack(); + SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); + SipURI requestURI = sipFactory.createSipURI("LittleGuy", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + prack.setRequestURI(requestURI); + prack.send(); + } + if(getServletContext().getInitParameter("cancelOn1xx") != null) { + try { + Thread.sleep(500); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + try { + resp.getRequest().getApplicationSession().setAttribute(TEST_ERROR_RESPONSE, "true"); + resp.getRequest().createCancel().send(); + } catch (IOException e) { + logger.error(e); + } + } + if(resp.getStatus() == 180 && getServletContext().getInitParameter("cancel") != null) { + String timeToWaitString = getServletContext().getInitParameter("servletTimer"); + if(timeToWaitString != null && !timeToWaitString.equals("0")) { + SipServletRequest cancelRequest = resp.getRequest().createCancel(); + timerService.createTimer(resp.getRequest().getApplicationSession(), 500, false, (Serializable) cancelRequest); + } + } + } finally { + release(); + } + } + + @Override + protected void doSuccessResponse(SipServletResponse sipServletResponse) + throws ServletException, IOException { + try { + access(); + logger.info("Got : " + sipServletResponse.getStatus() + " " + + sipServletResponse.getMethod()); + int status = sipServletResponse.getStatus(); + if (status == SipServletResponse.SC_OK && "REGISTER".equalsIgnoreCase(sipServletResponse.getMethod())) { + sipServletResponse.getSession().setInvalidateWhenReady(false); + timerService.createTimer(sipServletResponse.getApplicationSession(), 20000L, false, (Serializable)sipServletResponse.getSession()); + } + if (status == SipServletResponse.SC_OK && "INVITE".equalsIgnoreCase(sipServletResponse.getMethod())) { + SipServletRequest ackRequest = sipServletResponse.createAck(); + ackRequest.send(); + long elapsed = System.currentTimeMillis() - sipServletResponse.getSession().getLastAccessedTime(); + //increased to 1 second,500 ms was amking some tests fail + if(elapsed > 1000) { + logger.error("lastAccessedTime was not updated => lastAccessedTime " + sipServletResponse.getSession().getLastAccessedTime() + " current Time " + System.currentTimeMillis()); + return; + } + + if(sipServletResponse.getRequest().isInitial() && !(sipServletResponse.getFrom().getURI() instanceof TelURL) && !(sipServletResponse.getTo().getURI() instanceof TelURL) && + ((SipURI)sipServletResponse.getFrom().getURI()).getUser() != null && + (((SipURI)sipServletResponse.getFrom().getURI()).getUser().equals("reinvite") || ((SipURI)sipServletResponse.getTo().getURI()).getUser().equals("reinvite"))) { + SipServletRequest request=sipServletResponse.getSession().createRequest("INVITE"); + request.send(); + } else { + if(sipServletResponse.getApplicationSession().getAttribute(ENCODE_URI) == null && getServletContext().getInitParameter(NO_BYE) == null) { + String timeToWaitForBye = getServletContext().getInitParameter("timeToWaitForBye"); + int delay = 2000; + if(timeToWaitForBye != null) { + delay = Integer.parseInt(timeToWaitForBye); + } + SipServletRequest sipServletRequest = sipServletResponse.getSession().createRequest("BYE"); + ServletTimer timer = timerService.createTimer(sipServletResponse.getApplicationSession(), delay, false, (Serializable)sipServletRequest); + sipServletResponse.getApplicationSession().setAttribute("timer", timer); + } + } + } + if(getServletContext().getInitParameter("closeReliableChannel")!= null) { + timerService.createTimer(sipFactory.createApplicationSession(), Long.valueOf(getServletContext().getInitParameter("timeout")), false, "" + sipServletResponse.getInitialRemotePort()); + } + if(getServletContext().getInitParameter("testKeepAlive") != null && sipServletResponse.getInitialRemotePort() != getTestPort(ctx)) { + SipConnector[] sipConnectors = (SipConnector[]) getServletContext().getAttribute("org.mobicents.servlet.sip.SIP_CONNECTORS"); + for (SipConnector sipConnector : sipConnectors) { + if(sipConnector.getIpAddress().equals(sipServletResponse.getLocalAddr()) && sipConnector.getPort() == sipServletResponse.getLocalPort() && sipConnector.getTransport().equals(sipServletResponse.getTransport())) { + sipServletResponse.getApplicationSession().setAttribute("keepAliveAddress", sipServletResponse.getInitialRemoteAddr()); + sipServletResponse.getApplicationSession().setAttribute("keepAlivePort", sipServletResponse.getInitialRemotePort()); + sipServletResponse.getApplicationSession().setAttribute("keepAlivetoSend", Integer.valueOf(getServletContext().getInitParameter("testKeepAlive"))); + keepAlivetimer = timerService.createTimer(sipServletResponse.getApplicationSession(), 0, 2000, false, false, sipConnector); + return; + } + } + } + } finally { + release(); + } + } + + @Override + protected void doRequest(SipServletRequest req) throws ServletException, + IOException { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + super.doRequest(req); + } + + @Override + protected void doResponse(SipServletResponse resp) throws ServletException, + IOException { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + super.doResponse(resp); + } + + @Override + protected void doInvite(SipServletRequest req) throws ServletException, + IOException { + try { + access(); + String requestURIStringified = req.getRequestURI().toString(); + logger.info(requestURIStringified); + if(req.getTo().getURI().toString().contains("nonrecordrouteeinvite")) { + req.createResponse(200).send(); + return; + } + if(req.getTo().getURI().toString().contains("recordrouteeinvite")) { + ((SipSessionExt)req.getSession()).setCopyRecordRouteHeadersOnSubsequentResponses(true); + req.createResponse(200).send(); + return; + } + if(!requestURIStringified.startsWith("sip:mss@sip-servlets.com;org.mobicents.servlet.sip.ApplicationSessionKey=") && !requestURIStringified.endsWith("%3Aorg.mobicents.servlet.sip.testsuite.ShootistApplication")) { + req.createResponse(500, "SipURI.toString() does not escape charachters according to RFC2396.").send(); + } + if(((SipURI)req.getFrom().getURI()).getUser().equalsIgnoreCase(ENCODE_URI)) { + if(req.getApplicationSession().getAttribute(ENCODE_URI) != null) { + req.createResponse(200).send(); + } else { + req.createResponse(500, "received a request using the encodeURI mechanism but not the same sip application session").send(); + } + } else { + req.createResponse(500, "received a request using the encodeURI mechanism but not the same sip application session").send(); + } + } finally { + release(); + } + } + + @Override + protected void doErrorResponse(SipServletResponse sipServletResponse) + throws ServletException, IOException { + try { + access(); + logger.info("Got : " + sipServletResponse.getStatus()); + logger.info("remote address : " + sipServletResponse.getRemoteAddr()); + if(sipServletResponse.getRemoteAddr() == null) { + // non regression test for https://github.com/Mobicents/sip-servlets/issues/59 + throw new IllegalArgumentException("remote address shouldn't be null for 408 Timeout generated by the container"); + } + if( getServletContext().getInitParameter("cancel") != null) { + long now = System.currentTimeMillis(); + if(sipServletResponse.getApplicationSession().getAttribute("timeSent") != null) { + long timeSent = (Long) sipServletResponse.getApplicationSession().getAttribute("timeSent"); + if(now - timeSent > 30000) { + sendMessage(sipFactory.createApplicationSession(), sipFactory, "30 sec passed"); + } + } + } + if(sipServletResponse.getStatus() == 408) { + sendMessage(sipFactory.createApplicationSession(), sipFactory, "408 received"); + sipServletResponse.getApplicationSession().invalidate(); + } + if(sipServletResponse.getStatus() == 422) { + try { + Thread.sleep(10000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + sipServletResponse.getSession().createRequest("INVITE").send(); + } + } finally { + release(); + } + } + + @Override + protected void doBye(SipServletRequest req) throws ServletException, + IOException { + try { + access(); + ServletTimer timer = (ServletTimer) req.getApplicationSession().getAttribute("timer"); + if(timer != null) { + timer.cancel(); + } + req.createResponse(SipServletResponse.SC_OK).send(); + } finally { + release(); + } + } + + // SipServletListener methods + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipServletListener#servletInitialized(javax.servlet.sip.SipServletContextEvent) + */ + public void servletInitialized(SipServletContextEvent ce) { + try { + access(); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + SipFactory sipFactory = (SipFactory)ce.getServletContext().getAttribute(SIP_FACTORY); + SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); + + String testServletListener = ce.getServletContext().getInitParameter("testServletListener"); + if(testServletListener != null) { + logger.error("servlet initialized " + this); + sendMessage(sipApplicationSession, sipFactory, "testServletListener"); + return; + } + String testContentLength = ce.getServletContext().getInitParameter("testContentLength"); + if(testContentLength != null) { + sendMessage(sipApplicationSession, sipFactory, null); + return; + } + + String userName = ce.getServletContext().getInitParameter("username"); + if(userName == null || userName.length() < 1) { + userName = "BigGuy"; + } + if(userName.equalsIgnoreCase("nullTest")) { + userName = ""; + } + URI fromURI = sipFactory.createSipURI(userName, "here.com"); + URI toURI = null; + if(ce.getServletContext().getInitParameter("urlType") != null) { + if(ce.getServletContext().getInitParameter("urlType").equalsIgnoreCase("tel")) { + try { + toURI = sipFactory.createURI("tel:+358-555-1234567"); + } catch (ServletParseException e) { + logger.error("Impossible to create the tel URL", e); + } + if(ce.getServletContext().getInitParameter("flag") != null) { + toURI.setParameter(ce.getServletContext().getInitParameter("flag"), ""); + } + if(ce.getServletContext().getInitParameter("enum") != null) { + DNSResolver dnsResolver = (DNSResolver) getServletContext().getAttribute("org.mobicents.servlet.sip.DNS_RESOLVER"); + toURI = dnsResolver.getSipURI(toURI); + } + } else if(ce.getServletContext().getInitParameter("urlType").equalsIgnoreCase("telAsSip")) { + try { + toURI = sipFactory.createURI("sip:+34666777888@192.168.0.20:" + getTestPort(ctx)); + } catch (ServletParseException e) { + logger.error("Impossible to create the tel URL as SIP", e); + } + + try { + toURI = sipFactory.createAddress("").getURI(); + } catch (ServletParseException e) { + logger.error("Impossible to create the tel URL as SIP", e); + } + } + } else { + toURI = sipFactory.createSipURI("LittleGuy", "there.com"); + } + String toTag = ce.getServletContext().getInitParameter("toTag"); + if(toTag != null) { + toURI.setParameter("tag", toTag); + } + String toParam = ce.getServletContext().getInitParameter("toParam"); + if(toParam != null) { + toURI.setParameter("toParam", toParam); + } + + String method = ce.getServletContext().getInitParameter("method"); + if(method == null) { + method = "INVITE"; + } + SipServletRequest sipServletRequest = null; + if(ce.getServletContext().getInitParameter("useStringFactory") != null) { + try { + sipServletRequest = sipFactory.createRequest(sipApplicationSession, method, "sip:LittleGuy@there.com", userName); + if(!sipServletRequest.getTo().toString().contains(userName)) { + logger.error("To Address and username should match!"); + return; + } + } catch (ServletParseException e) { + logger.error("Impossible to create the " + method + " request ", e); + return; + } + } else { + sipServletRequest = sipFactory.createRequest(sipApplicationSession, method, sipFactory.createAddress(fromURI, "from display"), sipFactory.createAddress(toURI,"to display")); + } + + String authHeader = ce.getServletContext().getInitParameter("auth-header"); + if(authHeader != null) { + // test Issue 1547 : can't add a Proxy-Authorization using SipServletMessage.addHeader + // please note that addAuthHeader is not used here + String headerToAdd = ce.getServletContext().getInitParameter("headerToAdd"); + sipServletRequest.addHeader(headerToAdd, authHeader); + if(headerToAdd.equals("Proxy-Authorization")) { + sipServletRequest.addHeader("Proxy-Authenticate", authHeader); + } + } + + String routeHeader = ce.getServletContext().getInitParameter("route"); + if(routeHeader != null) { + try { + sipServletRequest.pushRoute((SipURI) sipFactory.createURI(routeHeader)); + } catch (ServletParseException e) { + logger.error("Couldn't create Route Header from " + routeHeader); + return; + } + } + + String outboundInterface = ce.getServletContext().getInitParameter("outboundInterface"); + if(outboundInterface != null) { + List outboundInterfaces = (List)getServletContext().getAttribute(OUTBOUND_INTERFACES); + + if(outboundInterfaces == null) throw new NullPointerException("Outbound interfaces should not be null"); + + for(SipURI uri:outboundInterfaces) { + logger.info("checking following outboudinterface" + uri +" against transport" + outboundInterface); + if(uri.toString().contains(outboundInterface)) { + logger.info("using following outboudinterface" + uri); + // pick the lo interface, since its universal on all machines + ((SipSessionExt)sipServletRequest.getSession()).setOutboundInterface(uri); + break; + } + } + } + if(!method.equalsIgnoreCase("REGISTER") && !method.equalsIgnoreCase("OPTIONS") && !method.equalsIgnoreCase("MESSAGE")) { + Address addr = null; + try { + addr = sipServletRequest.getAddressHeader("Contact"); + } catch (ServletParseException e1) { + } + if(addr == null) return; // Fail the test, we need that header + String prack = ce.getServletContext().getInitParameter("prack"); + if(prack != null) { + sipServletRequest.addHeader("Require", "100rel"); + } + addr.setParameter("headerparam1", "headervalue1"); + addr.setParameter("param5", "ffff"); + addr.setParameter("+sip.instance", "\"\""); + addr.getURI().setParameter("uriparam", "urivalue"); + if (ce.getServletContext().getInitParameter("testContactHeader") != null){ + addr.setParameter("param0", "value0"); + addr.setParameter("qparam1", "value1"); + addr.setParameter("param2", "value2"); + addr.setParameter("qparam3", "value3"); + } + } + String dontSetRURI = ce.getServletContext().getInitParameter("dontSetRURI"); + if(dontSetRURI == null) { + String host = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx); + if(ce.getServletContext().getInitParameter("testIOException") != null) { + host = ce.getServletContext().getInitParameter("testIOException"); + } + if(ce.getServletContext().getInitParameter("host") != null) { + host = ce.getServletContext().getInitParameter("host"); + } + SipURI requestURI = sipFactory.createSipURI("LittleGuy", host); + requestURI.setSecure(ce.getServletContext().getInitParameter("secureRURI")!=null); + if(ce.getServletContext().getInitParameter("encodeRequestURI") != null) { + sipApplicationSession.encodeURI(requestURI); + sipApplicationSession.setAttribute(ENCODE_URI, "true"); + } + if(ce.getServletContext().getInitParameter("transportRURI") != null) { + requestURI.setTransportParam(ce.getServletContext().getInitParameter("transportRURI")); + if(method.equalsIgnoreCase("REGISTER")) { + sipServletRequest.addHeader("Contact", "sips:LittleGuy@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + } + } + // http://code.google.com/p/sipservlets/issues/detail?id=156 and http://code.google.com/p/sipservlets/issues/detail?id=172 + if(ce.getServletContext().getInitParameter("setRandomContact") != null) { + if(method.equalsIgnoreCase("REGISTER")) { + sipServletRequest.addHeader("Contact", "sip:random@172.172.172.172:3289"); + } + if(method.equalsIgnoreCase("OPTIONS") || method.equalsIgnoreCase("MESSAGE")) { + try { + sipServletRequest.addHeader("Contact", "sip:random@172.172.172.172:3289"); + logger.error("JSR 289, Section 4.1.3 The Contact Header Field: Contact header is a system header except for the following messages: 4. 200/OPTIONS responses. Container should have thrown an exception"); + throw new IllegalStateException("JSR 289, Section 4.1.3 The Contact Header Field: Contact header is a system header except for the following messages: 4. 200/OPTIONS responses. Container should have thrown an exception"); + } catch(Exception e) { + } + try { + Address contactAddress = sipServletRequest.getAddressHeader("Contact"); + ((SipURI)contactAddress.getURI()).setUser("optionUser"); + ((SipURI)contactAddress.getURI()).setHost("optionHost.com"); + logger.error("JSR 289, Section 4.1.3 The Contact Header Field: Contact header is a system header except for the following messages: 4. 200/OPTIONS responses. Container should have thrown an exception"); + throw new IllegalStateException("JSR 289, Section 4.1.3 The Contact Header Field: Contact header is a system header except for the following messages: 4. 200/OPTIONS responses. Container should have thrown an exception"); + } catch(Exception e) { + } + try { + Parameterable contactHeader = sipServletRequest.getParameterableHeader("Contact"); + contactHeader.setParameter("optionParam", "optionValue"); + } catch (ServletParseException e) { + logger.error("an error occured while getting the contact Header", e); + } + + } + } +// try { + sipServletRequest.setRequestURI(requestURI); +// } catch (ServletParseException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } + if(ce.getServletContext().getInitParameter("enum") != null) { + sipServletRequest.setRequestURI(toURI); + } + } + String testErrorResponse = ce.getServletContext().getInitParameter(TEST_ERROR_RESPONSE); + if(testErrorResponse != null) { + sipServletRequest.getApplicationSession().setAttribute(TEST_ERROR_RESPONSE, "true"); + } + if(sipServletRequest.getTo().getParameter("tag") != null) { + logger.error("the ToTag should be empty, not sending the request"); + return; + } + + String testRemoteAddrAndPort = ce.getServletContext().getInitParameter("testRemoteAddrAndPort"); + if(testRemoteAddrAndPort != null) { + sipServletRequest.getRemoteAddr(); + sipServletRequest.getRemotePort(); + sipServletRequest.getRemoteHost(); + sipServletRequest.getRemoteUser(); + sipServletRequest.getInitialRemoteAddr(); + sipServletRequest.getInitialPoppedRoute(); + sipServletRequest.getInitialRemotePort(); + sipServletRequest.getInitialTransport(); + } + String testMultipleReasonHeaders = ce.getServletContext().getInitParameter("testMultipleReasonHeaders"); + if(testMultipleReasonHeaders != null) { + sipServletRequest.addHeader("Reason", "SIP ;cause=200 ;text=\"Call completed elsewhere\""); + sipServletRequest.addHeader("Reason", "Q.850 ;cause=16 ;text=\"Terminated\""); + } + // test for http://code.google.com/p/sipservlets/issues/detail?id=31 + Parameterable paramVia = null; + try { + String via = sipServletRequest.getHeader("Via"); + paramVia = sipServletRequest.getParameterableHeader("Via"); + + logger.info("Via Header " + via); + logger.info("Param Via Header " + paramVia); + } catch (ServletParseException e) { + logger.error("couln't parse the Via Header ", e); + } + paramVia.setParameter("rport", ""); + if (ce.getServletContext().getInitParameter("testViaHeader") != null){ + paramVia.setParameter("param0", "value0"); + paramVia.setParameter("qparam1", "value1"); + paramVia.setParameter("param2", "value2"); + paramVia.setParameter("qparam3", "value3"); + } + boolean gotException = false; + try { + paramVia.setParameter("branch", ""); + } catch (IllegalStateException e) { + gotException = true; + } + if(gotException) { + logger.info("got the expected exception on Via Header branch setting"); + } else { + throw new IllegalStateException("didn't get the expected exception on branch modification of the Via Header"); + } + if (ce.getServletContext().getInitParameter("testFromHeader") != null){ + sipServletRequest.getFrom().setParameter("param0", "value0"); + sipServletRequest.getFrom().setParameter("qparam1", "value1"); + sipServletRequest.getFrom().setParameter("param2", "value2"); + sipServletRequest.getFrom().setParameter("qparam3", "value3"); + } + if (ce.getServletContext().getInitParameter("testToHeader") != null){ + sipServletRequest.getTo().setParameter("param0", "value0"); + sipServletRequest.getTo().setParameter("qparam1", "value1"); + sipServletRequest.getTo().setParameter("param2", "value2"); + sipServletRequest.getTo().setParameter("qparam3", "value3"); + } + if(testRemoteAddrAndPort != null) { + sipServletRequest.getRemoteAddr(); + sipServletRequest.getRemotePort(); + sipServletRequest.getRemoteHost(); + sipServletRequest.getRemoteUser(); + sipServletRequest.getInitialRemoteAddr(); + sipServletRequest.getInitialPoppedRoute(); + sipServletRequest.getInitialRemotePort(); + sipServletRequest.getInitialTransport(); + } + if(ce.getServletContext().getInitParameter("testMultipartBytes") != null) { + // https://code.google.com/p/sipservlets/issues/detail?id=169 + try { + sipServletRequest.setContent(new String("test Multipart"), "multipart/unknown"); + } catch (UnsupportedEncodingException e) { + throw new IllegalStateException("couldn't set the content", e); + } + } + if(ce.getServletContext().getInitParameter("testAddressParam") != null) { + // https://code.google.com/p/sipservlets/issues/detail?id=245 + try { + sipServletRequest.getFrom().setDisplayName("Test name"); + sipServletRequest.getFrom().setParameter("epid", "00112233"); + sipServletRequest.getTo().setParameter("epid", "33221100"); + + Address address = sipFactory.createAddress(sipFactory.createURI("sip:test@address.example.com")); + address.setParameter("epid", "bzz"); + sipServletRequest.addAddressHeader("TestAddress", address, true); + + logger.info("testAddressParam Test Address" + address); + logger.info("request " + sipServletRequest); + } catch (ServletParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + if(ce.getServletContext().getInitParameter("testGruu") != null) { + logger.info("testGruu Test Address"); + // https://github.com/Mobicents/sip-servlets/issues/51 + try { + // Support for https://tools.ietf.org/html/rfc5627 + Address address = sipFactory.createAddress(""); + sipServletRequest.addAddressHeader("Contact", address, true); + logger.info("request " + sipServletRequest); + sipServletRequest.removeHeader("Contact"); + + // Support for https://tools.ietf.org/html/draft-ietf-sip-gruu-10#section-14.1 for Lync interop + address = sipFactory.createAddress(""); + sipServletRequest.addAddressHeader("Contact", address, true); + logger.info("request " + sipServletRequest); + + } catch (ServletParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + try { + sipServletRequest.send(); + } catch (IOException e) { + if(ce.getServletContext().getInitParameter("testIOException") != null) { + logger.info("expected exception thrown" + e); + ((SipURI)sipServletRequest.getRequestURI()).setHost("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); + ((SipURI)sipServletRequest.getRequestURI()).setPort(getTestPort(ctx)); + ((SipURI)sipServletRequest.getRequestURI()).setTransportParam("udp"); + try { + sipServletRequest.send(); + sendMessage(sipApplicationSession, sipFactory, "IOException thrown"); + } catch (IOException e1) { + logger.error("Unexpected exception while sending the INVITE request",e1); + } + } else { + logger.error("Unexpected exception while sending the INVITE request",e); + } + } + if(ce.getServletContext().getInitParameter("cancel") != null) { + SipServletRequest cancelRequest = sipServletRequest.createCancel(); + sipServletRequest.getApplicationSession().setAttribute(TEST_ERROR_RESPONSE, "true"); + String timeToWaitString = ce.getServletContext().getInitParameter("servletTimer"); + if(timeToWaitString == null) { + try { + Thread.sleep(500); + cancelRequest.send(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } catch (IOException e) { + logger.error(e); + } + } else if(timeToWaitString.equals("0")) { + if(getServletContext().getInitParameter("servletTimer") != null) { + timerService.createTimer(sipServletRequest.getApplicationSession(), 0, false, (Serializable) cancelRequest); + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + } + } finally { + release(); + } + } + + public void timeout(ServletTimer timer) { + try { + Serializable info = timer.getInfo(); + if (info instanceof String) { + String port = (String)info; + SipConnector[] sipConnectors = (SipConnector[]) getServletContext().getAttribute("org.mobicents.servlet.sip.SIP_CONNECTORS"); + for (SipConnector sipConnector : sipConnectors) { + if(sipConnector.getIpAddress().equals(System.getProperty("org.mobicents.testsuite.testhostaddr")) && sipConnector.getTransport().equalsIgnoreCase("TCP")) { + try { + boolean changed = sipConnector.closeReliableConnection(System.getProperty("org.mobicents.testsuite.testhostaddr"), Integer.valueOf(port)); + logger.info("SipConnector reliable connection killed changed " + System.getProperty("org.mobicents.testsuite.testhostaddr") +":"+ Integer.valueOf(port)+ " changed " + changed); + if(changed) { + keepAlivetimer.cancel(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + return; + } + access(); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + if(info instanceof SipConnector) { + String remoteAddress = (String) timer.getApplicationSession().getAttribute("keepAliveAddress"); + int remotePort = (Integer) timer.getApplicationSession().getAttribute("keepAlivePort"); + int keepAlivetoSend = (Integer) timer.getApplicationSession().getAttribute("keepAlivetoSend"); + Integer keepAliveSent = (Integer) timer.getApplicationSession().getAttribute("keepAliveSent"); + if(keepAliveSent == null) { + keepAliveSent = 0; + } + logger.info("keepalive sent " + keepAliveSent + " ,keepAliveToSend " + keepAlivetoSend); + if(keepAliveSent < keepAlivetoSend) { + try { + ((SipConnector)info).sendHeartBeat(remoteAddress, remotePort); + } catch (Exception e) { + logger.error("problem sending heartbeat to " + remoteAddress+":"+ remotePort); + timer.cancel(); + } + keepAliveSent = keepAliveSent.intValue() +1; + timer.getApplicationSession().setAttribute("keepAliveSent", new Integer(keepAliveSent)); + if(keepAliveSent >= keepAlivetoSend) { + try { + ((SipConnector)info).setKeepAliveTimeout(remoteAddress, remotePort, -1); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + } else if(info instanceof SipSession){ + SipSession sipSession = (SipSession) info; + try { + sipSession.createRequest("REGISTER").send(); + } catch (IOException e) { + logger.error("Unexpected exception while sending the REGISTER request",e); + } + } else { + SipServletRequest sipServletRequest = (SipServletRequest) timer.getInfo(); + sipServletRequest.getApplicationSession().setAttribute("timeSent", Long.valueOf(System.currentTimeMillis())); + try { + // http://code.google.com/p/sipservlets/issues/detail?id=31 + sipServletRequest.getParameterableHeader("Via").setParameter("rport", ""); + sipServletRequest.send(); + } catch (IOException e) { + logger.error("Unexpected exception while sending the BYE request",e); + } catch (ServletParseException e) { + logger.error("Couldn't parse via header for BYE request",e); + } + timer.cancel(); + } + } finally { + release(); + } + } + + public void access() { + if(!isAlreadyAccessed.compareAndSet(false, true)) { + sendMessage(sipFactory.createApplicationSession(), sipFactory, "servlet is already being accessed !", null); + } + } + + public void release() { + isAlreadyAccessed.set(false); + } + + /** + * @param sipApplicationSession + * @param storedFactory + */ + private void sendMessage(SipApplicationSession sipApplicationSession, + SipFactory storedFactory, String content) { + try { + SipServletRequest sipServletRequest = storedFactory.createRequest( + sipApplicationSession, + "MESSAGE", + "sip:sender@sip-servlets.com", + "sip:receiver@sip-servlets.com"); + SipURI sipUri=storedFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + sipServletRequest.setRequestURI(sipUri); + if(content != null) { + sipServletRequest.setContentLength(content.length()); + sipServletRequest.setContent(content, CONTENT_TYPE); + } else { + sipServletRequest.setContentLength(0); + } + sipServletRequest.send(); + } catch (ServletParseException e) { + logger.error("Exception occured while parsing the addresses",e); + } catch (IOException e) { + logger.error("Exception occured while sending the request",e); + } + } + + public void sessionCreated(SipSessionEvent se) { + // TODO Auto-generated method stub + + } + + public void sessionDestroyed(SipSessionEvent se) { + // TODO Auto-generated method stub + + } + + public void sessionReadyToInvalidate(SipSessionEvent se) { + if(se.getSession().getApplicationSession().getAttribute(TEST_ERROR_RESPONSE) != null) { + sendMessage(sipFactory.createApplicationSession(), sipFactory, "sipSessionReadyToInvalidate", null); + } + } + + public void sessionCreated(SipApplicationSessionEvent ev) { + // TODO Auto-generated method stub + + } + + public void sessionDestroyed(SipApplicationSessionEvent ev) { + // TODO Auto-generated method stub + + } + + public void sessionExpired(SipApplicationSessionEvent ev) { + // TODO Auto-generated method stub + + } + + public void sessionReadyToInvalidate(SipApplicationSessionEvent ev) { + if(ev.getApplicationSession().getAttribute(TEST_ERROR_RESPONSE) != null) { + sendMessage(sipFactory.createApplicationSession(), sipFactory, "sipAppSessionReadyToInvalidate", null); + } + } + + /** + * @param sipApplicationSession + * @param storedFactory + */ + private void sendMessage(SipApplicationSession sipApplicationSession, + SipFactory storedFactory, String content, String transport) { + try { + SipServletRequest sipServletRequest = storedFactory.createRequest( + sipApplicationSession, + "MESSAGE", + "sip:sender@sip-servlets.com", + "sip:receiver@sip-servlets.com"); + sipServletRequest.addHeader("Ext", "Test 1, 2 ,3"); + SipURI sipUri = storedFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + if(transport != null) { + if(transport.equalsIgnoreCase(ListeningPoint.TCP)) { + sipUri = storedFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + } + sipUri.setTransportParam(transport); + } + sipServletRequest.setRequestURI(sipUri); + sipServletRequest.setContentLength(content.length()); + sipServletRequest.setContent(content, CONTENT_TYPE); + sipServletRequest.setHeader("EarlyMediaResponses", new Integer(numberOf183Responses).toString()); + sipServletRequest.setHeader("EarlyMedia180Responses", new Integer(numberOf180Responses).toString()); + + sipServletRequest.send(); + } catch (ServletParseException e) { + logger.error("Exception occured while parsing the addresses",e); + } catch (IOException e) { + logger.error("Exception occured while sending the request",e); + } + } + + + @Override + public void sipConnectorAdded(SipConnector connector) { + + } + + @Override + public void sipConnectorRemoved(SipConnector connector) { + + } + + @Override + public void onKeepAliveTimeout(SipConnector connector, String peerAddress, + int peerPort) { + logger.error("SipConnector " + connector + " remotePeer " + peerAddress +":"+ peerPort); + keepAlivetimer.cancel(); + sendMessage(sipFactory.createApplicationSession(), sipFactory, "shootist onKeepAliveTimeout", "tcp"); + } + + public static Integer getTestPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("testPort"); + logger.info("TestPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5080; + } + } + + public static Integer getServletContainerPort(ServletContext ctx) { + String cPort = ctx.getInitParameter("servletContainerPort"); + logger.info("TestPort at:" + cPort); + if (cPort != null) { + return Integer.valueOf(cPort); + } else { + return 5070; + } + } } \ No newline at end of file diff --git a/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp/WEB-INF/sip.xml b/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp/WEB-INF/sip.xml index cb726c1071..4d709885a8 100644 --- a/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp/WEB-INF/sip.xml +++ b/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp/WEB-INF/sip.xml @@ -8,7 +8,10 @@ - + + org.restcomm.servlets.sip.QUOTABLE_PARAMETER + qparam1,qparam3 + ShootistSipServlet ShootistSipServlet @@ -24,4 +27,4 @@ org.mobicents.servlet.sip.testsuite.ShootistSipServlet - \ No newline at end of file + diff --git a/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/SimpleContainerListener.java b/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/SimpleContainerListener.java index db3d0262ff..4220473ca0 100644 --- a/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/SimpleContainerListener.java +++ b/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/SimpleContainerListener.java @@ -22,14 +22,15 @@ package org.mobicents.servlet.sip.testsuite; import javax.annotation.Resource; +import javax.servlet.ServletContext; import javax.servlet.sip.SipFactory; -import javax.servlet.sip.SipServletRequest; import javax.servlet.sip.SipServletResponse; import javax.servlet.sip.annotation.SipListener; import org.apache.log4j.Logger; -import org.mobicents.javax.servlet.CongestionControlEvent; +import org.mobicents.javax.servlet.ContainerEvent; import org.mobicents.javax.servlet.ContainerListener; +import org.mobicents.javax.servlet.RequestThrottledEvent; /** * @author jean.deruelle@gmail.com @@ -42,20 +43,35 @@ public class SimpleContainerListener implements ContainerListener { @Resource SipFactory sipFactory; - public void onCongestionControlStarted(CongestionControlEvent event) { - SimpleSipServlet.sendMessage(sipFactory.createApplicationSession(), sipFactory, "congestionControlStarted", null); - } - - public void onCongestionControlStopped(CongestionControlEvent event) { - SimpleSipServlet.sendMessage(sipFactory.createApplicationSession(), sipFactory, "congestionControlStopped", null); - } - public SipServletResponse onRequestThrottled(SipServletRequest request, CongestionControlEvent event) { - SipServletResponse sipServletResponse = request.createResponse(503, ""); + public void onRequestThrottled(RequestThrottledEvent event, ServletContext ctx) { + SipServletResponse sipServletResponse = event.getRequest().createResponse(503, ""); sipServletResponse.addHeader("Reason", event.getReason().toString()); sipServletResponse.addHeader("ReasonMessage", event.getMessage()); - return sipServletResponse; + ctx.setAttribute("org.mobicents.servlet.sip.THROTTLED_RESPONSE", sipServletResponse); } + + public void sendEvent(ContainerEvent event, ServletContext ctx) { + logger.info("Received event:" + event.getEventType().toString()); + SimpleSipServlet.sendMessage(sipFactory.createApplicationSession(), sipFactory, event.getEventType().toString(), null); + switch (event.getEventType()){ + case CONGESTION_STARTED: + break; + case CONGESTION_STOPPED: + break; + case GRACEFUL_SHUTDOWN_STARTED: + break; + case GRACEFUL_SHUTDOWN_CHECK: + ctx.setAttribute("PREVENT_GRACEFULL", true); + break; + case REQUEST_THROTTLED: + onRequestThrottled((RequestThrottledEvent) event, ctx); + break; + default: + + } + } + } diff --git a/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/SimpleSipServlet.java b/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/SimpleSipServlet.java index 4b91ad9c4b..4256bbb5e3 100644 --- a/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/SimpleSipServlet.java +++ b/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/SimpleSipServlet.java @@ -19,6 +19,7 @@ package org.mobicents.servlet.sip.testsuite; +import gov.nist.javax.sip.header.extensions.SessionExpiresHeader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -30,6 +31,7 @@ import javax.annotation.Resource; import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.sip.Address; import javax.servlet.sip.AuthInfo; @@ -101,6 +103,7 @@ public class SimpleSipServlet private static final String TEST_SERIALIZATION = "serialization"; private static final String TEST_FROM_TO_HEADER_MODIFICATION = "fromToHeaderModification"; private static final String TEST_LOCALLY_GENERATED_REMOTE_ADDRESS = "locallyGeneratedRemoteAddress"; + private static final String TEST_SESSION_EXPIRES_PARAMETERABLE = "testSessionExpiresParameterable"; @Resource SipFactory sipFactory; @@ -108,6 +111,7 @@ public class SimpleSipServlet TimerService timerService; SipSession registerSipSession; SipSession inviteSipSession; + static ServletContext ctx; int timeout = 15000; @@ -129,6 +133,7 @@ public void init(ServletConfig servletConfig) throws ServletException { logger.info("the simple sip servlet has been started"); new File("expirationFailure.tmp").delete(); super.init(servletConfig); + ctx = servletConfig.getServletContext(); } /** @@ -148,7 +153,19 @@ protected void doInvite(SipServletRequest request) throws ServletException, if(fromString.contains(TEST_NO_ACK_RECEIVED)) { request.createResponse(SipServletResponse.SC_OK).send(); return; - } + } + if(fromString.contains(TEST_SESSION_EXPIRES_PARAMETERABLE)){ + SipServletResponse res = request.createResponse(SipServletResponse.SC_OK); + res.addHeader(SessionExpiresHeader.NAME, "3000"); + try { + res.getParameterableHeader(SessionExpiresHeader.NAME).setParameter("session-param", "value"); + res.send(); + return; + } catch (ServletParseException e) { + request.createResponse(SipServletResponse.SC_SERVER_INTERNAL_ERROR).send(); + return; + } + } if(fromString.contains(TEST_LOCALLY_GENERATED_REMOTE_ADDRESS)) { // https://code.google.com/p/sipservlets/issues/detail?id=137 SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); @@ -523,7 +540,7 @@ protected void doInvite(SipServletRequest request) throws ServletException, sipServletResponse = request.createResponse(SipServletResponse.SC_OK); if(fromString.contains(TEST_FLAG_PARAM)) { try { - sipServletResponse.setHeader("Contact", "sip:" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070"); + sipServletResponse.setHeader("Contact", "sip:" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getServletContainerPort(ctx)); logger.error("an IllegalArgumentException should be thrown when trying to set the Contact Header on a 2xx response"); sipServletResponse = request.createResponse(SipServletResponse.SC_SERVER_INTERNAL_ERROR); sipServletResponse.send(); @@ -550,7 +567,7 @@ protected void doInvite(SipServletRequest request) throws ServletException, sipServletResponse.send(); return; } - contact = sipFactory.createParameterable("sip:user@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080;flagparam"); + contact = sipFactory.createParameterable("sip:user@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx) + ";flagparam"); contactStringified = contact.toString().trim(); logger.info("Contact Header with flag param " + contactStringified); if(contactStringified.endsWith("flagparam=")) { @@ -737,7 +754,7 @@ protected void doCancel(SipServletRequest request) throws ServletException, "MESSAGE", "sip:sender@sip-servlets.com", "sip:receiver@sip-servlets.com"); - SipURI sipUri=sipFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); + SipURI sipUri=sipFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); sipServletRequest.setRequestURI(sipUri); sipServletRequest.setContentLength(CANCEL_RECEIVED.length()); sipServletRequest.setContent(CANCEL_RECEIVED, CONTENT_TYPE); @@ -756,7 +773,7 @@ protected void doRegister(SipServletRequest req) throws ServletException, contact.setExpires(3600); logger.info("REGISTER Contact Address.toString = " + contact.toString()); int response = SipServletResponse.SC_OK; - if(!(";expires=3600").equals(contact.toString())) { + if(!(";expires=3600").equals(contact.toString())) { response = SipServletResponse.SC_SERVER_INTERNAL_ERROR; } SipServletResponse resp = req.createResponse(response); @@ -814,7 +831,9 @@ protected void doOptions(SipServletRequest req) throws ServletException, */ public void noAckReceived(SipErrorEvent ee) { logger.error("noAckReceived."); - sendMessage(ee.getRequest().getApplicationSession(), sipFactory, "noAckReceived", null); + //create new session, since event one is expired + SipApplicationSession createApplicationSession = sipFactory.createApplicationSession(); + sendMessage(createApplicationSession, sipFactory, "noAckReceived", null); } /** @@ -877,7 +896,7 @@ public void timeout(ServletTimer timer) { String port = (String)info; SipConnector[] sipConnectors = (SipConnector[]) getServletContext().getAttribute("org.mobicents.servlet.sip.SIP_CONNECTORS"); for (SipConnector sipConnector : sipConnectors) { - if(sipConnector.getIpAddress().equals(System.getProperty("org.mobicents.testsuite.testhostaddr")) && sipConnector.getPort() == 5070 && sipConnector.getTransport().equalsIgnoreCase("TCP")) { + if(sipConnector.getIpAddress().equals(System.getProperty("org.mobicents.testsuite.testhostaddr")) && sipConnector.getPort() == getServletContainerPort(ctx) && sipConnector.getTransport().equalsIgnoreCase("TCP")) { try { boolean changed = sipConnector.setKeepAliveTimeout(System.getProperty("org.mobicents.testsuite.testhostaddr"), Integer.valueOf(port), Long.valueOf(getServletContext().getInitParameter("changeKeepAliveTimeout"))); logger.info("SipConnector timeoutvalue changed " + getServletContext().getInitParameter("changeKeepAliveTimeout") + " changed " + changed + "for " + System.getProperty("org.mobicents.testsuite.testhostaddr") +":"+ Integer.valueOf(port)); @@ -898,7 +917,7 @@ private void sendRegister() throws ServletParseException, IOException { register = registerSipSession.createRequest("REGISTER"); } else { SipApplicationSession app = sipFactory.createApplicationSession(); - register = sipFactory.createRequest(app, "REGISTER", "sip:testRegisterSavedSession@simple-servlet.com", "sip:you@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5058"); + register = sipFactory.createRequest(app, "REGISTER", "sip:testRegisterSavedSession@simple-servlet.com", "sip:you@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getRegisterPort(ctx)); Parameterable contact = sipFactory.createParameterable("sip:john@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":6090;expires=900"); register.addParameterableHeader("Contact", contact, true); registerSipSession = register.getSession(); @@ -917,7 +936,7 @@ private void sendRegister(SipSession sipSession, boolean removeContact) throws S register = sipSession.createRequest("REGISTER"); } else { SipApplicationSession app = sipFactory.createApplicationSession(); - register = sipFactory.createRequest(app, "REGISTER", "sip:testRegisterCSeq@simple-servlet.com", "sip:you@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5058"); + register = sipFactory.createRequest(app, "REGISTER", "sip:testRegisterCSeq@simple-servlet.com", "sip:you@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getRegisterPort(ctx)); Parameterable contact = sipFactory.createParameterable("sip:john@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":6090;expires=900"); register.addParameterableHeader("Contact", contact, true); } @@ -963,10 +982,10 @@ public static void sendMessage(SipApplicationSession sipApplicationSession, "sip:sender@sip-servlets.com", "sip:receiver@sip-servlets.com"); sipServletRequest.addHeader("Ext", "Test 1, 2 ,3"); - SipURI sipUri = storedFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); + SipURI sipUri = storedFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); if(transport != null) { if(transport.equalsIgnoreCase(ListeningPoint.TCP)) { - sipUri = storedFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5081"); + sipUri = storedFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); } sipUri.setTransportParam(transport); } @@ -974,6 +993,10 @@ public static void sendMessage(SipApplicationSession sipApplicationSession, sipServletRequest.setContentLength(content.length()); sipServletRequest.setContent(content, CONTENT_TYPE); sipServletRequest.send(); + SipApplicationSession applicationSession = sipServletRequest.getApplicationSession(false); + if (applicationSession!= null) { + applicationSession.invalidate(); + } } catch (ServletParseException e) { logger.error("Exception occured while parsing the addresses",e); } catch (IOException e) { @@ -1096,4 +1119,35 @@ public void onKeepAliveTimeout(SipConnector connector, String peerAddress, } } } + + + public static Integer getRegisterPort(ServletContext ctx) { + String rPort = ctx.getInitParameter("registerPort"); + logger.info("registerPort at:" + rPort); + if (rPort != null) { + return Integer.valueOf(rPort); + } else { + return 5058; + } + } + + public static Integer getTestPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("testPort"); + logger.info("TestPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5080; + } + } + + public static Integer getServletContainerPort(ServletContext ctx) { + String cPort = ctx.getInitParameter("servletContainerPort"); + logger.info("TestPort at:" + cPort); + if (cPort != null) { + return Integer.valueOf(cPort); + } else { + return 5070; + } + } } \ No newline at end of file diff --git a/sip-servlets-test-suite/applications/speed-dial-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/SpeedDialSipServlet.java b/sip-servlets-test-suite/applications/speed-dial-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/SpeedDialSipServlet.java index 2d0cac06e3..8ff0cf6721 100644 --- a/sip-servlets-test-suite/applications/speed-dial-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/SpeedDialSipServlet.java +++ b/sip-servlets-test-suite/applications/speed-dial-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/SpeedDialSipServlet.java @@ -1,376 +1,430 @@ -/* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2014, Telestax Inc and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - * - * This file incorporates work covered by the following copyright contributed under the GNU LGPL : Copyright 2007-2011 Red Hat. - */ - -package org.mobicents.servlet.sip.testsuite; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.StringTokenizer; - -import javax.annotation.Resource; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.sip.Proxy; -import javax.servlet.sip.ServletParseException; -import javax.servlet.sip.SipApplicationSession; -import javax.servlet.sip.SipApplicationSessionEvent; -import javax.servlet.sip.SipApplicationSessionListener; -import javax.servlet.sip.SipErrorEvent; -import javax.servlet.sip.SipErrorListener; -import javax.servlet.sip.SipFactory; -import javax.servlet.sip.SipServlet; -import javax.servlet.sip.SipServletRequest; -import javax.servlet.sip.SipServletResponse; -import javax.servlet.sip.SipURI; -import javax.servlet.sip.URI; -import javax.sip.ListeningPoint; - -import org.apache.log4j.Logger; - - -public class SpeedDialSipServlet extends SipServlet implements SipErrorListener, SipApplicationSessionListener { - private static final long serialVersionUID = 1L; - private static transient Logger logger = Logger.getLogger(SpeedDialSipServlet.class); - - private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; - private static final String REMOTE_TRANSPORT = "udp"; - private static final int REMOTE_PORT = 5080; - private static final String REMOTE_LOCALHOST_ADDR = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; - - private static final String INITIAL_REMOTE_TRANSPORT = "udp"; - private static final int INITIAL_REMOTE_PORT = 5090; - private static final String INITIAL_REMOTE_LOCALHOST_ADDR = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; - - private static final String LOCAL_TRANSPORT = "udp"; - private static final int LOCAL_PORT = 5070; - private static final String LOCAL_LOCALHOST_ADDR = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; - - private static final String TEST_USER_REMOTE = "remote"; - - private static boolean isRecordRoute = true; - - Map dialNumberToSipUriMapping = null; - - @Resource - SipFactory sipFactory; - - /** Creates a new instance of SpeedDialSipServlet */ - public SpeedDialSipServlet() {} - - @Override - public void init(ServletConfig servletConfig) throws ServletException { - logger.info("the speed dial sip servlet has been started"); - super.init(servletConfig); - dialNumberToSipUriMapping = new HashMap(); - dialNumberToSipUriMapping.put("1", "sip:receiver@sip-servlets.com"); - dialNumberToSipUriMapping.put("2", "sip:mranga@sip-servlets.com"); - dialNumberToSipUriMapping.put("3", "sip:vlad@sip-servlets.com"); - dialNumberToSipUriMapping.put("4", "sip:bartek@sip-servlets.com"); - dialNumberToSipUriMapping.put("5", "sip:jeand@sip-servlets.com"); - dialNumberToSipUriMapping.put("6", "sip:receiver-failover@sip-servlets.com"); - // https://code.google.com/p/sipservlets/issues/detail?id=273 - dialNumberToSipUriMapping.put("7", "sip:receiver-prack@sip-servlets.com"); - dialNumberToSipUriMapping.put("8", "sip:cancel-receiver@sip-servlets.com"); - dialNumberToSipUriMapping.put("b2bua", "sip:fromProxy@sip-servlets.com"); - dialNumberToSipUriMapping.put("9", "sip:receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090"); - dialNumberToSipUriMapping.put("test-callResponseBacks", "sip:receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090,sip:receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5091"); - dialNumberToSipUriMapping.put("forward-pending-sender", "sip:forward-pending-sender@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - dialNumberToSipUriMapping.put("factory-sender", "sip:factory-sender@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - String initParam = servletConfig.getServletContext().getInitParameter("record_route"); - if(initParam != null && initParam.equals("false")) { - isRecordRoute = false; - } - logger.info("Speed dial sip servlet is record routing ?" + isRecordRoute); - } - - @Override - protected void doInvite(SipServletRequest request) throws ServletException, - IOException { - - logger.info("Got request:\n" + request.toString()); - logger.info(request.getRequestURI().toString()); - if(request.isInitial()) { - if(request.isInitial()) { - String user = ((SipURI)request.getFrom().getURI()).getUser(); - if(user.contains(TEST_USER_REMOTE)) { - String transport ="udp"; - if(user.contains("tcp")) { - transport="tcp"; - } - if(!checkRequestAddressPortTransport(request, transport)) { - return ; - } - } - - String dialNumber = ((SipURI)request.getRequestURI()).getUser(); - String mappedUri = dialNumberToSipUriMapping.get(dialNumber); - if(mappedUri != null) { - SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); - Proxy proxy = request.getProxy(); - proxy.setProxyTimeout(120); - proxy.setRecordRoute(isRecordRoute); - proxy.setParallel(false); - proxy.setSupervised(true); - logger.info("proxying to " + mappedUri); - if(mappedUri.contains(",")) { - List uris = new ArrayList(); - StringTokenizer stringTokenizer = new StringTokenizer(mappedUri, ","); - while (stringTokenizer.hasMoreTokens()) { - String uri = stringTokenizer.nextToken(); - uris.add(sipFactory.createURI(uri)); - } - proxy.proxyTo(uris); - } else { - proxy.proxyTo(sipFactory.createURI(mappedUri)); - } - } else { - SipServletResponse sipServletResponse = - request.createResponse(SipServletResponse.SC_NOT_ACCEPTABLE_HERE, "No mapping for " + dialNumber); - sipServletResponse.send(); - } - } - } - } - - private boolean checkRequestAddressPortTransport(SipServletRequest request, String transport) throws IOException { - boolean isCorrect = false; - if(request.getRemoteAddr().equals(REMOTE_LOCALHOST_ADDR) && request.getTransport().equalsIgnoreCase(transport)) { - if(transport.equalsIgnoreCase("tcp")) { - logger.info("remote tcp information is correct"); - isCorrect =true; - } else { - if(request.getRemotePort() == REMOTE_PORT){ - logger.info("remote udp information is correct"); - } - isCorrect =true; - } - } - if(request.getRemoteAddr() == null) { - isCorrect = false; - } - if(!isCorrect){ - logger.error("remote information is incorrect"); - logger.error("remote addr " + request.getRemoteAddr()); - logger.error("remote port " + request.getRemotePort()); - logger.error("remote transport " + request.getTransport()); - SipServletResponse sipServletResponse = - request.createResponse(SipServletResponse.SC_SERVER_INTERNAL_ERROR, "Incorrect remote information"); - sipServletResponse.send(); - return false; - } - isCorrect = false; - if(request.getInitialRemoteAddr().equals(REMOTE_LOCALHOST_ADDR) && request.getInitialTransport().equalsIgnoreCase(transport)) { - if(transport.equalsIgnoreCase("tcp")) { - logger.info("initial remote tcp information is correct"); - isCorrect =true; - } else { - if(request.getInitialRemotePort() == REMOTE_PORT){ - logger.info("initial remote udp information is correct"); - } - isCorrect =true; - } - } - if(request.getInitialRemoteAddr() == null) { - isCorrect = false; - } - if(!isCorrect){ - logger.error("initial remote information is incorrect"); - logger.error("initial remote addr " + request.getInitialRemoteAddr()); - logger.error("initial remote port " + request.getInitialRemotePort()); - logger.error("initial remote transport " + request.getInitialTransport()); - SipServletResponse sipServletResponse = - request.createResponse(SipServletResponse.SC_SERVER_INTERNAL_ERROR, "Incorrect initial remote information"); - sipServletResponse.send(); - return false; - } - isCorrect = false; - if(request.getLocalAddr().equals(LOCAL_LOCALHOST_ADDR) && request.getTransport().equalsIgnoreCase(transport)) { - if(transport.equalsIgnoreCase("tcp")) { - logger.info("local tcp information is correct"); - isCorrect =true; - } else { - if(request.getLocalPort() == LOCAL_PORT){ - logger.info("local udp information is correct"); - } - isCorrect =true; - } - } - if(request.getLocalAddr() == null) { - isCorrect = false; - } - if(!isCorrect){ - logger.error("local information is incorrect"); - logger.error("local addr " + request.getLocalAddr()); - logger.error("local port " + request.getLocalPort()); - logger.error("local transport " + request.getTransport()); - SipServletResponse sipServletResponse = - request.createResponse(SipServletResponse.SC_SERVER_INTERNAL_ERROR, "Incorrect local information"); - sipServletResponse.send(); - return false; - } - return true; - } - - @Override - protected void doErrorResponse(SipServletResponse resp) - throws ServletException, IOException { - logger.info("Got Error response " + resp); - if(resp.getTo().toString().contains("test-callResponseBacks")) { - resp.getApplicationSession().setAttribute("errorResponseReceivedAtAppLevel", "true"); - } - if(resp.getApplicationSession().getAttribute("errorResponseReceivedAtAppLevel") != null) { - throw new IllegalStateException("Error Response Received at Application Level but we should only see the best final response"); - } - } - - @Override - protected void doBranchResponse(SipServletResponse resp) - throws ServletException, IOException { - logger.info("Got Branch response " + resp); - if(resp.getTo().toString().contains("test-callResponseBacks")) { - if(resp.getStatus() >= 400) { - resp.getApplicationSession().setAttribute("doBranchErrorResponseReceivedAtAppLevel", "true"); - } - if(resp.getStatus() >= 200) { - resp.getApplicationSession().setAttribute("doBranchSuccessResponseReceivedAtAppLevel", "true"); - } - } - } - - protected void doSuccessResponse(SipServletResponse resp) - throws ServletException, IOException { - logger.info("Got Success response " + resp); - if(resp.getApplicationSession().getAttribute("errorResponseReceivedAtAppLevel") != null) { - throw new IllegalStateException("Error Response Received at Application Level but we should only see the best final response"); - } - if(resp.getTo().toString().contains("test-callResponseBacks") && !resp.isBranchResponse()) { - resp.getApplicationSession().setAttribute("doSuccessResponseReceivedAtAppLevel", "true"); - } - if(((SipURI)resp.getFrom().getURI()).getUser().equalsIgnoreCase(TEST_USER_REMOTE)) { - if(resp.getRemoteAddr().equals(LOCAL_LOCALHOST_ADDR) && resp.getRemotePort() == LOCAL_PORT && resp.getTransport().equalsIgnoreCase(LOCAL_TRANSPORT)) { - logger.info("remote information is correct"); - } else { - if(resp.getRemotePort()!=5090){ // 5090 is the remote client - logger.error("remote information is incorrect"); - logger.error("remote addr " + resp.getRemoteAddr()); - logger.error("remote port " + resp.getRemotePort()); - logger.error("remote transport " + resp.getTransport()); - throw new IllegalArgumentException("remote information is incorrect"); - } - } - if(resp.getInitialRemoteAddr().equals(INITIAL_REMOTE_LOCALHOST_ADDR) && resp.getInitialRemotePort() == INITIAL_REMOTE_PORT && resp.getInitialTransport().equalsIgnoreCase(INITIAL_REMOTE_TRANSPORT)) { - logger.info("Initial remote information is correct"); - } else { - logger.error("Initial remote information is incorrect"); - logger.error("Initial remote addr " + resp.getInitialRemoteAddr()); - logger.error("Initial remote port " + resp.getInitialRemotePort()); - logger.error("Initial remote transport " + resp.getInitialTransport()); - throw new IllegalArgumentException("initial remote information is incorrect"); - } - if(resp.getLocalAddr().equals(LOCAL_LOCALHOST_ADDR) && resp.getLocalPort() == LOCAL_PORT && resp.getTransport().equalsIgnoreCase(LOCAL_TRANSPORT)) { - logger.info("local information is correct"); - } else { - logger.error("local information is incorrect"); - logger.error("local addr " + resp.getLocalAddr()); - logger.error("local port " + resp.getLocalPort()); - logger.error("local transport " + resp.getTransport()); - throw new IllegalArgumentException("local information is incorrect"); - } - } - } - - @Override - protected void doCancel(SipServletRequest req) throws ServletException, - IOException { - logger.error("CANCEL seen at proxy " + req); - } - - // SipErrorListener methods - /** - * {@inheritDoc} - */ - public void noAckReceived(SipErrorEvent ee) { - logger.error("noAckReceived."); - } - - /** - * {@inheritDoc} - */ - public void noPrackReceived(SipErrorEvent ee) { - logger.error("noPrackReceived."); - } - - - - /** - * @param sipApplicationSession - * @param storedFactory - */ - private void sendMessage(SipApplicationSession sipApplicationSession, - SipFactory storedFactory, String content, String transport) { - try { - SipServletRequest sipServletRequest = storedFactory.createRequest( - sipApplicationSession, - "MESSAGE", - "sip:sender@sip-servlets.com", - "sip:receiver@sip-servlets.com"); - sipServletRequest.addHeader("Ext", "Test 1, 2 ,3"); - SipURI sipUri = storedFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - if(transport != null) { - if(transport.equalsIgnoreCase(ListeningPoint.TCP)) { - sipUri = storedFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5081"); - } - sipUri.setTransportParam(transport); - } - sipServletRequest.setRequestURI(sipUri); - sipServletRequest.setContentLength(content.length()); - sipServletRequest.setContent(content, CONTENT_TYPE); - sipServletRequest.send(); - } catch (ServletParseException e) { - logger.error("Exception occured while parsing the addresses",e); - } catch (IOException e) { - logger.error("Exception occured while sending the request",e); - } - } - - public void sessionCreated(SipApplicationSessionEvent ev) { - - } - - public void sessionDestroyed(SipApplicationSessionEvent ev) { - - } - - public void sessionExpired(SipApplicationSessionEvent ev) { - - } - - public void sessionReadyToInvalidate(SipApplicationSessionEvent ev) { - if(ev.getApplicationSession().getAttribute("doSuccessResponseReceivedAtAppLevel") != null && - ev.getApplicationSession().getAttribute("doBranchErrorResponseReceivedAtAppLevel") != null && - ev.getApplicationSession().getAttribute("doBranchSuccessResponseReceivedAtAppLevel") != null) { - sendMessage(sipFactory.createApplicationSession(), sipFactory, "allResponsesReceivedCorrectlyOnEachCallBack", null); - } - } -} +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2014, Telestax Inc and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * + * This file incorporates work covered by the following copyright contributed under the GNU LGPL : Copyright 2007-2011 Red Hat. + */ + +package org.mobicents.servlet.sip.testsuite; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; + +import javax.annotation.Resource; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.sip.Proxy; +import javax.servlet.sip.ServletParseException; +import javax.servlet.sip.SipApplicationSession; +import javax.servlet.sip.SipApplicationSessionEvent; +import javax.servlet.sip.SipApplicationSessionListener; +import javax.servlet.sip.SipErrorEvent; +import javax.servlet.sip.SipErrorListener; +import javax.servlet.sip.SipFactory; +import javax.servlet.sip.SipServlet; +import javax.servlet.sip.SipServletRequest; +import javax.servlet.sip.SipServletResponse; +import javax.servlet.sip.SipURI; +import javax.servlet.sip.URI; +import javax.sip.ListeningPoint; + +import org.apache.log4j.Logger; + + +public class SpeedDialSipServlet extends SipServlet implements SipErrorListener, SipApplicationSessionListener { + private static final long serialVersionUID = 1L; + private static transient Logger logger = Logger.getLogger(SpeedDialSipServlet.class); + + private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; + private static final String REMOTE_LOCALHOST_ADDR = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; + + private static final String INITIAL_REMOTE_TRANSPORT = "udp"; + private static final String INITIAL_REMOTE_LOCALHOST_ADDR = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; + + private static final String LOCAL_TRANSPORT = "udp"; + private static final String LOCAL_LOCALHOST_ADDR = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; + + private static final String TEST_USER_REMOTE = "remote"; + + private static boolean isRecordRoute = true; + + Map dialNumberToSipUriMapping = null; + + @Resource + SipFactory sipFactory; + + static ServletContext ctx; + + /** Creates a new instance of SpeedDialSipServlet */ + public SpeedDialSipServlet() {} + + @Override + public void init(ServletConfig servletConfig) throws ServletException { + logger.info("the speed dial sip servlet has been started"); + super.init(servletConfig); + ctx = servletConfig.getServletContext(); + dialNumberToSipUriMapping = new HashMap(); + dialNumberToSipUriMapping.put("1", "sip:receiver@sip-servlets.com"); + dialNumberToSipUriMapping.put("2", "sip:mranga@sip-servlets.com"); + dialNumberToSipUriMapping.put("3", "sip:vlad@sip-servlets.com"); + dialNumberToSipUriMapping.put("4", "sip:bartek@sip-servlets.com"); + dialNumberToSipUriMapping.put("5", "sip:jeand@sip-servlets.com"); + dialNumberToSipUriMapping.put("6", "sip:receiver-failover@sip-servlets.com"); + // https://code.google.com/p/sipservlets/issues/detail?id=273 + dialNumberToSipUriMapping.put("7", "sip:receiver-prack@sip-servlets.com"); + dialNumberToSipUriMapping.put("8", "sip:cancel-receiver@sip-servlets.com"); + dialNumberToSipUriMapping.put("b2bua", "sip:fromProxy@sip-servlets.com"); + dialNumberToSipUriMapping.put("9", "sip:receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getReceiverPort(ctx)); + dialNumberToSipUriMapping.put("test-callResponseBacks", "sip:receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getReceiverPort(ctx)+ ",sip:receiver@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getCutmePort(ctx)); + dialNumberToSipUriMapping.put("forward-pending-sender", "sip:forward-pending-sender@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + dialNumberToSipUriMapping.put("forward-pending-changeFromTo-sender", "sip:forward-pending-changeFromTo-sender@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + dialNumberToSipUriMapping.put("factory-sender", "sip:factory-sender@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + String initParam = servletConfig.getServletContext().getInitParameter("record_route"); + if(initParam != null && initParam.equals("false")) { + isRecordRoute = false; + } + logger.info("Speed dial sip servlet is record routing ?" + isRecordRoute); + } + + @Override + protected void doInvite(SipServletRequest request) throws ServletException, + IOException { + + logger.info("Got request:\n" + request.toString()); + logger.info(request.getRequestURI().toString()); + if(request.isInitial()) { + if(request.isInitial()) { + String user = ((SipURI)request.getFrom().getURI()).getUser(); + if(user.contains(TEST_USER_REMOTE)) { + String transport ="udp"; + if(user.contains("tcp")) { + transport="tcp"; + } + if(!checkRequestAddressPortTransport(request, transport)) { + return ; + } + } + + String dialNumber = ((SipURI)request.getRequestURI()).getUser(); + String mappedUri = dialNumberToSipUriMapping.get(dialNumber); + if(mappedUri != null) { + SipFactory sipFactory = (SipFactory) getServletContext().getAttribute(SIP_FACTORY); + Proxy proxy = request.getProxy(); + proxy.setProxyTimeout(120); + proxy.setRecordRoute(isRecordRoute); + proxy.setParallel(false); + proxy.setSupervised(true); + logger.info("proxying to " + mappedUri); + if(mappedUri.contains(",")) { + List uris = new ArrayList(); + StringTokenizer stringTokenizer = new StringTokenizer(mappedUri, ","); + while (stringTokenizer.hasMoreTokens()) { + String uri = stringTokenizer.nextToken(); + uris.add(sipFactory.createURI(uri)); + } + proxy.proxyTo(uris); + } else { + proxy.proxyTo(sipFactory.createURI(mappedUri)); + } + } else { + SipServletResponse sipServletResponse = + request.createResponse(SipServletResponse.SC_NOT_ACCEPTABLE_HERE, "No mapping for " + dialNumber); + sipServletResponse.send(); + } + } + } else { + if(request.getFrom().getURI().toString().contains("forward-pending-changeFromTo-sender") || + request.getFrom().getURI().toString().contains("forward-pending-changeFromTo-sender")) { + logger.info("Got subsequent request:\n" + request.toString()); + request.getFrom().setDisplayName("From changed"); + request.getFrom().setURI(sipFactory.createURI("sip:fromchanged@sip-servlets.com")); + request.getTo().setDisplayName("To changed"); + request.getTo().setURI(sipFactory.createURI("sip:tochanged@sip-servlets.com")); + } + } + } + + private boolean checkRequestAddressPortTransport(SipServletRequest request, String transport) throws IOException { + boolean isCorrect = false; + if(request.getRemoteAddr().equals(REMOTE_LOCALHOST_ADDR) && request.getTransport().equalsIgnoreCase(transport)) { + if(transport.equalsIgnoreCase("tcp")) { + logger.info("remote tcp information is correct"); + isCorrect =true; + } else { + if(request.getRemotePort() == getTestPort(ctx)){ + logger.info("remote udp information is correct"); + } + isCorrect =true; + } + } + if(request.getRemoteAddr() == null) { + isCorrect = false; + } + if(!isCorrect){ + logger.error("remote information is incorrect"); + logger.error("remote addr " + request.getRemoteAddr()); + logger.error("remote port " + request.getRemotePort()); + logger.error("remote transport " + request.getTransport()); + SipServletResponse sipServletResponse = + request.createResponse(SipServletResponse.SC_SERVER_INTERNAL_ERROR, "Incorrect remote information"); + sipServletResponse.send(); + return false; + } + isCorrect = false; + if(request.getInitialRemoteAddr().equals(REMOTE_LOCALHOST_ADDR) && request.getInitialTransport().equalsIgnoreCase(transport)) { + if(transport.equalsIgnoreCase("tcp")) { + logger.info("initial remote tcp information is correct"); + isCorrect =true; + } else { + if(request.getInitialRemotePort() == getTestPort(ctx)){ + logger.info("initial remote udp information is correct"); + } + isCorrect =true; + } + } + if(request.getInitialRemoteAddr() == null) { + isCorrect = false; + } + if(!isCorrect){ + logger.error("initial remote information is incorrect"); + logger.error("initial remote addr " + request.getInitialRemoteAddr()); + logger.error("initial remote port " + request.getInitialRemotePort()); + logger.error("initial remote transport " + request.getInitialTransport()); + SipServletResponse sipServletResponse = + request.createResponse(SipServletResponse.SC_SERVER_INTERNAL_ERROR, "Incorrect initial remote information"); + sipServletResponse.send(); + return false; + } + isCorrect = false; + if(request.getLocalAddr().equals(LOCAL_LOCALHOST_ADDR) && request.getTransport().equalsIgnoreCase(transport)) { + if(transport.equalsIgnoreCase("tcp")) { + logger.info("local tcp information is correct"); + isCorrect =true; + } else { + if(request.getLocalPort() == getServletContainerPort(ctx)){ + logger.info("local udp information is correct"); + } + isCorrect =true; + } + } + if(request.getLocalAddr() == null) { + isCorrect = false; + } + if(!isCorrect){ + logger.error("local information is incorrect"); + logger.error("local addr " + request.getLocalAddr()); + logger.error("local port " + request.getLocalPort()); + logger.error("local transport " + request.getTransport()); + SipServletResponse sipServletResponse = + request.createResponse(SipServletResponse.SC_SERVER_INTERNAL_ERROR, "Incorrect local information"); + sipServletResponse.send(); + return false; + } + return true; + } + + @Override + protected void doErrorResponse(SipServletResponse resp) + throws ServletException, IOException { + logger.info("Got Error response " + resp); + if(resp.getTo().toString().contains("test-callResponseBacks")) { + resp.getApplicationSession().setAttribute("errorResponseReceivedAtAppLevel", "true"); + } + if(resp.getApplicationSession().getAttribute("errorResponseReceivedAtAppLevel") != null) { + throw new IllegalStateException("Error Response Received at Application Level but we should only see the best final response"); + } + } + + @Override + protected void doBranchResponse(SipServletResponse resp) + throws ServletException, IOException { + logger.info("Got Branch response " + resp); + if(resp.getTo().toString().contains("test-callResponseBacks")) { + if(resp.getStatus() >= 400) { + resp.getApplicationSession().setAttribute("doBranchErrorResponseReceivedAtAppLevel", "true"); + } + if(resp.getStatus() >= 200) { + resp.getApplicationSession().setAttribute("doBranchSuccessResponseReceivedAtAppLevel", "true"); + } + } + } + + protected void doSuccessResponse(SipServletResponse resp) + throws ServletException, IOException { + logger.info("Got Success response " + resp); + if(resp.getApplicationSession().getAttribute("errorResponseReceivedAtAppLevel") != null) { + throw new IllegalStateException("Error Response Received at Application Level but we should only see the best final response"); + } + if(resp.getTo().toString().contains("test-callResponseBacks") && !resp.isBranchResponse()) { + resp.getApplicationSession().setAttribute("doSuccessResponseReceivedAtAppLevel", "true"); + } + if(((SipURI)resp.getFrom().getURI()).getUser().equalsIgnoreCase(TEST_USER_REMOTE)) { + if(resp.getRemoteAddr().equals(LOCAL_LOCALHOST_ADDR) && resp.getRemotePort() == getServletContainerPort(ctx) + && resp.getTransport().equalsIgnoreCase(LOCAL_TRANSPORT)) { + logger.info("remote information is correct"); + } else { + if(resp.getRemotePort()!=getReceiverPort(ctx)){ // 5090 is the remote client + logger.error("remote information is incorrect"); + logger.error("remote addr " + resp.getRemoteAddr()); + logger.error("remote port " + resp.getRemotePort()); + logger.error("remote transport " + resp.getTransport()); + throw new IllegalArgumentException("remote information is incorrect"); + } + } + if(resp.getInitialRemoteAddr().equals(INITIAL_REMOTE_LOCALHOST_ADDR) + && resp.getInitialRemotePort() == getReceiverPort(ctx) + && resp.getInitialTransport().equalsIgnoreCase(INITIAL_REMOTE_TRANSPORT)) { + logger.info("Initial remote information is correct"); + } else { + logger.error("Initial remote information is incorrect"); + logger.error("Initial remote addr " + resp.getInitialRemoteAddr()); + logger.error("Initial remote port " + resp.getInitialRemotePort()); + logger.error("Initial remote transport " + resp.getInitialTransport()); + throw new IllegalArgumentException("initial remote information is incorrect"); + } + if(resp.getLocalAddr().equals(LOCAL_LOCALHOST_ADDR) && resp.getLocalPort() == getServletContainerPort(ctx) + && resp.getTransport().equalsIgnoreCase(LOCAL_TRANSPORT)) { + logger.info("local information is correct"); + } else { + logger.error("local information is incorrect"); + logger.error("local addr " + resp.getLocalAddr()); + logger.error("local port " + resp.getLocalPort()); + logger.error("local transport " + resp.getTransport()); + throw new IllegalArgumentException("local information is incorrect"); + } + } + } + + @Override + protected void doCancel(SipServletRequest req) throws ServletException, + IOException { + logger.error("CANCEL seen at proxy " + req); + } + + // SipErrorListener methods + /** + * {@inheritDoc} + */ + public void noAckReceived(SipErrorEvent ee) { + logger.error("noAckReceived."); + } + + /** + * {@inheritDoc} + */ + public void noPrackReceived(SipErrorEvent ee) { + logger.error("noPrackReceived."); + } + + + + /** + * @param sipApplicationSession + * @param storedFactory + */ + private void sendMessage(SipApplicationSession sipApplicationSession, + SipFactory storedFactory, String content, String transport) { + try { + SipServletRequest sipServletRequest = storedFactory.createRequest( + sipApplicationSession, + "MESSAGE", + "sip:sender@sip-servlets.com", + "sip:receiver@sip-servlets.com"); + sipServletRequest.addHeader("Ext", "Test 1, 2 ,3"); + SipURI sipUri = storedFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + if(transport != null) { + if(transport.equalsIgnoreCase(ListeningPoint.TCP)) { + sipUri = storedFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5081"); + } + sipUri.setTransportParam(transport); + } + sipServletRequest.setRequestURI(sipUri); + sipServletRequest.setContentLength(content.length()); + sipServletRequest.setContent(content, CONTENT_TYPE); + sipServletRequest.send(); + } catch (ServletParseException e) { + logger.error("Exception occured while parsing the addresses",e); + } catch (IOException e) { + logger.error("Exception occured while sending the request",e); + } + } + + public void sessionCreated(SipApplicationSessionEvent ev) { + + } + + public void sessionDestroyed(SipApplicationSessionEvent ev) { + + } + + public void sessionExpired(SipApplicationSessionEvent ev) { + + } + + public void sessionReadyToInvalidate(SipApplicationSessionEvent ev) { + if(ev.getApplicationSession().getAttribute("doSuccessResponseReceivedAtAppLevel") != null && + ev.getApplicationSession().getAttribute("doBranchErrorResponseReceivedAtAppLevel") != null && + ev.getApplicationSession().getAttribute("doBranchSuccessResponseReceivedAtAppLevel") != null) { + sendMessage(sipFactory.createApplicationSession(), sipFactory, "allResponsesReceivedCorrectlyOnEachCallBack", null); + } + } + + public static Integer getTestPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("testPort"); + logger.info("TestPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5080; + } + } + + public static Integer getReceiverPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("receiverPort"); + logger.info("ReceiverPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5090; + } + } + + public static Integer getCutmePort(ServletContext ctx) { + String tPort = ctx.getInitParameter("cutmePort"); + logger.info("CutmePort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5091; + } + } + + public static Integer getServletContainerPort(ServletContext ctx) { + String cPort = ctx.getInitParameter("servletContainerPort"); + logger.info("TestPort at:" + cPort); + if (cPort != null) { + return Integer.valueOf(cPort); + } else { + return 5070; + } + } +} diff --git a/sip-servlets-test-suite/applications/subscriber-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/SubscriberSipServlet.java b/sip-servlets-test-suite/applications/subscriber-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/SubscriberSipServlet.java index 13cbd02c9c..234b4b76c1 100644 --- a/sip-servlets-test-suite/applications/subscriber-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/SubscriberSipServlet.java +++ b/sip-servlets-test-suite/applications/subscriber-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/SubscriberSipServlet.java @@ -1,386 +1,412 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite; - -import java.io.IOException; -import java.util.Enumeration; - -import javax.annotation.Resource; -import javax.mail.BodyPart; -import javax.mail.Header; -import javax.mail.MessagingException; -import javax.mail.Multipart; -import javax.mail.internet.MimeMultipart; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.sip.Parameterable; -import javax.servlet.sip.ServletTimer; -import javax.servlet.sip.SipApplicationSession; -import javax.servlet.sip.SipFactory; -import javax.servlet.sip.SipServlet; -import javax.servlet.sip.SipServletContextEvent; -import javax.servlet.sip.SipServletListener; -import javax.servlet.sip.SipServletRequest; -import javax.servlet.sip.SipServletResponse; -import javax.servlet.sip.SipSession; -import javax.servlet.sip.SipSessionEvent; -import javax.servlet.sip.SipSessionListener; -import javax.servlet.sip.SipURI; -import javax.servlet.sip.TimerListener; -import javax.servlet.sip.TimerService; -import javax.servlet.sip.URI; - -import org.apache.log4j.Logger; - -/** - * - * @author Jean Deruelle - * - */ -public class SubscriberSipServlet - extends SipServlet - implements SipServletListener, TimerListener, SipSessionListener { - private static final long serialVersionUID = 1L; - private static final String TEST_SAME_CONTAINER_USER_NAME = "sameContainerUserName"; - private static transient Logger logger = Logger.getLogger(SubscriberSipServlet.class); - private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; - private static final String SIP_SESSION_READY_TO_BE_INVALIDATED = "sipSessionReadyToBeInvalidated"; - - @Resource - SipFactory sipFactory; - - /** Creates a new instance of SubscriberSipServlet */ - public SubscriberSipServlet() { - } - - @Override - public void init(ServletConfig servletConfig) throws ServletException { - logger.info("the Subscriber sip servlet has been started"); - super.init(servletConfig); - } - - /** - * {@inheritDoc} - */ - protected void doInvite(SipServletRequest request) throws ServletException, - IOException { - logger.info("from : " + request.getFrom()); - logger.info("Got request: " - + request.getMethod()); - - //If we receive an INVITE, we cancel the timer to avoid acting as UAC and sending REFER - ServletTimer servletTimer = (ServletTimer)getServletContext().getAttribute("servletTimer"); - servletTimer.cancel(); - - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_RINGING); - sipServletResponse.send(); - request.getSession().setAttribute("inviteReceived", "true"); - try { - Thread.sleep(2000); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - sipServletResponse = request.createResponse(SipServletResponse.SC_OK); - sipServletResponse.send(); - } - - /** - * {@inheritDoc} - */ - protected void doBye(SipServletRequest request) throws ServletException, - IOException { - - logger.info("Got BYE request: " + request); - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); - sipServletResponse.send(); - request.getSession().setAttribute("byeReceived", "true"); - } - - @Override - protected void doAck(SipServletRequest request) throws ServletException, - IOException { - SipServletRequest subscribe = request.getSession().createRequest("SUBSCRIBE"); - subscribe.setHeader("Expires", "200"); - subscribe.setHeader("Event", "reg; id=1"); - try { - subscribe.send(); - } catch (IOException e) { - logger.error(e); - } - } - - @Override - protected void doSuccessResponse(SipServletResponse sipServletResponse) - throws ServletException, IOException { - logger.info("Got : " + sipServletResponse.getStatus() + " " - + sipServletResponse.getMethod()); - if(sipServletResponse.getSession().getAttribute(TEST_SAME_CONTAINER_USER_NAME) != null && "INVITE".equals(sipServletResponse.getMethod())) { - sipServletResponse.createAck().send(); - try { - Thread.sleep(2000); - } catch (InterruptedException e1) { - } - SipServletRequest subscribe = sipServletResponse.getSession().createRequest("SUBSCRIBE"); - subscribe.setHeader("Expires", "200"); - subscribe.setHeader("Event", "reg; id=1"); - try { - subscribe.send(); - } catch (IOException e) { - logger.error(e); - } - } - } - - @Override - protected void doNotify(SipServletRequest request) throws ServletException, - IOException { - logger.info("Got notify : " - + request.getMethod()); - request.getApplicationSession().setAttribute("sendMessage", "true"); - String state = request.getHeader("Subscription-State"); - Parameterable parameterable = request.getParameterableHeader("Subscription-State"); - logger.info("state " + state); - logger.info("session id " + request.getSession().getId()); - logger.info("sameContainerUserName attribute in session " + request.getSession().getAttribute(TEST_SAME_CONTAINER_USER_NAME)); - logger.info("byeReceived attribute in session " + request.getSession().getAttribute("byeReceived")); - - if("Active".equalsIgnoreCase(state)) { - SipServletRequest subscriberRequest = request.getSession().createRequest("SUBSCRIBE"); - SipURI requestURI = ((SipFactory)getServletContext().getAttribute(SIP_FACTORY)).createSipURI("LittleGuy", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - subscriberRequest.setRequestURI(requestURI); - subscriberRequest.setHeader("Expires", "0"); - subscriberRequest.setHeader("Event", request.getHeader("Event")); - try { - subscriberRequest.send(); - } catch (IOException e) { - logger.error(e); - } - } - if(state != null && state.contains("terminated") && request.getSession().getAttribute(TEST_SAME_CONTAINER_USER_NAME) != null) { - if(request.getSession().getAttribute("byeReceived") == null) { - request.getSession().createRequest("BYE").send(); - SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); - SipURI fromURI = sipFactory.createSipURI("receiver", "sip-servlets.com"); - SipURI requestURI = sipFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - SipServletRequest sipServletRequest = sipFactory.createRequest(sipApplicationSession, "MESSAGE", fromURI, request.getFrom().getURI()); - String messageContent = "dialogCompleted"; - sipServletRequest.setContentLength(messageContent.length()); - sipServletRequest.setContent(messageContent, CONTENT_TYPE); - sipServletRequest.setRequestURI(requestURI); - sipServletRequest.send(); - } - } - if(getServletContext().getInitParameter("testMultipart") != null ) { - String contentType = request.getContentType(); - String contentTypeFromHeader = request.getHeader("Content-Type"); - logger.info("contentType " + contentType); - logger.info("contentTypeFromHeader " + contentTypeFromHeader); - - if(!contentType.trim().equals("multipart/related;type=\"application/rlmi+xml\";start=\"\";boundary=\"50UBfW7LSCVLtggUPe5z\"") || - !contentType.trim().equals(contentTypeFromHeader.trim())) { - logger.error("ContentType is incorrect " + contentType + " contentTypeFromHeader " + contentTypeFromHeader); - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_SERVER_INTERNAL_ERROR); - sipServletResponse.send(); - return; - } - - Multipart multipart = (Multipart) request.getContent(); - try { - int count = multipart.getCount(); - logger.info("mulitpart count " + count); - sendMessage(request.getSession(), "" + count); - BodyPart bodyPart = multipart.getBodyPart(0); - logger.info("body part 0 's content type " + bodyPart.getContentType()); - logger.info("body part 0 's content " + bodyPart.getContent()); - Enumeration headers = bodyPart.getAllHeaders(); - while (headers.hasMoreElements()) { - Header header = (Header) headers.nextElement(); - logger.info("body part 0 's headers: name = " + header.getName() + ", value = " + header.getValue()); - } - } catch (MessagingException e) { - logger.error("couldn't get count ", e); - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_SERVER_INTERNAL_ERROR); - sipServletResponse.send(); - return; - } - } - if(getServletContext().getInitParameter("testMimeMultipartWhitespaces") != null) { - MimeMultipart multipart = (MimeMultipart) request.getContent(); - try { - BodyPart bodyPart = multipart.getBodyPart("<317A166E4BEB17EA1A24F417@telecomsys.com>"); - int count = multipart.getCount(); - logger.info("mulitpart count " + count); - sendMessage(request.getSession(), "" + count); - logger.info("body part 0 's content type " + bodyPart.getContentType()); - logger.info("body part 0 's content " + bodyPart.getContent()); - Enumeration headers = bodyPart.getAllHeaders(); - while (headers.hasMoreElements()) { - Header header = (Header) headers.nextElement(); - logger.info("body part 0 's headers: name = " + header.getName() + ", value = " + header.getValue()); - } - } catch (MessagingException e) { - logger.error("couldn't get count ", e); - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_SERVER_INTERNAL_ERROR); - sipServletResponse.send(); - return; - } - } - if(getServletContext().getInitParameter("no200OKToNotify") == null) { - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); - sipServletResponse.send(); - } else { - logger.info("not sending 200 to Initial Notify as specified by the test configuration"); - } - if(getServletContext().getInitParameter("testSendMultipart") != null ) { - Multipart multipart = (Multipart) request.getContent(); - if(multipart != null) { - try { - int count = multipart.getCount(); - logger.info("mulitpart count " + count); - sendMessage(request.getSession(), "" + count); - BodyPart bodyPart = multipart.getBodyPart(0); - logger.info("body part 0 's content type " + bodyPart.getContentType()); - logger.info("body part 0 's content " + bodyPart.getContent()); - Enumeration headers = bodyPart.getAllHeaders(); - while (headers.hasMoreElements()) { - Header header = (Header) headers.nextElement(); - logger.info("body part 0 's headers: name = " + header.getName() + ", value = " + header.getValue()); - } - } catch (MessagingException e) { - logger.error("couldn't get count ", e); - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_SERVER_INTERNAL_ERROR); - sipServletResponse.send(); - return; - } - } - SipServletRequest infoRequest = request.getSession().createRequest("INFO"); - infoRequest.setContentLength(request.getContentLength()); - infoRequest.setContent(multipart, multipart.getContentType()); - infoRequest.setRequestURI(request.getAddressHeader("Contact").getURI()); - infoRequest.send(); - } - } - - // SipServletListener methods - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipServletListener#servletInitialized(javax.servlet.sip.SipServletContextEvent) - */ - public void servletInitialized(SipServletContextEvent ce) { - if(ce.getServletContext().getInitParameter("requestURI") != null) { - SipFactory sipFactory = (SipFactory)ce.getServletContext().getAttribute(SIP_FACTORY); - SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); - - URI fromURI = sipFactory.createSipURI("BigGuy", "here.com"); - URI toURI = sipFactory.createSipURI("LittleGuy", "there.com"); - SipServletRequest sipServletRequest = - sipFactory.createRequest(sipApplicationSession, "INVITE", fromURI, toURI); - SipURI requestURI = sipFactory.createSipURI(TEST_SAME_CONTAINER_USER_NAME, ce.getServletContext().getInitParameter("requestURI")); - sipServletRequest.setRequestURI(requestURI); - sipServletRequest.getSession().setAttribute(TEST_SAME_CONTAINER_USER_NAME, Boolean.TRUE); - logger.info("session id " + sipServletRequest.getSession().getId()); - try { - sipServletRequest.send(); - } catch (IOException e) { - logger.error("Unexpected exception while sending the INVITE request",e); - } - } else if (ce.getServletContext().getInitParameter("testMultipart") == null && ce.getServletContext().getInitParameter("testMimeMultipartWhitespaces") == null){ - SipFactory sipFactory = (SipFactory)ce.getServletContext().getAttribute(SIP_FACTORY); - SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); - TimerService timerService = (TimerService)ce.getServletContext().getAttribute(TIMER_SERVICE); - sipApplicationSession.setAttribute("sipFactory", sipFactory); - ServletTimer servletTimer = timerService.createTimer(sipApplicationSession, 2000, false, null); - ce.getServletContext().setAttribute("servletTimer", servletTimer); - } - } - - /* - * (non-Javadoc) - * @see javax.servlet.sip.TimerListener#timeout(javax.servlet.sip.ServletTimer) - */ - public void timeout(ServletTimer timer) { - SipFactory sipFactory = (SipFactory) timer.getApplicationSession().getAttribute("sipFactory"); - SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); - SipURI fromURI = sipFactory.createSipURI("BigGuy", "here.com"); - SipURI toURI = sipFactory.createSipURI("LittleGuy", "there.com"); - SipServletRequest sipServletRequest = - sipFactory.createRequest(sipApplicationSession, "SUBSCRIBE", fromURI, toURI); - SipURI requestURI = sipFactory.createSipURI("LittleGuy", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - sipServletRequest.setRequestURI(requestURI); - sipServletRequest.setHeader("Expires", "200"); - sipServletRequest.setHeader("Event", "reg; id=2"); - try { - sipServletRequest.send(); - } catch (IOException e) { - logger.error(e); - } - sipServletRequest = - sipFactory.createRequest(sipApplicationSession, "SUBSCRIBE", fromURI, toURI); - sipServletRequest.setRequestURI(requestURI); - sipServletRequest.setHeader("Expires", "200"); - sipServletRequest.setHeader("Event", "reg; id=1"); - try { - sipServletRequest.send(); - } catch (IOException e) { - logger.error(e); - } - } - - public void sessionCreated(SipSessionEvent se) { - // TODO Auto-generated method stub - - } - - public void sessionDestroyed(SipSessionEvent se) { - // TODO Auto-generated method stub - - } - - public void sessionReadyToInvalidate(SipSessionEvent se) { - logger.info("sip session ready to Invalidate " + se.getSession()); - if(se.getSession().getApplicationSession().getAttribute("sendMessage") != null) { - sendMessage(se.getSession(), SIP_SESSION_READY_TO_BE_INVALIDATED); - } - } - - /** - * @param se - */ - private void sendMessage(SipSession sipSession, String body) { - try { - SipServletRequest sipServletRequest = sipFactory.createRequest( - sipFactory.createApplicationSession(), - "MESSAGE", - sipSession.getLocalParty(), - sipSession.getRemoteParty()); - SipURI sipUri=sipFactory.createSipURI("LittleGuy", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - sipServletRequest.setRequestURI(sipUri); - sipServletRequest.setContentLength(body.length()); - sipServletRequest.setContent(body, CONTENT_TYPE); - sipServletRequest.send(); - } catch (IOException e) { - logger.error("Exception occured while sending the request",e); - } - } +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite; + +import java.io.IOException; +import java.util.Enumeration; + +import javax.annotation.Resource; +import javax.mail.BodyPart; +import javax.mail.Header; +import javax.mail.MessagingException; +import javax.mail.Multipart; +import javax.mail.internet.MimeMultipart; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.sip.Parameterable; +import javax.servlet.sip.ServletTimer; +import javax.servlet.sip.SipApplicationSession; +import javax.servlet.sip.SipFactory; +import javax.servlet.sip.SipServlet; +import javax.servlet.sip.SipServletContextEvent; +import javax.servlet.sip.SipServletListener; +import javax.servlet.sip.SipServletRequest; +import javax.servlet.sip.SipServletResponse; +import javax.servlet.sip.SipSession; +import javax.servlet.sip.SipSessionEvent; +import javax.servlet.sip.SipSessionListener; +import javax.servlet.sip.SipURI; +import javax.servlet.sip.TimerListener; +import javax.servlet.sip.TimerService; +import javax.servlet.sip.URI; + +import org.apache.log4j.Logger; + +/** + * + * @author Jean Deruelle + * + */ +public class SubscriberSipServlet + extends SipServlet + implements SipServletListener, TimerListener, SipSessionListener { + private static final long serialVersionUID = 1L; + private static final String TEST_SAME_CONTAINER_USER_NAME = "sameContainerUserName"; + private static transient Logger logger = Logger.getLogger(SubscriberSipServlet.class); + private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; + private static final String SIP_SESSION_READY_TO_BE_INVALIDATED = "sipSessionReadyToBeInvalidated"; + + @Resource + SipFactory sipFactory; + + static ServletContext ctx; + + /** Creates a new instance of SubscriberSipServlet */ + public SubscriberSipServlet() { + } + + @Override + public void init(ServletConfig servletConfig) throws ServletException { + logger.info("the Subscriber sip servlet has been started"); + super.init(servletConfig); + ctx = servletConfig.getServletContext(); + } + + /** + * {@inheritDoc} + */ + protected void doInvite(SipServletRequest request) throws ServletException, + IOException { + logger.info("from : " + request.getFrom()); + logger.info("Got request: " + + request.getMethod()); + + //If we receive an INVITE, we cancel the timer to avoid acting as UAC and sending REFER + ServletTimer servletTimer = (ServletTimer)getServletContext().getAttribute("servletTimer"); + servletTimer.cancel(); + + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_RINGING); + sipServletResponse.send(); + request.getSession().setAttribute("inviteReceived", "true"); + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + sipServletResponse = request.createResponse(SipServletResponse.SC_OK); + sipServletResponse.send(); + } + + /** + * {@inheritDoc} + */ + protected void doBye(SipServletRequest request) throws ServletException, + IOException { + + logger.info("Got BYE request: " + request); + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); + sipServletResponse.send(); + request.getSession().setAttribute("byeReceived", "true"); + } + + @Override + protected void doAck(SipServletRequest request) throws ServletException, + IOException { + SipServletRequest subscribe = request.getSession().createRequest("SUBSCRIBE"); + subscribe.setHeader("Expires", "200"); + subscribe.setHeader("Event", "reg; id=1"); + try { + subscribe.send(); + } catch (IOException e) { + logger.error(e); + } + } + + @Override + protected void doSuccessResponse(SipServletResponse sipServletResponse) + throws ServletException, IOException { + logger.info("Got : " + sipServletResponse.getStatus() + " " + + sipServletResponse.getMethod()); + if(sipServletResponse.getSession().getAttribute(TEST_SAME_CONTAINER_USER_NAME) != null && "INVITE".equals(sipServletResponse.getMethod())) { + sipServletResponse.createAck().send(); + try { + Thread.sleep(2000); + } catch (InterruptedException e1) { + } + SipServletRequest subscribe = sipServletResponse.getSession().createRequest("SUBSCRIBE"); + subscribe.setHeader("Expires", "200"); + subscribe.setHeader("Event", "reg; id=1"); + try { + subscribe.send(); + } catch (IOException e) { + logger.error(e); + } + } + } + + @Override + protected void doNotify(SipServletRequest request) throws ServletException, + IOException { + logger.info("Got notify : " + + request.getMethod()); + request.getApplicationSession().setAttribute("sendMessage", "true"); + String state = request.getHeader("Subscription-State"); + Parameterable parameterable = request.getParameterableHeader("Subscription-State"); + logger.info("state " + state); + logger.info("session id " + request.getSession().getId()); + logger.info("sameContainerUserName attribute in session " + request.getSession().getAttribute(TEST_SAME_CONTAINER_USER_NAME)); + logger.info("byeReceived attribute in session " + request.getSession().getAttribute("byeReceived")); + + if("Active".equalsIgnoreCase(state)) { + SipServletRequest subscriberRequest = request.getSession().createRequest("SUBSCRIBE"); + SipURI requestURI = ((SipFactory)getServletContext().getAttribute(SIP_FACTORY)).createSipURI("LittleGuy", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + subscriberRequest.setRequestURI(requestURI); + subscriberRequest.setHeader("Expires", "0"); + subscriberRequest.setHeader("Event", request.getHeader("Event")); + try { + subscriberRequest.send(); + } catch (IOException e) { + logger.error(e); + } + } + if(state != null && state.contains("terminated") && request.getSession().getAttribute(TEST_SAME_CONTAINER_USER_NAME) != null) { + if(request.getSession().getAttribute("byeReceived") == null) { + request.getSession().createRequest("BYE").send(); + SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); + SipURI fromURI = sipFactory.createSipURI("receiver", "sip-servlets.com"); + SipURI requestURI = sipFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + SipServletRequest sipServletRequest = sipFactory.createRequest(sipApplicationSession, "MESSAGE", fromURI, request.getFrom().getURI()); + String messageContent = "dialogCompleted"; + sipServletRequest.setContentLength(messageContent.length()); + sipServletRequest.setContent(messageContent, CONTENT_TYPE); + sipServletRequest.setRequestURI(requestURI); + sipServletRequest.send(); + } + } + if(getServletContext().getInitParameter("testMultipart") != null ) { + String contentType = request.getContentType(); + String contentTypeFromHeader = request.getHeader("Content-Type"); + logger.info("contentType " + contentType); + logger.info("contentTypeFromHeader " + contentTypeFromHeader); + + if(!contentType.trim().equals("multipart/related;type=\"application/rlmi+xml\";start=\"\";boundary=\"50UBfW7LSCVLtggUPe5z\"") || + !contentType.trim().equals(contentTypeFromHeader.trim())) { + logger.error("ContentType is incorrect " + contentType + " contentTypeFromHeader " + contentTypeFromHeader); + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_SERVER_INTERNAL_ERROR); + sipServletResponse.send(); + return; + } + + Multipart multipart = (Multipart) request.getContent(); + try { + int count = multipart.getCount(); + logger.info("mulitpart count " + count); + sendMessage(request.getSession(), "" + count); + BodyPart bodyPart = multipart.getBodyPart(0); + logger.info("body part 0 's content type " + bodyPart.getContentType()); + logger.info("body part 0 's content " + bodyPart.getContent()); + Enumeration headers = bodyPart.getAllHeaders(); + while (headers.hasMoreElements()) { + Header header = (Header) headers.nextElement(); + logger.info("body part 0 's headers: name = " + header.getName() + ", value = " + header.getValue()); + } + } catch (MessagingException e) { + logger.error("couldn't get count ", e); + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_SERVER_INTERNAL_ERROR); + sipServletResponse.send(); + return; + } + } + if(getServletContext().getInitParameter("testMimeMultipartWhitespaces") != null) { + MimeMultipart multipart = (MimeMultipart) request.getContent(); + try { + BodyPart bodyPart = multipart.getBodyPart("<317A166E4BEB17EA1A24F417@telecomsys.com>"); + int count = multipart.getCount(); + logger.info("mulitpart count " + count); + sendMessage(request.getSession(), "" + count); + logger.info("body part 0 's content type " + bodyPart.getContentType()); + logger.info("body part 0 's content " + bodyPart.getContent()); + Enumeration headers = bodyPart.getAllHeaders(); + while (headers.hasMoreElements()) { + Header header = (Header) headers.nextElement(); + logger.info("body part 0 's headers: name = " + header.getName() + ", value = " + header.getValue()); + } + } catch (MessagingException e) { + logger.error("couldn't get count ", e); + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_SERVER_INTERNAL_ERROR); + sipServletResponse.send(); + return; + } + } + if(getServletContext().getInitParameter("no200OKToNotify") == null) { + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); + sipServletResponse.send(); + } else { + logger.info("not sending 200 to Initial Notify as specified by the test configuration"); + } + if(getServletContext().getInitParameter("testSendMultipart") != null ) { + Multipart multipart = (Multipart) request.getContent(); + if(multipart != null) { + try { + int count = multipart.getCount(); + logger.info("mulitpart count " + count); + sendMessage(request.getSession(), "" + count); + BodyPart bodyPart = multipart.getBodyPart(0); + logger.info("body part 0 's content type " + bodyPart.getContentType()); + logger.info("body part 0 's content " + bodyPart.getContent()); + Enumeration headers = bodyPart.getAllHeaders(); + while (headers.hasMoreElements()) { + Header header = (Header) headers.nextElement(); + logger.info("body part 0 's headers: name = " + header.getName() + ", value = " + header.getValue()); + } + } catch (MessagingException e) { + logger.error("couldn't get count ", e); + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_SERVER_INTERNAL_ERROR); + sipServletResponse.send(); + return; + } + } + SipServletRequest infoRequest = request.getSession().createRequest("INFO"); + infoRequest.setContentLength(request.getContentLength()); + if(multipart != null) { + infoRequest.setContent(multipart, multipart.getContentType()); + } + infoRequest.setRequestURI(request.getAddressHeader("Contact").getURI()); + infoRequest.send(); + } + } + + // SipServletListener methods + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipServletListener#servletInitialized(javax.servlet.sip.SipServletContextEvent) + */ + public void servletInitialized(SipServletContextEvent ce) { + if(ce.getServletContext().getInitParameter("requestURI") != null) { + SipFactory sipFactory = (SipFactory)ce.getServletContext().getAttribute(SIP_FACTORY); + SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); + + URI fromURI = sipFactory.createSipURI("BigGuy", "here.com"); + URI toURI = sipFactory.createSipURI("LittleGuy", "there.com"); + SipServletRequest sipServletRequest = + sipFactory.createRequest(sipApplicationSession, "INVITE", fromURI, toURI); + SipURI requestURI = sipFactory.createSipURI(TEST_SAME_CONTAINER_USER_NAME, ce.getServletContext().getInitParameter("requestURI")); + sipServletRequest.setRequestURI(requestURI); + sipServletRequest.getSession().setAttribute(TEST_SAME_CONTAINER_USER_NAME, Boolean.TRUE); + logger.info("session id " + sipServletRequest.getSession().getId()); + try { + sipServletRequest.send(); + } catch (IOException e) { + logger.error("Unexpected exception while sending the INVITE request",e); + } + } else if (ce.getServletContext().getInitParameter("testMultipart") == null && ce.getServletContext().getInitParameter("testMimeMultipartWhitespaces") == null){ + SipFactory sipFactory = (SipFactory)ce.getServletContext().getAttribute(SIP_FACTORY); + SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); + TimerService timerService = (TimerService)ce.getServletContext().getAttribute(TIMER_SERVICE); + sipApplicationSession.setAttribute("sipFactory", sipFactory); + ServletTimer servletTimer = timerService.createTimer(sipApplicationSession, 2000, false, null); + ce.getServletContext().setAttribute("servletTimer", servletTimer); + } + } + + /* + * (non-Javadoc) + * @see javax.servlet.sip.TimerListener#timeout(javax.servlet.sip.ServletTimer) + */ + public void timeout(ServletTimer timer) { + SipFactory sipFactory = (SipFactory) timer.getApplicationSession().getAttribute("sipFactory"); + SipApplicationSession sipApplicationSession = sipFactory.createApplicationSession(); + SipURI fromURI = sipFactory.createSipURI("BigGuy", "here.com"); + SipURI toURI = sipFactory.createSipURI("LittleGuy", "there.com"); + SipServletRequest sipServletRequest = + sipFactory.createRequest(sipApplicationSession, "SUBSCRIBE", fromURI, toURI); + SipURI requestURI = sipFactory.createSipURI("LittleGuy", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + sipServletRequest.setRequestURI(requestURI); + sipServletRequest.setHeader("Expires", "200"); + sipServletRequest.setHeader("Event", "reg; id=2"); + try { + sipServletRequest.send(); + } catch (IOException e) { + logger.error(e); + } + sipServletRequest = + sipFactory.createRequest(sipApplicationSession, "SUBSCRIBE", fromURI, toURI); + sipServletRequest.setRequestURI(requestURI); + sipServletRequest.setHeader("Expires", "200"); + sipServletRequest.setHeader("Event", "reg; id=1"); + try { + sipServletRequest.send(); + } catch (IOException e) { + logger.error(e); + } + } + + public void sessionCreated(SipSessionEvent se) { + // TODO Auto-generated method stub + + } + + public void sessionDestroyed(SipSessionEvent se) { + // TODO Auto-generated method stub + + } + + public void sessionReadyToInvalidate(SipSessionEvent se) { + logger.info("sip session ready to Invalidate " + se.getSession()); + if(se.getSession().getApplicationSession().getAttribute("sendMessage") != null) { + sendMessage(se.getSession(), SIP_SESSION_READY_TO_BE_INVALIDATED); + } + } + + /** + * @param se + */ + private void sendMessage(SipSession sipSession, String body) { + try { + SipServletRequest sipServletRequest = sipFactory.createRequest( + sipFactory.createApplicationSession(), + "MESSAGE", + sipSession.getLocalParty(), + sipSession.getRemoteParty()); + SipURI sipUri=sipFactory.createSipURI("LittleGuy", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + sipServletRequest.setRequestURI(sipUri); + sipServletRequest.setContentLength(body.length()); + sipServletRequest.setContent(body, CONTENT_TYPE); + sipServletRequest.send(); + } catch (IOException e) { + logger.error("Exception occured while sending the request",e); + } + } + + public static Integer getTestPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("testPort"); + logger.info("TestPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5080; + } + } + + public static Integer getServletContainerPort(ServletContext ctx) { + String cPort = ctx.getInitParameter("servletContainerPort"); + logger.info("TestPort at:" + cPort); + if (cPort != null) { + return Integer.valueOf(cPort); + } else { + return 5070; + } + } } \ No newline at end of file diff --git a/sip-servlets-test-suite/applications/timers-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/TimersSipServlet.java b/sip-servlets-test-suite/applications/timers-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/TimersSipServlet.java index 863da574af..9fe36f8838 100644 --- a/sip-servlets-test-suite/applications/timers-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/TimersSipServlet.java +++ b/sip-servlets-test-suite/applications/timers-sip-servlet/src/main/java/org/mobicents/servlet/sip/testsuite/TimersSipServlet.java @@ -1,301 +1,325 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite; - -import java.io.IOException; -import java.util.Properties; - -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NamingException; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.sip.ServletParseException; -import javax.servlet.sip.ServletTimer; -import javax.servlet.sip.SipApplicationSession; -import javax.servlet.sip.SipApplicationSessionEvent; -import javax.servlet.sip.SipApplicationSessionListener; -import javax.servlet.sip.SipFactory; -import javax.servlet.sip.SipServlet; -import javax.servlet.sip.SipServletRequest; -import javax.servlet.sip.SipServletResponse; -import javax.servlet.sip.SipSession; -import javax.servlet.sip.SipURI; -import javax.servlet.sip.TimerListener; -import javax.servlet.sip.TimerService; - -import org.apache.log4j.Logger; - -/** - * - * @author Jean Deruelle - * - */ -public class TimersSipServlet - extends SipServlet - implements SipApplicationSessionListener, TimerListener { - private static final long serialVersionUID = 1L; - private static final String RECURRING_TIME = "recurringTime"; - private static final String RECURRING = "recurring"; - private static final String ALREADY_EXTENDED = "alreadyExtended"; - private static final String ALREADY_INVALIDATED = "alreadyInvalidated"; - - - private static transient Logger logger = Logger.getLogger(TimersSipServlet.class); - - private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; - private static final String SIP_APP_SESSION_EXPIRED = "sipAppSessionExpired"; - private static final String SIP_APP_SESSION_READY_TO_BE_INVALIDATED = "sipAppSessionReadyToBeInvalidated"; - private static final String TIMER_EXPIRED = "timerExpired"; - private static final String RECURRING_TIMER_EXPIRED = "recurringTimerExpired"; - - private SipFactory sipFactory; - - - /** Creates a new instance of TimersSipServlet */ - public TimersSipServlet() { - } - - @Override - public void init(ServletConfig servletConfig) throws ServletException { - super.init(servletConfig); - logger.info("the timers test sip servlet has been started"); - try { - // Getting the Sip factory from the JNDI Context - Properties jndiProps = new Properties(); - Context initCtx = new InitialContext(jndiProps); - Context envCtx = (Context) initCtx.lookup("java:comp/env"); - sipFactory = (SipFactory) envCtx.lookup("sip/org.mobicents.servlet.sip.testsuite.TimersApplication/SipFactory"); - logger.info("Sip Factory ref from JNDI : " + sipFactory); - } catch (NamingException e) { - throw new ServletException("Uh oh -- JNDI problem !", e); - } - } - - /** - * {@inheritDoc} - */ - protected void doInvite(SipServletRequest request) throws ServletException, - IOException { - - logger.info("Got request: " - + request.getMethod()); -// SipServletResponse ringingResponse = request.createResponse(SipServletResponse.SC_RINGING); -// ringingResponse.send(); - SipServletResponse okResponse = request.createResponse(SipServletResponse.SC_OK); - okResponse.send(); - request.getApplicationSession().setAttribute("sipFactory", sipFactory); - request.getApplicationSession().setInvalidateWhenReady(true); - String fromString = request.getFrom().toString(); - if(fromString.contains("checkReload")) { - TimerService timerService = (TimerService) getServletContext().getAttribute(TIMER_SERVICE); - timerService.createTimer(request.getApplicationSession(), 1000, false, null); - } else if(fromString.contains("expExtInDialog")) { - request.getApplicationSession().setAttribute("expExtInDialog", "true"); - request.getApplicationSession().setAttribute("sipSessionId", request.getSession().getId()); - } else { - //create a timer to test the feature - TimerService timerService = (TimerService) getServletContext().getAttribute(TIMER_SERVICE); - timerService.createTimer(request.getApplicationSession(), 1000, false, null); - //create a recurring timer to test the feature - timerService.createTimer(request.getApplicationSession(), 3000, 3000, true, false, RECURRING); - request.getApplicationSession().setAttribute(RECURRING_TIME, Integer.valueOf(0)); - } - } - - @Override - protected void doSuccessResponse(SipServletResponse resp) - throws ServletException, IOException { - - if("MESSAGE".equals(resp.getMethod())) { - resp.getSession().invalidate(); - } else if("INVITE".equals(resp.getMethod())) { - resp.createAck().send(); - } - } - - /** - * {@inheritDoc} - */ - protected void doBye(SipServletRequest request) throws ServletException, - IOException { - - logger.info("Got BYE request: " + request); - SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); - sipServletResponse.send(); - } - - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipApplicationSessionListener#sessionExpired(javax.servlet.sip.SipApplicationSessionEvent) - */ - public void sessionExpired(SipApplicationSessionEvent ev) { - logger.info("sip application session expired " + ev.getApplicationSession()); - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - boolean sendMessage = true; - if(ev.getApplicationSession().getAttribute("expExtInDialog") == null) { - if(!ev.getApplicationSession().isReadyToInvalidate() && ev.getApplicationSession().getAttribute(ALREADY_EXTENDED) == null) { - logger.info("extending lifetime of sip app session" + ev.getApplicationSession()); - ev.getApplicationSession().setExpires(1); - ev.getApplicationSession().setAttribute(ALREADY_EXTENDED, Boolean.TRUE); - } - } else { - if(ev.getApplicationSession().getAttribute("reInviteSent") == null) { - SipSession sipSession = ev.getApplicationSession().getSipSession((String) ev.getApplicationSession().getAttribute("sipSessionId")); - ev.getApplicationSession().setAttribute("reInviteSent", "true"); - try { - sipSession.createRequest("INVITE").send(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - sendMessage = false; - } - } - if(sendMessage) { - SipFactory storedFactory = (SipFactory)ev.getApplicationSession().getAttribute("sipFactory"); - try { - SipServletRequest sipServletRequest = storedFactory.createRequest( - ev.getApplicationSession(), - "MESSAGE", - "sip:sender@sip-servlets.com", - "sip:receiver@sip-servlets.com"); - SipURI sipUri=storedFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - sipServletRequest.setRequestURI(sipUri); - sipServletRequest.setContentLength(SIP_APP_SESSION_EXPIRED.length()); - sipServletRequest.setContent(SIP_APP_SESSION_EXPIRED, CONTENT_TYPE); - sipServletRequest.send(); - } catch (ServletParseException e) { - logger.error("Exception occured while parsing the addresses",e); - } catch (IOException e) { - logger.error("Exception occured while sending the request",e); - } - } - } - - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipApplicationSessionListener#sessionCreated(javax.servlet.sip.SipApplicationSessionEvent) - */ - public void sessionCreated(SipApplicationSessionEvent ev) { - logger.info("sip application session created " + ev.getApplicationSession()); - } - - /* - * (non-Javadoc) - * @see javax.servlet.sip.SipApplicationSessionListener#sessionDestroyed(javax.servlet.sip.SipApplicationSessionEvent) - */ - public void sessionDestroyed(SipApplicationSessionEvent ev) { - logger.info("sip application session destroyed " + ev.getApplicationSession()); - - } - - /* - * (non-Javadoc) - * @see javax.servlet.sip.TimerListener#timeout(javax.servlet.sip.ServletTimer) - */ - public void timeout(ServletTimer timer) { - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - SipApplicationSession sipApplicationSession = timer.getApplicationSession(); - Integer recurringTime = (Integer) sipApplicationSession.getAttribute(RECURRING_TIME); - if(recurringTime != null) { - logger.info("timer expired " + timer.getId() + " , info " + timer.getInfo() + " , recurring Time " + recurringTime.intValue()); - } else { - logger.info("timer expired " + timer.getId() + " , info " + timer.getInfo()); - } - SipFactory storedFactory = (SipFactory)sipApplicationSession.getAttribute("sipFactory"); - if(timer.getInfo() == null) { - sendMessage(sipApplicationSession, storedFactory, TIMER_EXPIRED); - } else { - int temp = recurringTime.intValue() + 1; - sipApplicationSession.setAttribute(RECURRING_TIME, Integer.valueOf(temp)); - if(temp > 2) { - sendMessage(sipApplicationSession, storedFactory, RECURRING_TIMER_EXPIRED); - timer.cancel(); - } - } - } - - /** - * @param sipApplicationSession - * @param storedFactory - */ - private void sendMessage(SipApplicationSession sipApplicationSession, - SipFactory storedFactory, String content) { - try { - SipServletRequest sipServletRequest = storedFactory.createRequest( - sipApplicationSession, - "MESSAGE", - "sip:sender@sip-servlets.com", - "sip:receiver@sip-servlets.com"); - SipURI sipUri=storedFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - sipServletRequest.setRequestURI(sipUri); - sipServletRequest.setContentLength(content.length()); - sipServletRequest.setContent(content, CONTENT_TYPE); - sipServletRequest.send(); - } catch (ServletParseException e) { - logger.error("Exception occured while parsing the addresses",e); - } catch (IOException e) { - logger.error("Exception occured while sending the request",e); - } - } - - public void sessionReadyToInvalidate(SipApplicationSessionEvent ev) { - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { - logger.error("ClassLoader " + cl); - throw new IllegalArgumentException("Bad Context Classloader : " + cl); - } - logger.info("sessionReadyToInvalidate called"); - if(ev.getApplicationSession().getAttribute(ALREADY_INVALIDATED) == null) { - ev.getApplicationSession().setAttribute(ALREADY_INVALIDATED, Boolean.TRUE); - SipApplicationSession sipApplicationSession = ev.getApplicationSession(); - SipFactory storedFactory = (SipFactory)sipApplicationSession.getAttribute("sipFactory"); - try { - SipServletRequest sipServletRequest = storedFactory.createRequest( - sipApplicationSession, - "MESSAGE", - "sip:sender@sip-servlets.com", - "sip:receiver@sip-servlets.com"); - SipURI sipUri=storedFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - sipServletRequest.setRequestURI(sipUri); - sipServletRequest.setContentLength(SIP_APP_SESSION_READY_TO_BE_INVALIDATED.length()); - sipServletRequest.setContent(SIP_APP_SESSION_READY_TO_BE_INVALIDATED, CONTENT_TYPE); - sipServletRequest.send(); - } catch (ServletParseException e) { - logger.error("Exception occured while parsing the addresses",e); - } catch (IOException e) { - logger.error("Exception occured while sending the request",e); - } - } - } - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite; + +import java.io.IOException; +import java.util.Properties; + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.sip.ServletParseException; +import javax.servlet.sip.ServletTimer; +import javax.servlet.sip.SipApplicationSession; +import javax.servlet.sip.SipApplicationSessionEvent; +import javax.servlet.sip.SipApplicationSessionListener; +import javax.servlet.sip.SipFactory; +import javax.servlet.sip.SipServlet; +import javax.servlet.sip.SipServletRequest; +import javax.servlet.sip.SipServletResponse; +import javax.servlet.sip.SipSession; +import javax.servlet.sip.SipURI; +import javax.servlet.sip.TimerListener; +import javax.servlet.sip.TimerService; + +import org.apache.log4j.Logger; + +/** + * + * @author Jean Deruelle + * + */ +public class TimersSipServlet + extends SipServlet + implements SipApplicationSessionListener, TimerListener { + private static final long serialVersionUID = 1L; + private static final String RECURRING_TIME = "recurringTime"; + private static final String RECURRING = "recurring"; + private static final String ALREADY_EXTENDED = "alreadyExtended"; + private static final String ALREADY_INVALIDATED = "alreadyInvalidated"; + + + private static transient Logger logger = Logger.getLogger(TimersSipServlet.class); + + private static final String CONTENT_TYPE = "text/plain;charset=UTF-8"; + private static final String SIP_APP_SESSION_EXPIRED = "sipAppSessionExpired"; + private static final String SIP_APP_SESSION_READY_TO_BE_INVALIDATED = "sipAppSessionReadyToBeInvalidated"; + private static final String TIMER_EXPIRED = "timerExpired"; + private static final String RECURRING_TIMER_EXPIRED = "recurringTimerExpired"; + + private SipFactory sipFactory; + + static ServletContext ctx; + + + /** Creates a new instance of TimersSipServlet */ + public TimersSipServlet() { + } + + @Override + public void init(ServletConfig servletConfig) throws ServletException { + super.init(servletConfig); + logger.info("the timers test sip servlet has been started"); + ctx = servletConfig.getServletContext(); + try { + // Getting the Sip factory from the JNDI Context + Properties jndiProps = new Properties(); + Context initCtx = new InitialContext(jndiProps); + Context envCtx = (Context) initCtx.lookup("java:comp/env"); + sipFactory = (SipFactory) envCtx.lookup("sip/org.mobicents.servlet.sip.testsuite.TimersApplication/SipFactory"); + logger.info("Sip Factory ref from JNDI : " + sipFactory); + } catch (NamingException e) { + throw new ServletException("Uh oh -- JNDI problem !", e); + } + } + + /** + * {@inheritDoc} + */ + protected void doInvite(SipServletRequest request) throws ServletException, + IOException { + + logger.info("Got request: " + + request.getMethod()); +// SipServletResponse ringingResponse = request.createResponse(SipServletResponse.SC_RINGING); +// ringingResponse.send(); + SipServletResponse okResponse = request.createResponse(SipServletResponse.SC_OK); + okResponse.send(); + request.getApplicationSession().setAttribute("sipFactory", sipFactory); + request.getApplicationSession().setInvalidateWhenReady(true); + String fromString = request.getFrom().toString(); + if(fromString.contains("checkReload")) { + TimerService timerService = (TimerService) getServletContext().getAttribute(TIMER_SERVICE); + timerService.createTimer(request.getApplicationSession(), 1000, false, null); + } else if(fromString.contains("expExtInDialog")) { + request.getApplicationSession().setAttribute("expExtInDialog", "true"); + request.getApplicationSession().setAttribute("sipSessionId", request.getSession().getId()); + } else { + //create a timer to test the feature + TimerService timerService = (TimerService) getServletContext().getAttribute(TIMER_SERVICE); + timerService.createTimer(request.getApplicationSession(), 1000, false, null); + //create a recurring timer to test the feature + timerService.createTimer(request.getApplicationSession(), 3000, 3000, true, false, RECURRING); + request.getApplicationSession().setAttribute(RECURRING_TIME, Integer.valueOf(0)); + } + } + + @Override + protected void doSuccessResponse(SipServletResponse resp) + throws ServletException, IOException { + + if("MESSAGE".equals(resp.getMethod())) { + resp.getSession().invalidate(); + } else if("INVITE".equals(resp.getMethod())) { + resp.createAck().send(); + } + } + + /** + * {@inheritDoc} + */ + protected void doBye(SipServletRequest request) throws ServletException, + IOException { + + logger.info("Got BYE request: " + request); + SipServletResponse sipServletResponse = request.createResponse(SipServletResponse.SC_OK); + sipServletResponse.send(); + } + + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipApplicationSessionListener#sessionExpired(javax.servlet.sip.SipApplicationSessionEvent) + */ + public void sessionExpired(SipApplicationSessionEvent ev) { + logger.info("sip application session expired " + ev.getApplicationSession()); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + boolean sendMessage = true; + if(ev.getApplicationSession().getAttribute("expExtInDialog") == null) { + if(!ev.getApplicationSession().isReadyToInvalidate() && ev.getApplicationSession().getAttribute(ALREADY_EXTENDED) == null) { + logger.info("extending lifetime of sip app session" + ev.getApplicationSession()); + ev.getApplicationSession().setExpires(1); + ev.getApplicationSession().setAttribute(ALREADY_EXTENDED, Boolean.TRUE); + } + } else { + if(ev.getApplicationSession().getAttribute("reInviteSent") == null) { + SipSession sipSession = ev.getApplicationSession().getSipSession((String) ev.getApplicationSession().getAttribute("sipSessionId")); + ev.getApplicationSession().setAttribute("reInviteSent", "true"); + try { + sipSession.createRequest("INVITE").send(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + sendMessage = false; + } + } + if(sendMessage) { + SipFactory storedFactory = (SipFactory)ev.getApplicationSession().getAttribute("sipFactory"); + try { + SipServletRequest sipServletRequest = storedFactory.createRequest( + ev.getApplicationSession(), + "MESSAGE", + "sip:sender@sip-servlets.com", + "sip:receiver@sip-servlets.com"); + SipURI sipUri=storedFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + sipServletRequest.setRequestURI(sipUri); + sipServletRequest.setContentLength(SIP_APP_SESSION_EXPIRED.length()); + sipServletRequest.setContent(SIP_APP_SESSION_EXPIRED, CONTENT_TYPE); + sipServletRequest.send(); + } catch (ServletParseException e) { + logger.error("Exception occured while parsing the addresses",e); + } catch (IOException e) { + logger.error("Exception occured while sending the request",e); + } + } + } + + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipApplicationSessionListener#sessionCreated(javax.servlet.sip.SipApplicationSessionEvent) + */ + public void sessionCreated(SipApplicationSessionEvent ev) { + logger.info("sip application session created " + ev.getApplicationSession()); + } + + /* + * (non-Javadoc) + * @see javax.servlet.sip.SipApplicationSessionListener#sessionDestroyed(javax.servlet.sip.SipApplicationSessionEvent) + */ + public void sessionDestroyed(SipApplicationSessionEvent ev) { + logger.info("sip application session destroyed " + ev.getApplicationSession()); + + } + + /* + * (non-Javadoc) + * @see javax.servlet.sip.TimerListener#timeout(javax.servlet.sip.ServletTimer) + */ + public void timeout(ServletTimer timer) { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + SipApplicationSession sipApplicationSession = timer.getApplicationSession(); + Integer recurringTime = (Integer) sipApplicationSession.getAttribute(RECURRING_TIME); + if(recurringTime != null) { + logger.info("timer expired " + timer.getId() + " , info " + timer.getInfo() + " , recurring Time " + recurringTime.intValue()); + } else { + logger.info("timer expired " + timer.getId() + " , info " + timer.getInfo()); + } + SipFactory storedFactory = (SipFactory)sipApplicationSession.getAttribute("sipFactory"); + if(timer.getInfo() == null) { + sendMessage(sipApplicationSession, storedFactory, TIMER_EXPIRED); + } else { + int temp = recurringTime.intValue() + 1; + sipApplicationSession.setAttribute(RECURRING_TIME, Integer.valueOf(temp)); + if(temp > 2) { + sendMessage(sipApplicationSession, storedFactory, RECURRING_TIMER_EXPIRED); + timer.cancel(); + } + } + } + + /** + * @param sipApplicationSession + * @param storedFactory + */ + private void sendMessage(SipApplicationSession sipApplicationSession, + SipFactory storedFactory, String content) { + try { + SipServletRequest sipServletRequest = storedFactory.createRequest( + sipApplicationSession, + "MESSAGE", + "sip:sender@sip-servlets.com", + "sip:receiver@sip-servlets.com"); + SipURI sipUri=storedFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + sipServletRequest.setRequestURI(sipUri); + sipServletRequest.setContentLength(content.length()); + sipServletRequest.setContent(content, CONTENT_TYPE); + sipServletRequest.send(); + } catch (ServletParseException e) { + logger.error("Exception occured while parsing the addresses",e); + } catch (IOException e) { + logger.error("Exception occured while sending the request",e); + } + } + + public void sessionReadyToInvalidate(SipApplicationSessionEvent ev) { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(!cl.getClass().getSimpleName().equals("WebappClassLoader")) { + logger.error("ClassLoader " + cl); + throw new IllegalArgumentException("Bad Context Classloader : " + cl); + } + logger.info("sessionReadyToInvalidate called"); + if(ev.getApplicationSession().getAttribute(ALREADY_INVALIDATED) == null) { + ev.getApplicationSession().setAttribute(ALREADY_INVALIDATED, Boolean.TRUE); + SipApplicationSession sipApplicationSession = ev.getApplicationSession(); + SipFactory storedFactory = (SipFactory)sipApplicationSession.getAttribute("sipFactory"); + try { + SipServletRequest sipServletRequest = storedFactory.createRequest( + sipApplicationSession, + "MESSAGE", + "sip:sender@sip-servlets.com", + "sip:receiver@sip-servlets.com"); + SipURI sipUri=storedFactory.createSipURI("receiver", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + getTestPort(ctx)); + sipServletRequest.setRequestURI(sipUri); + sipServletRequest.setContentLength(SIP_APP_SESSION_READY_TO_BE_INVALIDATED.length()); + sipServletRequest.setContent(SIP_APP_SESSION_READY_TO_BE_INVALIDATED, CONTENT_TYPE); + sipServletRequest.send(); + } catch (ServletParseException e) { + logger.error("Exception occured while parsing the addresses",e); + } catch (IOException e) { + logger.error("Exception occured while sending the request",e); + } + } + } + + public static Integer getTestPort(ServletContext ctx) { + String tPort = ctx.getInitParameter("testPort"); + logger.info("TestPort at:" + tPort); + if (tPort != null) { + return Integer.valueOf(tPort); + } else { + return 5080; + } + } + + public static Integer getServletContainerPort(ServletContext ctx) { + String cPort = ctx.getInitParameter("servletContainerPort"); + logger.info("TestPort at:" + cPort); + if (cPort != null) { + return Integer.valueOf(cPort); + } else { + return 5070; + } + } + +} diff --git a/sip-servlets-test-suite/sipp-scenarios/clustering/ar/worstcase-affinity-lb-configuration.properties b/sip-servlets-test-suite/sipp-scenarios/clustering/ar/worstcase-affinity-lb-configuration.properties index 7ec15153f6..35b1060dc2 100644 --- a/sip-servlets-test-suite/sipp-scenarios/clustering/ar/worstcase-affinity-lb-configuration.properties +++ b/sip-servlets-test-suite/sipp-scenarios/clustering/ar/worstcase-affinity-lb-configuration.properties @@ -1,77 +1,102 @@ -# Mobicents Load Balancer Settings +# TelScale Load Balancer Settings # For an overview of the Mobicents Load Balancer visit http://docs.google.com/present/view?id=dc5jp5vx_89cxdvtxcm +# The Load balancer will listen for both TCP and UDP connections -# The binding address of the load balancer +# The binding address of the load balancer. This also specifies the +# default value for both internalHost and externalHost if not specified separately. host=127.0.0.1 +# If set, Proxy will use this address to patch responses from Restcomm so subsequent request will reach the proxy +#public-ip= + +# The binding address of the load balancer where clients should connect (if the host property is not specified) +#externalHost= # The RMI port used for heartbeat signals rmiRegistryPort=2000 +# The port to be used used for the Remote Object +rmiRemoteObjectPort=2001 + +# The SIP ports used where client should connect +externalUdpPort=5060 +#externalTcpPort=5060 +#externalTlsPort=5061 +#externalWsPort=5062 +#externalWssPort=5063 + +# The binding address of the load balancer where SIP application servers should connect (if the host property is not specified) +#internalHost=127.0.0.1 -# The SIP port used where client should connect -externalPort=5060 - # The SIP port from where servers will receive messages # delete if you want to use only one port for both inbound and outbound) -# if you like to activate the integrated HTTP load balancer, this is the entry point -internalPort=5065 +internalUdpPort=5065 +#internalTcpPort=5066 +#internalTlsPort=5067 +#internalWsPort=5068 +#internalWssPort=5069 # The HTTP port for HTTP forwarding httpPort=2080 +# The HTTPS port for HTTPS forwarding +httpsPort=2081 #If no nodes are active the LB can redirect the traffic to the unavailableHost specified in this property, #otherwise, it will return 503 Service Unavailable #unavailableHost=google.com -#Specify UDP or TCP (for now both must be the same) -internalTransport=UDP -externalTransport=UDP - -# If you are using IP load balancer, put the IP address and port here +# If you are using IP load balancer, put the IP address and ports here #externalIpLoadBalancerAddress=127.0.0.1 -#externalIpLoadBalancerPort=111 +#externalIpLoadBalancerUdpPort=111 +#externalIpLoadBalancerTcpPort=112 +#externalIpLoadBalancerTlsPort=113 +#externalIpLoadBalancerWsPort=114 +#externalIpLoadBalancerWssPort=115 # Requests initited from the App Servers can route to this address (if you are using 2 IP load balancers for bidirectional SIP LB) #internalIpLoadBalancerAddress=127.0.0.1 -#internalIpLoadBalancerPort=111 +#internalIpLoadBalancerUdpPort=111 +#internalIpLoadBalancerTcpPort=112 +#internalIpLoadBalancerTlsPort=113 +#internalIpLoadBalancerWsPort=114 +#internalIpLoadBalancerWssPort=115 + +# The addresses in the SIP LB Via headers can be either the real addresses or those specified in the external and internal IP LB addresses + +#useIpLoadBalancerAddressInViaHeaders=false # Designate extra IP addresses as serer nodes #extraServerNodes=222.221.21.12:21,45.6.6.7:9003,33.5.6.7,33.9.9.2 +#Performance Testing mode. Special mode for performance testing of LB server with sipp clients. Set this to true and the extra server nodes will be +#registered as active nodes and will receive traffic from LB. Also these node will never expire. +performanceTestingMode=false + # Call-ID affinity algortihm settings. This algorithm is the default. No need to uncomment it. algorithmClass=org.mobicents.tools.sip.balancer.WorstCaseUdpTestAffinityAlgorithm +#algorithmClass=org.mobicents.tools.sip.balancer.CallIDAffinityBalancerAlgorithm # This property specifies how much time to keep an association before being evitcted. # It is needed to avoid memory leaks on dead calls. The time is in seconds. #callIdAffinityMaxTimeInCache=500 +#The following attribute specified the policy after failover. If set to true all calls from the failed node +#will go to a new healthy node (all calls to the same node). If set to false the calls will go to random new nodes. +#callIdAffinityGroupFailover=false -# Uncomment to enable the consistent hash based on Call-ID algorithm. -#algorithmClass=org.mobicents.tools.sip.balancer.HeaderConsistentHashBalancerAlgorithm -# This property is not required, it defaults to Call-ID if not set, cna be "from.user" or "to.user" when you want the SIP URI username -#sipHeaderAffinityKey=Call-ID -#specify the GET HTTP parameter to be used as hash key -#httpAffinityKey=appsession - -# Uncomment to enable the persistent consistent hash based on Call-ID algorithm. -#algorithmClass=org.mobicents.tools.sip.balancer.PersistentConsistentHashBalancerAlgorithm -# This property is not required, it defaults to Call-ID if not set -#sipHeaderAffinityKey=Call-ID -#specify the GET HTTP parameter to be used as hash key -#httpAffinityKey=appsession - -#This is the JBoss Cache 3.1 configuration file (with jgroups), if not specified it will use default -#persistentConsistentHashCacheConfiguration=/home/config.xml - -# Call-ID affinity algortihm settings. This algorithm is the default. No need to uncomment it. -#algorithmClass=org.mobicents.tools.sip.balancer.CallIDAffinityBalancerAlgorithm +# Uncomment to enable the UserBasedAlgorithm algorithm. +#algorithmClass=org.mobicents.tools.sip.balancer.UserBasedAlgorithm +# This property is required +#sipHeaderAffinityKey=To # This property specifies how much time to keep an association before being evitcted. # It is needed to avoid memory leaks on dead calls. The time is in seconds. -#callIdAffinityMaxTimeInCache=500 +#userAffinityMaxTimeInCache=500 +#The following attribute specified the policy after failover. If set to true all calls from the failed node +#will go to a new healthy node (all calls to the same node). If set to false the calls will go to random new nodes. +#userAffinityGroupFailover=false # Uncomment to enable the consistent hash based on Call-ID algorithm. #algorithmClass=org.mobicents.tools.sip.balancer.HeaderConsistentHashBalancerAlgorithm -# This property is not required, it defaults to Call-ID if not set, cna be "from.user" or "to.user" when you want the SIP URI username +# This property is not required, it defaults to Call-ID if not set, can be "From" or "To" when you want the SIP URI username #sipHeaderAffinityKey=Call-ID #specify the GET HTTP parameter to be used as hash key #httpAffinityKey=appsession - + # Uncomment to enable the persistent consistent hash based on Call-ID algorithm. #algorithmClass=org.mobicents.tools.sip.balancer.PersistentConsistentHashBalancerAlgorithm # This property is not required, it defaults to Call-ID if not set @@ -82,24 +107,85 @@ algorithmClass=org.mobicents.tools.sip.balancer.WorstCaseUdpTestAffinityAlgorith #This is the JBoss Cache 3.1 configuration file (with jgroups), if not specified it will use default #persistentConsistentHashCacheConfiguration=/home/config.xml +#If a node doesnt check in within that time (in ms), it is considered dead. +nodeTimeout=8400 +#The consistency of the above condition is checked every heartbeatInterval milliseconds +heartbeatInterval=150 +#Should load balancer send response 100 TRYING message, after INVITE request +isSendTrying=true + #JSIP stack configuration..... -javax.sip.STACK_NAME = SipBalancerForwarder -javax.sip.AUTOMATIC_DIALOG_SUPPORT = off +javax.sip.STACK_NAME=SipBalancerForwarder +javax.sip.AUTOMATIC_DIALOG_SUPPORT=off # You need 16 for logging traces. 32 for debug + traces. # Your code will limp at 32 but it is best for debugging. -gov.nist.javax.sip.TRACE_LEVEL = 0 - -// Specify if message contents should be logged. +# LOG4J means the level will be configurable from the JOG4J config file +gov.nist.javax.sip.TRACE_LEVEL=LOG4J +#Specify if message contents should be logged. gov.nist.javax.sip.LOG_MESSAGE_CONTENT=false +gov.nist.javax.sip.DEBUG_LOG=logs/sipbalancerforwarderdebug.txt +gov.nist.javax.sip.SERVER_LOG=logs/sipbalancerforwarder.xml +gov.nist.javax.sip.THREAD_POOL_SIZE=64 +gov.nist.javax.sip.REENTRANT_LISTENER=true +gov.nist.javax.sip.AGGRESSIVE_CLEANUP=true +gov.nist.javax.sip.RECEIVE_UDP_BUFFER_SIZE=65536 +gov.nist.javax.sip.SEND_UDP_BUFFER_SIZE=65536 +# prevent DOS attacks +gov.nist.javax.sip.MAX_LISTENER_RESPONSE_TIME=120 +gov.nist.javax.sip.MAX_MESSAGE_SIZE=10000 +gov.nist.javax.sip.AGGRESSIVE_CLEANUP=true +gov.nist.javax.sip.MAX_FORK_TIME_SECONDS=0 +gov.nist.javax.sip.AUTOMATIC_DIALOG_ERROR_HANDLING=false +gov.nist.javax.sip.MESSAGE_PROCESSOR_FACTORY=gov.nist.javax.sip.stack.NioMessageProcessorFactory -gov.nist.javax.sip.DEBUG_LOG = /Users/vladimirralev/logs/sipbalancerforwarderdebug.txt -gov.nist.javax.sip.SERVER_LOG = /Users/vladimirralev/logs/sipbalancerforwarder.xml -gov.nist.javax.sip.THREAD_POOL_SIZE = 64 -gov.nist.javax.sip.REENTRANT_LISTENER = true -gov.nist.javax.sip.TCP_POST_PARSING_THREAD_POOL_SIZE = -1 -gov.nist.javax.sip.MAX_MESSAGE_SIZE=2000 +#SMPP Load Balancer Settings +smppName=SMPP Load Balancer +# The address of the load balancer +smppHost=127.0.0.1 +# The port of the load balancer +smppPort=2776 +# The port of the load balancer for SSL protocol +#smppSslPort=2876 +# it is recommended that at any time there were no more than +#10 (ten) SMPP messages are outstanding +maxConnectionSize=10 +# Is NIO enabled +nonBlockingSocketsEnabled=true +# Is default session counters enabled +defaultSessionCountersEnabled=true +# Response timeout for load balancer in milliseconds +timeoutResponse=10000 +# Session initialization timer +timeoutConnection=1000 +# Enquire Link Timer +timeoutEnquire=50000 +# Time between reconnection +reconnectPeriod=1000 +# Connection check timer in load balancer +timeoutConnectionCheckClientSide=1000 +# Connection check server side timer +timeoutConnectionCheckServerSide=1000 -#If a node doesnt check in within that time (in ms), it is considered dead -nodeTimeout=5100 -#The consistency of the above condition is checked every heartbeatInterval milliseconds -heartbeatInterval=5000 \ No newline at end of file +# SSL configuration +#points to the keystore file we generated before +#javax.net.ssl.keyStore=/opt/loadbalancer/config/keystore +#provides the password we used when we generated the keystore +#javax.net.ssl.keyStorePassword=123456 +#points to the truststore file we generated before +#javax.net.ssl.trustStore=/opt/loadbalancer/config/keystore +#provides the password we used when we generated the truststore +#javax.net.ssl.trustStorePassword=123456 +#this is important because sipp supports only TLSv1 and so we need to restrict the protocols only to that +gov.nist.javax.sip.TLS_CLIENT_PROTOCOLS=TLSv1 +#can be : Enabled, Disabled, DisabledAll, Want +#if Enabled, used to request and require client certificate authentication: the connection will terminate if no suitable client certificate is presented +#if Want, used to request client certificate authentication, but keep the connection if no authentication is provided +#if Disabled or DisabledAll does not use authentication +gov.nist.javax.sip.TLS_CLIENT_AUTH_TYPE=Disabled +#ssl will provide some extra debugging information for the SSL if uncomment it +#javax.net.debug=ssl +#Terminate all secure traffic coming from the outside world HTTPs, SIP TLS, WSS will be terminated at LB side +#terminateTLSTraffic=true +#Statistic +#port for statistic +statisticPort=2006 diff --git a/sip-servlets-test-suite/sipp-scenarios/clustering/auto-clustering-failover-test.sh b/sip-servlets-test-suite/sipp-scenarios/clustering/auto-clustering-failover-test.sh index aa79fba07e..30a70ce4ca 100755 --- a/sip-servlets-test-suite/sipp-scenarios/clustering/auto-clustering-failover-test.sh +++ b/sip-servlets-test-suite/sipp-scenarios/clustering/auto-clustering-failover-test.sh @@ -1,11 +1,16 @@ +#!/bin/bash export EXAMPLES_HOME=../../../sip-servlets-examples -export config1="all" -export config2="port-1" +export config1="node1" +export config2="node2" + +export deployments_dir1="deployments" +export deployments_dir2="deployments-node2" + export KILL_PARAMS="-9" export FULLSTARTSLEEP=200 export HALFSTARTSLEEP=200 -export CALLS=5 +export CALLS=1 if [ "x$1" != "x" ]; then export FULLSTARTSLEEP=$1 @@ -27,15 +32,36 @@ export EXIT_CODE=0; rm -rf result.txt +echo "killing all sipp processes" +killall sipp + +echo "killing all jboss processes" +ps -aef | grep jboss +JBPIDS=$(pgrep -d" " -f "jboss"); +echo "Currently running jboss processes $JBPIDS" + +if [[ -z "$JBPIDS" ]]; then + echo "no running jboss processes" +else + for i in "${$JBPIDS[@]}" + do + echo "killing JBoss process $i" + kill -9 $i + done +fi + +ps -aef | grep jboss +ps -aef | grep sipp + # Start SIP LB -sed 's/load-balancer-TEMPLATE/load-balancer-normal/g' ./lb-logging.properties >lb-logging.properties.normal +#sed 's/load-balancer-TEMPLATE/load-balancer-normal/g' ./lb-logging.properties >lb-logging.properties.normal echo "#!/bin/sh" > auto-startlb.sh -echo "java -Djava.util.logging.config.file=lb-logging.properties.normal -server -Xms1536m -Xmx1536m -XX:PermSize=128M -XX:MaxPermSize=256M -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -jar $JBOSS_HOME/sip-balancer/sip-balancer-jar-with-dependencies.jar -mobicents-balancer-config=$JBOSS_HOME/sip-balancer/lb-configuration.properties" >> auto-startlb.sh +echo "java -Djava.util.logging.config.file=lb-log4j.xml -server -Xms1536m -Xmx1536m -XX:PermSize=128M -XX:MaxPermSize=256M -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -jar $JBOSS_HOME/sip-balancer/sip-balancer-jar-2.1.0-SNAPSHOT-jar-with-dependencies.jar -mobicents-balancer-config=$JBOSS_HOME/sip-balancer/lb-configuration.properties" >> auto-startlb.sh chmod +x auto-startlb.sh -sed 's/load-balancer-TEMPLATE/load-balancer-worst/g' ./lb-logging.properties >lb-logging.properties.worst +#sed 's/load-balancer-TEMPLATE/load-balancer-worst/g' ./lb-logging.properties >lb-logging.properties.worst echo "#!/bin/sh" > auto-startlb-worst.sh -echo "java -Djava.util.logging.config.file=lb-logging.properties.worst -server -Xms1536m -Xmx1536m -XX:PermSize=128M -XX:MaxPermSize=256M -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -jar $JBOSS_HOME/sip-balancer/sip-balancer-jar-with-dependencies.jar -mobicents-balancer-config=ar/worstcase-affinity-lb-configuration.properties" >> auto-startlb-worst.sh +echo "java -Djava.util.logging.config.file=lb-log4j.xml -server -Xms1536m -Xmx1536m -XX:PermSize=128M -XX:MaxPermSize=256M -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -jar $JBOSS_HOME/sip-balancer/sip-balancer-jar-2.1.0-SNAPSHOT-jar-with-dependencies.jar -mobicents-balancer-config=ar/worstcase-affinity-lb-configuration.properties" >> auto-startlb-worst.sh chmod +x auto-startlb-worst.sh # Uncomment this if you want to keep the original affinity testing. @@ -44,6 +70,25 @@ chmod +x auto-startlb-worst.sh #echo "java -server -Xms1536m -Xmx1536m -XX:PermSize=128M -XX:MaxPermSize=256M -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -jar $JBOSS_HOME/sip-balancer/sip-balancer-jar-with-dependencies.jar -mobicents-balancer-config=ar/worstcase-affinity-lb-configuration.properties" >> auto-startlb.sh #chmod +x auto-startlb.sh +rm -rf $JBOSS_HOME/standalone/$deployments_dir1 +rm -rf $JBOSS_HOME/standalone/$deployments_dir2 + +rm -f $JBOSS_HOME/standalone/log/* + +mkdir -p $JBOSS_HOME/standalone/$deployments_dir1 +mkdir -p $JBOSS_HOME/standalone/$deployments_dir2 + +cp -fv $JBOSS_HOME/standalone/configuration/standalone-sip-ha.xml $JBOSS_HOME/standalone/configuration/standalone-sip-ha-$config1.xml +cp -fv $JBOSS_HOME/standalone/configuration/standalone-sip-ha.xml $JBOSS_HOME/standalone/configuration/standalone-sip-ha-$config2.xml + +sed -i "s|path=\"server.*\"|path=\"server-$config1.log\"|" $JBOSS_HOME/standalone/configuration/standalone-sip-ha-$config1.xml +sed -i "s|path=\"deployments\"|path=\"$deployments_dir1\"|" $JBOSS_HOME/standalone/configuration/standalone-sip-ha-$config1.xml + +sed -i "s|path=\"server.*\"|path=\"server-$config2.log\"|" $JBOSS_HOME/standalone/configuration/standalone-sip-ha-$config2.xml +sed -i "s|path=\"deployments\"|path=\"$deployments_dir2\"|" $JBOSS_HOME/standalone/configuration/standalone-sip-ha-$config2.xml + +sed -i "s|||" $JBOSS_HOME/standalone/configuration/standalone-sip-ha-$config1.xml +sed -i "s|||" $JBOSS_HOME/standalone/configuration/standalone-sip-ha-$config2.xml ./auto-startlb.sh > siplb.out & export SIPLB=$! @@ -54,8 +99,8 @@ echo "SIP LB $SIPLB" ################################## echo "Test Custom B2BUA" echo "================================" -./auto-prepare-example.sh custom-b2bua $config1 -./auto-prepare-example.sh custom-b2bua $config2 +./auto-prepare-example.sh custom-b2bua $deployments_dir1 +./auto-prepare-example.sh custom-b2bua $deployments_dir2 ./auto-start-jboss-server.sh $config2 config2.pid 1 custom-b2bua @@ -96,8 +141,8 @@ sleep 10 ################################## echo "Test b2bua" echo "================================" -./auto-prepare-example.sh b2bua $config1 -./auto-prepare-example.sh b2bua $config2 +./auto-prepare-example.sh b2bua $deployments_dir1 +./auto-prepare-example.sh b2bua $deployments_dir2 ./auto-start-jboss-server.sh $config2 config2.pid 1 b2bua @@ -143,8 +188,8 @@ sleep 10 ################################## echo "Test proxy" echo "================================" -./auto-prepare-example.sh proxy $config1 -./auto-prepare-example.sh proxy $config2 +./auto-prepare-example.sh proxy $deployments_dir1 +./auto-prepare-example.sh proxy $deployments_dir2 ./auto-start-jboss-server.sh $config2 config2.pid 1 proxy @@ -190,8 +235,8 @@ sleep 10 ################################## echo "Test UAS" echo "================================" -./auto-prepare-example.sh uas $config1 -./auto-prepare-example.sh uas $config2 +./auto-prepare-example.sh uas $deployments_dir1 +./auto-prepare-example.sh uas $deployments_dir2 ./auto-start-jboss-server.sh $config2 config2.pid 1 uas @@ -234,8 +279,6 @@ sleep $HALFSTARTSLEEP ./auto-run-test.sh uas-reinvite result.txt $CALLS -#if [ "x$3" == "xjboss-5" ]; then - #The test killed server 1, so we start it again ./auto-start-jboss-server.sh $config1 config1.pid 0 uas-timer @@ -271,8 +314,8 @@ sleep 10 ################################## echo "Test UAS with servers bound to 0.0.0.0" echo "================================" -./auto-prepare-example.sh uas $config1 -./auto-prepare-example.sh uas $config2 +./auto-prepare-example.sh uas $deployments_dir1 +./auto-prepare-example.sh uas $deployments_dir2 ./auto-start-jboss-server-0.0.0.0.sh $config2 config2.pid $ports2 2 uas-0.0.0.0 ./auto-start-jboss-server-0.0.0.0.sh $config1 config1.pid $ports1 1 uas-0.0.0.0 @@ -293,257 +336,257 @@ sleep 10 ################################## # Test UAS reinvite passivation ################################## -echo "Test UAS Reinvite Passivation" -echo "================================" -./auto-prepare-example.sh uas-passivation $config1 -./auto-prepare-example.sh uas-passivation $config2 +#echo "Test UAS Reinvite Passivation" +#echo "================================" +#./auto-prepare-example.sh uas-passivation $config1 +#./auto-prepare-example.sh uas-passivation $config2 -./auto-start-jboss-server.sh $config2 config2.pid 1 uas-reinvite-passivation +#./auto-start-jboss-server.sh $config2 config2.pid 1 uas-reinvite-passivation #Wait to boot -sleep $HALFSTARTSLEEP +#sleep $HALFSTARTSLEEP -./auto-start-jboss-server.sh $config1 config1.pid 0 uas-reinvite-passivation +#./auto-start-jboss-server.sh $config1 config1.pid 0 uas-reinvite-passivation #Wait to boot -sleep $HALFSTARTSLEEP +#sleep $HALFSTARTSLEEP -./auto-run-test.sh uas-reinvite-passivation result.txt $CALLS +#./auto-run-test.sh uas-reinvite-passivation result.txt $CALLS #Kill the app servers -./auto-kill-process-tree.sh `cat config1.pid` $config1 -./auto-kill-process-tree.sh `cat config2.pid` $config2 +#./auto-kill-process-tree.sh `cat config1.pid` $config1 +#./auto-kill-process-tree.sh `cat config2.pid` $config2 -sleep 10 +#sleep 10 ################################## # Test UAS SAS Expiration Timer passivation ################################## -echo "Test UAS SAS Expiration Timer Passivation" -echo "================================" -./auto-prepare-example.sh uas-passivation $config1 -./auto-prepare-example.sh uas-passivation $config2 +#echo "Test UAS SAS Expiration Timer Passivation" +#echo "================================" +#./auto-prepare-example.sh uas-passivation $config1 +#./auto-prepare-example.sh uas-passivation $config2 -./auto-start-jboss-server.sh $config2 config2.pid 1 uas-sas-timer-passivation +#./auto-start-jboss-server.sh $config2 config2.pid 1 uas-sas-timer-passivation #Wait to boot -sleep $HALFSTARTSLEEP +#sleep $HALFSTARTSLEEP -./auto-start-jboss-server.sh $config1 config1.pid 0 uas-sas-timer-passivation +#./auto-start-jboss-server.sh $config1 config1.pid 0 uas-sas-timer-passivation #Wait to boot -sleep $HALFSTARTSLEEP +#sleep $HALFSTARTSLEEP -./auto-run-test.sh uas-sas-timer-passivation result.txt $CALLS +#./auto-run-test.sh uas-sas-timer-passivation result.txt $CALLS #Kill the app servers -./auto-kill-process-tree.sh `cat config1.pid` $config1 -./auto-kill-process-tree.sh `cat config2.pid` $config2 +#./auto-kill-process-tree.sh `cat config1.pid` $config1 +#./auto-kill-process-tree.sh `cat config2.pid` $config2 -sleep 10 +#sleep 10 ################################## # Test UAS Servlet Timer passivation ################################## -echo "Test UAS Servlet Timer Passivation" -echo "================================" -./auto-prepare-example.sh uas-passivation $config1 -./auto-prepare-example.sh uas-passivation $config2 +#echo "Test UAS Servlet Timer Passivation" +#echo "================================" +#./auto-prepare-example.sh uas-passivation $config1 +#./auto-prepare-example.sh uas-passivation $config2 -./auto-start-jboss-server.sh $config2 config2.pid 1 uas-timer-passivation +#./auto-start-jboss-server.sh $config2 config2.pid 1 uas-timer-passivation #Wait to boot -sleep $HALFSTARTSLEEP +#sleep $HALFSTARTSLEEP -./auto-start-jboss-server.sh $config1 config1.pid 0 uas-timer-passivation +#./auto-start-jboss-server.sh $config1 config1.pid 0 uas-timer-passivation #Wait to boot -sleep $HALFSTARTSLEEP +#sleep $HALFSTARTSLEEP -./auto-run-test.sh uas-timer-passivation result.txt $CALLS +#./auto-run-test.sh uas-timer-passivation result.txt $CALLS #Kill the app servers -./auto-kill-process-tree.sh `cat config1.pid` $config1 -./auto-kill-process-tree.sh `cat config2.pid` $config2 +#./auto-kill-process-tree.sh `cat config1.pid` $config1 +#./auto-kill-process-tree.sh `cat config2.pid` $config2 -sleep 10 +#sleep 10 ################################## # Test proxy early failover ################################## -echo "Test proxy early failover" -echo "================================" -./auto-prepare-example.sh proxy-early $config1 -./auto-prepare-example.sh proxy-early $config2 +#echo "Test proxy early failover" +#echo "================================" +#./auto-prepare-example.sh proxy-early $config1 +#./auto-prepare-example.sh proxy-early $config2 -./auto-start-jboss-server.sh $config2 config2.pid 1 proxy-early +#./auto-start-jboss-server.sh $config2 config2.pid 1 proxy-early #Wait to boot -sleep $HALFSTARTSLEEP +#sleep $HALFSTARTSLEEP -./auto-start-jboss-server.sh $config1 config1.pid 0 proxy-early +#./auto-start-jboss-server.sh $config1 config1.pid 0 proxy-early #Wait to boot -sleep $HALFSTARTSLEEP +#sleep $HALFSTARTSLEEP -./auto-run-test.sh proxy-early result.txt $CALLS +#./auto-run-test.sh proxy-early result.txt $CALLS #Kill the app servers -./auto-kill-process-tree.sh `cat config1.pid` $config1 -./auto-kill-process-tree.sh `cat config2.pid` $config2 +#./auto-kill-process-tree.sh `cat config1.pid` $config1 +#./auto-kill-process-tree.sh `cat config2.pid` $config2 -sleep 10 +#sleep 10 ################################## # Test Custom B2BUA Early Dialog Failover ################################## -echo "Test Custom B2BUA Early Dialog Failover" -echo "================================" -./auto-prepare-example.sh custom-b2bua-early $config1 -./auto-prepare-example.sh custom-b2bua-early $config2 +#echo "Test Custom B2BUA Early Dialog Failover" +#echo "================================" +#./auto-prepare-example.sh custom-b2bua-early $config1 +#./auto-prepare-example.sh custom-b2bua-early $config2 -./auto-start-jboss-server.sh $config2 config2.pid 1 custom-b2bua-early +#./auto-start-jboss-server.sh $config2 config2.pid 1 custom-b2bua-early #Wait to boot -sleep $HALFSTARTSLEEP +#sleep $HALFSTARTSLEEP -./auto-start-jboss-server.sh $config1 config1.pid 0 custom-b2bua-early +#./auto-start-jboss-server.sh $config1 config1.pid 0 custom-b2bua-early #Wait to boot -sleep $HALFSTARTSLEEP +#sleep $HALFSTARTSLEEP -./auto-run-test.sh custom-b2bua-early result.txt $CALLS +#./auto-run-test.sh custom-b2bua-early result.txt $CALLS #Kill the app servers -./auto-kill-process-tree.sh `cat config1.pid` $config1 -./auto-kill-process-tree.sh `cat config2.pid` $config2 +#./auto-kill-process-tree.sh `cat config1.pid` $config1 +#./auto-kill-process-tree.sh `cat config2.pid` $config2 -sleep 10 +#sleep 10 ################################## # Test b2bua Early Dialog Failover ################################## -echo "Test b2bua early dialog failover" -echo "================================" -./auto-prepare-example.sh b2bua-early $config1 -./auto-prepare-example.sh b2bua-early $config2 +#echo "Test b2bua early dialog failover" +#echo "================================" +#./auto-prepare-example.sh b2bua-early $config1 +#./auto-prepare-example.sh b2bua-early $config2 -./auto-start-jboss-server.sh $config2 config2.pid 1 b2bua-early +#./auto-start-jboss-server.sh $config2 config2.pid 1 b2bua-early #Wait to boot -sleep $HALFSTARTSLEEP +#sleep $HALFSTARTSLEEP -./auto-start-jboss-server.sh $config1 config1.pid 0 b2bua-early +#./auto-start-jboss-server.sh $config1 config1.pid 0 b2bua-early #Wait to boot -sleep $HALFSTARTSLEEP +#sleep $HALFSTARTSLEEP -./auto-run-test.sh b2bua-early result.txt $CALLS +#./auto-run-test.sh b2bua-early result.txt $CALLS #Kill the app servers -./auto-kill-process-tree.sh `cat config1.pid` $config1 -./auto-kill-process-tree.sh `cat config2.pid` $config2 +#./auto-kill-process-tree.sh `cat config1.pid` $config1 +#./auto-kill-process-tree.sh `cat config2.pid` $config2 -sleep 10 +#sleep 10 ################################## # Test b2bua Linked Requests Early Dialog Failover ################################## -echo "Test b2bua early linked requests dialog failover" -echo "================================" -./auto-prepare-example.sh b2bua-early $config1 -./auto-prepare-example.sh b2bua-early $config2 +#echo "Test b2bua early linked requests dialog failover" +#echo "================================" +#./auto-prepare-example.sh b2bua-early $config1 +#./auto-prepare-example.sh b2bua-early $config2 -./auto-start-jboss-server.sh $config2 config2.pid 1 b2bua-early-linked +#./auto-start-jboss-server.sh $config2 config2.pid 1 b2bua-early-linked #Wait to boot -sleep $HALFSTARTSLEEP +#sleep $HALFSTARTSLEEP -./auto-start-jboss-server.sh $config1 config1.pid 0 b2bua-early-linked +#./auto-start-jboss-server.sh $config1 config1.pid 0 b2bua-early-linked #Wait to boot -sleep $HALFSTARTSLEEP +#sleep $HALFSTARTSLEEP -./auto-run-test.sh b2bua-early-linked result.txt $CALLS +#./auto-run-test.sh b2bua-early-linked result.txt $CALLS #Kill the app servers -./auto-kill-process-tree.sh `cat config1.pid` $config1 -./auto-kill-process-tree.sh `cat config2.pid` $config2 +#./auto-kill-process-tree.sh `cat config1.pid` $config1 +#./auto-kill-process-tree.sh `cat config2.pid` $config2 -sleep 10 +#sleep 10 ################################## # Test b2bua Forward Ack Early Dialog Failover ################################## -echo "Test b2bua early dialog failover Forward Ack" -echo "================================" +#echo "Test b2bua early dialog failover Forward Ack" +#echo "================================" -./auto-start-jboss-server.sh $config2 config2.pid 1 b2bua-early-fwd-ack +#./auto-start-jboss-server.sh $config2 config2.pid 1 b2bua-early-fwd-ack #Wait to boot -sleep $HALFSTARTSLEEP +#sleep $HALFSTARTSLEEP -./auto-start-jboss-server.sh $config1 config1.pid 0 b2bua-early-fwd-ack +#./auto-start-jboss-server.sh $config1 config1.pid 0 b2bua-early-fwd-ack #Wait to boot -sleep $HALFSTARTSLEEP +#sleep $HALFSTARTSLEEP -./auto-run-test.sh b2bua-early-fwd-ack result.txt $CALLS +#./auto-run-test.sh b2bua-early-fwd-ack result.txt $CALLS #Kill the app servers -./auto-kill-process-tree.sh `cat config1.pid` $config1 -./auto-kill-process-tree.sh `cat config2.pid` $config2 +#./auto-kill-process-tree.sh `cat config1.pid` $config1 +#./auto-kill-process-tree.sh `cat config2.pid` $config2 -sleep 10 +#sleep 10 ################################## # Test AR ################################## -echo "Test Proxy-B2bua AR" -echo "================================" +#echo "Test Proxy-B2bua AR" +#echo "================================" #We must kill the LB here and make it use worstcase affinity -./auto-kill-process-tree.sh $SIPLB siplb -./auto-startlb-worst.sh > siplb.out & -export SIPLB=$! -echo "SIP LB $SIPLB" +#./auto-kill-process-tree.sh $SIPLB siplb +#./auto-startlb-worst.sh > siplb.out & +#export SIPLB=$! +#echo "SIP LB $SIPLB" -./auto-prepare-example.sh proxy-b2bua-ar $config1 -./auto-prepare-example.sh proxy-b2bua-ar $config2 +#./auto-prepare-example.sh proxy-b2bua-ar $config1 +#./auto-prepare-example.sh proxy-b2bua-ar $config2 -./auto-start-jboss-server.sh $config2 config2.pid 1 proxy-b2bua-ar +#./auto-start-jboss-server.sh $config2 config2.pid 1 proxy-b2bua-ar #Wait to boot -sleep $HALFSTARTSLEEP +#sleep $HALFSTARTSLEEP -./auto-start-jboss-server.sh $config1 config1.pid 0 proxy-b2bua-ar +#./auto-start-jboss-server.sh $config1 config1.pid 0 proxy-b2bua-ar # SIPp should be running by the time JBoss finishes the startup, hence we use half start time here. #cleanup flag files for this test -rm -rf *.flag +#rm -rf *.flag -sleep $HALFSTARTSLEEP -./auto-run-test.sh proxy-b2bua-ar result.txt $CALLS +#sleep $HALFSTARTSLEEP +#./auto-run-test.sh proxy-b2bua-ar result.txt $CALLS -sleep 20 -if [ -f lssdestryed.flag -a -f cb2buadestryed.flag ]; then +#sleep 20 +#if [ -f lssdestryed.flag -a -f cb2buadestryed.flag ]; then #success if both flags are present - echo "proxy-b2bua-ar-invalidation 0" >> result.txt -else +# echo "proxy-b2bua-ar-invalidation 0" >> result.txt +#else #failure is one of the flags is missing - echo "proxy-b2bua-ar-invalidation 1" >> result.txt -fi +# echo "proxy-b2bua-ar-invalidation 1" >> result.txt +#fi #some debug info -cat result.txt -ls +#cat result.txt +#ls #Kill the app servers -./auto-kill-process-tree.sh `cat config1.pid` $config1 -./auto-kill-process-tree.sh `cat config2.pid` $config2 +#./auto-kill-process-tree.sh `cat config1.pid` $config1 +#./auto-kill-process-tree.sh `cat config2.pid` $config2 -sleep 10 +#sleep 10 ################################## @@ -551,8 +594,11 @@ sleep 10 ################################## echo "Test UAC" echo "================================" -./auto-prepare-example.sh uac $config1 -Dsend.on.init=true -./auto-prepare-example.sh uac $config2 -Dsend.on.init=false +ORIG_MAVEN_OPTS=$MAVEN_OPTS +export MAVEN_CMD_OPTS="$ORIG_MAVEN_OPTS -Dsend.on.init=true" +./auto-prepare-example.sh uac $deployments_dir1 +export MAVEN_CMD_OPTS="$ORIG_MAVEN_OPTS -Dsend.on.init=false" +./auto-prepare-example.sh uac $deployments_dir2 ./auto-start-jboss-server.sh $config2 config2.pid 1 uac @@ -577,8 +623,8 @@ sleep 10 ################################## echo "Test UAC REGISTER" echo "================================" -./auto-prepare-example.sh uac-register $config1 -Dsend.on.init=true -./auto-prepare-example.sh uac-register $config2 -Dsend.on.init=false +./auto-prepare-example.sh uac-register $deployments_dir1 -Dsend.on.init=true +./auto-prepare-example.sh uac-register $deployments_dir2 -Dsend.on.init=false ./auto-start-jboss-server.sh $config2 config2.pid 1 uac-register diff --git a/sip-servlets-test-suite/sipp-scenarios/clustering/auto-kill-process-tree.sh b/sip-servlets-test-suite/sipp-scenarios/clustering/auto-kill-process-tree.sh index 528aa29aff..69153c44d4 100755 --- a/sip-servlets-test-suite/sipp-scenarios/clustering/auto-kill-process-tree.sh +++ b/sip-servlets-test-suite/sipp-scenarios/clustering/auto-kill-process-tree.sh @@ -12,10 +12,14 @@ do sleep .4 # give some time for the clean shutdown to reach out echo "Hard Killing script $2 child process $child because parent pid = $pid" kill -9 $child # kill it immediately without wasting more time + kill -9 $pid # kill it immediately without wasting more time + ps -aef | grep jboss export killed="yes" + echo $killed done if [ "no" = $killed ]; then echo "The app server is not dead? We will sleep. We must raise error here, because this server should have been dead." + ps -aef | grep jboss sleep 1 fi diff --git a/sip-servlets-test-suite/sipp-scenarios/clustering/auto-prepare-example.sh b/sip-servlets-test-suite/sipp-scenarios/clustering/auto-prepare-example.sh index 2a7a296f1d..929688781f 100755 --- a/sip-servlets-test-suite/sipp-scenarios/clustering/auto-prepare-example.sh +++ b/sip-servlets-test-suite/sipp-scenarios/clustering/auto-prepare-example.sh @@ -1,100 +1,119 @@ -export config=$2 +#export config=$2 +export deployments_dir=$2 #Reconfigure application server , deploy example - +rm ./apps_to_deploy if [ $# -ne 0 ]; then case $1 in proxy) echo "Distributed example used is proxy" - mvn clean install -f $EXAMPLES_HOME/location-service-distributable/pom.xml - rm -rf $JBOSS_HOME/server/$config/deploy/location-service-distributable-*.war - cp $EXAMPLES_HOME/location-service-distributable/target/location-service-distributable-*.war $JBOSS_HOME/server/$config/deploy - cp $EXAMPLES_HOME/location-service-distributable/distributable-location-service-dar.properties $JBOSS_HOME/server/$config/conf/dars/mobicents-dar.properties - ;; + echo "location-service-distributable" > ./apps_to_deploy + DAR_TO_COPY=$EXAMPLES_HOME/location-service-distributable/distributable-location-service-dar.properties + ;; proxy-early) + # TODO: adapt to eap-6.4 echo "Distributed example used is proxy early failover" - mvn clean install -f $EXAMPLES_HOME/location-service-distributable/pom.xml - rm -rf $JBOSS_HOME/server/$config/deploy/location-service-distributable-*.war - cp $EXAMPLES_HOME/location-service-distributable/target/location-service-distributable-*.war $JBOSS_HOME/server/$config/deploy - cp $EXAMPLES_HOME/location-service-distributable/distributable-location-service-dar.properties $JBOSS_HOME/server/$config/conf/dars/mobicents-dar.properties - cp setup/jboss-5/mss-sip-stack-jboss-early-failover.properties $JBOSS_HOME/server/$config/conf/mss-sip-stack.properties + #MAVEN_PROJECT_TO_BUILD = $EXAMPLES_HOME/location-service-distributable/pom.xml + #rm -rf $JBOSS_HOME/server/$config/deploy/location-service-distributable-*.war + #cp $EXAMPLES_HOME/location-service-distributable/target/location-service-distributable-*.war $JBOSS_HOME/server/$config/deploy + #cp $EXAMPLES_HOME/location-service-distributable/distributable-location-service-dar.properties $JBOSS_HOME/server/$config/conf/dars/mobicents-dar.properties + #cp setup/jboss-5/mss-sip-stack-jboss-early-failover.properties $JBOSS_HOME/server/$config/conf/mss-sip-stack.properties ;; b2bua) echo "Distributed example used is b2bua" - mvn clean install -f $EXAMPLES_HOME/call-forwarding-distributable/pom.xml - rm -rf $JBOSS_HOME/server/$config/deploy/call-forwarding-distributable-*.war - cp $EXAMPLES_HOME/call-forwarding-distributable/target/call-forwarding-distributable-*.war $JBOSS_HOME/server/$config/deploy - cp $EXAMPLES_HOME/call-forwarding-distributable/distributable-call-forwarding-dar.properties $JBOSS_HOME/server/$config/conf/dars/mobicents-dar.properties - ;; + echo "call-forwarding-distributable" > ./apps_to_deploy + DAR_TO_COPY=$EXAMPLES_HOME/call-forwarding-distributable/distributable-call-forwarding-dar.properties + ;; b2bua-early) + # TODO: adapt to eap-6.4 echo "Distributed example used is b2bua early failover" - mvn clean install -f $EXAMPLES_HOME/call-forwarding-distributable/pom.xml - rm -rf $JBOSS_HOME/server/$config/deploy/call-forwarding-distributable-*.war - cp $EXAMPLES_HOME/call-forwarding-distributable/target/call-forwarding-distributable-*.war $JBOSS_HOME/server/$config/deploy - cp $EXAMPLES_HOME/call-forwarding-distributable/distributable-call-forwarding-dar.properties $JBOSS_HOME/server/$config/conf/dars/mobicents-dar.properties - cp setup/jboss-5/mss-sip-stack-jboss-early-failover.properties $JBOSS_HOME/server/$config/conf/mss-sip-stack.properties + #MAVEN_PROJECT_TO_BUILD=$EXAMPLES_HOME/call-forwarding-distributable/pom.xml + #rm -rf $JBOSS_HOME/server/$config/deploy/call-forwarding-distributable-*.war + #cp $EXAMPLES_HOME/call-forwarding-distributable/target/call-forwarding-distributable-*.war $JBOSS_HOME/server/$config/deploy + #cp $EXAMPLES_HOME/call-forwarding-distributable/distributable-call-forwarding-dar.properties $JBOSS_HOME/server/$config/conf/dars/mobicents-dar.properties + #cp setup/jboss-5/mss-sip-stack-jboss-early-failover.properties $JBOSS_HOME/server/$config/conf/mss-sip-stack.properties ;; - custom-b2bua) - echo "Distributed example used is custom b2bua" - mvn clean install -f $EXAMPLES_HOME/custom-call-forwarding-distributable/pom.xml - rm -rf $JBOSS_HOME/server/$config/deploy/custom-call-forwarding-distributable-*.war - cp $EXAMPLES_HOME/custom-call-forwarding-distributable/target/custom-call-forwarding-distributable-*.war $JBOSS_HOME/server/$config/deploy - cp $EXAMPLES_HOME/custom-call-forwarding-distributable/distributable-call-forwarding-dar.properties $JBOSS_HOME/server/$config/conf/dars/mobicents-dar.properties + custom-b2bua*) + echo "Distributed example used is custom b2bua" + echo "custom-call-forwarding-distributable" > ./apps_to_deploy + DAR_TO_COPY=$EXAMPLES_HOME/custom-call-forwarding-distributable/distributable-call-forwarding-dar.properties ;; custom-b2bua-early) + # TODO: adapt to eap-6.4 echo "Distributed example used is custom b2bua early failover" - mvn clean install -f $EXAMPLES_HOME/custom-call-forwarding-distributable/pom.xml - rm -rf $JBOSS_HOME/server/$config/deploy/custom-call-forwarding-distributable-*.war - cp $EXAMPLES_HOME/custom-call-forwarding-distributable/target/custom-call-forwarding-distributable-*.war $JBOSS_HOME/server/$config/deploy - cp $EXAMPLES_HOME/custom-call-forwarding-distributable/distributable-call-forwarding-dar.properties $JBOSS_HOME/server/$config/conf/dars/mobicents-dar.properties - cp setup/jboss-5/mss-sip-stack-jboss-early-failover.properties $JBOSS_HOME/server/$config/conf/mss-sip-stack.properties + #MAVEN_PROJECT_TO_BUILD=$EXAMPLES_HOME/custom-call-forwarding-distributable/pom.xml + #rm -rf $JBOSS_HOME/server/$config/deploy/custom-call-forwarding-distributable-*.war + #cp $EXAMPLES_HOME/custom-call-forwarding-distributable/target/custom-call-forwarding-distributable-*.war $JBOSS_HOME/server/$config/deploy + #cp $EXAMPLES_HOME/custom-call-forwarding-distributable/distributable-call-forwarding-dar.properties $JBOSS_HOME/server/$config/conf/dars/mobicents-dar.properties + #cp setup/jboss-5/mss-sip-stack-jboss-early-failover.properties $JBOSS_HOME/server/$config/conf/mss-sip-stack.properties ;; c2c) + # TODO: adapt to eap-6.4 echo "Distributed example used is Click To call" - mvn clean install -f .$EXAMPLES_HOME/click2call-distributable/pom.xml - rm -rf $JBOSS_HOME/server/$config/deploy/click2call-distributable*.war - cp $EXAMPLES_HOME/click2call-distributable/target/click2call-distributable*.war $JBOSS_HOME/server/$config/deploy/click2call-distributable.war - echo "" > $JBOSS_HOME/server/all/conf/dars/mobicents-dar.properties + #MAVEN_PROJECT_TO_BUILD=$EXAMPLES_HOME/click2call-distributable/pom.xml + #rm -rf $JBOSS_HOME/server/$config/deploy/click2call-distributable*.war + #cp $EXAMPLES_HOME/click2call-distributable/target/click2call-distributable*.war $JBOSS_HOME/server/$config/deploy/click2call-distributable.war + #echo "" > $JBOSS_HOME/server/all/conf/dars/mobicents-dar.properties ;; uas) echo "Distributed example used is uas" - mvn clean install -f $EXAMPLES_HOME/simple-sip-servlet-distributable/pom.xml - rm -rf $JBOSS_HOME/server/$config/deploy/simple-sip-servlet-distributable-*.war - cp $EXAMPLES_HOME/simple-sip-servlet-distributable/target/simple-sip-servlet-distributable-*.war $JBOSS_HOME/server/$config/deploy - cp $EXAMPLES_HOME/simple-sip-servlet-distributable/distributable-simple-dar.properties $JBOSS_HOME/server/$config/conf/dars/mobicents-dar.properties + echo "simple-sip-servlet-distributable" > ./apps_to_deploy + DAR_TO_COPY=$EXAMPLES_HOME/simple-sip-servlet-distributable/distributable-simple-dar.properties ;; uas-passivation) - echo "Distributed example used is uas" - mvn clean install -f $EXAMPLES_HOME/simple-sip-servlet-distributable/pom.xml - rm -rf $JBOSS_HOME/server/$config/deploy/simple-sip-servlet-distributable-*.war - cp $EXAMPLES_HOME/simple-sip-servlet-distributable/target/simple-sip-servlet-distributable-*.war $JBOSS_HOME/server/$config/deploy - cp $EXAMPLES_HOME/simple-sip-servlet-distributable/distributable-simple-dar.properties $JBOSS_HOME/server/$config/conf/dars/mobicents-dar.properties - cp ./setup/jboss-5/war-deployers-jboss-beans-passivation-enabled.xml $JBOSS_HOME/server/$config/deployers/jbossweb.deployer/META-INF/war-deployers-jboss-beans.xml + # TODO: adapt to eap-6.4 + #echo "Distributed example used is uas" + #MAVEN_PROJECT_TO_BUILD=$EXAMPLES_HOME/simple-sip-servlet-distributable/pom.xml + #rm -rf $JBOSS_HOME/server/$config/deploy/simple-sip-servlet-distributable-*.war + #cp $EXAMPLES_HOME/simple-sip-servlet-distributable/target/simple-sip-servlet-distributable-*.war $JBOSS_HOME/server/$config/deploy + #cp $EXAMPLES_HOME/simple-sip-servlet-distributable/distributable-simple-dar.properties $JBOSS_HOME/server/$config/conf/dars/mobicents-dar.properties + #cp ./setup/jboss-5/war-deployers-jboss-beans-passivation-enabled.xml $JBOSS_HOME/server/$config/deployers/jbossweb.deployer/META-INF/war-deployers-jboss-beans.xml ;; uac) - echo "Distributed example used is uas" - mvn clean install $3 -Dsip.method=INVITE -f $EXAMPLES_HOME/shootist-sip-servlet-distributable/pom.xml - rm -rf $JBOSS_HOME/server/$config/deploy/shootist-sip-servlet-distributable-*.war - cp $EXAMPLES_HOME/shootist-sip-servlet-distributable/target/shootist-sip-servlet-distributable-*.war $JBOSS_HOME/server/$config/deploy - cp $EXAMPLES_HOME/shootist-sip-servlet-distributable/distributable-shootist-dar.properties $JBOSS_HOME/server/$config/conf/dars/mobicents-dar.properties + echo "Distributed example used is uac" + MAVEN_CMD_OPTS="$MAVEN_CMD_OPTS -Dsip.method=INVITE" + echo "shootist-sip-servlet-distributable" > ./apps_to_deploy + DAR_TO_COPY=$EXAMPLES_HOME/shootist-sip-servlet-distributable/distributable-shootist-dar.properties ;; uac-register) echo "Distributed example used is uac REGISTER" - mvn clean install $3 -Dsip.method=REGISTER -f $EXAMPLES_HOME/shootist-sip-servlet-distributable/pom.xml - mvn clean install $3 -f $EXAMPLES_HOME/shootist-sip-servlet-distributable/pom.xml - rm -rf $JBOSS_HOME/server/$config/deploy/shootist-sip-servlet-distributable-*.war - cp $EXAMPLES_HOME/shootist-sip-servlet-distributable/target/shootist-sip-servlet-distributable-*.war $JBOSS_HOME/server/$config/deploy - cp $EXAMPLES_HOME/shootist-sip-servlet-distributable/distributable-shootist-dar.properties $JBOSS_HOME/server/$config/conf/dars/mobicents-dar.properties + MAVEN_CMD_OPTS="$MAVEN_CMD_OPTS -Dsip.method=REGISTER" + echo "shootist-sip-servlet-distributable" > ./apps_to_deploy + DAR_TO_COPY=$EXAMPLES_HOME/shootist-sip-servlet-distributable/distributable-shootist-dar.properties ;; proxy-b2bua-ar) echo "Distributed example used is proxy-b2bua-ar" - mvn clean install -f $EXAMPLES_HOME/custom-call-forwarding-distributable/pom.xml - rm -rf $JBOSS_HOME/server/$config/deploy/custom-call-forwarding-distributable-*.war - cp $EXAMPLES_HOME/custom-call-forwarding-distributable/target/custom-call-forwarding-distributable-*.war $JBOSS_HOME/server/$config/deploy - mvn clean install -f $EXAMPLES_HOME/location-service-distributable/pom.xml - rm -rf $JBOSS_HOME/server/$config/deploy/location-service-distributable-*.war - cp $EXAMPLES_HOME/location-service-distributable/target/location-service-distributable-*.war $JBOSS_HOME/server/$config/deploy - cp ar/proxy-b2bua-ar-dar.properties $JBOSS_HOME/server/$config/conf/dars/mobicents-dar.properties - cp setup/jboss-5/mss-sip-stack-jboss.properties $JBOSS_HOME/server/$config/conf/mss-sip-stack.properties + echo "custom-call-forwarding-distributable" > ./apps_to_deploy + echo "location-service-distributable" >> ./apps_to_deploy + DAR_TO_COPY=ar/proxy-b2bua-ar-dar.properties + PROPERTIES_TO_COPY=setup/jboss-7/mss-sip-stack-jboss.properties esac fi + +if [ "x$DAR_TO_COPY" != "x" ]; then + cp $DAR_TO_COPY $JBOSS_HOME/standalone/configuration/dars/mobicents-dar.properties +fi + +if [ "x$PROPERTIES_TO_COPY" != "x" ]; then + cp $PROPERTIES_TO_COPY $JBOSS_HOME/standalone/configuration/mss-sip-stack.properties +fi + +while read CURRENT_APP +do + echo Processing App "$CURRENT_APP" + + mvn -q $MAVEN_CMD_OPTS clean install -f $EXAMPLES_HOME/$CURRENT_APP/pom.xml + if [ "x$3" = "x" ]; then + rm -f $JBOSS_HOME/standalone/$deployments_dir/$CURRENT_APP-* + cp $EXAMPLES_HOME/$CURRENT_APP/target/$CURRENT_APP-*.war $JBOSS_HOME/standalone/$deployments_dir + fi + + if [ "x$3" = "xredeployIfFailed" ]; then + if [ "`echo $JBOSS_HOME/standalone/$deployments_dir/$CURRENT_APP-*.failed`" != "$JBOSS_HOME/standalone/$deployments_dir/$CURRENT_APP-*.failed" ]; then + echo "Previous deployment failed" + rm -f $JBOSS_HOME/standalone/$deployments_dir/$CURRENT_APP-* + cp $EXAMPLES_HOME/$CURRENT_APP/target/$CURRENT_APP-*.war $JBOSS_HOME/standalone/$deployments_dir + fi + fi + +done < "./apps_to_deploy" diff --git a/sip-servlets-test-suite/sipp-scenarios/clustering/auto-run-test.sh b/sip-servlets-test-suite/sipp-scenarios/clustering/auto-run-test.sh index 33ffbd22cd..924a340df7 100755 --- a/sip-servlets-test-suite/sipp-scenarios/clustering/auto-run-test.sh +++ b/sip-servlets-test-suite/sipp-scenarios/clustering/auto-run-test.sh @@ -1,10 +1,12 @@ #Start tests for the current configuration with 80 sec timeout export TERM=vt100 +sudo tcpdump -ni lo -s 0 -w ./$1.pcap & ./clustering-failover-test.sh $1 120 120 $3 #Keep track of the status export CURRENT_CODE=$? echo "$1 $CURRENT_CODE" >> $2 +sudo killall tcpdump ./auto-kill-process-tree.sh `cat config1.pid` $config1 -cp $JBOSS_HOME/server/$config1/log/server.log ./$1-$config1-server.log -cp $JBOSS_HOME/server/$config2/log/server.log ./$1-$config2-server.log +cp $JBOSS_HOME/standalone/log/server-$config1.log ./$1-$config1-server.log +cp $JBOSS_HOME/standalone/log/server-$config2.log ./$1-$config2-server.log diff --git a/sip-servlets-test-suite/sipp-scenarios/clustering/auto-start-jboss-server-jboss-5-0.0.0.0.sh b/sip-servlets-test-suite/sipp-scenarios/clustering/auto-start-jboss-server-jboss-5-0.0.0.0.sh index 7680f70231..0710c2c9ea 100755 --- a/sip-servlets-test-suite/sipp-scenarios/clustering/auto-start-jboss-server-jboss-5-0.0.0.0.sh +++ b/sip-servlets-test-suite/sipp-scenarios/clustering/auto-start-jboss-server-jboss-5-0.0.0.0.sh @@ -1,4 +1,5 @@ $JBOSS_HOME/bin/run.sh -Djboss.server.log.threshold=DEBUG -b 0.0.0.0 -c "$1" "-Djboss.service.binding.set=$3 -Djboss.messaging.ServerPeerID=$4" > "jboss-$1-$5.out"& +#take java pid for later use, instead of standalone export jbosspid=$! echo "Starting app server. The pid for $2 is $jbosspid" echo $jbosspid > $2 diff --git a/sip-servlets-test-suite/sipp-scenarios/clustering/auto-start-jboss-server.sh b/sip-servlets-test-suite/sipp-scenarios/clustering/auto-start-jboss-server.sh index 21fcaa2b59..97c7e0cc54 100755 --- a/sip-servlets-test-suite/sipp-scenarios/clustering/auto-start-jboss-server.sh +++ b/sip-servlets-test-suite/sipp-scenarios/clustering/auto-start-jboss-server.sh @@ -1,10 +1,15 @@ -export JAVA_OPTS="-server -Xms1536m -Xmx1536m -XX:PermSize=128M -XX:MaxPermSize=256M -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode" +#export JAVA_OPTS="-server -Xms1536m -Xmx1536m -XX:PermSize=128M -XX:MaxPermSize=256M -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode" +pwd if [ "0" = $3 ]; then echo "Port configuration is 0. Using default command. No need for hacks." - $JBOSS_HOME/bin/run.sh -Djboss.server.log.threshold=INFO -c $1 > jboss-$1-$4.out 2>&1 & + echo "$JBOSS_HOME/bin/standalone.sh -Djboss.server.log.threshold=INFO -c standalone-sip-ha-$1.xml -Djboss.node.name=$1" +##-Djboss.socket.binding.port-offset=1$30 apparently,starting both nodes with offset makes LB malfuntion + $JBOSS_HOME/bin/standalone.sh -Djboss.server.log.threshold=INFO -c standalone-sip-ha-$1.xml -Djboss.node.name=$1 > jboss-$1-$4.out 2>&1 & else - $JBOSS_HOME/bin/run.sh -Djboss.server.log.threshold=INFO -c $1 -Djboss.service.binding.set=ports-0$3 -Djboss.messaging.ServerPeerID=$3 > jboss-$1-$4.out 2>&1 & + echo "$JBOSS_HOME/bin/standalone.sh -Djboss.server.log.threshold=INFO -c standalone-sip-ha-$1.xml -Djboss.node.name=$1 -Djboss.socket.binding.port-offset=2$30 -Djboss.server.data.dir=$JBOSS_HOME/standalone/data2 -Djboss.server.log.dir=$JBOSS_HOME/standalone/log2 -Djboss.server.temp.dir=$JBOSS_HOME/standalone/tmp2" + $JBOSS_HOME/bin/standalone.sh -Djboss.server.log.threshold=INFO -c standalone-sip-ha-$1.xml -Djboss.node.name=$1 -Djboss.socket.binding.port-offset=2$30 -Djboss.server.data.dir=$JBOSS_HOME/standalone/data2 -Djboss.server.log.dir=$JBOSS_HOME/standalone/log2 -Djboss.server.temp.dir=$JBOSS_HOME/standalone/tmp2 > jboss-$1-$4.out 2>&1 & fi +#take java pid for later use, instead of standalone export jbosspid=$! -echo "Starting app server. The pid for $2 is $jbosspid and other options ports are $3 config is $4" +echo "Starting app server $1. The pid for $2 is $jbosspid and other options ports are $3 config is $4" echo $jbosspid > $2 diff --git a/sip-servlets-test-suite/sipp-scenarios/clustering/auto-startlb.sh b/sip-servlets-test-suite/sipp-scenarios/clustering/auto-startlb.sh index a3521d05a8..2d2668bc96 100755 --- a/sip-servlets-test-suite/sipp-scenarios/clustering/auto-startlb.sh +++ b/sip-servlets-test-suite/sipp-scenarios/clustering/auto-startlb.sh @@ -1,2 +1,5 @@ #!/bin/sh -java -server -Xms1536m -Xmx1536m -XX:PermSize=128M -XX:MaxPermSize=256M -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -Djava.util.logging.config.file=lb-logging.properties -jar /home/vralev/test/mss-1.3-SNAPSHOT-jboss-4.2.3.GA/sip-balancer/sip-balancer-jar-with-dependencies.jar -mobicents-balancer-config=/home/vralev/test/mss-1.3-SNAPSHOT-jboss-4.2.3.GA/sip-balancer/lb-configuration.properties + +java -DlogConfigFile=$JBOSS_HOME/sip-balancer/lb-log4j.xml -Djava.util.logging.config.file=lb-logging.properties.normal -server -Xms1536m -Xmx1536m -XX:PermSize=128M -XX:MaxPermSize=256M -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -jar $JBOSS_HOME/tools/sip-balancer/sip-balancer-jar-with-dependencies.jar -mobicents-balancer-config=$JBOSS_HOME/sip-balancer/lb-configuration.properties + + diff --git a/sip-servlets-test-suite/sipp-scenarios/clustering/clustering-failover-test.sh b/sip-servlets-test-suite/sipp-scenarios/clustering/clustering-failover-test.sh index 5548e432de..cda902d707 100644 --- a/sip-servlets-test-suite/sipp-scenarios/clustering/clustering-failover-test.sh +++ b/sip-servlets-test-suite/sipp-scenarios/clustering/clustering-failover-test.sh @@ -4,127 +4,158 @@ export TEST_IP=127.0.0.1 export MSS_IP=$TEST_IP export LB_IP=$TEST_IP export SIPP_IP=$TEST_IP -#export SIPP_OPTIONS="-t t1" -export ACTIVE_TIMEOUT=$2 -#export BACKGROUNDMETHOD="-bg" -export RATE=$3 -export CALLS=$4 + + +if [ "x$SIPP_TIMEOUT" = "x" ]; then + export ACTIVE_TIMEOUT=$2 +else + export ACTIVE_TIMEOUT=$SIPP_TIMEOUT +fi + +if [ "x$CALL_RATE" = "x" ]; then + export RATE=$3 +else + export RATE=$CALL_RATE +fi +if [ "x$CALLS" = "x" ]; then + export CALLS=$4 +fi echo Using $MSS_IP as the MSS test IP echo Using $LB_IP as the Load Balancer IP echo Using $SIPP_IP as the SIPp IP +if [ "x$RESULTS_DIR" = "x" ]; then + CSV_FILE=$1.csv +else + CSV_FILE=$RESULTS_DIR/$1.csv +fi + +if [ "x$SIPP_OPTIONS" = "x" ]; then + SIPP_OPTIONS="-i $SIPP_IP -trace_err -trace_msg -nd " +fi +if [ "x$SIPP_RECEIVER_OPTIONS" = "x" ]; then + SIPP_RECEIVER_OPTIONS="-p 5090 $SIPP_OPTIONS" +fi +if [ "x$SIPP_SENDER_OPTIONS" = "x" ]; then + SIPP_SENDER_OPTIONS="$SIPP_OPTIONS -p 5050 -rsa $LB_IP:5060 -timeout $ACTIVE_TIMEOUT -timeout_error -trace_stat -stf $CSV_FILE -r $RATE -m $CALLS" +fi + +echo "SIPP_RECEIVER_OPTIONS: $SIPP_RECEIVER_OPTIONS" +echo "SIPP_SENDER_OPTIONS: $SIPP_SENDER_OPTIONS" + + if [ $# -eq 4 ]; then case $1 in proxy) - rm ./proxy/*.log + rm -f ./proxy/*.log echo "Distributed example used is proxy"; - echo""| sipp $MSS_IP:5080 -sf proxy/location-service-receiver.xml -i $SIPP_IP -p 5090 -nd >sipp-uas-log-$1.txt 2>&1 & - sipp $MSS_IP:5080 -s receiver-failover -sf proxy/location-service-sender.xml -trace_err -i $SIPP_IP -p 5050 -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -timeout $ACTIVE_TIMEOUT -timeout_error -nd + echo""| $PRECOMPILED_SIPP $MSS_IP:5080 -sf proxy/location-service-receiver.xml $SIPP_RECEIVER_OPTIONS >sipp-uas-log-$1.txt 2>&1 & + $PRECOMPILED_SIPP $MSS_IP:5080 -s receiver-failover -sf proxy/location-service-sender.xml $SIPP_SENDER_OPTIONS ;; proxy-early) - rm ./proxy/*.log + rm -f ./proxy/*.log echo "Distributed example used is proxy early dialog failover"; - echo""| sipp $MSS_IP:5080 -sf proxy/location-service-receiver-early.xml -i $SIPP_IP -p 5090 -nd >sipp-uas-log-$1.txt 2>&1 & - sipp $MSS_IP:5080 -s receiver-failover -sf proxy/location-service-sender-early.xml -trace_err -i $SIPP_IP -p 5050 -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -timeout $ACTIVE_TIMEOUT -timeout_error -nd + echo""| sipp $MSS_IP:5080 -sf proxy/location-service-receiver-early.xml $SIPP_RECEIVER_OPTIONS >sipp-uas-log-$1.txt 2>&1 & + $PRECOMPILED_SIPP $MSS_IP:5080 -s receiver-failover -sf proxy/location-service-sender-early.xml $SIPP_SENDER_OPTIONS ;; proxy-remote-send-bye) - rm ./proxy/*.log + rm -f ./proxy/*.log echo "Distributed example used is proxy remote send bye"; - echo""| sipp $MSS_IP:5080 -sf proxy/location-service-receiver-sends-bye.xml -i $SIPP_IP -p 5090 -nd >sipp-uas-log-$1.txt 2>&1 & - sipp $MSS_IP:5080 -s receiver-failover -sf proxy/location-service-sender-receives-bye.xml -trace_err -i $SIPP_IP -p 5050 -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -nd -timeout $ACTIVE_TIMEOUT -timeout_error + echo""| $PRECOMPILED_SIPP $MSS_IP:5080 -sf proxy/location-service-receiver-sends-bye.xml $SIPP_RECEIVER_OPTIONS >sipp-uas-log-$1.txt 2>&1 & + $PRECOMPILED_SIPP $MSS_IP:5080 -s receiver-failover -sf proxy/location-service-sender-receives-bye.xml $SIPP_SENDER_OPTIONS ;; proxy-indialog-info) - rm ./proxy/*.log + rm -f ./proxy/*.log echo "Distributed example used is proxy indialog info"; - echo""| sipp $MSS_IP:5080 -sf proxy/location-service-indialog-info-receiver.xml -i $SIPP_IP -p 5090 -nd >sipp-uas-log-$1.txt 2>&1 & - sipp $MSS_IP:5080 -s receiver-failover -sf proxy/location-service-indialog-info-sender.xml -trace_err -i $SIPP_IP -p 5050 -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -nd -timeout $ACTIVE_TIMEOUT -timeout_error + echo""| $PRECOMPILED_SIPP $MSS_IP:5080 -sf proxy/location-service-indialog-info-receiver.xml $SIPP_RECEIVER_OPTIONS >sipp-uas-log-$1.txt 2>&1 & + $PRECOMPILED_SIPP $MSS_IP:5080 -s receiver-failover -sf proxy/location-service-indialog-info-sender.xml $SIPP_SENDER_OPTIONS ;; proxy-termination) - rm ./proxy/*.log + rm -f ./proxy/*.log echo "Distributed example used is proxy termination"; - echo""| sipp $MSS_IP:5080 -sf proxy/location-service-termination-receiver.xml -i $SIPP_IP -p 5090 -nd >sipp-uas-log-$1.txt 2>&1 & - sipp $MSS_IP:5080 -s receiver-failover -sf proxy/location-service-termination-sender.xml -trace_err -i $SIPP_IP -p 5050 -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -nd -timeout $ACTIVE_TIMEOUT -timeout_error + echo""| $PRECOMPILED_SIPP $MSS_IP:5080 -sf proxy/location-service-termination-receiver.xml $SIPP_RECEIVER_OPTIONS >sipp-uas-log-$1.txt 2>&1 & + $PRECOMPILED_SIPP $MSS_IP:5080 -s receiver-failover -sf proxy/location-service-termination-sender.xml $SIPP_SENDER_OPTIONS ;; custom-b2bua) - rm ./b2bua/*.log + rm -f ./b2bua/*.log echo "Distributed example used is custom b2bua"; - echo""| sipp $MSS_IP:5080 -sf b2bua/custom-call-forwarding-receiver.xml -trace_err -trace_msg -nd -i $SIPP_IP -p 5090 >sipp-uas-log-$1.txt 2>&1 & - sipp $MSS_IP:5080 -s receiver -sf b2bua/custom-call-forwarding-sender.xml -trace_err -i $SIPP_IP -p 5050 -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -timeout $ACTIVE_TIMEOUT -timeout_error -nd + echo""| $PRECOMPILED_SIPP $MSS_IP:5080 -sf b2bua/custom-call-forwarding-receiver.xml $SIPP_RECEIVER_OPTIONS >sipp-uas-log-$1.txt 2>&1 & + $PRECOMPILED_SIPP $MSS_IP:5080 -s receiver -sf b2bua/custom-call-forwarding-sender.xml $SIPP_SENDER_OPTIONS ;; custom-b2bua-early) - rm ./b2bua/*.log + rm -f ./b2bua/*.log echo "Distributed example used is custom b2bua early dialog failover"; - echo""| sipp $MSS_IP:5080 -sf b2bua/custom-call-forwarding-receiver-early.xml -i $SIPP_IP -nd -p 5090 >sipp-uas-log-$1.txt 2>&1 & - sipp $MSS_IP:5080 -s receiver -sf b2bua/custom-call-forwarding-sender-early.xml -trace_err -i $SIPP_IP -p 5050 -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -timeout $ACTIVE_TIMEOUT -timeout_error -nd - ;; + echo""| $PRECOMPILED_SIPP $MSS_IP:5080 -sf b2bua/custom-call-forwarding-receiver-early.xml $SIPP_RECEIVER_OPTIONS >sipp-uas-log-$1.txt 2>&1 & + $PRECOMPILED_SIPP $MSS_IP:5080 -s receiver -sf b2bua/custom-call-forwarding-sender-early.xml $SIPP_SENDER_OPTIONS + ;; custom-b2bua-udp-tcp) - rm ./b2bua/*.log + rm -f ./b2bua/*.log echo "Distributed example used is custom b2bua udp tcp"; - echo""| sipp $MSS_IP:5080 -sf b2bua/custom-call-forwarding-receiver.xml -nd -i $SIPP_IP -p 5090 -t t1 >sipp-uas-log-$1.txt 2>&1 & - sipp $MSS_IP:5080 -s receiver-tcp -sf b2bua/custom-call-forwarding-sender.xml -trace_err -i $SIPP_IP -p 5050 -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -timeout $ACTIVE_TIMEOUT -timeout_error -nd + echo""| $PRECOMPILED_SIPP $MSS_IP:5080 -sf b2bua/custom-call-forwarding-receiver.xml -t t1 $SIPP_RECEIVER_OPTIONS >sipp-uas-log-$1.txt 2>&1 & + $PRECOMPILED_SIPP $MSS_IP:5080 -s receiver-tcp -sf b2bua/custom-call-forwarding-sender.xml $SIPP_SENDER_OPTIONS ;; custom-b2bua-tcp-tcp) - rm ./b2bua/*.log + rm -f ./b2bua/*.log echo "Distributed example used is custom b2bua tcp tcp"; - echo""| sipp $MSS_IP:5080 -nd -sf b2bua/custom-call-forwarding-receiver.xml -i $SIPP_IP -p 5090 -t t1 >sipp-uas-log-$1.txt 2>&1 & - sipp $MSS_IP:5080 -s receiver-tcp -nd -sf b2bua/custom-call-forwarding-sender.xml -trace_err -i $SIPP_IP -p 5050 -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -timeout $ACTIVE_TIMEOUT -t t1 -timeout_error + echo""| $PRECOMPILED_SIPP $MSS_IP:5080 -sf b2bua/custom-call-forwarding-receiver.xml -t t1 $SIPP_RECEIVER_OPTIONS >sipp-uas-log-$1.txt 2>&1 & + $PRECOMPILED_SIPP $MSS_IP:5080 -s receiver-tcp -sf b2bua/custom-call-forwarding-sender.xml $SIPP_SENDER_OPTIONS ;; b2bua) - rm ./b2bua/*.log + rm -f ./b2bua/*.log echo "Distributed example used is b2bua"; - echo""| sipp $MSS_IP:5080 -sf b2bua/call-forwarding-receiver.xml -i $SIPP_IP -p 5090 -nd >sipp-uas-log-$1.txt 2>&1 & - sipp $MSS_IP:5080 -s receiver -sf b2bua/call-forwarding-sender.xml -trace_err -i $SIPP_IP -p 5050 -nd -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -timeout $ACTIVE_TIMEOUT $SIPP_OPTIONS -timeout_error + echo""| $PRECOMPILED_SIPP $MSS_IP:5080 -sf b2bua/call-forwarding-receiver.xml $SIPP_RECEIVER_OPTIONS >sipp-uas-log-$1.txt 2>&1 & + $PRECOMPILED_SIPP $MSS_IP:5080 -s receiver -sf b2bua/call-forwarding-sender.xml $SIPP_SENDER_OPTIONS ;; b2bua-info) - rm ./b2bua/*.log + rm -f ./b2bua/*.log echo "Distributed example used is b2bua info"; - echo""| sipp $MSS_IP:5080 -sf b2bua/call-forwarding-receiver-info.xml -i $SIPP_IP -p 5090 -nd >sipp-uas-log-$1.txt 2>&1 & - sipp $MSS_IP:5080 -s receiver -sf b2bua/call-forwarding-sender-info.xml -trace_err -i $SIPP_IP -p 5050 -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -nd -timeout $ACTIVE_TIMEOUT $SIPP_OPTIONS -timeout_error + echo""| sipp $MSS_IP:5080 -sf b2bua/call-forwarding-receiver-info.xml $SIPP_RECEIVER_OPTIONS >sipp-uas-log-$1.txt 2>&1 & + $PRECOMPILED_SIPP $MSS_IP:5080 -s receiver -sf b2bua/call-forwarding-sender-info.xml $SIPP_SENDER_OPTIONS ;; b2bua-early) - rm ./b2bua/*.log + rm -f ./b2bua/*.log echo "Distributed example used is b2bua early dialog failover"; - echo""| sipp $MSS_IP:5080 -sf b2bua/call-forwarding-receiver-early.xml -i $SIPP_IP -p 5090 -nd >sipp-uas-log-$1.txt 2>&1 & - sipp $MSS_IP:5080 -s receiver -sf b2bua/call-forwarding-sender-early.xml -trace_err -nd -i $SIPP_IP -p 5050 -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -timeout $ACTIVE_TIMEOUT $SIPP_OPTIONS -timeout_error + echo""| $PRECOMPILED_SIPP $MSS_IP:5080 -sf b2bua/call-forwarding-receiver-early.xml $SIPP_RECEIVER_OPTIONS >sipp-uas-log-$1.txt 2>&1 & + $PRECOMPILED_SIPP $MSS_IP:5080 -s receiver -sf b2bua/call-forwarding-sender-early.xml $SIPP_SENDER_OPTIONS ;; b2bua-early-linked) - rm ./b2bua/*.log + rm -f ./b2bua/*.log echo "Distributed example used is b2bua early dialog failover with linked requests"; - echo""| sipp $MSS_IP:5080 -sf b2bua/call-forwarding-receiver-early.xml -i $SIPP_IP -p 5090 -nd >sipp-uas-log-$1.txt 2>&1 & - sipp $MSS_IP:5080 -s receiver-linked -sf b2bua/call-forwarding-sender-early.xml -nd -trace_err -i $SIPP_IP -p 5050 -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -timeout $ACTIVE_TIMEOUT $SIPP_OPTIONS -timeout_error + echo""| $PRECOMPILED_SIPP $MSS_IP:5080 -sf b2bua/call-forwarding-receiver-early.xml $SIPP_RECEIVER_OPTIONS >sipp-uas-log-$1.txt 2>&1 & + PRECOMPILED_SIPP $MSS_IP:5080 -s receiver-linked -sf b2bua/call-forwarding-sender-early.xml $SIPP_SENDER_OPTIONS ;; b2bua-early-fwd-ack) - rm ./b2bua/*.log + rm -f ./b2bua/*.log echo "Distributed example used is b2bua early dialog failover"; - echo""| sipp $MSS_IP:5080 -sf b2bua/call-forwarding-receiver-early.xml -i $SIPP_IP -p 5090 -nd >sipp-uas-log-$1.txt 2>&1 & - sipp $MSS_IP:5080 -s receiver-fwd-ack -sf b2bua/call-forwarding-sender-early.xml -trace_err -i $SIPP_IP -p 5050 -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -nd -timeout $ACTIVE_TIMEOUT $SIPP_OPTIONS -timeout_error + echo""| $PRECOMPILED_SIPP $MSS_IP:5080 -sf b2bua/call-forwarding-receiver-early.xml $SIPP_RECEIVER_OPTIONS >sipp-uas-log-$1.txt 2>&1 & + $PRECOMPILED_SIPP $MSS_IP:5080 -s receiver-fwd-ack -sf b2bua/call-forwarding-sender-early.xml $SIPP_SENDER_OPTIONS ;; b2bua-remote-send-bye) - rm ./b2bua/*.log + rm -f ./b2bua/*.log echo "Distributed example used is b2bua-remote-send-bye"; - echo""| sipp $MSS_IP:5080 -sf b2bua/call-forwarding-receiver-sends-bye.xml -i $SIPP_IP -p 5090 -nd >sipp-uas-log-$1.txt 2>&1 & - sipp $MSS_IP:5080 -s receiver -sf b2bua/call-forwarding-sender-receives-bye.xml -trace_err -i $SIPP_IP -p 5050 -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -nd -timeout $ACTIVE_TIMEOUT -timeout_error + echo""| $PRECOMPILED_SIPP $MSS_IP:5080 -sf b2bua/call-forwarding-receiver-sends-bye.xml $SIPP_RECEIVER_OPTIONS >sipp-uas-log-$1.txt 2>&1 & + $PRECOMPILED_SIPP $MSS_IP:5080 -s receiver -sf b2bua/call-forwarding-sender-receives-bye.xml $SIPP_SENDER_OPTIONS ;; b2bua-remote-send-bye-no-ring) - rm ./b2bua/*.log + rm -f ./b2bua/*.log echo "Distributed example used is b2bua-remote-send-bye-no-ring"; - echo""| sipp $MSS_IP:5080 -sf b2bua/call-forwarding-receiver-sends-bye-no-ring.xml -i $SIPP_IP -p 5090 -nd >sipp-uas-log-$1.txt 2>&1 & - sipp $MSS_IP:5080 -s receiver -sf b2bua/call-forwarding-sender-receives-bye.xml -trace_err -i $SIPP_IP -p 5050 -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -nd -timeout $ACTIVE_TIMEOUT -timeout_error + echo""| $PRECOMPILED_SIPP $MSS_IP:5080 -sf b2bua/call-forwarding-receiver-sends-bye-no-ring.xml $SIPP_RECEIVER_OPTIONS >sipp-uas-log-$1.txt 2>&1 & + $PRECOMPILED_SIPP $MSS_IP:5080 -s receiver -sf b2bua/call-forwarding-sender-receives-bye.xml $SIPP_SENDER_OPTIONS ;; uac) - rm ./uac/*.log + rm -f ./uac/*.log echo "Distributed example used is uac"; - sipp $MSS_IP:5080 -sf uac/receiver.xml -i $SIPP_IP -p 5090 -trace_msg -timeout $ACTIVE_TIMEOUT -timeout_error -nd + $PRECOMPILED_SIPP $MSS_IP:5080 -sf uac/receiver.xml -p 5090 ;; uac-register) - rm ./uac/*.log + rm -f ./uac/*.log echo "Distributed example used is uac register"; - sipp $MSS_IP:5080 -sf uac/register-receiver.xml -i $SIPP_IP -p 5090 -trace_msg -timeout $ACTIVE_TIMEOUT -timeout_error -nd + $PRECOMPILED_SIPP $MSS_IP:5080 -sf uac/register-receiver.xml -p 5090 ;; c2c) - rm ./converged-click2call/*.log + rm -f ./converged-click2call/*.log echo "Distributed example used is 3pcc"; echo "Now, quickly navigate a browser to this URL: http://"$MSS_IP"/click2call-distributable/call?to=sip:to@"$SIPP_IP":5090&from=sip:from@"$SIPP_IP":5091"; echo "Then, wait a few secs for the dialog to be established and kill the primary server. The secondary server will take over."; @@ -133,89 +164,89 @@ if [ $# -eq 4 ]; then echo "There are sample config files to run apache and mod_jkon localhost in the converged-click2call directory."; echo "If you need more info about how to configure mod_jk see http://www.jboss.org/community/docs/DOC-12525"; killall sipp - sipp $MSS_IP:5080 -sf converged-click2call/receiver.xml -i $SIPP_IP -p 5090 -trace_msg -timeout 100 -bg - sipp $MSS_IP:5080 -sf converged-click2call/receiver-sendbye.xml -i $SIPP_IP -p 5091 -trace_msg -timeout 100 -bg + $PRECOMPILED_SIPP $MSS_IP:5080 -sf converged-click2call/receiver.xml -timeout 100 -bg + $PRECOMPILED_SIPP $MSS_IP:5080 -sf converged-click2call/receiver-sendbye.xml -p 5091 -timeout 100 -bg sleep 1 #wget "http://$MSS_IP/click2call-distributable/call?to=sip:to@$SIPP_IP:5090&from=sip:from@$SIPP_IP:5091" ;; uas-reinvite) - rm ./uas/*.log + rm -f ./uas/*.log echo "Distributed example used is uas reinvite"; - sipp $MSS_IP:5080 -s reinvite -sf uas/clustering-reinvite-uac.xml -trace_err -i $SIPP_IP -p 5050 -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -nd -timeout $ACTIVE_TIMEOUT -timeout_error + $PRECOMPILED_SIPP $MSS_IP:5080 -s reinvite -sf uas/clustering-reinvite-uac.xml $SIPP_SENDER_OPTIONS ;; uas-no-attributes) - rm ./uas/*.log + rm -f ./uas/*.log echo "Distributed example used is uas no attributes"; - sipp $MSS_IP:5080 -s NoAttributes -sf uas/clustering-uac-no-attrs.xml -trace_err -i $SIPP_IP -p 5050 -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -nd -timeout $ACTIVE_TIMEOUT -timeout_error + $PRECOMPILED_SIPP $MSS_IP:5080 -s NoAttributes -sf uas/clustering-uac-no-attrs.xml $SIPP_SENDER_OPTIONS ;; uas-remove-attributes) - rm ./uas/*.log + rm -f ./uas/*.log echo "Distributed example used is uas remove attributes"; - sipp $MSS_IP:5080 -s reinvite-RemoveAttributes -sf uas/clustering-reinvite-uac.xml -trace_err -i $SIPP_IP -p 5050 -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -nd -timeout $ACTIVE_TIMEOUT -timeout_error + $PRECOMPILED_SIPP $MSS_IP:5080 -s reinvite-RemoveAttributes -sf uas/clustering-reinvite-uac.xml $SIPP_SENDER_OPTIONS ;; uas-reinvite-passivation) - rm ./uas/*.log + rm -f ./uas/*.log echo "Distributed example used is uas reinvite passivation make sure to make at least 2 calls to the same node so that it gets activated"; - sipp $MSS_IP:5080 -s reinvite -sf uas/clustering-reinvite-uac-passivation.xml -trace_err -i $SIPP_IP -p 5050 -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -nd -timeout $ACTIVE_TIMEOUT -timeout_error + $PRECOMPILED_SIPP $MSS_IP:5080 -s reinvite -sf uas/clustering-reinvite-uac-passivation.xml $SIPP_SENDER_OPTIONS ;; uas-timer) - rm ./uas/*.log + rm -f ./uas/*.log echo "Distributed example used is uas timer"; - sipp $MSS_IP:5080 -s yousendbye -sf uas/clustering-uac-timer.xml -trace_err -i $SIPP_IP -p 5050 -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -nd -timeout $ACTIVE_TIMEOUT -timeout_error + $PRECOMPILED_SIPP $MSS_IP:5080 -s yousendbye -sf uas/clustering-uac-timer.xml $SIPP_SENDER_OPTIONS ;; uas-injected-timer) - rm ./uas/*.log + rm -f ./uas/*.log echo "Distributed example used is uas injected timer"; - sipp $MSS_IP:5080 -s yousendbye-injectedtimer -sf uas/clustering-uac-timer.xml -trace_err -i $SIPP_IP -p 5050 -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -nd -timeout $ACTIVE_TIMEOUT -timeout_error + $PRECOMPILED_SIPP $MSS_IP:5080 -s yousendbye-injectedtimer -sf uas/clustering-uac-timer.xml $SIPP_SENDER_OPTIONS ;; uas-cancel-timer) - rm ./uas/*.log + rm -f ./uas/*.log echo "Distributed example used is uas cancel timer"; - sipp $MSS_IP:5080 -s cancelservlettimer -sf uas/clustering-uac.xml -trace_err -i $SIPP_IP -p 5050 -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -nd -timeout $ACTIVE_TIMEOUT -timeout_error + $PRECOMPILED_SIPP $MSS_IP:5080 -s cancelservlettimer -sf uas/clustering-uac.xml $SIPP_SENDER_OPTIONS ;; uas-timer-passivation) - rm ./uas/*.log + rm -f ./uas/*.log echo "Distributed example used is uas timer passivation"; - sipp $MSS_IP:5080 -s yousendbye -sf uas/clustering-uac-timer-passivation.xml -trace_err -i $SIPP_IP -p 5050 -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -nd -timeout $ACTIVE_TIMEOUT -timeout_error + $PRECOMPILED_SIPP $MSS_IP:5080 -s yousendbye -sf uas/clustering-uac-timer-passivation.xml $SIPP_SENDER_OPTIONS ;; uas-sas-timer) # kill first node after the ACK - rm ./uas/*.log + rm -f ./uas/*.log echo "Distributed example used is uas sas timer"; - sipp $MSS_IP:5080 -s sastimersendbye -sf uas/clustering-uac-timer.xml -trace_err -i $SIPP_IP -p 5050 -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -nd -timeout $ACTIVE_TIMEOUT -timeout_error + $PRECOMPILED_SIPP $MSS_IP:5080 -s sastimersendbye -sf uas/clustering-uac-timer.xml $SIPP_SENDER_OPTIONS ;; uas-sas-timer-passivation) # kill first node after the ACK - rm ./uas/*.log + rm -f ./uas/*.log echo "Distributed example used is uas sas timer passivation"; - sipp $MSS_IP:5080 -s sastimersendbye -sf uas/clustering-uac-timer-passivation.xml -trace_err -i $SIPP_IP -p 5050 -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -nd -timeout $ACTIVE_TIMEOUT -timeout_error + $PRECOMPILED_SIPP $MSS_IP:5080 -s sastimersendbye -sf uas/clustering-uac-timer-passivation.xml $SIPP_SENDER_OPTIONS ;; uas-reinvite-sas-timer) # kill first node after the first ACK - rm ./uas/*.log + rm -f ./uas/*.log echo "Distributed example used is uas reinvite sas timer"; - sipp $MSS_IP:5080 -s sastimersendbye -sf uas/clustering-reinvite-sas-timer.xml -trace_err -i $SIPP_IP -p 5050 -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -nd -timeout $ACTIVE_TIMEOUT -timeout_error + $PRECOMPILED_SIPP $MSS_IP:5080 -s sastimersendbye -sf uas/clustering-reinvite-sas-timer.xml $SIPP_SENDER_OPTIONS ;; uas-activation) - rm ./uas/*.log + rm -f ./uas/*.log echo "Distributed example used is uas activation"; - sipp $MSS_IP:5080 -s isendbye-test-activation -sf uas/clustering-uac.xml -trace_err -i $SIPP_IP -p 5050 -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -nd -timeout $ACTIVE_TIMEOUT -timeout_error + $PRECOMPILED_SIPP $MSS_IP:5080 -s isendbye-test-activation -sf uas/clustering-uac.xml $SIPP_SENDER_OPTIONS ;; uas) - rm ./uas/*.log + rm -f ./uas/*.log echo "Distributed example used is uas"; - sipp $MSS_IP:5080 -s isendbye -sf uas/clustering-uac.xml -trace_err -i $SIPP_IP -p 5050 -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -nd -timeout $ACTIVE_TIMEOUT -timeout_error + $PRECOMPILED_SIPP $MSS_IP:5080 -s isendbye -sf uas/clustering-uac.xml $SIPP_SENDER_OPTIONS ;; uas-0.0.0.0) - rm ./uas/*.log + rm -f ./uas/*.log echo "Distributed example used is uas-0.0.0.0"; - sipp $MSS_IP:5080 -s isendbye -sf uas/clustering-uac.xml -trace_err -i $SIPP_IP -p 5050 -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -nd -timeout $ACTIVE_TIMEOUT -timeout_error + $PRECOMPILED_SIPP $MSS_IP:5080 -s isendbye -sf uas/clustering-uac.xml $SIPP_SENDER_OPTIONS ;; proxy-b2bua-ar) - rm ./ar/*.log + rm -f ./ar/*.log echo "Distributed example used is proxy-b2bua-ar"; - echo""| sipp $MSS_IP:5060 -sf ar/proxy-b2bua-ar-receiver.xml -i $SIPP_IP -p 5090 -nd >sipp-uas-log-$1.txt 2>&1 & - sipp $MSS_IP:5060 -s receiver-failover -sf ar/proxy-b2bua-ar-sender.xml -trace_err -i $SIPP_IP -p 5050 -r $RATE -m $CALLS -rsa $LB_IP:5060 -trace_msg -timeout $ACTIVE_TIMEOUT -timeout_error + echo""| $PRECOMPILED_SIPP $MSS_IP:5060 -sf ar/proxy-b2bua-ar-receiver.xml $SIPP_RECEIVER_OPTIONS >sipp-uas-log-$1.txt 2>&1 & + $PRECOMPILED_SIPP $MSS_IP:5060 -s receiver-failover -sf ar/proxy-b2bua-ar-sender.xml $SIPP_SENDER_OPTIONS ;; esac else diff --git a/sip-servlets-test-suite/sipp-scenarios/clustering/clustering-perf-test.sh b/sip-servlets-test-suite/sipp-scenarios/clustering/clustering-perf-test.sh index 5d951e0717..64f9d7329a 100644 --- a/sip-servlets-test-suite/sipp-scenarios/clustering/clustering-perf-test.sh +++ b/sip-servlets-test-suite/sipp-scenarios/clustering/clustering-perf-test.sh @@ -15,25 +15,25 @@ if [ $# -ne 0 ]; then proxy) rm ./proxy/*.log echo "Distributed example used is proxy"; - ./sipp $MSS_IP:5080 -sf proxy/location-service-receiver.xml -i $SIPP_IP -p 5090 -bg - ./sipp $MSS_IP:5080 -s receiver-failover -sf proxy/location-service-sender.xml -trace_err -i $SIPP_IP -p 5050 -r 10 -m 100000 -rsa $LB_IP:5060 -nd + $PRECOMPILED_SIPP $MSS_IP:5080 -sf proxy/location-service-receiver.xml -i $SIPP_IP -p 5090 -bg + $PRECOMPILED_SIPP $MSS_IP:5080 -s receiver-failover -sf proxy/location-service-sender.xml -trace_err -i $SIPP_IP -p 5050 -r 10 -m 100000 -rsa $LB_IP:5060 -nd ;; b2bua) rm ./b2bua/*.log echo "Distributed example used is b2bua"; - ./sipp $MSS_IP:5080 -sf b2bua/call-forwarding-receiver.xml -i $SIPP_IP -p 5090 -bg - ./sipp $MSS_IP:5080 -s receiver -sf b2bua/call-forwarding-sender.xml -trace_err -i $SIPP_IP -p 5050 -r 10 -m 100000 -rsa $LB_IP:5060 -nd + $PRECOMPILED_SIPP $MSS_IP:5080 -sf b2bua/call-forwarding-receiver.xml -i $SIPP_IP -p 5090 -bg + $PRECOMPILED_SIPP $MSS_IP:5080 -s receiver -sf b2bua/call-forwarding-sender.xml -trace_err -i $SIPP_IP -p 5050 -r 10 -m 100000 -rsa $LB_IP:5060 -nd ;; b2bua-remote-send-bye) rm ./b2bua/*.log echo "Distributed example used is b2bua-remote-send-bye"; - ./sipp $MSS_IP:5080 -sf b2bua/call-forwarding-receiver-sends-bye.xml -i $SIPP_IP -p 5090 -bg -trace_msg -timeout 30 - ./sipp $MSS_IP:5080 -s receiver -sf b2bua/call-forwarding-sender-receives-bye.xml -trace_err -i $SIPP_IP -p 5050 -r 1 -m 1 -rsa $LB_IP:5060 -nd + $PRECOMPILED_SIPP $MSS_IP:5080 -sf b2bua/call-forwarding-receiver-sends-bye.xml -i $SIPP_IP -p 5090 -bg -trace_msg -timeout 30 + $PRECOMPILED_SIPP $MSS_IP:5080 -s receiver -sf b2bua/call-forwarding-sender-receives-bye.xml -trace_err -i $SIPP_IP -p 5050 -r 1 -m 1 -rsa $LB_IP:5060 -nd ;; uac) rm ./uac/*.log echo "Distributed example used is uac"; - ./sipp $MSS_IP:5080 -sf uac/receiver.xml -i $SIPP_IP -p 5090 -timeout 30 + $PRECOMPILED_SIPP $MSS_IP:5080 -sf uac/receiver.xml -i $SIPP_IP -p 5090 -timeout 30 ;; c2c) rm ./converged-click2call/*.log @@ -45,26 +45,26 @@ if [ $# -ne 0 ]; then echo "There are sample config files to run apache and mod_jkon localhost in the converged-click2call directory."; echo "If you need more info about how to configure mod_jk see http://www.jboss.org/community/docs/DOC-12525"; killall sipp - ./sipp $MSS_IP:5080 -sf converged-click2call/receiver.xml -i $SIPP_IP -p 5090 -timeout 100 -bg - ./sipp $MSS_IP:5080 -sf converged-click2call/receiver-sendbye.xml -i $SIPP_IP -p 5091 -timeout 100 -bg + $PRECOMPILED_SIPP $MSS_IP:5080 -sf converged-click2call/receiver.xml -i $SIPP_IP -p 5090 -timeout 100 -bg + $PRECOMPILED_SIPP $MSS_IP:5080 -sf converged-click2call/receiver-sendbye.xml -i $SIPP_IP -p 5091 -timeout 100 -bg sleep 1 #wget "http://localhost/click2call-distributable/call?to=sip:to@$TEST_IP:5090&from=sip:from@$TEST_IP:5091" ;; uas-reinvite) rm ./uas/*.log echo "Distributed example used is uas"; - ./sipp $MSS_IP:5080 -s isendbye -sf uas/clustering-reinvite-uac.xml -trace_err -i $SIPP_IP -p 5050 -r 1 -m 1 -rsa $LB_IP:5060 -nd + $PRECOMPILED_SIPP $MSS_IP:5080 -s isendbye -sf uas/clustering-reinvite-uac.xml -trace_err -i $SIPP_IP -p 5050 -r 1 -m 1 -rsa $LB_IP:5060 -nd ;; uas-timer) rm ./uas/*.log echo "Distributed example used is uas"; - ./sipp $MSS_IP:5080 -s yousendbye -sf uas/clustering-uac-timer.xml -trace_err -i $SIPP_IP -p 5050 -r 1 -m 1 -rsa $LB_IP:5060 -nd + $PRECOMPILED_SIPP $MSS_IP:5080 -s yousendbye -sf uas/clustering-uac-timer.xml -trace_err -i $SIPP_IP -p 5050 -r 1 -m 1 -rsa $LB_IP:5060 -nd ;; *) rm ./uas/*.log echo "Distributed example used is uas"; #./sipp $TEST_IP:5080 -s isendbye -sf uas/clustering-uac.xml -trace_err -trace_msg -i $TEST_IP -p 5055 -r 1 -m 100000 -rsa $TEST_IP:5060 -nd - ./sipp $MSS_IP:5080 -s isendbye -sf uas/clustering-uac.xml -i $SIPP_IP -p 5055 -r 10 -m 100000 -rsa $LB_IP:5060 -nd + $PRECOMPILED_SIPP $MSS_IP:5080 -s isendbye -sf uas/clustering-uac.xml -i $SIPP_IP -p 5055 -r 10 -m 100000 -rsa $LB_IP:5060 -nd ;; esac fi diff --git a/sip-servlets-test-suite/sipp-scenarios/clustering/killserver.sh b/sip-servlets-test-suite/sipp-scenarios/clustering/killserver.sh index 0b2c61a948..c2e431f13c 100755 --- a/sip-servlets-test-suite/sipp-scenarios/clustering/killserver.sh +++ b/sip-servlets-test-suite/sipp-scenarios/clustering/killserver.sh @@ -1,4 +1,5 @@ pid=`cat $1` +echo "About to kill pid to cause failover:$pid" sleep $2 sleep 2 ./auto-kill-process-tree.sh $pid $1 diff --git a/sip-servlets-test-suite/sipp-scenarios/clustering/lb-configuration.properties b/sip-servlets-test-suite/sipp-scenarios/clustering/lb-configuration.properties index 0f4cae5f8d..8230e6aefc 100644 --- a/sip-servlets-test-suite/sipp-scenarios/clustering/lb-configuration.properties +++ b/sip-servlets-test-suite/sipp-scenarios/clustering/lb-configuration.properties @@ -1,77 +1,101 @@ -# Mobicents Load Balancer Settings +# TelScale Load Balancer Settings # For an overview of the Mobicents Load Balancer visit http://docs.google.com/present/view?id=dc5jp5vx_89cxdvtxcm +# The Load balancer will listen for both TCP and UDP connections -# The binding address of the load balancer +# The binding address of the load balancer. This also specifies the +# default value for both internalHost and externalHost if not specified separately. host=127.0.0.1 +# If set, Proxy will use this address to patch responses from Restcomm so subsequent request will reach the proxy +#public-ip= + +# The binding address of the load balancer where clients should connect (if the host property is not specified) +#externalHost= # The RMI port used for heartbeat signals rmiRegistryPort=2000 +# The port to be used used for the Remote Object +rmiRemoteObjectPort=2001 + +# The SIP ports used where client should connect +externalUdpPort=5060 +#externalTcpPort=5060 +#externalTlsPort=5061 +#externalWsPort=5062 +#externalWssPort=5063 + +# The binding address of the load balancer where SIP application servers should connect (if the host property is not specified) +#internalHost=127.0.0.1 -# The SIP port used where client should connect -externalPort=5060 - # The SIP port from where servers will receive messages # delete if you want to use only one port for both inbound and outbound) -# if you like to activate the integrated HTTP load balancer, this is the entry point -internalPort=5065 +internalUdpPort=5065 +#internalTcpPort=5066 +#internalTlsPort=5067 +#internalWsPort=5068 +#internalWssPort=5069 # The HTTP port for HTTP forwarding httpPort=2080 +# The HTTPS port for HTTPS forwarding +httpsPort=2081 #If no nodes are active the LB can redirect the traffic to the unavailableHost specified in this property, #otherwise, it will return 503 Service Unavailable #unavailableHost=google.com -#Specify UDP or TCP (for now both must be the same) -internalTransport=UDP -externalTransport=UDP - -# If you are using IP load balancer, put the IP address and port here +# If you are using IP load balancer, put the IP address and ports here #externalIpLoadBalancerAddress=127.0.0.1 -#externalIpLoadBalancerPort=111 +#externalIpLoadBalancerUdpPort=111 +#externalIpLoadBalancerTcpPort=112 +#externalIpLoadBalancerTlsPort=113 +#externalIpLoadBalancerWsPort=114 +#externalIpLoadBalancerWssPort=115 # Requests initited from the App Servers can route to this address (if you are using 2 IP load balancers for bidirectional SIP LB) #internalIpLoadBalancerAddress=127.0.0.1 -#internalIpLoadBalancerPort=111 +#internalIpLoadBalancerUdpPort=111 +#internalIpLoadBalancerTcpPort=112 +#internalIpLoadBalancerTlsPort=113 +#internalIpLoadBalancerWsPort=114 +#internalIpLoadBalancerWssPort=115 + +# The addresses in the SIP LB Via headers can be either the real addresses or those specified in the external and internal IP LB addresses + +#useIpLoadBalancerAddressInViaHeaders=false # Designate extra IP addresses as serer nodes #extraServerNodes=222.221.21.12:21,45.6.6.7:9003,33.5.6.7,33.9.9.2 +#Performance Testing mode. Special mode for performance testing of LB server with sipp clients. Set this to true and the extra server nodes will be +#registered as active nodes and will receive traffic from LB. Also these node will never expire. +performanceTestingMode=false + # Call-ID affinity algortihm settings. This algorithm is the default. No need to uncomment it. #algorithmClass=org.mobicents.tools.sip.balancer.CallIDAffinityBalancerAlgorithm # This property specifies how much time to keep an association before being evitcted. # It is needed to avoid memory leaks on dead calls. The time is in seconds. #callIdAffinityMaxTimeInCache=500 +#The following attribute specified the policy after failover. If set to true all calls from the failed node +#will go to a new healthy node (all calls to the same node). If set to false the calls will go to random new nodes. +#callIdAffinityGroupFailover=false -# Uncomment to enable the consistent hash based on Call-ID algorithm. -#algorithmClass=org.mobicents.tools.sip.balancer.HeaderConsistentHashBalancerAlgorithm -# This property is not required, it defaults to Call-ID if not set, cna be "from.user" or "to.user" when you want the SIP URI username -#sipHeaderAffinityKey=Call-ID -#specify the GET HTTP parameter to be used as hash key -#httpAffinityKey=appsession - -# Uncomment to enable the persistent consistent hash based on Call-ID algorithm. -#algorithmClass=org.mobicents.tools.sip.balancer.PersistentConsistentHashBalancerAlgorithm -# This property is not required, it defaults to Call-ID if not set -#sipHeaderAffinityKey=Call-ID -#specify the GET HTTP parameter to be used as hash key -#httpAffinityKey=appsession - -#This is the JBoss Cache 3.1 configuration file (with jgroups), if not specified it will use default -#persistentConsistentHashCacheConfiguration=/home/config.xml - -# Call-ID affinity algortihm settings. This algorithm is the default. No need to uncomment it. -#algorithmClass=org.mobicents.tools.sip.balancer.CallIDAffinityBalancerAlgorithm +# Uncomment to enable the UserBasedAlgorithm algorithm. +#algorithmClass=org.mobicents.tools.sip.balancer.UserBasedAlgorithm +# This property is required +#sipHeaderAffinityKey=To # This property specifies how much time to keep an association before being evitcted. # It is needed to avoid memory leaks on dead calls. The time is in seconds. -#callIdAffinityMaxTimeInCache=500 +#userAffinityMaxTimeInCache=500 +#The following attribute specified the policy after failover. If set to true all calls from the failed node +#will go to a new healthy node (all calls to the same node). If set to false the calls will go to random new nodes. +#userAffinityGroupFailover=false # Uncomment to enable the consistent hash based on Call-ID algorithm. #algorithmClass=org.mobicents.tools.sip.balancer.HeaderConsistentHashBalancerAlgorithm -# This property is not required, it defaults to Call-ID if not set, cna be "from.user" or "to.user" when you want the SIP URI username +# This property is not required, it defaults to Call-ID if not set, can be "From" or "To" when you want the SIP URI username #sipHeaderAffinityKey=Call-ID #specify the GET HTTP parameter to be used as hash key #httpAffinityKey=appsession - + # Uncomment to enable the persistent consistent hash based on Call-ID algorithm. #algorithmClass=org.mobicents.tools.sip.balancer.PersistentConsistentHashBalancerAlgorithm # This property is not required, it defaults to Call-ID if not set @@ -82,28 +106,85 @@ externalTransport=UDP #This is the JBoss Cache 3.1 configuration file (with jgroups), if not specified it will use default #persistentConsistentHashCacheConfiguration=/home/config.xml +#If a node doesnt check in within that time (in ms), it is considered dead. +nodeTimeout=8400 +#The consistency of the above condition is checked every heartbeatInterval milliseconds +heartbeatInterval=150 +#Should load balancer send response 100 TRYING message, after INVITE request +isSendTrying=true + #JSIP stack configuration..... -javax.sip.STACK_NAME = SipBalancerForwarder -javax.sip.AUTOMATIC_DIALOG_SUPPORT = off +javax.sip.STACK_NAME=SipBalancerForwarder +javax.sip.AUTOMATIC_DIALOG_SUPPORT=off # You need 16 for logging traces. 32 for debug + traces. # Your code will limp at 32 but it is best for debugging. -# LOG4J means the level will be configurable from the LOG4J config file -gov.nist.javax.sip.TRACE_LEVEL = LOG4J - +# LOG4J means the level will be configurable from the JOG4J config file +gov.nist.javax.sip.TRACE_LEVEL=LOG4J #Specify if message contents should be logged. -gov.nist.javax.sip.LOG_MESSAGE_CONTENT=true - -gov.nist.javax.sip.DEBUG_LOG = logs/sipbalancerforwarderdebug.txt -gov.nist.javax.sip.SERVER_LOG = logs/sipbalancerforwarder.xml -gov.nist.javax.sip.THREAD_POOL_SIZE = 64 -gov.nist.javax.sip.REENTRANT_LISTENER = true +gov.nist.javax.sip.LOG_MESSAGE_CONTENT=false +gov.nist.javax.sip.DEBUG_LOG=logs/sipbalancerforwarderdebug.txt +gov.nist.javax.sip.SERVER_LOG=logs/sipbalancerforwarder.xml +gov.nist.javax.sip.THREAD_POOL_SIZE=64 +gov.nist.javax.sip.REENTRANT_LISTENER=true gov.nist.javax.sip.AGGRESSIVE_CLEANUP=true +gov.nist.javax.sip.RECEIVE_UDP_BUFFER_SIZE=65536 +gov.nist.javax.sip.SEND_UDP_BUFFER_SIZE=65536 +# prevent DOS attacks +gov.nist.javax.sip.MAX_LISTENER_RESPONSE_TIME=120 +gov.nist.javax.sip.MAX_MESSAGE_SIZE=10000 +gov.nist.javax.sip.AGGRESSIVE_CLEANUP=true +gov.nist.javax.sip.MAX_FORK_TIME_SECONDS=0 +gov.nist.javax.sip.AUTOMATIC_DIALOG_ERROR_HANDLING=false gov.nist.javax.sip.MESSAGE_PROCESSOR_FACTORY=gov.nist.javax.sip.stack.NioMessageProcessorFactory -#If a node doesnt check in within that time (in ms), it is considered dead. -nodeTimeout=8400 -#The consistency of the above condition is checked every heartbeatInterval milliseconds -heartbeatInterval=150 +#SMPP Load Balancer Settings +smppName=SMPP Load Balancer +# The address of the load balancer +smppHost=127.0.0.1 +# The port of the load balancer +smppPort=2776 +# The port of the load balancer for SSL protocol +#smppSslPort=2876 +# it is recommended that at any time there were no more than +#10 (ten) SMPP messages are outstanding +maxConnectionSize=10 +# Is NIO enabled +nonBlockingSocketsEnabled=true +# Is default session counters enabled +defaultSessionCountersEnabled=true +# Response timeout for load balancer in milliseconds +timeoutResponse=10000 +# Session initialization timer +timeoutConnection=1000 +# Enquire Link Timer +timeoutEnquire=50000 +# Time between reconnection +reconnectPeriod=1000 +# Connection check timer in load balancer +timeoutConnectionCheckClientSide=1000 +# Connection check server side timer +timeoutConnectionCheckServerSide=1000 -# VALVE -gov.nist.javax.sip.gov.nist.javax.sip.SIP_MESSAGE_VALVE=org.mobicents.tools.sip.balancer.SIPBalancerValveProcessor \ No newline at end of file +# SSL configuration +#points to the keystore file we generated before +#javax.net.ssl.keyStore=/opt/loadbalancer/config/keystore +#provides the password we used when we generated the keystore +#javax.net.ssl.keyStorePassword=123456 +#points to the truststore file we generated before +#javax.net.ssl.trustStore=/opt/loadbalancer/config/keystore +#provides the password we used when we generated the truststore +#javax.net.ssl.trustStorePassword=123456 +#this is important because sipp supports only TLSv1 and so we need to restrict the protocols only to that +gov.nist.javax.sip.TLS_CLIENT_PROTOCOLS=TLSv1 +#can be : Enabled, Disabled, DisabledAll, Want +#if Enabled, used to request and require client certificate authentication: the connection will terminate if no suitable client certificate is presented +#if Want, used to request client certificate authentication, but keep the connection if no authentication is provided +#if Disabled or DisabledAll does not use authentication +gov.nist.javax.sip.TLS_CLIENT_AUTH_TYPE=Disabled +#ssl will provide some extra debugging information for the SSL if uncomment it +#javax.net.debug=ssl +#Terminate all secure traffic coming from the outside world HTTPs, SIP TLS, WSS will be terminated at LB side +#terminateTLSTraffic=true +#Statistic +#port for statistic +statisticPort=2006 diff --git a/sip-servlets-test-suite/sipp-scenarios/clustering/lb-log4j.xml b/sip-servlets-test-suite/sipp-scenarios/clustering/lb-log4j.xml new file mode 100644 index 0000000000..550dd8a653 --- /dev/null +++ b/sip-servlets-test-suite/sipp-scenarios/clustering/lb-log4j.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sip-servlets-test-suite/sipp-scenarios/clustering/perftest/mss-cluster-goals.xsl b/sip-servlets-test-suite/sipp-scenarios/clustering/perftest/mss-cluster-goals.xsl new file mode 100644 index 0000000000..02bbcd668f --- /dev/null +++ b/sip-servlets-test-suite/sipp-scenarios/clustering/perftest/mss-cluster-goals.xsl @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sip-servlets-test-suite/sipp-scenarios/clustering/proxy/location-service-receiver.xml b/sip-servlets-test-suite/sipp-scenarios/clustering/proxy/location-service-receiver.xml index e8e15b215f..bba5251bed 100644 --- a/sip-servlets-test-suite/sipp-scenarios/clustering/proxy/location-service-receiver.xml +++ b/sip-servlets-test-suite/sipp-scenarios/clustering/proxy/location-service-receiver.xml @@ -51,8 +51,11 @@ - - + + + + + diff --git a/sip-servlets-test-suite/sipp-scenarios/clustering/proxy/location-service-sender.xml b/sip-servlets-test-suite/sipp-scenarios/clustering/proxy/location-service-sender.xml index 82f6c3ab2f..e3b86c9080 100644 --- a/sip-servlets-test-suite/sipp-scenarios/clustering/proxy/location-service-sender.xml +++ b/sip-servlets-test-suite/sipp-scenarios/clustering/proxy/location-service-sender.xml @@ -85,4 +85,5 @@ - \ No newline at end of file + + diff --git a/sip-servlets-test-suite/sipp-scenarios/performance/b2bua/call-forwarding-receiver.xml b/sip-servlets-test-suite/sipp-scenarios/performance/b2bua/call-forwarding-receiver.xml index 9b3b88b001..f9b164f777 100644 --- a/sip-servlets-test-suite/sipp-scenarios/performance/b2bua/call-forwarding-receiver.xml +++ b/sip-servlets-test-suite/sipp-scenarios/performance/b2bua/call-forwarding-receiver.xml @@ -53,7 +53,7 @@ - + + - + - + ;tag=[call_number] - To: sut - Call-ID: [call_id] - CSeq: 1 INVITE - Contact: sip:sipp@[local_ip]:[local_port] - Max-Forwards: 70 - Subject: Performance Test - Content-Type: application/sdp - Content-Length: [len] - - v=0 - o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] - s=- - c=IN IP[media_ip_type] [media_ip] - t=0 0 - m=audio [media_port] RTP/AVP 0 + + INVITE sip:[service]@sip-servlets.com SIP/2.0 + Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] + From: sipp ;tag=[call_number] + To: sut + Call-ID: [call_id] + CSeq: 1 INVITE + Contact: sip:sipp@[local_ip]:[local_port] + Max-Forwards: 70 + Subject: Performance Test + Content-Type: application/sdp + Content-Length: [len] + + v=0 + o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] + s=- + c=IN IP[media_ip_type] [media_ip] + t=0 0 + m=audio [media_port] RTP/AVP 0 a=rtpmap:0 PCMU/8000 - - ]]> - - - - - - - - + + ]]> + + + + + + + + ;tag=[call_number] - To: sut [peer_tag_param] - Call-ID: [call_id] - CSeq: 1 ACK - Contact: sip:sipp@[local_ip]:[local_port] - Max-Forwards: 70 - [routes] - Subject: Performance Test + ACK [next_url] SIP/2.0 + Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] + From: sipp ;tag=[call_number] + To: sut [peer_tag_param] + Call-ID: [call_id] + CSeq: 1 ACK + Contact: sip:sipp@[local_ip]:[local_port] + Max-Forwards: 70 + [routes] + Subject: Performance Test Content-Length: 0 ]]> - - - - ;tag=[call_number] - To: sut [peer_tag_param] - Call-ID: [call_id] - CSeq: 2 BYE - Contact: sip:sipp@[local_ip]:[local_port] - [routes] - Max-Forwards: 70 - Subject: Performance Test - Content-Length: 0 - - ]]> - - - - - - - - + + + + ;tag=[call_number] + To: sut [peer_tag_param] + Call-ID: [call_id] + CSeq: 2 BYE + Contact: sip:sipp@[local_ip]:[local_port] + [routes] + Max-Forwards: 70 + Subject: Performance Test + Content-Length: 0 + + ]]> + + + + + + + + + diff --git a/sip-servlets-test-suite/sipp-scenarios/performance/prepare-jboss-7-domain-for-perf.sh b/sip-servlets-test-suite/sipp-scenarios/performance/prepare-jboss-7-domain-for-perf.sh new file mode 100644 index 0000000000..ae91b528e7 --- /dev/null +++ b/sip-servlets-test-suite/sipp-scenarios/performance/prepare-jboss-7-domain-for-perf.sh @@ -0,0 +1,41 @@ +export JBOSS_CONFIG=domain +export SIPSERVLETS_DIR=$WORKSPACE/sip-servlets +mvn clean install -f $SIPSERVLETS_DIR/pom.xml -P as7 +export VERSION=7.0.0-TelScale-SNAPSHOT + +#cp jboss-5-setup/mss-sip-stack-jboss.properties $JBOSS_HOME/$JBOSS_CONFIG/conf/mss-sip-stack.properties +#cp jboss-5-setup/context-jboss-5.xml $JBOSS_HOME/$JBOSS_CONFIG/deploy/jbossweb.sar/context.xml +#cp jboss-5-setup/jboss-beans.xml $JBOSS_HOME/$JBOSS_CONFIG/deploy/jbossweb.sar/META-INF/jboss-beans.xml +#cp jboss-5-setup/metadata-deployer-jboss-beans.xml $JBOSS_HOME/$JBOSS_CONFIG/deployers/metadata-deployer-jboss-beans.xml +#cp jboss-5-setup/war-deployers-jboss-beans.xml $JBOSS_HOME/$JBOSS_CONFIG/deployers/jbossweb.deployer/META-INF/war-deployers-jboss-beans.xml +#cp jboss-5-setup/log4j.xml $JBOSS_HOME/$JBOSS_CONFIG/conf/jboss-log4j.xml +#cp jboss-5-setup/server-jboss-5.xml $JBOSS_HOME/$JBOSS_CONFIG/deploy/jbossweb.sar/server.xml + +echo "Will change log level to WARN" +sed 's/INFO/WARN/g' $JBOSS_HOME/$JBOSS_CONFIG/configuration/domain-sip.xml +sed 's/ERROR/WARN/g' $JBOSS_HOME/$JBOSS_CONFIG/configuration/domain-sip.xml +sed 's/DEBUG/WARN/g' $JBOSS_HOME/$JBOSS_CONFIG/configuration/domain-sip.xml + +if [ $# -ne 0 ]; then + case $1 in + proxy) + echo "Distributed example used is proxy" + mvn clean install -f $SIPSERVLETS_DIR/sip-servlets-examples/location-service/pom.xml + echo "deploy $SIPSERVLETS_DIR/sip-servlets-examples/location-service/target/location-service-$VERSION.war --all-server-groups" > ./deploymentCommand + $JBOSS_HOME/bin/jboss-cli.sh --connect --file=./deploymentCommand + cp $SIPSERVLETS_DIR/sip-servlets-examples/location-service/locationservice-dar.properties $JBOSS_HOME/$JBOSS_CONFIG/configuration/dars/mobicents-dar.properties + ;; + b2bua) + echo "Distributed example used is b2bua" + mvn clean install -f $SIPSERVLETS_DIR/sip-servlets-examples/call-forwarding/pom.xml + cp $SIPSERVLETS_DIR/sip-servlets-examples/call-forwarding/target/call-forwarding-*.war $JBOSS_HOME/$JBOSS_CONFIG/deployments + cp $SIPSERVLETS_DIR/sip-servlets-examples/call-forwarding/call-forwarding-b2bua-servlet-dar.properties $JBOSS_HOME/$JBOSS_CONFIG/configuration/dars/mobicents-dar.properties + ;; + *) + echo "Distributed example used is uas" + mvn clean install -f $SIPSERVLETS_DIR/sip-servlets-examples/simple-sip-servlet/pom.xml + cp $SIPSERVLETS_DIR/sip-servlets-examples/simple-sip-servlet/target/simple-sip-servlet-*.war $JBOSS_HOME/$JBOSS_CONFIG/deployments + cp $SIPSERVLETS_DIR/sip-servlets-examples/simple-sip-servlet/simple-dar.properties $JBOSS_HOME/$JBOSS_CONFIG/configuration/dars/mobicents-dar.properties + ;; + esac +fi diff --git a/sip-servlets-test-suite/sipp-scenarios/performance/prepare-jboss-7-server-for-perf.sh b/sip-servlets-test-suite/sipp-scenarios/performance/prepare-jboss-7-server-for-perf.sh new file mode 100644 index 0000000000..3f139e5ae8 --- /dev/null +++ b/sip-servlets-test-suite/sipp-scenarios/performance/prepare-jboss-7-server-for-perf.sh @@ -0,0 +1,43 @@ +export JBOSS_CONFIG=standalone +export SIPSERVLETS_DIR=$WORKSPACE/sip-servlets +mvn -q clean install -f $SIPSERVLETS_DIR/pom.xml -P as7 + +#cp jboss-5-setup/mss-sip-stack-jboss.properties $JBOSS_HOME/$JBOSS_CONFIG/conf/mss-sip-stack.properties +#cp jboss-5-setup/context-jboss-5.xml $JBOSS_HOME/$JBOSS_CONFIG/deploy/jbossweb.sar/context.xml +#cp jboss-5-setup/jboss-beans.xml $JBOSS_HOME/$JBOSS_CONFIG/deploy/jbossweb.sar/META-INF/jboss-beans.xml +#cp jboss-5-setup/metadata-deployer-jboss-beans.xml $JBOSS_HOME/$JBOSS_CONFIG/deployers/metadata-deployer-jboss-beans.xml +#cp jboss-5-setup/war-deployers-jboss-beans.xml $JBOSS_HOME/$JBOSS_CONFIG/deployers/jbossweb.deployer/META-INF/war-deployers-jboss-beans.xml +#cp jboss-5-setup/log4j.xml $JBOSS_HOME/$JBOSS_CONFIG/conf/jboss-log4j.xml +#cp jboss-5-setup/server-jboss-5.xml $JBOSS_HOME/$JBOSS_CONFIG/deploy/jbossweb.sar/server.xml + +if [ "x$LOG_LEVEL" = "x" ]; then + LOG_LEVEL=WARN +fi +echo "Will change log level to $LOG_LEVEL" + +sed -i "s/INFO/$LOG_LEVEL/g" $JBOSS_HOME/$JBOSS_CONFIG/configuration/standalone-sip.xml +sed -i "s/ERROR/$LOG_LEVEL/g" $JBOSS_HOME/$JBOSS_CONFIG/configuration/standalone-sip.xml +sed -i "s/DEBUG/$LOG_LEVEL/g" $JBOSS_HOME/$JBOSS_CONFIG/configuration/standalone-sip.xml + +if [ $# -ne 0 ]; then + case $1 in + proxy) + echo "Distributed example used is proxy" + mvn -q clean install -f $SIPSERVLETS_DIR/sip-servlets-examples/location-service/pom.xml + cp $SIPSERVLETS_DIR/sip-servlets-examples/location-service/target/location-service-*.war $JBOSS_HOME/$JBOSS_CONFIG/deployments + cp $SIPSERVLETS_DIR/sip-servlets-examples/location-service/locationservice-dar.properties $JBOSS_HOME/$JBOSS_CONFIG/configuration/dars/mobicents-dar.properties + ;; + b2bua) + echo "Distributed example used is b2bua" + mvn clean install -f $SIPSERVLETS_DIR/sip-servlets-examples/call-forwarding/pom.xml + cp $SIPSERVLETS_DIR/sip-servlets-examples/call-forwarding/target/call-forwarding-*.war $JBOSS_HOME/$JBOSS_CONFIG/deployments + cp $SIPSERVLETS_DIR/sip-servlets-examples/call-forwarding/call-forwarding-b2bua-servlet-dar.properties $JBOSS_HOME/$JBOSS_CONFIG/configuration/dars/mobicents-dar.properties + ;; + *) + echo "Distributed example used is uas" + mvn clean install -f $SIPSERVLETS_DIR/sip-servlets-examples/simple-sip-servlet/pom.xml + cp $SIPSERVLETS_DIR/sip-servlets-examples/simple-sip-servlet/target/simple-sip-servlet-*.war $JBOSS_HOME/$JBOSS_CONFIG/deployments + cp $SIPSERVLETS_DIR/sip-servlets-examples/simple-sip-servlet/simple-dar.properties $JBOSS_HOME/$JBOSS_CONFIG/configuration/dars/mobicents-dar.properties + ;; + esac +fi diff --git a/sip-servlets-test-suite/sipp-scenarios/performance/proxy-scenario/performance-proxy-uac.xml b/sip-servlets-test-suite/sipp-scenarios/performance/proxy-scenario/performance-proxy-uac.xml index aa95dbc816..e57d8b53ad 100644 --- a/sip-servlets-test-suite/sipp-scenarios/performance/proxy-scenario/performance-proxy-uac.xml +++ b/sip-servlets-test-suite/sipp-scenarios/performance/proxy-scenario/performance-proxy-uac.xml @@ -5,7 +5,7 @@ - + - + @@ -56,8 +56,7 @@ ]]> - - + + diff --git a/sip-servlets-test-suite/sipp-scenarios/performance/proxy-scenario/performance-proxy-uas.xml b/sip-servlets-test-suite/sipp-scenarios/performance/proxy-scenario/performance-proxy-uas.xml index 6763ca6d1f..17c4c737c6 100644 --- a/sip-servlets-test-suite/sipp-scenarios/performance/proxy-scenario/performance-proxy-uas.xml +++ b/sip-servlets-test-suite/sipp-scenarios/performance/proxy-scenario/performance-proxy-uas.xml @@ -53,7 +53,7 @@ - + - + - + - + @@ -78,4 +78,5 @@ + diff --git a/sip-servlets-test-suite/sipp-scenarios/performance/start-jboss-server-for-perf.sh b/sip-servlets-test-suite/sipp-scenarios/performance/start-jboss-server-for-perf.sh index f35fe5007b..059175b5d4 100755 --- a/sip-servlets-test-suite/sipp-scenarios/performance/start-jboss-server-for-perf.sh +++ b/sip-servlets-test-suite/sipp-scenarios/performance/start-jboss-server-for-perf.sh @@ -1,2 +1,2 @@ export JAVA_OPTS="-server -Xms2048m -Xmx2048m -XX:PermSize=128M -XX:MaxPermSize=256M -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode" -sh $JBOSS_HOME/bin/run.sh run +sh $JBOSS_HOME/bin/standalone.sh -c standalone-sip.xml diff --git a/sip-servlets-test-suite/tck/default-as7.properties b/sip-servlets-test-suite/tck/default-as7.properties new file mode 100644 index 0000000000..54f95bdf19 --- /dev/null +++ b/sip-servlets-test-suite/tck/default-as7.properties @@ -0,0 +1,30 @@ +#default properties + +#server side IP address +server.host=127.0.0.1 +server.port=5180 +server.http.port=8180 +server.application.httproot=apitestapp + +#client side transport used to send/receive sip message +#Because of some constraints of JAIN-SIP (the SIP stack used by TCK client side) +#the test cases about proxy will fail if the TCP is used. Keep the transport +#configuration as udp +transport=udp + +#client side UA properties +ua1.username=alice +ua1.displayname=Alice +ua1.port=5071 +ua2.username=bob +ua2.displayname=Bob +ua2.port=5072 +ua3.username=jim +ua3.displayname=Jim +ua3.port=5073 +ua4.username=tom +ua4.displayname=Tom +ua4.port=5074 +#wait duration of client side to receive sip message +wait.duration=21000 + diff --git a/sip-servlets-test-suite/testsuite/.classpath b/sip-servlets-test-suite/testsuite/.classpath index 04993ea6a2..62e11d1550 100644 --- a/sip-servlets-test-suite/testsuite/.classpath +++ b/sip-servlets-test-suite/testsuite/.classpath @@ -4,11 +4,12 @@ - - + + - + + @@ -19,42 +20,62 @@ + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - + + + + - - - - - - + + + + + + + + + + + + \ No newline at end of file diff --git a/sip-servlets-test-suite/testsuite/.project b/sip-servlets-test-suite/testsuite/.project index d0cc54d171..892c02c1e0 100644 --- a/sip-servlets-test-suite/testsuite/.project +++ b/sip-servlets-test-suite/testsuite/.project @@ -1,7 +1,7 @@ sip-servlets-test-suite - Mobicents SIP Servlets. NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse. + Restcomm SIP Servlets. NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse. sip-servlets-spec sip-servlets-core-api diff --git a/sip-servlets-test-suite/testsuite/pom.xml b/sip-servlets-test-suite/testsuite/pom.xml index 8ac55b77a7..d7b40d4b80 100644 --- a/sip-servlets-test-suite/testsuite/pom.xml +++ b/sip-servlets-test-suite/testsuite/pom.xml @@ -222,39 +222,113 @@ test - - nl.jqno.equalsverifier - equalsverifier - 2.0.2 - - - - - - maven-compiler-plugin - - 1.5 - 1.5 - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.10 - - always - - **/TestSipListener.java - - -Dorg.mobicents.testsuite.testhostaddr=${org.mobicents.testsuite.testhostaddr} -XX:MaxPermSize=256m -Xms1024m -Xmx1024m - - - - - - - equalsverifier-repository - http://equalsverifier.googlecode.com/svn/maven/ - - + + nl.jqno.equalsverifier + equalsverifier + 2.0.2 + + + + com.bea.sipservlet.tck + tck-approuter + 1.1 + test + + + + + + maven-compiler-plugin + + 1.5 + 1.5 + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.10 + + + true + + **/TestSipListener.java + + **/Shootme491Test.java + **/ProxyAckTest.java + + + **/*Test.java + + 2 + + + false + + -Dorg.mobicents.testsuite.testhostaddr=${org.mobicents.testsuite.testhostaddr} -XX:MaxPermSize=256m -Xms256m -Xmx1024m + + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.20 + + + true + + **/TestSipListener.java + + + **/*Test.java + + 2 + + false + + + -Dorg.mobicents.testsuite.testhostaddr=${org.mobicents.testsuite.testhostaddr} -XX:MaxPermSize=256m -Xms256m -Xmx1024m + + + + + + + + equalsverifier-repository + http://equalsverifier.googlecode.com/svn/maven/ + + diff --git a/sip-servlets-test-suite/testsuite/src/main/java/org/mobicents/servlet/sip/SipEmbedded.java b/sip-servlets-test-suite/testsuite/src/main/java/org/mobicents/servlet/sip/SipEmbedded.java index aa826908ee..6570ddd440 100644 --- a/sip-servlets-test-suite/testsuite/src/main/java/org/mobicents/servlet/sip/SipEmbedded.java +++ b/sip-servlets-test-suite/testsuite/src/main/java/org/mobicents/servlet/sip/SipEmbedded.java @@ -19,7 +19,6 @@ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ - package org.mobicents.servlet.sip; import java.io.File; import java.io.IOException; @@ -62,17 +61,17 @@ /** * This class is emulating an embedded tomcat configured with sip servlets extension * to allow deployment of sip servlets apps to it. It is for the test suite purposes only for now... - * + * * @author Jean Deruelle * @author Vladimir Ralev */ -public class SipEmbedded { +public class SipEmbedded { private static transient Logger log = Logger.getLogger(SipEmbedded.class); private String loggingFilePath = null; - + private String darConfigurationFilePath = null; - + private String path = null; private SipStandardService sipService = null; @@ -80,29 +79,29 @@ public class SipEmbedded { private StandardHost host = null; private String serviceFullClassName; - + private String serverName; - + MBeanServer mBeanServer = null; - + private boolean isHA = false; - + private int callIdSize = -1; - + private int tagSize = -1; /** * Default Constructor - * + * */ public SipEmbedded(String serverName, String serviceFullClassName) { this.serviceFullClassName = serviceFullClassName; this.serverName = serverName; } - + /** * Default Constructor - * + * */ public SipEmbedded(String serverName, String serviceFullClassName, int callIdSize, int tagSize) { this.serviceFullClassName = serviceFullClassName; @@ -113,7 +112,7 @@ public SipEmbedded(String serverName, String serviceFullClassName, int callIdSiz /** * Basic Accessor setting the value of the context path - * + * * @param path - * the path */ @@ -124,35 +123,35 @@ public void setPath(String path) { /** * Basic Accessor returning the value of the context path - * + * * @return - the context path */ public String getPath() { return path; - } + } /** * Init the tomcat server * @param tomcatBasePath the base path of the server - * @param sipStackProperties + * @param sipStackProperties * @throws Exception */ - public void initTomcat(String tomcatBasePath, Properties sipStackProperties) throws Exception { + public void initTomcat(String tomcatBasePath, Properties sipStackProperties) throws Exception { setPath(tomcatBasePath); // Set the home directory // System.setProperty("CATALINA_HOME", getPath()); // System.setProperty("CATALINA_BASE", getPath()); // System.setProperty("catalina.home", getPath()); -// System.setProperty("catalina.base", getPath()); +// System.setProperty("catalina.base", getPath()); //logging configuration System.setProperty("java.util.logging.config.file", loggingFilePath + "logging.properties"); - DOMConfigurator.configure(loggingFilePath + "log4j.xml"); + DOMConfigurator.configure(loggingFilePath + "log4j.xml"); // BasicConfigurator.configure(); -// PropertyConfigurator.configure(loggingFilePath); +// PropertyConfigurator.configure(loggingFilePath); //Those are for trying to make it work under mvn test command // don't know why but some jars aren't loaded - // Retrieving MBean server + // Retrieving MBean server MBeanUtils.createServer(); if (MBeanServerFactory.findMBeanServer(null).size() > 0) { mBeanServer = @@ -165,23 +164,23 @@ public void initTomcat(String tomcatBasePath, Properties sipStackProperties) thr initDirs(); initNaming(); initClassLoaders(); - + Thread.currentThread().setContextClassLoader(catalinaLoader); SecurityClassLoad.securityClassLoad(catalinaLoader); - + /* * - */ - // Create an embedded server + */ + // Create an embedded server sipService = (SipStandardService) Class.forName(serviceFullClassName).newInstance(); sipService.setName(serverName); sipService.setSipStackProperties(sipStackProperties); sipService.setSipApplicationDispatcherClassName(SipApplicationDispatcherImpl.class.getName()); -// sipService.setSipApplicationRouterClassName(DefaultApplicationRouter.class.getName()); +// sipService.setSipApplicationRouterClassName(DefaultApplicationRouter.class.getName()); sipService.setDarConfigurationFileLocation(darConfigurationFilePath); sipService.setCongestionControlCheckingInterval(-1); sipService.setAdditionalParameterableHeaders("additionalParameterableHeader"); @@ -193,19 +192,19 @@ public void initTomcat(String tomcatBasePath, Properties sipStackProperties) thr sipService.setTagHashMaxLength(tagSize); } if(isHA) { - sipService.setSipPathName("org.mobicents.ha"); + sipService.setSipPathName("org.mobicents.ha.balancing.only"); sipService.setBalancers("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); } // sipService.setBypassRequestExecutor(true); // sipService.setBypassResponseExecutor(true); - // Create an engine + // Create an engine SipStandardEngine engine = new SipStandardEngine(); engine.setName(serverName); engine.setBaseDir(getPath()); engine.setDefaultHost("localhost"); engine.setService(sipService); // Install the assembled container hierarchy - + sipService.setContainer(engine); sipService.init(); // Create a default virtual host @@ -213,12 +212,12 @@ public void initTomcat(String tomcatBasePath, Properties sipStackProperties) thr host = new StandardHost(); host.setAppBase(getPath() + "/webapps"); host.setName("localhost"); - host.setConfigClass(StandardContext.class.getName()); + host.setConfigClass(StandardContext.class.getName()); host.setAppBase("webapps"); host.addLifecycleListener(new SipHostConfig()); host.setAutoDeploy(false); host.setDeployOnStartup(false); - engine.addChild(host); + engine.addChild(host); } /** @@ -228,26 +227,27 @@ public void addHttpConnector(String ipAddress, int port) throws Exception { Connector httpConnector = new Connector( Http11Protocol.class.getName()); Http11Protocol httpProtocolHandler = (Http11Protocol) httpConnector - .getProtocolHandler(); + .getProtocolHandler(); httpProtocolHandler.setAddress(InetAddress.getByName(ipAddress)); - httpProtocolHandler.setPort(port); + httpProtocolHandler.setPort(port); httpConnector.setPort(port); httpProtocolHandler.setProperty("port", ""+port); httpProtocolHandler.setDisableUploadTimeout(true); httpProtocolHandler.setMaxHttpHeaderSize(8192); // httpProtocolHandler.setMaxSpareThreads(75); // httpProtocolHandler.setMinSpareThreads(75); - httpProtocolHandler.setMaxThreads(150); + httpProtocolHandler.setMaxThreads(150); sipService.addConnector(httpConnector); } - + /** * This method Starts the Tomcat server. */ public void startTomcat() throws Exception { // Start the embedded server - sipService.start(); + sipService.start(); + sipService.getSipApplicationDispatcher().putInService(); } /** @@ -256,7 +256,7 @@ public void startTomcat() throws Exception { public void restartTomcat() throws Exception { // Start the embedded server host.start(); - sipService.start(); + sipService.start(); } /** @@ -268,41 +268,41 @@ public Connector addSipConnector(String connectorName, String ipAddress, int por .getProtocolHandler(); udpProtocolHandler.setPort(port); udpProtocolHandler.setIpAddress(ipAddress); - udpProtocolHandler.setSignalingTransport(transport); + udpProtocolHandler.setSignalingTransport(transport); sipService.addConnector(udpSipConnector); return udpSipConnector; } /** - * + * * @return */ public Connector[] findConnectors() { return sipService.findConnectors(); } - + /** - * + * * @param connector */ - public void removeConnector(Connector connector) { + public void removeConnector(Connector connector) { sipService.removeConnector(connector); } - + /** * This method Stops the Tomcat server. */ public void stopTomcat() { // Stop the embedded server Server server = null; - if(sipService != null) { + if(sipService != null) { try { server = sipService.getServer(); - sipService.stop(); + sipService.stop(); } catch (LifecycleException e) { log.error("SipService already stopped ", e); - } + } Connector[] connectors = sipService.findConnectors(); // Fix regression on the testsuite causing Tomcat not to remove properly the connectors // and making the tests hang @@ -310,10 +310,10 @@ public void stopTomcat() { try { connector.stop(); connector.destroy(); - } catch (LifecycleException e) { + } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); - } + } sipService.removeConnector(connector); } if(server != null) { @@ -328,6 +328,10 @@ public void stopTomcat() { * @param contextPath the context Path of the context to deploy */ public boolean deployContext(String docBase, String name, String path) { + return deployAppContext(docBase, name, path).getAvailable(); + } + + public SipStandardContext deployAppContext(String docBase, String name, String path) { SipStandardContext context = new SipStandardContext(); context.setDocBase(docBase); context.setName(name); @@ -337,9 +341,12 @@ public boolean deployContext(String docBase, String name, String path) { context.addLifecycleListener(new SipContextConfig()); context.setManager(new SipStandardManager()); host.addChild(context); - return context.getAvailable(); + return context; } - public boolean deployContext(String docBase, String name, String path, int appSessionTimeout) { + boolean deployContext(String docBase, String name, String path, int appSessionTimeout) { + return deployAppContext(docBase, name, path, 0).getAvailable(); + } + public SipStandardContext deployAppContext(String docBase, String name, String path, int appSessionTimeout) { SipStandardContext context = new SipStandardContext(); context.setDocBase(docBase); context.setName(name); @@ -350,16 +357,16 @@ public boolean deployContext(String docBase, String name, String path, int appSe context.addLifecycleListener(new SipContextConfig()); context.setManager(new SipStandardManager()); host.addChild(context); - return context.getAvailable(); + return context; } - + public boolean deployContext(SipStandardContext context) { context.setParent(host); context.setProcessTlds(false); host.addChild(context); - return context.getAvailable(); + return context.getAvailable(); } - + public void undeployContext(Container context) { host.removeChild(context); } @@ -379,8 +386,8 @@ public String getLoggingFilePath() { public void setLoggingFilePath(String loggingFilePath) { this.loggingFilePath = loggingFilePath; } - - + + /** * Is naming enabled ? */ @@ -392,20 +399,20 @@ public void setLoggingFilePath(String loggingFilePath) { protected static final Integer IS_JAR = Integer.valueOf(1); protected static final Integer IS_GLOB = Integer.valueOf(2); protected static final Integer IS_URL = Integer.valueOf(3); - + protected ClassLoader commonLoader = null; protected ClassLoader catalinaLoader = null; protected ClassLoader sharedLoader = null; - + private void initClassLoaders() throws Exception { - + commonLoader = createClassLoader(serverName + "/common", null); if( commonLoader == null ) { // no config file, default to this loader - we might be in a 'single' env. commonLoader=this.getClass().getClassLoader(); } catalinaLoader = createClassLoader(serverName + "/server", commonLoader); - sharedLoader = createClassLoader(serverName + "/shared", commonLoader); + sharedLoader = createClassLoader(serverName + "/shared", commonLoader); } @@ -419,7 +426,7 @@ private ClassLoader createClassLoader(String name, ClassLoader parent) ArrayList repositoryLocations = new ArrayList(); ArrayList repositoryTypes = new ArrayList(); int i; - + StringTokenizer tokenizer = new StringTokenizer(value, ","); while (tokenizer.hasMoreElements()) { String repository = tokenizer.nextToken(); @@ -430,20 +437,20 @@ private ClassLoader createClassLoader(String name, ClassLoader parent) while ((i=repository.indexOf(CATALINA_HOME_TOKEN))>=0) { replace=true; if (i>0) { - repository = repository.substring(0,i) + getCatalinaHome() + repository = repository.substring(0,i) + getCatalinaHome() + repository.substring(i+CATALINA_HOME_TOKEN.length()); } else { - repository = getCatalinaHome() + repository = getCatalinaHome() + repository.substring(CATALINA_HOME_TOKEN.length()); } } while ((i=repository.indexOf(CATALINA_BASE_TOKEN))>=0) { replace=true; if (i>0) { - repository = repository.substring(0,i) + getCatalinaBase() + repository = repository.substring(0,i) + getCatalinaBase() + repository.substring(i+CATALINA_BASE_TOKEN.length()); } else { - repository = getCatalinaBase() + repository = getCatalinaBase() + repository.substring(CATALINA_BASE_TOKEN.length()); } } @@ -476,7 +483,7 @@ private ClassLoader createClassLoader(String name, ClassLoader parent) String[] locations = (String[]) repositoryLocations.toArray(new String[0]); Integer[] types = (Integer[]) repositoryTypes.toArray(new Integer[0]); - + ClassLoader classLoader = createClassLoader (locations, types, parent); @@ -516,8 +523,8 @@ public String getCatalinaBase() { // return System.getProperty("catalina.base", getCatalinaHome()); return getPath(); } - - + + /** * Create and return a new class loader, based on the configuration * defaults and the specified directory paths: @@ -621,7 +628,7 @@ protected void setSecurityProtection(){ securityConfig.setPackageDefinition(); securityConfig.setPackageAccess(); } - + /** Initialize naming - this should only enable java:env and root naming. * If tomcat is embeded in an application that already defines those - * it shouldn't do it. @@ -681,7 +688,7 @@ protected void initDirs() { } } } - // last resort - for minimal/embedded cases. + // last resort - for minimal/embedded cases. if(catalinaHome==null) { catalinaHome=System.getProperty("user.dir"); } @@ -712,7 +719,7 @@ protected void initDirs() { } System.setProperty("catalina.base", catalinaBase); } - + String temp = System.getProperty("java.io.tmpdir"); if (temp == null || (!(new File(temp)).exists()) || (!(new File(temp)).isDirectory())) { diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/NetworkPortAssigner.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/NetworkPortAssigner.java new file mode 100644 index 0000000000..aa7ac0567e --- /dev/null +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/NetworkPortAssigner.java @@ -0,0 +1,100 @@ +package org.mobicents.servlet.sip; + +import java.io.EOFException; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.lang.management.ManagementFactory; +import java.nio.channels.FileChannel; +import java.util.concurrent.atomic.AtomicInteger; +import org.apache.log4j.Logger; + +public class NetworkPortAssigner { + + private static final Logger LOGGER = Logger.getLogger(NetworkPortAssigner.class); + private static final int PORT_RANGE = 150; + + //provide ports above system reserved range + private static final int PORT_MAX_BASE = 65534; + + private static final int INITIAL_PORT_VALUE; + + private static final AtomicInteger PORT_SEQ = new AtomicInteger(0); + + private static final int PID; + + static { + final String jvmName = ManagementFactory.getRuntimeMXBean().getName(); + final int index = jvmName.indexOf('@'); + + if (index < 1) { + // part before '@' empty (index = 0) / '@' not found (index = -1) + PID = 0; + } else { + PID = Integer.parseInt(jvmName.substring(0, index)); + } + + INITIAL_PORT_VALUE = PORT_MAX_BASE - ((PID % PORT_RANGE) * PORT_RANGE); + LOGGER.info("PID:" + PID); + LOGGER.info("PID:" + PID + ",INITIAL_PORT_VALUE:" + INITIAL_PORT_VALUE); + } + + public synchronized static int retrieveNextPort() { + int nextPort = PORT_MAX_BASE; + try { + nextPort = retrieveNextPortByFile(); + } catch (IOException ex) { + ex.printStackTrace(); + } + LOGGER.info("PID:" + PID + ",nextPort:" + nextPort); + return nextPort; + } + + public static int retrieveNextPortBySeq() { + int nextPort = INITIAL_PORT_VALUE - (PORT_SEQ.getAndAdd(1) % PORT_RANGE); + return nextPort; + } + + public static int retrieveNextPortByFile() throws FileNotFoundException, IOException { + int nextPort = PORT_MAX_BASE; + //assume maven convention, create file under target so its cleaned + File portFile = new File("./target/portFile"); + try { + if (!portFile.exists()) { + portFile.createNewFile(); + LOGGER.info("PID:" + PID + ",portFile created"); + } else { + LOGGER.info("PID:" + PID + ",portFile already exists"); + } + } catch (IOException ex) { + LOGGER.info("PID:" + PID + ", there is problem when creating portFile"); + } + + RandomAccessFile aFile = null; + try { + aFile = new RandomAccessFile(portFile, "rwd"); + FileChannel channel = aFile.getChannel(); + channel.lock(); + try { + int readInt = aFile.readInt(); + nextPort = readInt - 1; + if (nextPort <= 0) { + nextPort = PORT_MAX_BASE - 1; + } + } catch (EOFException eExp) { + //file was empty, it was just created + nextPort = PORT_MAX_BASE - 1; + LOGGER.info("PID:" + PID + ",sequence resetted"); + } + //rewrite existing value by resetting pointer to the start + aFile.seek(0); + aFile.writeInt(nextPort); + } finally { + if (aFile != null) { + aFile.close(); + } + } + return nextPort; + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/SipServletTestCase.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/SipServletTestCase.java index 12ce31adf3..4a10f18a69 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/SipServletTestCase.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/SipServletTestCase.java @@ -1,156 +1,240 @@ -/* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2014, Telestax Inc and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - */ - -package org.mobicents.servlet.sip; - -import java.io.File; -import java.io.InputStream; -import java.util.Properties; - -import javax.sip.ListeningPoint; - -import junit.framework.TestCase; - -import org.apache.catalina.connector.Connector; -import org.apache.log4j.Logger; - -/** - * This class is responsible for reading up the properties configuration file - * and starting/stopping tomcat. It delegates to the test case inheriting from it - * the deployment of the context and the location of the dar configuration file - * since it should map to the test case. - */ -public abstract class SipServletTestCase extends TestCase { - private static transient Logger logger = Logger.getLogger(SipServletTestCase.class); - protected String tomcatBasePath; - protected String projectHome; - protected SipEmbedded tomcat; - protected String sipIpAddress = null; - protected String httpIpAddress = null; - protected String serviceFullClassName = "org.mobicents.servlet.sip.catalina.SipStandardService"; - protected String serverName = "SIP-Servlet-Tomcat-Server"; - protected String listeningPointTransport = ListeningPoint.UDP; - protected boolean createTomcatOnStartup = true; - protected boolean autoDeployOnStartup = true; - protected boolean initTomcatOnStartup = true; - protected boolean startTomcatOnStartup = true; - protected boolean addSipConnectorOnStartup = true; - protected Connector sipConnector; - - public SipServletTestCase(String name) { - super(name); - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - if(System.getProperty("org.mobicents.testsuite.testhostaddr") == null) { - System.setProperty("org.mobicents.testsuite.testhostaddr", "127.0.0.1");// [::1] for IPv6 - } - if(sipIpAddress == null) { - sipIpAddress = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; - } - httpIpAddress = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; - logger.info("sip ip address is " + sipIpAddress); - logger.info("http ip address is " + httpIpAddress); - //Reading properties - Properties properties = new Properties(); - InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream( - "org/mobicents/servlet/sip/testsuite/testsuite.properties"); - try{ - properties.load(inputStream); - } catch (NullPointerException e) { - inputStream = SipServletTestCase.class.getResourceAsStream( - "org/mobicents/servlet/sip/testsuite/testsuite.properties"); - properties.load(inputStream); - } - - // First try to use the env variables - useful for shell scripting - tomcatBasePath = System.getenv("CATALINA_HOME"); - projectHome = System.getenv("SIP_SERVLETS_HOME"); - - // Otherwise use the properties - if(this.tomcatBasePath == null || this.tomcatBasePath.length() <= 0) - this.tomcatBasePath = properties.getProperty("tomcat.home"); - if(this.projectHome == null || this.projectHome.length() <= 0) - this.projectHome = properties.getProperty("project.home"); - logger.info("Tomcat base Path is : " + tomcatBasePath); - logger.info("Project Home is : " + projectHome); - //starting tomcat - if(createTomcatOnStartup) { - createTomcat(); - } - } - - protected void createTomcat() throws Exception { - tomcat = new SipEmbedded(serverName, serviceFullClassName); - tomcat.setLoggingFilePath( - projectHome + File.separatorChar + "sip-servlets-test-suite" + - File.separatorChar + "testsuite" + - File.separatorChar + "src" + - File.separatorChar + "test" + - File.separatorChar + "resources" + File.separatorChar); - logger.info("Log4j path is : " + tomcat.getLoggingFilePath()); - String darConfigurationFile = getDarConfigurationFile(); - tomcat.setDarConfigurationFilePath(darConfigurationFile); - if(initTomcatOnStartup) { - Properties sipStackProperties = getSipStackProperties(); - tomcat.initTomcat(tomcatBasePath, sipStackProperties); - tomcat.addHttpConnector(httpIpAddress, 8080); - /* - * - */ - if(addSipConnectorOnStartup) { - sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, 5070, listeningPointTransport); - } - } - if(startTomcatOnStartup) { - tomcat.startTomcat(); - } - if(autoDeployOnStartup) { - deployApplication(); - } - } - - protected Properties getSipStackProperties() { - return null; - } - - @Override - protected void tearDown() throws Exception { - if(createTomcatOnStartup) - tomcat.stopTomcat(); - super.tearDown(); - } - - /** - * Delegates the choice of the application to deploy to the test case - */ - protected abstract void deployApplication(); - - /** - * Delegates the choice of the default application router - * configuration file to use to the test case - */ - protected abstract String getDarConfigurationFile(); -} +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2014, Telestax Inc and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + */ + +package org.mobicents.servlet.sip; + +import java.io.Closeable; +import java.io.File; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import javax.sip.ListeningPoint; +import static junit.framework.Assert.assertTrue; + +import junit.framework.TestCase; +import org.apache.catalina.Realm; + +import org.apache.catalina.connector.Connector; +import org.apache.catalina.deploy.ApplicationParameter; +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; +import org.mobicents.servlet.sip.catalina.SipStandardManager; +import org.mobicents.servlet.sip.startup.SipContextConfig; +import org.mobicents.servlet.sip.startup.SipStandardContext; + +/** + * This class is responsible for reading up the properties configuration file + * and starting/stopping tomcat. It delegates to the test case inheriting from it + * the deployment of the context and the location of the dar configuration file + * since it should map to the test case. + */ +public abstract class SipServletTestCase extends TestCase { + private static transient Logger logger = Logger.getLogger(SipServletTestCase.class); + protected String tomcatBasePath; + protected String projectHome; + protected SipEmbedded tomcat; + protected String sipIpAddress = null; + protected String httpIpAddress = null; + protected String serviceFullClassName = "org.mobicents.servlet.sip.catalina.SipStandardService"; + protected String serverName = "SIP-Servlet-Tomcat-Server"; + protected String listeningPointTransport = ListeningPoint.UDP; + protected boolean createTomcatOnStartup = true; + protected boolean autoDeployOnStartup = true; + protected boolean initTomcatOnStartup = true; + protected boolean startTomcatOnStartup = true; + protected boolean addSipConnectorOnStartup = true; + protected Connector sipConnector; + protected int httpContainerPort = 8080; + protected int containerPort = 5070; + protected SipStandardContext ctx; + + public SipServletTestCase(String name) { + super(name); + httpContainerPort = NetworkPortAssigner.retrieveNextPort(); + } + + protected List testResources; + + private void closeResources() throws Exception { + for (Closeable rAux : testResources) { + try { + rAux.close(); + } catch (Exception e) { + + } + } + } + + + @Override + protected void setUp() throws Exception { + super.setUp(); + testResources = new ArrayList(); + if(System.getProperty("org.mobicents.testsuite.testhostaddr") == null) { + System.setProperty("org.mobicents.testsuite.testhostaddr", "127.0.0.1");// [::1] for IPv6 + } + if(sipIpAddress == null) { + sipIpAddress = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; + } + httpIpAddress = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; + logger.info("sip ip address is " + sipIpAddress); + logger.info("http ip address is " + httpIpAddress); + //Reading properties + Properties properties = new Properties(); + InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream( + "org/mobicents/servlet/sip/testsuite/testsuite.properties"); + try{ + properties.load(inputStream); + } catch (NullPointerException e) { + inputStream = SipServletTestCase.class.getResourceAsStream( + "org/mobicents/servlet/sip/testsuite/testsuite.properties"); + properties.load(inputStream); + } + + // First try to use the env variables - useful for shell scripting + tomcatBasePath = System.getenv("CATALINA_HOME"); + projectHome = System.getenv("SIP_SERVLETS_HOME"); + + // Otherwise use the properties + if(this.tomcatBasePath == null || this.tomcatBasePath.length() <= 0) + this.tomcatBasePath = properties.getProperty("tomcat.home"); + if(this.projectHome == null || this.projectHome.length() <= 0) + this.projectHome = properties.getProperty("project.home"); + logger.info("Tomcat base Path is : " + tomcatBasePath); + logger.info("Project Home is : " + projectHome); + //starting tomcat + if(createTomcatOnStartup) { + createTomcat(); + } + } + + protected void createTomcat() throws Exception { + tomcat = new SipEmbedded(serverName, serviceFullClassName); + tomcat.setLoggingFilePath( + projectHome + File.separatorChar + "sip-servlets-test-suite" + + File.separatorChar + "testsuite" + + File.separatorChar + "src" + + File.separatorChar + "test" + + File.separatorChar + "resources" + File.separatorChar); + logger.info("Log4j path is : " + tomcat.getLoggingFilePath()); + String darConfigurationFile = getDarConfigurationFile(); + tomcat.setDarConfigurationFilePath(darConfigurationFile); + if(initTomcatOnStartup) { + Properties sipStackProperties = getSipStackProperties(); + tomcat.initTomcat(tomcatBasePath, sipStackProperties); + tomcat.addHttpConnector(httpIpAddress, httpContainerPort); + /* + * + */ + if(addSipConnectorOnStartup) { + sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, containerPort, listeningPointTransport); + } + } + if(startTomcatOnStartup) { + tomcat.startTomcat(); + } + if(autoDeployOnStartup) { + deployApplication(); + } + } + + protected Properties getSipStackProperties() { + return null; + } + + @Override + protected void tearDown() throws Exception { + closeResources(); + //close tomcat even if not started automatically,since most test + //cases are not explicitly stopping tomcat + Connector[] conns = tomcat.findConnectors(); + for (Connector cAux: conns) { + tomcat.removeConnector(cAux); + } + tomcat.stopTomcat(); + super.tearDown(); + } + + /** + * Delegates the choice of the application to deploy to the test case + */ + protected abstract void deployApplication(); + + /** + * Delegates the choice of the default application router + * configuration file to use to the test case + */ + protected abstract String getDarConfigurationFile(); + + + protected SipStandardContext deployShootist(Map params,ConcurrencyControlMode concurrencyControlMode) { + return deployApplication(projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp", + params, concurrencyControlMode); + } + + + protected SipStandardContext deployApplication(String docBase, Map params,ConcurrencyControlMode concurrencyControlMode) { + return deployApplication(docBase, "sip-test-context", params, concurrencyControlMode); + } + + protected SipStandardContext deployApplication(String docBase, String name, Map params,ConcurrencyControlMode concurrencyControlMode) { + return deployApplication(docBase, name, params, concurrencyControlMode, null, null); + } + + protected SipStandardContext deployApplication(String docBase, String name, Map params,ConcurrencyControlMode concurrencyControlMode, Realm realm) { + return deployApplication(docBase, name, params, concurrencyControlMode, null, realm); + } + protected SipStandardContext deployApplication(String docBase, String name, Map params, + ConcurrencyControlMode concurrencyControlMode, Integer sessionTimeout, Realm realm) { + SipStandardContext context = new SipStandardContext(); + context.setDocBase(docBase); + context.setName(name); + context.setPath("/" + name); + context.addLifecycleListener(new SipContextConfig()); + context.setManager(new SipStandardManager()); + if(concurrencyControlMode != null) { + context.setConcurrencyControlMode(concurrencyControlMode); + } + if (sessionTimeout != null) { + context.setSipApplicationSessionTimeout(sessionTimeout); + } + if (realm != null) { + context.setRealm(realm); + } + if (params != null) { + for (Map.Entry param : params.entrySet()) { + ApplicationParameter applicationParameter = new ApplicationParameter(); + applicationParameter.setName(param.getKey()); + applicationParameter.setValue(param.getValue()); + context.addApplicationParameter(applicationParameter); + } + } + ctx = context; + assertTrue(tomcat.deployContext(context)); + return context; + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/SipUnitServletTestCase.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/SipUnitServletTestCase.java index 0c600f3210..7841fdc2a0 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/SipUnitServletTestCase.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/SipUnitServletTestCase.java @@ -1,177 +1,242 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip; - -import java.io.File; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.ListIterator; -import java.util.Properties; - -import javax.sip.ListeningPoint; - -import org.apache.log4j.Logger; -import org.cafesip.sipunit.SipCall; -import org.cafesip.sipunit.SipResponse; -import org.cafesip.sipunit.SipTestCase; - -/** - * This class is responsible for reading up the properties configuration file - * and starting/stopping tomcat. It delegates to the test case inheriting from it - * the deployment of the context and the location of the dar configuration file - * since it should map to the test case. - */ -public abstract class SipUnitServletTestCase extends SipTestCase { - private static transient Logger logger = Logger.getLogger(SipUnitServletTestCase.class); - protected String tomcatBasePath; - protected String projectHome; - protected SipEmbedded tomcat; - protected String serviceFullClassName = "org.mobicents.servlet.sip.catalina.SipStandardService"; - protected String sipIpAddress; - protected String httpIpAddress; - protected String serverName = "SIP-Servlet-Tomcat-Server"; - protected String listeningPointTransport = ListeningPoint.UDP; - protected boolean createTomcatOnStartup = true; - protected boolean autoDeployOnStartup = true; - protected boolean initTomcatOnStartup = true; - protected boolean startTomcatOnStartup = true; - protected boolean addSipConnectorOnStartup = true; - - public SipUnitServletTestCase(String name) { - super(name); - } - - @Override - public void setUp() throws Exception { - super.setUp(); - if(System.getProperty("org.mobicents.testsuite.testhostaddr") == null) { - System.setProperty("org.mobicents.testsuite.testhostaddr", "127.0.0.1");// [::1] for IPv6 - } - sipIpAddress = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; - httpIpAddress = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; - logger.info("sip ip address is " + sipIpAddress); - logger.info("http ip address is " + httpIpAddress); - //Reading properties - Properties properties = new Properties(); - InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream( - "org/mobicents/servlet/sip/testsuite/testsuite.properties"); - try{ - properties.load(inputStream); - } catch (NullPointerException e) { - inputStream = SipServletTestCase.class.getResourceAsStream( - "org/mobicents/servlet/sip/testsuite/testsuite.properties"); - properties.load(inputStream); - } - - // First try to use the env variables - useful for shell scripting - tomcatBasePath = System.getenv("CATALINA_HOME"); - projectHome = System.getenv("SIP_SERVLETS_HOME"); - - // Otherwise use the properties - if(this.tomcatBasePath == null || this.tomcatBasePath.length() <= 0) - this.tomcatBasePath = properties.getProperty("tomcat.home"); - if(this.projectHome == null || this.projectHome.length() <= 0) - this.projectHome = properties.getProperty("project.home"); - logger.info("Tomcat base Path is : " + tomcatBasePath); - logger.info("Project Home is : " + projectHome); - //starting tomcat - if(createTomcatOnStartup) { - tomcat = new SipEmbedded(serverName, serviceFullClassName); - tomcat.setLoggingFilePath( - projectHome + File.separatorChar + "sip-servlets-test-suite" + - File.separatorChar + "testsuite" + - File.separatorChar + "src" + - File.separatorChar + "test" + - File.separatorChar + "resources" + File.separatorChar); - logger.info("Log4j path is : " + tomcat.getLoggingFilePath()); - String darConfigurationFile = getDarConfigurationFile(); - tomcat.setDarConfigurationFilePath(darConfigurationFile); - if(initTomcatOnStartup) { - tomcat.initTomcat(tomcatBasePath, null); - tomcat.addHttpConnector(httpIpAddress, 8080); - /* - * - */ - if(addSipConnectorOnStartup) { - tomcat.addSipConnector(serverName, sipIpAddress, 5070, listeningPointTransport); - } - } - if(startTomcatOnStartup) { - tomcat.startTomcat(); - } - if(autoDeployOnStartup) { - deployApplication(); - } - } - } - - @Override - public void tearDown() throws Exception { - if(createTomcatOnStartup) - tomcat.stopTomcat(); - super.tearDown(); - } - - /** - * Delegates the choice of the application to deploy to the test case - */ - protected abstract void deployApplication(); - - /** - * Delegates the choice of the default application router - * configuration file to use to the test case - */ - protected abstract String getDarConfigurationFile(); - - /** - * This method returns the last received response with status code matching - * the given parameter. - * - * @param statusCode - * Indicates the type of response to return. - * @return SipResponse object or null, if not found. - */ - protected SipResponse findResponse(SipCall sipCall, int statusCode) { - ArrayList responses = sipCall.getAllReceivedResponses(); - - ListIterator i = responses.listIterator(responses.size()); - if(logger.isDebugEnabled()) { - logger.debug("All responses received :"); - } - while (i.hasPrevious()) { - SipResponse resp = (SipResponse) i.previous(); - if(logger.isDebugEnabled()) { - logger.debug("response received : "+ resp.getStatusCode()); - } - if (resp.getStatusCode() == statusCode) { - return resp; - } - } - - return null; - } -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip; + +import java.io.Closeable; +import java.io.File; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.Properties; + +import javax.sip.ListeningPoint; +import static junit.framework.Assert.assertTrue; +import org.apache.catalina.connector.Connector; +import org.apache.catalina.deploy.ApplicationParameter; + +import org.apache.log4j.Logger; +import org.cafesip.sipunit.SipCall; +import org.cafesip.sipunit.SipResponse; +import org.cafesip.sipunit.SipTestCase; +import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; +import org.mobicents.servlet.sip.catalina.SipStandardManager; +import org.mobicents.servlet.sip.startup.SipContextConfig; +import org.mobicents.servlet.sip.startup.SipStandardContext; + +/** + * This class is responsible for reading up the properties configuration file + * and starting/stopping tomcat. It delegates to the test case inheriting from it + * the deployment of the context and the location of the dar configuration file + * since it should map to the test case. + */ +public abstract class SipUnitServletTestCase extends SipTestCase { + private static transient Logger logger = Logger.getLogger(SipUnitServletTestCase.class); + protected String tomcatBasePath; + protected String projectHome; + protected SipEmbedded tomcat; + protected String sipIpAddress = null; + protected String httpIpAddress = null; + protected String serviceFullClassName = "org.mobicents.servlet.sip.catalina.SipStandardService"; + protected String serverName = "SIP-Servlet-Tomcat-Server"; + protected String listeningPointTransport = ListeningPoint.UDP; + protected boolean createTomcatOnStartup = true; + protected boolean autoDeployOnStartup = true; + protected boolean initTomcatOnStartup = true; + protected boolean startTomcatOnStartup = true; + protected boolean addSipConnectorOnStartup = true; + protected Connector sipConnector; + protected int httpContainerPort = 8080; + protected int containerPort = 5070; + protected SipStandardContext ctx; + + public SipUnitServletTestCase(String name) { + super(name); + httpContainerPort = NetworkPortAssigner.retrieveNextPort(); + } + + protected List testResources; + + private void closeResources() throws Exception { + for (Closeable rAux : testResources) { + try { + rAux.close(); + } catch (Exception e) { + + } + } + } + + @Override + public void setUp() throws Exception { + super.setUp(); + testResources = new ArrayList(); + if(System.getProperty("org.mobicents.testsuite.testhostaddr") == null) { + System.setProperty("org.mobicents.testsuite.testhostaddr", "127.0.0.1");// [::1] for IPv6 + } + if(sipIpAddress == null) { + sipIpAddress = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; + } + httpIpAddress = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; + logger.info("sip ip address is " + sipIpAddress); + logger.info("http ip address is " + httpIpAddress); + //Reading properties + Properties properties = new Properties(); + InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream( + "org/mobicents/servlet/sip/testsuite/testsuite.properties"); + try{ + properties.load(inputStream); + } catch (NullPointerException e) { + inputStream = SipServletTestCase.class.getResourceAsStream( + "org/mobicents/servlet/sip/testsuite/testsuite.properties"); + properties.load(inputStream); + } + + // First try to use the env variables - useful for shell scripting + tomcatBasePath = System.getenv("CATALINA_HOME"); + projectHome = System.getenv("SIP_SERVLETS_HOME"); + + // Otherwise use the properties + if(this.tomcatBasePath == null || this.tomcatBasePath.length() <= 0) + this.tomcatBasePath = properties.getProperty("tomcat.home"); + if(this.projectHome == null || this.projectHome.length() <= 0) + this.projectHome = properties.getProperty("project.home"); + logger.info("Tomcat base Path is : " + tomcatBasePath); + logger.info("Project Home is : " + projectHome); + //starting tomcat + if(createTomcatOnStartup) { + tomcat = new SipEmbedded(serverName, serviceFullClassName); + tomcat.setLoggingFilePath( + projectHome + File.separatorChar + "sip-servlets-test-suite" + + File.separatorChar + "testsuite" + + File.separatorChar + "src" + + File.separatorChar + "test" + + File.separatorChar + "resources" + File.separatorChar); + logger.info("Log4j path is : " + tomcat.getLoggingFilePath()); + String darConfigurationFile = getDarConfigurationFile(); + tomcat.setDarConfigurationFilePath(darConfigurationFile); + if(initTomcatOnStartup) { + tomcat.initTomcat(tomcatBasePath, null); + tomcat.addHttpConnector(httpIpAddress, httpContainerPort); + /* + * + */ + if(addSipConnectorOnStartup) { + sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, containerPort, listeningPointTransport); + } + } + if(startTomcatOnStartup) { + tomcat.startTomcat(); + } + if(autoDeployOnStartup) { + deployApplication(); + } + } + } + + @Override + public void tearDown() throws Exception { + closeResources(); + //close tomcat even if not started automatically,since most test + //cases are not explicitly stopping tomcat + tomcat.stopTomcat(); + super.tearDown(); + } + + /** + * Delegates the choice of the application to deploy to the test case + */ + protected abstract void deployApplication(); + + /** + * Delegates the choice of the default application router + * configuration file to use to the test case + */ + protected abstract String getDarConfigurationFile(); + + /** + * This method returns the last received response with status code matching + * the given parameter. + * + * @param statusCode + * Indicates the type of response to return. + * @return SipResponse object or null, if not found. + */ + protected SipResponse findResponse(SipCall sipCall, int statusCode) { + ArrayList responses = sipCall.getAllReceivedResponses(); + + ListIterator i = responses.listIterator(responses.size()); + if(logger.isDebugEnabled()) { + logger.debug("All responses received :"); + } + while (i.hasPrevious()) { + SipResponse resp = (SipResponse) i.previous(); + if(logger.isDebugEnabled()) { + logger.debug("response received : "+ resp.getStatusCode()); + } + if (resp.getStatusCode() == statusCode) { + return resp; + } + } + + return null; + } + + protected SipStandardContext deployShootist(Map params,ConcurrencyControlMode concurrencyControlMode) { + return deployApplication(projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp", + params, concurrencyControlMode); + } + + + protected SipStandardContext deployApplication(String docBase, Map params,ConcurrencyControlMode concurrencyControlMode) { + return deployApplication(docBase, "sip-test-context", params, concurrencyControlMode); + } + + protected SipStandardContext deployApplication(String docBase, String name, Map params,ConcurrencyControlMode concurrencyControlMode) { + SipStandardContext context = new SipStandardContext(); + context.setDocBase(docBase); + context.setName(name); + context.setPath("/" + name); + context.addLifecycleListener(new SipContextConfig()); + context.setManager(new SipStandardManager()); + if(concurrencyControlMode != null) { + context.setConcurrencyControlMode(concurrencyControlMode); + } + if (params != null) { + for (Map.Entry param : params.entrySet()) { + ApplicationParameter applicationParameter = new ApplicationParameter(); + applicationParameter.setName(param.getKey()); + applicationParameter.setValue(param.getValue()); + context.addApplicationParameter(applicationParameter); + } + } + ctx = context; + assertTrue(tomcat.deployContext(context)); + return context; + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/tck/AppRouterTCKTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/tck/AppRouterTCKTest.java new file mode 100644 index 0000000000..2a6286c966 --- /dev/null +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/tck/AppRouterTCKTest.java @@ -0,0 +1,112 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.tck; + +import java.util.Properties; + +import org.apache.log4j.Logger; +import org.junit.Ignore; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.catalina.SipStandardService; + +/** + * This test class just allows to debug TCK test cases in your IDE + * @author + */ +public class AppRouterTCKTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(AppRouterTCKTest.class); + + public AppRouterTCKTest(String name) { + super(name); + startTomcatOnStartup = true; + autoDeployOnStartup = true; + addSipConnectorOnStartup = true; + } + + @Override + public void deployApplication() { + assertTrue(tomcat.deployContext( + projectHome + "/build/jsr289-tck/tck/dist/ar_continue.sar", + "sip-test-context-continue", "sip-test-continue")); + assertTrue(tomcat.deployContext( + projectHome + "/build/jsr289-tck/tck/dist/ar_internalroutemodifier.sar", + "sip-test-context-int-mod", "sip-test-int-mod")); + assertTrue(tomcat.deployContext( + projectHome + "/build/jsr289-tck/tck/dist/ar_reverse.sar", + "sip-test-context-reverse", "sip-test-reverse")); + assertTrue(tomcat.deployContext( + projectHome + "/build/jsr289-tck/tck/dist/ar_suburiregion.sar", + "sip-test-context-suburiregion", "sip-test-suburiregion")); + assertTrue(tomcat.deployContext( + projectHome + "/build/jsr289-tck/tck/dist/ar_success.sar", + "sip-test-context-ar_success", "sip-test-ar_success")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/callcontroller/call-forwarding-b2bua-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + //changes approuter to TCK one + System.setProperty("javax.servlet.sip.ar.spi.SipApplicationRouterProvider", "com.bea.sipservlet.tck.ar.TckApplicationRouterProvider"); + containerPort = 5080; + super.setUp(); + } + + @Ignore("Place breakpoint here and run TCK test case") + public void testAppRouterTCKApp() throws Exception { + assertTrue(true); + + } + + @Override + protected Properties getSipStackProperties() { + Properties sipStackProperties = new Properties(); + sipStackProperties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", + "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", + "32"); + sipStackProperties.setProperty(SipStandardService.DEBUG_LOG_STACK_PROP, + tomcatBasePath + "/" + "mss-jsip-" + getName() + "-debug.txt"); + sipStackProperties.setProperty(SipStandardService.SERVER_LOG_STACK_PROP, + tomcatBasePath + "/" + "mss-jsip-" + getName() + "-messages.xml"); + sipStackProperties.setProperty("javax.sip.STACK_NAME", "mss-" + getName()); + sipStackProperties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", "off"); + sipStackProperties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.THREAD_POOL_SIZE", "64"); + sipStackProperties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.MAX_FORK_TIME_SECONDS", "5"); + sipStackProperties.setProperty(SipStandardService.LOOSE_DIALOG_VALIDATION, "true"); + sipStackProperties.setProperty(SipStandardService.PASS_INVITE_NON_2XX_ACK_TO_LISTENER, "true"); + return sipStackProperties; + } + + @Override + protected void tearDown() throws Exception { + logger.info("Test completed"); + super.tearDown(); + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/tck/B2BUATCKTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/tck/B2BUATCKTest.java new file mode 100644 index 0000000000..6e2e5c5305 --- /dev/null +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/tck/B2BUATCKTest.java @@ -0,0 +1,101 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.tck; + +import java.util.Properties; + +import org.apache.log4j.Logger; +import org.junit.Ignore; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.catalina.SipStandardService; + + +/** + * This test class just allows to debug TCK test cases in your IDE + * @author + */ +public class B2BUATCKTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(B2BUATCKTest.class); + + public B2BUATCKTest(String name) { + super(name); + startTomcatOnStartup = true; + autoDeployOnStartup = true; + addSipConnectorOnStartup = true; + } + + @Override + public void deployApplication() { + assertTrue(tomcat.deployContext( + projectHome + "/build/jsr289-tck/tck/dist/b2bua.sar", + "sip-test-context-b2bua", "sip-test-b2bua")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/callcontroller/call-forwarding-b2bua-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + //changes approuter to TCK one + System.setProperty("javax.servlet.sip.ar.spi.SipApplicationRouterProvider", "com.bea.sipservlet.tck.ar.TckApplicationRouterProvider"); + containerPort = 5080; + super.setUp(); + } + + @Ignore("Place breakpoint here and run TCK test case") + public void testB2BUATCKApp() throws Exception { + assertTrue(true); + + } + + @Override + protected Properties getSipStackProperties() { + Properties sipStackProperties = new Properties(); + sipStackProperties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", + "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", + "32"); + sipStackProperties.setProperty(SipStandardService.DEBUG_LOG_STACK_PROP, + tomcatBasePath + "/" + "mss-jsip-" + getName() + "-debug.txt"); + sipStackProperties.setProperty(SipStandardService.SERVER_LOG_STACK_PROP, + tomcatBasePath + "/" + "mss-jsip-" + getName() + "-messages.xml"); + sipStackProperties.setProperty("javax.sip.STACK_NAME", "mss-" + getName()); + sipStackProperties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", "off"); + sipStackProperties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.THREAD_POOL_SIZE", "64"); + sipStackProperties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.MAX_FORK_TIME_SECONDS", "5"); + sipStackProperties.setProperty(SipStandardService.LOOSE_DIALOG_VALIDATION, "true"); + sipStackProperties.setProperty(SipStandardService.PASS_INVITE_NON_2XX_ACK_TO_LISTENER, "true"); + return sipStackProperties; + } + + @Override + protected void tearDown() throws Exception { + logger.info("Test completed"); + super.tearDown(); + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/AllTests.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/AllTests.java index f8117d516e..c8ff73739b 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/AllTests.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/AllTests.java @@ -88,6 +88,7 @@ import org.mobicents.servlet.sip.testsuite.session.SessionStateUACSipServletTest; import org.mobicents.servlet.sip.testsuite.session.SessionStateUASSipServletTest; import org.mobicents.servlet.sip.testsuite.session.SipAppSessionTerminationTest; +import org.mobicents.servlet.sip.testsuite.simple.QuotedParameterSipServletTest; import org.mobicents.servlet.sip.testsuite.simple.ShootistSipServletTest; import org.mobicents.servlet.sip.testsuite.simple.ShootistTelURLSipServletTest; import org.mobicents.servlet.sip.testsuite.simple.ShootmeSipServletTest; @@ -193,6 +194,7 @@ public static Test suite() { suite.addTestSuite(SipURITest.class); suite.addTestSuite(AddressTest.class); suite.addTestSuite(TelURLTest.class); + suite.addTestSuite(QuotedParameterSipServletTest.class); // $JUnit-END$ return suite; diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/PhoneCloseable.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/PhoneCloseable.java new file mode 100644 index 0000000000..1b526d3f6e --- /dev/null +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/PhoneCloseable.java @@ -0,0 +1,17 @@ +package org.mobicents.servlet.sip.testsuite; + +import java.io.Closeable; +import java.io.IOException; +import org.cafesip.sipunit.SipPhone; + +public class PhoneCloseable implements Closeable { + SipPhone phone; + + public PhoneCloseable(SipPhone phone) { + this.phone = phone; + } + + public void close() throws IOException { + phone.dispose(); + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/ProtocolObjects.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/ProtocolObjects.java index 6d80a47e6a..3c6aaa8b55 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/ProtocolObjects.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/ProtocolObjects.java @@ -1,165 +1,171 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite; - -import java.util.HashSet; -import java.util.Map; -import java.util.Properties; - -import javax.sip.ObjectInUseException; -import javax.sip.SipException; -import javax.sip.SipFactory; -import javax.sip.SipProvider; -import javax.sip.SipStack; -import javax.sip.address.AddressFactory; -import javax.sip.header.HeaderFactory; -import javax.sip.message.MessageFactory; - - - -/** - * @author M. Ranganathan - * - */ -public class ProtocolObjects { - public final AddressFactory addressFactory; - - public final MessageFactory messageFactory; - - public final HeaderFactory headerFactory; - - public final SipStack sipStack; - - private int logLevel = 32; - - String logFileDirectory = "logs/"; - - public final String transport; - - private boolean isStarted; - - public ProtocolObjects(String stackname, String pathname, String transport, - boolean autoDialog, String outboundProxy, String threadPoolSize, String reentrantListener, Map additionalProperties) { - this.transport = transport; - SipFactory sipFactory = SipFactory.getInstance(); - sipFactory.resetFactory(); - sipFactory.setPathName(pathname); - Properties properties = new Properties(); - properties.setProperty("javax.sip.STACK_NAME", stackname); - - if(outboundProxy != null) { - properties.setProperty("javax.sip.OUTBOUND_PROXY", outboundProxy + "/" - + transport); - } - // The following properties are specific to nist-sip - // and are not necessarily part of any other jain-sip - // implementation. - properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", logFileDirectory - + stackname + "debuglog.txt"); - properties.setProperty("gov.nist.javax.sip.SERVER_LOG", - logFileDirectory + stackname + "log.xml"); - - properties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", - (autoDialog ? "on" : "off")); - - // For the forked subscribe notify test - properties.setProperty("javax.sip.FORKABLE_EVENTS", "foo"); - - - // Dont use the router for all requests. -// properties.setProperty("javax.sip.USE_ROUTER_FOR_ALL_URIS", "false"); - - properties.setProperty("gov.nist.javax.sip.THREAD_POOL_SIZE", threadPoolSize == null ? "1" : threadPoolSize); - properties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", reentrantListener == null ? "false" : reentrantListener); - - // Set to 0 in your production code for max speed. - // You need 16 for logging traces. 32 for debug + traces. - // Your code will limp at 32 but it is best for debugging. - properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", Integer.valueOf( - logLevel).toString()); - - if(additionalProperties != null) { - properties.putAll(additionalProperties); - } - - try { - // Create SipStack object - sipStack = sipFactory.createSipStack(properties); - System.out.println("createSipStack " + sipStack); - } catch (Exception e) { - // could not find - // gov.nist.jain.protocol.ip.sip.SipStackImpl - // in the classpath - e.printStackTrace(); - System.err.println(e.getMessage()); - throw new RuntimeException("Stack failed to initialize"); - } - - try { - headerFactory = sipFactory.createHeaderFactory(); - addressFactory = sipFactory.createAddressFactory(); - messageFactory = sipFactory.createMessageFactory(); - } catch (SipException ex) { - ex.printStackTrace(); - throw new RuntimeException(ex); - } - } - - public ProtocolObjects(String stackname, String pathname, String transport, - boolean autoDialog, String outboundProxy, String threadPoolSize, String reentrantListener) { - - this(stackname, pathname, transport, autoDialog, outboundProxy, threadPoolSize, reentrantListener, null); - } - - public synchronized void destroy() { - HashSet hashSet = new HashSet(); - - for (SipProvider sipProvider : hashSet) { - hashSet.add(sipProvider); - } - - for (SipProvider sipProvider : hashSet) { - for (int j = 0; j < 5; j++) { - try { - sipStack.deleteSipProvider(sipProvider); - } catch (ObjectInUseException ex) { - try { - Thread.sleep(1000); - } catch (Exception e) { - } - - } - } - } - - sipStack.stop(); - } - - public void start() throws Exception { - if (this.isStarted) - return; - sipStack.start(); - this.isStarted = true; - - } -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite; + +import java.io.Closeable; +import java.io.IOException; +import java.util.HashSet; +import java.util.Map; +import java.util.Properties; + +import javax.sip.ObjectInUseException; +import javax.sip.SipException; +import javax.sip.SipFactory; +import javax.sip.SipProvider; +import javax.sip.SipStack; +import javax.sip.address.AddressFactory; +import javax.sip.header.HeaderFactory; +import javax.sip.message.MessageFactory; + + + +/** + * @author M. Ranganathan + * + */ +public class ProtocolObjects implements Closeable { + public final AddressFactory addressFactory; + + public final MessageFactory messageFactory; + + public final HeaderFactory headerFactory; + + public final SipStack sipStack; + + private int logLevel = 32; + + String logFileDirectory = "target/logs/"; + + public final String transport; + + private boolean isStarted; + + public ProtocolObjects(String stackname, String pathname, String transport, + boolean autoDialog, String outboundProxy, String threadPoolSize, String reentrantListener, Map additionalProperties) { + this.transport = transport; + SipFactory sipFactory = SipFactory.getInstance(); + sipFactory.resetFactory(); + sipFactory.setPathName(pathname); + Properties properties = new Properties(); + properties.setProperty("javax.sip.STACK_NAME", stackname); + + if(outboundProxy != null) { + properties.setProperty("javax.sip.OUTBOUND_PROXY", outboundProxy + "/" + + transport); + } + // The following properties are specific to nist-sip + // and are not necessarily part of any other jain-sip + // implementation. + properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", logFileDirectory + + stackname + "debuglog.txt"); + properties.setProperty("gov.nist.javax.sip.SERVER_LOG", + logFileDirectory + stackname + "log.xml"); + + properties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", + (autoDialog ? "on" : "off")); + + // For the forked subscribe notify test + properties.setProperty("javax.sip.FORKABLE_EVENTS", "foo"); + + + // Dont use the router for all requests. +// properties.setProperty("javax.sip.USE_ROUTER_FOR_ALL_URIS", "false"); + + properties.setProperty("gov.nist.javax.sip.THREAD_POOL_SIZE", threadPoolSize == null ? "1" : threadPoolSize); + properties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", reentrantListener == null ? "false" : reentrantListener); + + // Set to 0 in your production code for max speed. + // You need 16 for logging traces. 32 for debug + traces. + // Your code will limp at 32 but it is best for debugging. + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", Integer.valueOf( + logLevel).toString()); + + if(additionalProperties != null) { + properties.putAll(additionalProperties); + } + + try { + // Create SipStack object + sipStack = sipFactory.createSipStack(properties); + System.out.println("createSipStack " + sipStack); + } catch (Exception e) { + // could not find + // gov.nist.jain.protocol.ip.sip.SipStackImpl + // in the classpath + e.printStackTrace(); + System.err.println(e.getMessage()); + throw new RuntimeException("Stack failed to initialize"); + } + + try { + headerFactory = sipFactory.createHeaderFactory(); + addressFactory = sipFactory.createAddressFactory(); + messageFactory = sipFactory.createMessageFactory(); + } catch (SipException ex) { + ex.printStackTrace(); + throw new RuntimeException(ex); + } + } + + public ProtocolObjects(String stackname, String pathname, String transport, + boolean autoDialog, String outboundProxy, String threadPoolSize, String reentrantListener) { + + this(stackname, pathname, transport, autoDialog, outboundProxy, threadPoolSize, reentrantListener, null); + } + + public synchronized void destroy() { + HashSet hashSet = new HashSet(); + + for (SipProvider sipProvider : hashSet) { + hashSet.add(sipProvider); + } + + for (SipProvider sipProvider : hashSet) { + for (int j = 0; j < 5; j++) { + try { + sipStack.deleteSipProvider(sipProvider); + } catch (ObjectInUseException ex) { + try { + Thread.sleep(1000); + } catch (Exception e) { + } + + } + } + } + + sipStack.stop(); + } + + public void start() throws Exception { + if (this.isStarted) + return; + sipStack.start(); + this.isStarted = true; + + } + + public void close() throws IOException { + destroy(); + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/StackCloseable.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/StackCloseable.java new file mode 100644 index 0000000000..ef608f0462 --- /dev/null +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/StackCloseable.java @@ -0,0 +1,18 @@ +package org.mobicents.servlet.sip.testsuite; + +import java.io.Closeable; +import java.io.IOException; +import org.cafesip.sipunit.SipStack; + +public class StackCloseable implements Closeable { + + SipStack stack; + + public StackCloseable(SipStack stack) { + this.stack = stack; + } + + public void close() throws IOException { + stack.dispose(); + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/TestSipListener.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/TestSipListener.java index 8fd3e22a90..3d150cc3c6 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/TestSipListener.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/TestSipListener.java @@ -1,3548 +1,3556 @@ -/* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2014, Telestax Inc and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - * - * This file incorporates work covered by the following copyright contributed under the GNU LGPL : Copyright 2007-2011 Red Hat. - */ - -package org.mobicents.servlet.sip.testsuite; - -import gov.nist.javax.sip.DialogExt; -import gov.nist.javax.sip.SipStackImpl; -import gov.nist.javax.sip.address.SipUri; -import gov.nist.javax.sip.header.HeaderExt; -import gov.nist.javax.sip.header.HeaderFactoryExt; -import gov.nist.javax.sip.header.ParameterNames; -import gov.nist.javax.sip.header.SIPETag; -import gov.nist.javax.sip.header.SIPHeaderNames; -import gov.nist.javax.sip.header.WWWAuthenticate; -import gov.nist.javax.sip.header.extensions.JoinHeader; -import gov.nist.javax.sip.header.extensions.ReplacesHeader; -import gov.nist.javax.sip.header.ims.PathHeader; -import gov.nist.javax.sip.message.MessageExt; -import gov.nist.javax.sip.stack.SIPTransactionStack; -import gov.nist.javax.sip.message.SIPResponse; -import gov.nist.javax.sip.stack.SIPDialog; -import gov.nist.javax.sip.stack.SIPTransaction; - -import java.text.ParseException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Random; -import java.util.concurrent.atomic.AtomicInteger; - -import javax.sip.ClientTransaction; -import javax.sip.Dialog; -import javax.sip.DialogTerminatedEvent; -import javax.sip.IOExceptionEvent; -import javax.sip.InvalidArgumentException; -import javax.sip.ListeningPoint; -import javax.sip.RequestEvent; -import javax.sip.ResponseEvent; -import javax.sip.ServerTransaction; -import javax.sip.SipException; -import javax.sip.SipListener; -import javax.sip.SipProvider; -import javax.sip.TransactionAlreadyExistsException; -import javax.sip.TransactionDoesNotExistException; -import javax.sip.TransactionTerminatedEvent; -import javax.sip.TransactionUnavailableException; -import javax.sip.address.Address; -import javax.sip.address.SipURI; -import javax.sip.address.TelURL; -import javax.sip.address.URI; -import javax.sip.header.AllowHeader; -import javax.sip.header.AuthenticationInfoHeader; -import javax.sip.header.AuthorizationHeader; -import javax.sip.header.CSeqHeader; -import javax.sip.header.CallIdHeader; -import javax.sip.header.ContactHeader; -import javax.sip.header.ContentLengthHeader; -import javax.sip.header.ContentTypeHeader; -import javax.sip.header.EventHeader; -import javax.sip.header.ExpiresHeader; -import javax.sip.header.ExtensionHeader; -import javax.sip.header.FromHeader; -import javax.sip.header.Header; -import javax.sip.header.MaxForwardsHeader; -import javax.sip.header.ProxyAuthenticateHeader; -import javax.sip.header.ProxyAuthorizationHeader; -import javax.sip.header.ReasonHeader; -import javax.sip.header.RecordRouteHeader; -import javax.sip.header.ReferToHeader; -import javax.sip.header.RequireHeader; -import javax.sip.header.RouteHeader; -import javax.sip.header.SIPETagHeader; -import javax.sip.header.SIPIfMatchHeader; -import javax.sip.header.SubscriptionStateHeader; -import javax.sip.header.SupportedHeader; -import javax.sip.header.ToHeader; -import javax.sip.header.ViaHeader; -import javax.sip.message.Request; -import javax.sip.message.Response; - -import org.apache.log4j.Logger; - -/** - * This class is a UAC template. Shootist is the guy that shoots and shootme is - * the guy that gets shot. - * - * @author M. Ranganathan - */ - -public class TestSipListener implements SipListener { - private String toTag = Integer.toString(new Random().nextInt(10000000)); - - public List allRequests = new LinkedList(); - public List allResponses = new LinkedList(); - - private static final String PLAIN_UTF8_CONTENT_SUBTYPE = "plain;charset=UTF-8"; - - private static final String TEXT_CONTENT_TYPE = "text"; - - private static final String PIDF_XML_SUBTYPE = "pidf+xml"; - - private static final String APPLICATION_CONTENT_TYPE = "application"; - - private boolean sendBye; - private int byeResponse = 200; - - public int bindings; - - public boolean extraRoute = false; - - private boolean sendJoinMessage; - - private boolean sendReplacesMessage; - - private boolean sendByeBeforeTerminatingNotify; - - private boolean sendByeAfterTerminatingNotify; - - private SipProvider sipProvider; - - public ProtocolObjects protocolObjects; - - private ContactHeader contactHeader; - - private ListeningPoint listeningPoint; - - private ClientTransaction inviteClientTid; - - private ServerTransaction inviteServerTid; - - private Dialog dialog; - - private Dialog joinDialog; - - private Dialog replacesDialog; - - public int myPort; - - private int peerPort; - - private String peerHostPort; - - private int dialogTerminatedCount; - - private int transctionTerminatedCount; - - private int transactionCount; - - private int dialogCount; - - private Request cancelRequest; - - private boolean cancelReceived; - - private boolean cancelOkReceived; - - private boolean ackSent; - - private boolean ackReceived; - - private boolean requestTerminatedReceived; - - private boolean byeReceived; - - private boolean redirectReceived; - - private boolean joinRequestReceived; - - private boolean replacesRequestReceived; - - private boolean okToByeReceived; - - private boolean authenticationErrorReceived; - - private URI requestURI; - - private Request inviteRequest; - - private Request messageRequest; - - private Response finalResponse; - - private Response informationalResponse; - - private boolean cancelSent; - - private boolean waitForCancel; - - private String lastMessageContent; - - private List allMessagesContent; - - private List allSubscriptionStates; - - private boolean finalResponseReceived; - - private int finalResponseToSend = -1; - - public int ackCount = 0; - - public int notifyCount = 0; - - public int numberOf491s = 0; - - private List provisionalResponsesToSend; - - private boolean useToURIasRequestUri; - - private boolean sendUpdateOn180; - - private String publishEvent = "reg"; - - private String sipETag; - - private String publishContentMessage; - - private boolean referReceived; - - private boolean challengeRequests; - private boolean multipleChallengeInResponse; - - private static Logger logger = Logger.getLogger(TestSipListener.class); - - DigestServerAuthenticationMethod dsam; - - private long timeToWaitBetweenProvisionnalResponse = 1000; - - private long timeToWaitBetweenSubsNotify = 1000; - - private boolean byeSent; - - private boolean serverErrorReceived; - - private long lastInfoResponseTime = -1; - - private Integer respondWithError = null; - - private long lastRegisterCSeqNumber = -1; - - private int finalResponseStatus; - - private boolean inviteReceived; - - private boolean sendReinvite; - - private boolean reinviteSent; - - private boolean abortProcessing; - - private boolean recordRoutingProxyTesting; - - public boolean b2buamessagereceived; - - public boolean txTimeoutReceived; - - private boolean sendSubsequentRequestsThroughSipProvider; - - private boolean testAckViaParam; - - private Request byeRequestReceived; - - private Request registerReceived; - - private long timeToWaitBeforeBye = 1000; - private long timeToWaitBeforeAck = 0; - - private boolean sendAck = true; - - private boolean prackSent; - - private boolean prackReceived; - - private Request prackRequestReceived; - - private boolean okToPrackReceived; - - private AtomicInteger rseqNumber = new AtomicInteger(1); - - public boolean sendByeInNewThread = false; - - private boolean useDefaultRoute = true; - - private boolean setTransport=true; - - private Response serviceUnavailableResponse = null; - - private int referResponseToSend = 202; - - private boolean sendNotifyForRefer = true; - - private Response inviteOkResponse; - - private boolean sendNotify = true; - private boolean sendNotifyBeforeResponseToSubscribe = false; - - private boolean countRetrans = false; - private int nbRetrans = 0; - - public Request firstRequest; - public Request lastInvite; - - private boolean disableSequenceNumberValidation = false; - - private boolean sendCancelOn1xx = false; - - private boolean testNextNonce =false; - private boolean testNC =false; - - private String nextNonce = null; - private int nc; - - private boolean dropRequest = false; - - private long waitBeforeFinalResponse = 0; - - private boolean sendUpdate; - - private boolean updateReceived; - - private boolean sendUpdateAfterUpdate = false; - - private boolean sendUpdateAfterPrack = false; - - private boolean sendUpdateAfterProvisionalResponses; - - private Request ackRequest; - - private boolean handleAuthorization = true; - - private Request updateRequest; - - private Request infoRequest; - - private Request optionsRequest; - - private boolean addRecordRouteForResponses; - - private RFC5626UseCase rfc5626UseCase; - - private String securityUser = "user"; - private String securityPwd = "pass"; - - private boolean sendProvisionalResponseBeforeChallenge = false; - - private boolean checkSDPNullOnChallengeRequests; - - class MyEventSource implements Runnable { - private TestSipListener notifier; - private EventHeader eventHeader; - - public MyEventSource(TestSipListener notifier, EventHeader eventHeader ) { - this.notifier = notifier; - this.eventHeader = eventHeader; - } - - public void run() { - try { - for (int i = 0; i < 1; i++) { - - Thread.sleep(timeToWaitBetweenSubsNotify); - Request request = this.notifier.dialog.createRequest(Request.NOTIFY); - SubscriptionStateHeader subscriptionState = protocolObjects.headerFactory - .createSubscriptionStateHeader(SubscriptionStateHeader.ACTIVE); - request.addHeader(subscriptionState); - request.addHeader(eventHeader); - - allSubscriptionStates.add(subscriptionState.getState().toLowerCase()); - // Lets mark our Contact -// ((SipURI)dialog.getLocalParty().getURI()).setParameter("id","not2"); - - ClientTransaction ct = sipProvider.getNewClientTransaction(request); - logger.info("NOTIFY Branch ID " + - ((ViaHeader)request.getHeader(ViaHeader.NAME)).getParameter("branch")); - this.notifier.dialog.sendRequest(ct); - logger.info("Dialog " + dialog); - logger.info("Dialog state after active NOTIFY: " + dialog.getState()); - if(sendByeBeforeTerminatingNotify && !byeSent) { - sendBye(); - } - } - } catch (Throwable ex) { - logger.info(ex.getMessage(), ex); - } - } - } - - public void processRequest(RequestEvent requestReceivedEvent) { - if(abortProcessing) { - logger.error("Processing aborted"); - return ; - } - - - Request request = requestReceivedEvent.getRequest(); - allRequests.add(request); - if(firstRequest == null) firstRequest = request; - ServerTransaction serverTransactionId = requestReceivedEvent - .getServerTransaction(); - - logger.info("\n\nRequest " + request.getMethod() - + " received at " + protocolObjects.sipStack.getStackName() - + " with server transaction id " + serverTransactionId - + " dialog " + requestReceivedEvent.getDialog()); - - if (request.getMethod().equals(Request.INVITE)) { - processInvite(requestReceivedEvent, serverTransactionId); - } - - if (request.getMethod().equals(Request.BYE)) { - processBye(request, serverTransactionId); - } - - if (request.getMethod().equals(Request.ACK)) { - processAck(request, serverTransactionId); - } - - if (request.getMethod().equals(Request.PRACK)) { - processPrack(request, serverTransactionId); - } - - if (request.getMethod().equals(Request.CANCEL)) { - processCancel(requestReceivedEvent, serverTransactionId); - } - - if (request.getMethod().equals(Request.MESSAGE)) { - processMessage(request, serverTransactionId); - } - - if (request.getMethod().equals(Request.REGISTER)) { - processRegister(request, serverTransactionId); - } - - if (request.getMethod().equals(Request.NOTIFY)) { - processNotify(requestReceivedEvent, serverTransactionId); - } - - if (request.getMethod().equals(Request.SUBSCRIBE)) { - processSubscribe(requestReceivedEvent, serverTransactionId); - } - - if (request.getMethod().equals(Request.UPDATE)) { - processUpdate(request, serverTransactionId); - } - - if (request.getMethod().equals(Request.OPTIONS)) { - processOptions(request, serverTransactionId); - } - - if (request.getMethod().equals(Request.INFO)) { - processInfo(request, serverTransactionId); - } - - if (request.getMethod().equals(Request.PUBLISH)) { - processPublish(requestReceivedEvent, serverTransactionId); - } - - if (request.getMethod().equals(Request.REFER)) { - processRefer(requestReceivedEvent, serverTransactionId); - } - } - - private void processPrack(Request request, - ServerTransaction serverTransactionId) { - - try { - prackReceived = true; - prackRequestReceived = request; - ServerTransaction st = serverTransactionId; - if (st == null) { - try { - st = sipProvider.getNewServerTransaction(request); - } catch ( TransactionAlreadyExistsException taex ) { - // This is a retransmission so just return. - return; - } - } - Response response = protocolObjects.messageFactory.createResponse( - 200, request); - Address address = protocolObjects.addressFactory - .createAddress("Shootme "); - contactHeader = protocolObjects.headerFactory.createContactHeader(address); - response.addHeader(contactHeader); - st.sendResponse(response); - - Thread.sleep(200); - - RequireHeader requireHeader = (RequireHeader) request.getHeader(RequireHeader.NAME); - if(provisionalResponsesToSend.size() > 0) { - logger.info("shootme: Creating provisional response with status code " + provisionalResponsesToSend.get(0)); - response = protocolObjects.messageFactory.createResponse( - provisionalResponsesToSend.get(0), inviteRequest); - requireHeader = protocolObjects.headerFactory.createRequireHeader("100rel"); - response.addHeader(requireHeader); - Header rseqHeader = protocolObjects.headerFactory.createRSeqHeader(rseqNumber.getAndIncrement()); - response.addHeader(rseqHeader); - ((MessageExt)response).getToHeader().setTag(((MessageExt) request).getToHeader().getTag()); - address = protocolObjects.addressFactory - .createAddress("Shootme "); - contactHeader = protocolObjects.headerFactory.createContactHeader(address); - response.addHeader(contactHeader); - dialog.sendReliableProvisionalResponse(response); - provisionalResponsesToSend.remove(0); - return; - } - - if(!sendUpdateAfterUpdate && !waitForCancel - // https://github.com/Mobicents/sip-servlets/issues/66 include UPDATE after PRACK - && !sendUpdateAfterPrack) - inviteServerTid.sendResponse(getFinalResponse()); - else { - logger.info("sendUpdateAfterUpdate or Waiting for CANCEL, stopping the PRACK processing and not sending 200 OK to INVITE"); - } - } catch(Exception e) { - logger.error("Unexpected exception while trying to send the 200 to PRACK " + request, e); - } - } - - public void processRefer(RequestEvent requestEvent, - ServerTransaction serverTransactionId) { - try { - SipProvider sipProvider = (SipProvider) requestEvent.getSource(); - Request request = requestEvent.getRequest(); - - logger.info("shootist: got a refer . ServerTxId = " + serverTransactionId); - ServerTransaction st = requestEvent.getServerTransaction(); - if (st == null) { - st = sipProvider.getNewServerTransaction(request); - } - inviteServerTid = st; - Dialog dialog = st.getDialog(); - - this.dialogCount ++; - this.dialog = dialog; - - logger.info("Shootme: dialog = " + dialog); - - Response response = protocolObjects.messageFactory.createResponse( - referResponseToSend, request); - sipETag = Integer.toString(new Random().nextInt(10000000)); - st.sendResponse(response); - this.transactionCount++; - logger.info("shootist: Sending " + referResponseToSend); - - List
headers = new ArrayList
(); - EventHeader eventHeader = (EventHeader) - protocolObjects.headerFactory.createHeader(EventHeader.NAME, "Refer"); - headers.add(eventHeader); - - if(sendNotifyForRefer) { - if(!referReceived) { - referReceived = true; - - SubscriptionStateHeader subscriptionStateHeader = (SubscriptionStateHeader) - protocolObjects.headerFactory.createHeader(SubscriptionStateHeader.NAME, "active;expires=3600"); - headers.add(subscriptionStateHeader); - allMessagesContent.add("SIP/2.0 100 Trying"); - sendInDialogSipRequest(Request.NOTIFY, "SIP/2.0 100 Trying", "message", "sipfrag;version=2.0", headers, null); - Thread.sleep(1000); - headers.remove(subscriptionStateHeader); - subscriptionStateHeader = (SubscriptionStateHeader) - protocolObjects.headerFactory.createHeader(SubscriptionStateHeader.NAME, "terminated;reason=noresource"); - headers.add(subscriptionStateHeader); - if(inviteRequest == null) { - ExtensionHeader extensionHeader = (ExtensionHeader) protocolObjects.headerFactory.createHeader("Out-Of-Dialog", "true"); - headers.add(extensionHeader); - } - allMessagesContent.add("SIP/2.0 200 OK"); - sendInDialogSipRequest(Request.NOTIFY, "SIP/2.0 200 OK", "message", "sipfrag;version=2.0", headers, null); - } else { - SubscriptionStateHeader subscriptionStateHeader = (SubscriptionStateHeader) - protocolObjects.headerFactory.createHeader(SubscriptionStateHeader.NAME, "active;expires=3600"); - headers.add(subscriptionStateHeader); - sendInDialogSipRequest(Request.NOTIFY, "SIP/2.0 100 Subsequent", "message", "sipfrag;version=2.0", headers, null); - } - } - - } catch (Exception ex) { - ex.printStackTrace(); - } - } - - private void processPublish(RequestEvent requestEvent, - ServerTransaction serverTransactionId) { - try { - SipProvider sipProvider = (SipProvider) requestEvent.getSource(); - Request request = requestEvent.getRequest(); - - logger.info("shootist: got a publish . ServerTxId = " + serverTransactionId); - ServerTransaction st = requestEvent.getServerTransaction(); - if (st == null) { - st = sipProvider.getNewServerTransaction(request); - } - inviteServerTid = st; - Dialog dialog = st.getDialog(); - - this.dialogCount ++; - this.dialog = dialog; - - logger.info("Shootme: dialog = " + dialog); - - if(request.getRawContent() != null) { - this.lastMessageContent = new String(request.getRawContent()); - allMessagesContent.add(new String(lastMessageContent)); - } - SIPIfMatchHeader sipIfMatchHeader = (SIPIfMatchHeader) request.getHeader(SIPIfMatchHeader.NAME); - boolean sipIfMatchFound = true; - if(sipIfMatchHeader!= null && sipIfMatchHeader.getETag() != null && !sipIfMatchHeader.getETag().equals(sipETag)) { - sipIfMatchFound = false; - } - if(sipIfMatchFound) { - - Response response = protocolObjects.messageFactory.createResponse( - 200, request); - sipETag = Integer.toString(new Random().nextInt(10000000)); - SIPETagHeader sipTagHeader = protocolObjects.headerFactory.createSIPETagHeader(sipETag); - response.addHeader(sipTagHeader); - response.addHeader(request.getHeader(ExpiresHeader.NAME)); - st.sendResponse(response); - this.transactionCount++; - logger.info("shootist: Sending OK."); - } else { - Response response = protocolObjects.messageFactory.createResponse( - 500, request); - serverTransactionId.sendResponse(response); - this.transactionCount++; - } - - } catch (Exception ex) { - ex.printStackTrace(); - } - } - - - public void processUpdate(Request request, - ServerTransaction serverTransactionId) { - try { - logger.info("shootist: got a update. ServerTxId = " + serverTransactionId); - if (serverTransactionId == null) { - logger.info("shootist: null TID."); - return; - } - - Dialog dialog = serverTransactionId.getDialog(); - logger.info("Dialog State = " + dialog.getState()); - Response response = protocolObjects.messageFactory.createResponse( - 200, request); - serverTransactionId.sendResponse(response); - this.transactionCount++; - logger.info("shootist: Sending OK."); - logger.info("Dialog State = " + dialog.getState()); - updateReceived = true; - updateRequest = request; - if (sendUpdateAfterUpdate) { - Request updateRequest = dialog.createRequest(Request.UPDATE); - - if (recordRoutingProxyTesting){ - ContactHeader contHdr = (ContactHeader) request.getHeader(ContactHeader.NAME); - SipURI sipUri = (SipURI)contHdr.getAddress().getURI(); - updateRequest.setRequestURI(sipUri); - } - - long seqNo = (((CSeqHeader) request.getHeader(CSeqHeader.NAME)).getSeqNumber()); - CSeqHeader cseqNew = protocolObjects.headerFactory.createCSeqHeader(++seqNo, "UPDATE"); - updateRequest.setHeader(cseqNew); - - ClientTransaction ct = sipProvider - .getNewClientTransaction(updateRequest); - ct.sendRequest(); - sendUpdate = true; - if(!prackReceived) { - sendUpdateAfterUpdate = false; - } - } - // https://github.com/Mobicents/sip-servlets/issues/66 send OK if there was an UPDATE after PRACK - if(!sendUpdateAfterUpdate && sendUpdateAfterPrack) - inviteServerTid.sendResponse(getFinalResponse()); - else { - logger.info("sendUpdateAfterUpdate or Waiting for CANCEL, stopping the PRACK processing and not sending 200 OK to INVITE"); - } - } catch (Exception ex) { - ex.printStackTrace(); - } - } - - public void processOptions(Request request, - ServerTransaction serverTransactionId) { - try { - logger.info("shootist: got a OPTIONS. ServerTxId = " + serverTransactionId); - - if (serverTransactionId == null) { - serverTransactionId = sipProvider.getNewServerTransaction(request); - } - if (serverTransactionId == null) { - logger.info("shootist: null TID."); - return; - } - - Dialog dialog = serverTransactionId.getDialog(); - if(dialog != null) { - logger.info("Dialog State = " + dialog.getState()); - } - if(!waitForCancel) { - Response response = protocolObjects.messageFactory.createResponse( - 200, request); - serverTransactionId.sendResponse(response); - this.transactionCount++; - logger.info("shootist: Sending OK."); - if(dialog != null) { - logger.info("Dialog State = " + dialog.getState()); - } - } - this.optionsRequest = request; - } catch (Exception ex) { - ex.printStackTrace(); - } - } - - public void processInfo(Request request, - ServerTransaction serverTransactionId) { - try { - logger.info("shootist: got a info. ServerTxId = " + serverTransactionId); - if (serverTransactionId == null) { - logger.info("shootist: null TID."); - return; - } - - Dialog dialog = serverTransactionId.getDialog(); - logger.info("Dialog State = " + dialog.getState()); - Response response = protocolObjects.messageFactory.createResponse( - 200, request); - serverTransactionId.sendResponse(response); - this.transactionCount++; - logger.info("shootist: Sending OK."); - logger.info("Dialog State = " + dialog.getState()); - infoRequest = request; - } catch (Exception ex) { - ex.printStackTrace(); - } - } - - /** - * Process the invite request. - */ - public void processSubscribe(RequestEvent requestEvent, - ServerTransaction serverTransaction) { - SipProvider sipProvider = (SipProvider) requestEvent.getSource(); - Request request = requestEvent.getRequest(); - try { - logger.info("notifier: got an Subscribe sending OK"); - logger.info("notifier: " + request); - logger.info("notifier : dialog = " + requestEvent.getDialog()); - EventHeader eventHeader = (EventHeader) request.getHeader(EventHeader.NAME); -// this.gotSubscribeRequest = true; - - // Always create a ServerTransaction, best as early as possible in the code - Response response = null; - ServerTransaction st = requestEvent.getServerTransaction(); - if (st == null) { - st = sipProvider.getNewServerTransaction(request); - } - - // Check if it is an initial SUBSCRIBE or a refresh / unsubscribe - boolean isInitial = requestEvent.getDialog() == null; - if ( isInitial ) { - // JvB: need random tags to test forking - String toTag = Integer.toHexString( (int) (Math.random() * Integer.MAX_VALUE) ); - response = protocolObjects.messageFactory.createResponse(202, request); - ToHeader toHeader = (ToHeader) response.getHeader(ToHeader.NAME); - - // Sanity check: to header should not ahve a tag. Else the dialog - // should have matched - toHeader.setTag(toTag); // Application is supposed to set. - - this.dialog = st.getDialog(); - // subscribe dialogs do not terminate on bye. - this.dialog.terminateOnBye(false); - } else { - response = protocolObjects.messageFactory.createResponse(202, request); - this.dialog = st.getDialog(); - // subscribe dialogs do not terminate on bye. - this.dialog.terminateOnBye(false); - } - - // Both 2xx response to SUBSCRIBE and NOTIFY need a Contact - Address address = protocolObjects.addressFactory.createAddress("Notifier "); - ((SipURI)address.getURI()).setPort( sipProvider.getListeningPoint(ListeningPoint.UDP).getPort() ); - ContactHeader contactHeader = protocolObjects.headerFactory.createContactHeader(address); - response.addHeader(contactHeader); - - // Expires header is mandatory in 2xx responses to SUBSCRIBE - ExpiresHeader expires = (ExpiresHeader) request.getHeader( ExpiresHeader.NAME ); - if (expires==null) { - expires = protocolObjects.headerFactory.createExpiresHeader(30); // rather short - } - response.addHeader( expires ); - - /* - * JvB: The SUBSCRIBE MUST be answered first. See RFC3265 3.1.6.2: - * "[...] a NOTIFY message is always sent immediately after any 200- - * class response to a SUBSCRIBE request" - * - * Do this before creating the NOTIFY request below - */ - if(!sendNotifyBeforeResponseToSubscribe) { - logger.info("Sending Response to Subscribe"); - Thread.sleep(waitBeforeFinalResponse); - st.sendResponse(response); - } else { - ((SIPDialog)dialog).setLastResponse((SIPTransaction)st, (SIPResponse)response); - } - //Thread.sleep(1000); // Be kind to implementations - - /* - * NOTIFY requests MUST contain a "Subscription-State" header with a - * value of "active", "pending", or "terminated". The "active" value - * indicates that the subscription has been accepted and has been - * authorized (in most cases; see section 5.2.). The "pending" value - * indicates that the subscription has been received, but that - * policy information is insufficient to accept or deny the - * subscription at this time. The "terminated" value indicates that - * the subscription is not active. - */ - if(sendNotify ) { - Request notifyRequest = dialog.createRequest("NOTIFY"); - - - // Mark the contact header, to check that the remote contact is updated - // ((SipURI)contactHeader.getAddress().getURI()).setParameter("id","not"); - - // Initial state is pending, second time we assume terminated (Expires==0) - SubscriptionStateHeader sstate = protocolObjects.headerFactory.createSubscriptionStateHeader( - expires.getExpires() != 0 ? SubscriptionStateHeader.PENDING : SubscriptionStateHeader.TERMINATED ); - allSubscriptionStates.add(sstate.getState().toLowerCase()); - - - // Need a reason for terminated - if ( sstate.getState().equalsIgnoreCase("terminated") ) { - sstate.setReasonCode( "deactivated" ); - } - - notifyRequest.addHeader(sstate); - notifyRequest.setHeader(eventHeader); - notifyRequest.setHeader(contactHeader); - // notifyRequest.setHeader(routeHeader); - ClientTransaction ct = sipProvider.getNewClientTransaction(notifyRequest); - - if(sstate.getState().equals(SubscriptionStateHeader.TERMINATED)) { - Thread.sleep(timeToWaitBetweenSubsNotify); - } - // Let the other side know that the tx is pending acceptance - // - dialog.sendRequest(ct); - logger.info("NOTIFY Branch ID " + - ((ViaHeader)request.getHeader(ViaHeader.NAME)).getParameter("branch")); - logger.info("Dialog " + dialog); - logger.info("Dialog state after pending NOTIFY: " + dialog.getState()); - - if (expires.getExpires() != 0) { - Thread myEventSource = new Thread(new MyEventSource(this,eventHeader)); - myEventSource.start(); - } - if(sendNotifyBeforeResponseToSubscribe) { - logger.info("Sending Response to Subscribe"); - Thread.sleep(waitBeforeFinalResponse); - st.sendResponse(response); - } - } - } catch (Throwable ex) { - logger.info(ex.getMessage(), ex); - } - } - - public void processNotify(RequestEvent requestEvent, - ServerTransaction serverTransactionId) { - SipProvider provider = (SipProvider) requestEvent.getSource(); - Request notify = requestEvent.getRequest(); - try { - logger.info("subscriber: got a notify count " + this.notifyCount++ ); - if (serverTransactionId == null) { - logger.info("subscriber: null TID."); - serverTransactionId = provider.getNewServerTransaction(notify); - } - Dialog dialog = serverTransactionId.getDialog(); -// if ( dialog != subscriberDialog ) { -// if (forkedDialog == null) { -// forkedDialog = dialog; -// } else { -// AbstractSubsnotifyTestCase.assertTrue("Dialog should be either the subscriber dialog ", -// forkedDialog == dialog); -// } -// } -// -// this.dialogs.add(dialog); - if(dialog != null) { - logger.info("Dialog State = " + dialog.getState()); - } - - Response response = protocolObjects.messageFactory.createResponse(finalResponseToSend, notify); - // SHOULD add a Contact - ContactHeader contact = null; - if(contactHeader != null) { - contact = (ContactHeader) contactHeader.clone(); - } else { - SipURI contactURI = protocolObjects.addressFactory.createSipURI(null, "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); - contactURI.setPort(listeningPoint.getPort()); - Address contactAddress = protocolObjects.addressFactory.createAddress(contactURI); - contact = protocolObjects.headerFactory.createContactHeader(contactAddress); - } - response.addHeader( contact ); - logger.info("Transaction State = " + serverTransactionId.getState()); - serverTransactionId.sendResponse(response); - if(dialog != null) { - logger.info("Dialog State = " + dialog.getState()); - } - SubscriptionStateHeader subscriptionState = (SubscriptionStateHeader) notify - .getHeader(SubscriptionStateHeader.NAME); - - // Subscription is terminated? - String state = subscriptionState.getState(); - allSubscriptionStates.add(state.toLowerCase()); - if(notify.getRawContent() != null) { - this.lastMessageContent = new String(notify.getRawContent()); - allMessagesContent.add(new String(lastMessageContent)); - } - if (state.equalsIgnoreCase(SubscriptionStateHeader.TERMINATED)) { - if(subscriptionState.getReasonCode() == null) { - dialog.delete(); - } - } else if (state.equalsIgnoreCase(SubscriptionStateHeader.ACTIVE)) { - if("reg".equalsIgnoreCase(((EventHeader)notify.getHeader(EventHeader.NAME)).getEventType())) { - if(sendByeBeforeTerminatingNotify) { - dialog.terminateOnBye(false); - sendBye(); - Thread.sleep(1000); - } - logger.info("Subscriber: sending unSUBSCRIBE"); - - // Else we end it ourselves - Request unsubscribe = dialog.createRequest(Request.SUBSCRIBE); - - logger.info( "dialog created:" + unsubscribe ); - // SHOULD add a Contact (done by dialog), lets mark it to test updates - // ((SipURI) dialog.getLocalParty().getURI()).setParameter( "id", "unsub" ); - ExpiresHeader expires = protocolObjects.headerFactory.createExpiresHeader(0); - unsubscribe.addHeader(expires); - // JvB note : stack should do this! - unsubscribe.addHeader(notify.getHeader(EventHeader.NAME)); // copy - // event - // header - logger.info("Sending Unsubscribe : " + unsubscribe); - logger.info("unsubscribe dialog " + dialog); - ClientTransaction ct = sipProvider.getNewClientTransaction(unsubscribe); - dialog.sendRequest(ct); - if(sendByeAfterTerminatingNotify) { - Thread.sleep(1000); - sendBye(); - } - } else if(sendByeBeforeTerminatingNotify) { - sendBye(); - } - } else { - logger.info("Subscriber: state now " + state);// pending - } - - } catch (Exception ex) { - logger.error("Unexpected exception",ex); - } - } - - private void processMessage(Request request, - ServerTransaction serverTransactionId) { - if(request.toString().contains("408 received")) { - txTimeoutReceived = true; - } - ServerTransaction serverTransaction = null; - - messageRequest = request; - try { - - serverTransaction = - (serverTransactionId == null? - sipProvider.getNewServerTransaction(request): - serverTransactionId); - } catch (javax.sip.TransactionAlreadyExistsException ex) { - ex.printStackTrace(); - return; - } catch (javax.sip.TransactionUnavailableException ex1) { - ex1.printStackTrace(); - return; - } - - ContentTypeHeader contentTypeHeader = (ContentTypeHeader) - request.getHeader(ContentTypeHeader.NAME); - boolean sendInvitewithJoin = false; - boolean sendInvitewithReplaces = false; - if(contentTypeHeader != null) { - if(TEXT_CONTENT_TYPE.equals(contentTypeHeader.getContentType())) { - this.lastMessageContent = new String(request.getRawContent()); - allMessagesContent.add(new String(lastMessageContent)); - if(lastMessageContent.indexOf("Join : ") != -1) { - this.lastMessageContent = lastMessageContent.substring("Join : ".length()); - sendInvitewithJoin = true; - } - if(lastMessageContent.indexOf("Replaces : ") != -1) { - this.lastMessageContent = lastMessageContent.substring("Replaces : ".length()); - sendInvitewithReplaces = true; - } - } - } else { - if(request.getHeader("From").toString().contains("b2bua@sip-servlets")) - b2buamessagereceived = true; - } - try { - Response okResponse = protocolObjects.messageFactory.createResponse( - Response.OK, request); - ToHeader toHeader = (ToHeader) okResponse.getHeader(ToHeader.NAME); - if (toHeader.getTag() == null) { - toHeader.setTag(Integer.toString(new Random().nextInt(10000000))); - } -// okResponse.addHeader(contactHeader); - serverTransaction.sendResponse(okResponse); - } catch (Exception ex) { - ex.printStackTrace(); - logger.error("error sending OK response to message", ex); - } - if(sendInvitewithJoin) { - try { - String fromUser = "receiver"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = protocolObjects.addressFactory.createSipURI( - fromUser, fromHost); - - String toUser = "join-receiver"; - String toHost = "sip-servlets.com"; - SipURI toAddress = protocolObjects.addressFactory.createSipURI( - toUser, toHost); - String[] headerNames = new String[] {"Join"}; - String[] headerContents = new String[] {lastMessageContent}; - sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, headerNames, headerContents, true); - } catch (Exception ex) { - ex.printStackTrace(); - logger.error("error sending INVITE with Join", ex); - } - } - if(sendInvitewithReplaces) { - try { - String fromUser = "receiver"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = protocolObjects.addressFactory.createSipURI( - fromUser, fromHost); - - String toUser = "replaces-receiver"; - String toHost = "sip-servlets.com"; - SipURI toAddress = protocolObjects.addressFactory.createSipURI( - toUser, toHost); - String[] headerNames = new String[] {"Replaces"}; - String[] headerContents = new String[] {lastMessageContent}; - sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, headerNames, headerContents, true); - } catch (Exception ex) { - ex.printStackTrace(); - logger.error("error sending INVITE with Join", ex); - } - } - } - - private void processRegister(Request request, - ServerTransaction serverTransactionId) { - - try { - registerReceived = request; - ServerTransaction serverTransaction = serverTransactionId == null? sipProvider.getNewServerTransaction(request) : serverTransactionId; - - System.out.println("challenge Requests ? " + challengeRequests); - lastRegisterCSeqNumber = ((CSeqHeader)request.getHeader("CSeq")).getSeqNumber(); - if(challengeRequests) { - // Verify AUTHORIZATION !!!!!!!!!!!!!!!! - dsam = new DigestServerAuthenticationMethod(); - dsam.initialize(); // it should read values from file, now all static - if ( !checkProxyAuthorization(request) ) { - Response responseauth = protocolObjects.messageFactory.createResponse(Response.PROXY_AUTHENTICATION_REQUIRED,request); - - ProxyAuthenticateHeader proxyAuthenticate = - protocolObjects.headerFactory.createProxyAuthenticateHeader(dsam.getScheme()); - proxyAuthenticate.setParameter("realm",dsam.getRealm(null)); - proxyAuthenticate.setParameter("nonce",dsam.generateNonce()); - //proxyAuthenticateImpl.setParameter("domain",authenticationMethod.getDomain()); - proxyAuthenticate.setParameter("opaque",""); - - proxyAuthenticate.setParameter("algorithm",dsam.getAlgorithm()); - if(testNC) { - proxyAuthenticate.setQop("auth"); - } - responseauth.setHeader(proxyAuthenticate); - // alexander kozlov : Adding the to tag to 407 as well - ToHeader toHeader = (ToHeader) responseauth.getHeader(ToHeader.NAME); - if (toHeader.getTag() == null) { - toHeader.setTag(Integer.toString(new Random().nextInt(10000000))); - } - - if (serverTransaction!=null) - serverTransaction.sendResponse(responseauth); - else - sipProvider.sendResponse(responseauth); - - System.out.println("RequestValidation: 407 PROXY_AUTHENTICATION_REQUIRED replied:\n"+responseauth.toString()); - return; - } else if(multipleChallengeInResponse && lastRegisterCSeqNumber > 2 && lastRegisterCSeqNumber % 2 == 1) { - Response responseauth = protocolObjects.messageFactory.createResponse(Response.PROXY_AUTHENTICATION_REQUIRED,request); - -// ListIterator
proxyAuthHeaders = request.getHeaders(ProxyAuthorizationHeader.NAME); -// while (proxyAuthHeaders.hasNext()) { -// ProxyAuthorizationHeader header = (ProxyAuthorizationHeader) proxyAuthHeaders.next(); -// ProxyAuthenticateHeader proxyAuthenticate = -// protocolObjects.headerFactory.createProxyAuthenticateHeader(dsam.getScheme()); -// proxyAuthenticate.setAlgorithm(header.getAlgorithm()); -// proxyAuthenticate.setNonce(header.getNonce()); -// proxyAuthenticate.setRealm(header.getRealm()); -// proxyAuthenticate.setParameter("username", header.getParameter("username")); -// proxyAuthenticate.setParameter("uri", header.getParameter("uri")); -// proxyAuthenticate.setParameter("response", header.getParameter("response")); -// proxyAuthenticate.setStale(false); -// logger.debug("Adding auth header to challenge response " + proxyAuthenticate); -// responseauth.addLast(proxyAuthenticate); -// } -// - ProxyAuthenticateHeader proxyAuthenticate = - protocolObjects.headerFactory.createProxyAuthenticateHeader(dsam.getScheme()); - proxyAuthenticate.setParameter("realm",dsam.getRealm(null)); - proxyAuthenticate.setParameter("nonce",dsam.generateNonce()); - //proxyAuthenticateImpl.setParameter("domain",authenticationMethod.getDomain()); - proxyAuthenticate.setParameter("opaque",""); - proxyAuthenticate.setStale(true); - - proxyAuthenticate.setParameter("algorithm",dsam.getAlgorithm()); - responseauth.addHeader(proxyAuthenticate); - // alexander kozlov : Adding the to tag to 407 as well - ToHeader toHeader = (ToHeader) responseauth.getHeader(ToHeader.NAME); - if (toHeader.getTag() == null) { - toHeader.setTag(Integer.toString(new Random().nextInt(10000000))); - } - - if (serverTransaction!=null) - serverTransaction.sendResponse(responseauth); - else - sipProvider.sendResponse(responseauth); - - System.out.println("RequestValidation: 407 PROXY_AUTHENTICATION_REQUIRED replied:\n"+responseauth.toString()); - } - } - - Response okResponse = protocolObjects.messageFactory.createResponse( - Response.OK, request); - if(testNextNonce) { - AuthenticationInfoHeader authenticationInfoHeader = protocolObjects.headerFactory.createAuthenticationInfoHeader(""); - nextNonce = dsam.generateNonce(); - authenticationInfoHeader.setNextNonce(nextNonce); - authenticationInfoHeader.removeParameter(ParameterNames.RESPONSE_AUTH); - okResponse.addHeader(authenticationInfoHeader); - } - ToHeader toHeader = (ToHeader) okResponse.getHeader(ToHeader.NAME); - if (toHeader.getTag() == null) { - toHeader.setTag(Integer.toString(new Random().nextInt(10000000))); - } -// okResponse.addHeader(contactHeader); - SupportedHeader supportedHeader = (SupportedHeader) request.getHeader(SupportedHeader.NAME); - PathHeader pathHeader = (PathHeader) request.getHeader(PathHeader.NAME); - contactHeader = (ContactHeader) request.getHeader(ContactHeader.NAME); - if(supportedHeader != null) { - okResponse.addHeader(supportedHeader); - if(((HeaderExt)supportedHeader).getValue().contains("outbound")) { - okResponse.addHeader(protocolObjects.headerFactory.createRequireHeader("outbound")); - contactHeader.setExpires(3600); - okResponse.addHeader(contactHeader); - if(pathHeader != null) { - okResponse.addHeader(pathHeader); - } - } - } - serverTransaction.sendResponse(okResponse); - } catch (Exception ex) { - ex.printStackTrace(); - logger.error("error sending OK response to message", ex); - } - } - - private void processCancel(RequestEvent requestEvent, - ServerTransaction serverTransactionId) { - try { - cancelReceived = true; - Thread.sleep(waitBeforeFinalResponse); - SipProvider sipProvider = (SipProvider) requestEvent.getSource(); - Request request = requestEvent.getRequest(); - setCancelRequest(request); - Response response = protocolObjects.messageFactory.createResponse( - Response.OK, request); - ServerTransaction st = requestEvent.getServerTransaction(); - - if (st == null) { - st = sipProvider.getNewServerTransaction(request); - } - Dialog dialog = st.getDialog(); - logger.info("Shootme: dialog = " + dialog); - st.sendResponse(response); - - response = protocolObjects.messageFactory.createResponse( - Response.REQUEST_TERMINATED, inviteRequest); - inviteServerTid.sendResponse(response); - } catch (Exception ex) { - ex.printStackTrace(); - logger.error("error sending CANCEL responses", ex); - } - } - - /** - * Process the invite request. - */ - public void processInvite(RequestEvent requestEvent, - ServerTransaction serverTransaction) { - inviteReceived = true; - SipProvider sipProvider = (SipProvider) requestEvent.getSource(); - Request request = requestEvent.getRequest(); - inviteRequest = request; - logger.info("shootme: got an Invite " + request); - if(dropRequest) { - logger.warn("dropping " + request); - return; - } - try { - ServerTransaction st = requestEvent.getServerTransaction(); - if (st == null) { - st = sipProvider.getNewServerTransaction(request); - } - inviteServerTid = st; - Dialog dialog = st.getDialog(); - if(request.getHeader(JoinHeader.NAME) != null) { - setJoinRequestReceived(true); - this.joinDialog = dialog; - } else if (request.getHeader(ReplacesHeader.NAME) != null) { - setReplacesRequestReceived(true); - this.replacesDialog = dialog; - } else { - this.dialogCount ++; - this.dialog = dialog; - } - - logger.info("Shootme: dialog = " + dialog); - if(dialog != null) { - logger.info("Shootme: dialog state = " + dialog.getState()); - } - if(dialog != null && disableSequenceNumberValidation) { - ((DialogExt)dialog).disableSequenceNumberValidation(); - } - this.inviteRequest = request; - - boolean sendReliably = false; - RequireHeader requireHeader = (RequireHeader) request.getHeader(RequireHeader.NAME); - if(requireHeader != null && "100rel".equalsIgnoreCase(requireHeader.getOptionTag().trim())) { - sendReliably = true; - } - - if(sendProvisionalResponseBeforeChallenge) { - sendProvisionalResponses(request, st, dialog, sendReliably); - } - if(challengeRequests) { - // Verify AUTHORIZATION !!!!!!!!!!!!!!!! - dsam = new DigestServerAuthenticationMethod(); - dsam.initialize(); // it should read values from file, now all static - if ( !checkProxyAuthorization(request) ) { - Thread.sleep(600); - if(!sendProvisionalResponseBeforeChallenge) { - Response response100 = protocolObjects.messageFactory.createResponse(100,request); - if (st!=null) - st.sendResponse(response100); - else - sipProvider.sendResponse(response100); - - Thread.sleep(600); - } - - Response responseauth = protocolObjects.messageFactory.createResponse(Response.PROXY_AUTHENTICATION_REQUIRED,request); - - ProxyAuthenticateHeader proxyAuthenticate = - protocolObjects.headerFactory.createProxyAuthenticateHeader(dsam.getScheme()); - proxyAuthenticate.setParameter("realm",dsam.getRealm(null)); - proxyAuthenticate.setParameter("nonce",dsam.generateNonce()); - //proxyAuthenticateImpl.setParameter("domain",authenticationMethod.getDomain()); - proxyAuthenticate.setParameter("opaque",""); - proxyAuthenticate.setParameter("stale","FALSE"); - proxyAuthenticate.setParameter("algorithm",dsam.getAlgorithm()); - responseauth.setHeader(proxyAuthenticate); - - if(multipleChallengeInResponse) { - proxyAuthenticate = - protocolObjects.headerFactory.createProxyAuthenticateHeader(dsam.getScheme()); - proxyAuthenticate.setParameter("realm",dsam.getRealm(null)); - proxyAuthenticate.setParameter("nonce",dsam.generateNonce()); - //proxyAuthenticateImpl.setParameter("domain",authenticationMethod.getDomain()); - proxyAuthenticate.setParameter("opaque",""); - proxyAuthenticate.setParameter("stale","true"); - proxyAuthenticate.setParameter("algorithm",dsam.getAlgorithm()); - responseauth.addHeader(proxyAuthenticate); - } - - ToHeader toHeader = (ToHeader) responseauth.getHeader(ToHeader.NAME); - toHeader.setTag(toTag); // Application is supposed to set. - - if(sendProvisionalResponseBeforeChallenge) { - provisionalResponsesToSend.clear(); - toTag = Integer.toString(new Random().nextInt(10000000)); - System.out.println("Resetted toTag to "+toTag); -// this.dialog.delete(); -// ((SIPTransactionStack)this.protocolObjects.sipStack).removeDialog((SIPDialog)dialog); -//// Thread.sleep(10000); -// this.dialog = null; - } - - if (st!=null) - st.sendResponse(responseauth); - else - sipProvider.sendResponse(responseauth); - - - System.out.println("RequestValidation: 407 PROXY_AUTHENTICATION_REQUIRED replied:\n"+responseauth.toString()); - return; - } - if(checkSDPNullOnChallengeRequests) { - //https://code.google.com/p/sipservlets/issues/detail?id=278 - if(request.getContentLength().getContentLength() > 0) { - throw new Exception("SDP should be empty"); - } - } - System.out.println("shootme: got an Invite with Authorization, sending Trying"); - } - if(!sendProvisionalResponseBeforeChallenge) { - sendProvisionalResponses(request, st, dialog, sendReliably); - } - - if (sendUpdateAfterProvisionalResponses) { - Request updateRequest = dialog.createRequest(Request.UPDATE); - - if (recordRoutingProxyTesting){ - ContactHeader contHdr = (ContactHeader) request.getHeader(ContactHeader.NAME); - SipURI sipUri = (SipURI)contHdr.getAddress().getURI(); - updateRequest.setRequestURI(sipUri); - } - - long seqNo = (((CSeqHeader) request.getHeader(CSeqHeader.NAME)).getSeqNumber()); - CSeqHeader cseqNew = protocolObjects.headerFactory.createCSeqHeader(++seqNo, "UPDATE"); - updateRequest.setHeader(cseqNew); - - sipProvider.sendRequest(updateRequest); - sendUpdate = true; - } - - if(respondWithError != null && !sendReliably) { - Response response = protocolObjects.messageFactory.createResponse( - respondWithError, request); - st.sendResponse(response); - return; - } - - - ContactHeader contactHeader = (ContactHeader)request.getHeader(ContactHeader.NAME); - if(contactHeader != null) { - Iterator it = request.getHeaders(ContactHeader.NAME); - int c=0; - while(it.hasNext()) {c++;it.next();} - bindings = c; - } - if(contactHeader != null && "0.0.0.0".equals(((SipURI)contactHeader.getAddress().getURI()).getHost())) { - abortProcessing = true; - throw new IllegalArgumentException("we received a contact header with 0.0.0.0 in an INVITE !"); - } - - if(!waitForCancel) { - Address address = protocolObjects.addressFactory.createAddress("Shootme "); - if(finalResponseToSend == Response.MOVED_TEMPORARILY) { - address = protocolObjects.addressFactory.createAddress("Shootme "); - } - contactHeader = protocolObjects.headerFactory.createContactHeader(address); - setFinalResponse(protocolObjects.messageFactory - .createResponse(finalResponseToSend, request)); - Response response = getFinalResponse(); - logger.debug("created final response " + response); - if(testAckViaParam) { - ViaHeader viaHeader = (ViaHeader)response.getHeader(ViaHeader.NAME); - viaHeader.setParameter("testAckViaParam", "true"); - } - if(testNextNonce) { - AuthenticationInfoHeader authenticationInfoHeader = protocolObjects.headerFactory.createAuthenticationInfoHeader(""); - nextNonce = dsam.generateNonce(); - authenticationInfoHeader.setNextNonce(nextNonce); - authenticationInfoHeader.removeParameter(ParameterNames.RESPONSE_AUTH); - response.addHeader(authenticationInfoHeader); - } - ToHeader toHeader = (ToHeader) response.getHeader(ToHeader.NAME); - if(sendProvisionalResponseBeforeChallenge) { - toHeader.removeParameter("tag"); - } - if(toHeader.getTag() == null) { - logger.debug("setting to Tag " + toTag); - toHeader.setTag(toTag); // Application is supposed to set. - } - getFinalResponse().addHeader(contactHeader); - if(isAddRecordRouteForResponses()) { - address = protocolObjects.addressFactory - .createAddress("sip:127.0.0.1:" + myPort +";transport="+protocolObjects.transport); - RecordRouteHeader recordRouteHeader = protocolObjects.headerFactory.createRecordRouteHeader(address); - response.addHeader(recordRouteHeader); - } - if(!sendReliably) { - Thread.sleep(waitBeforeFinalResponse); - logger.debug("sending back response " + response); - st.sendResponse(response); - } - - if(sendUpdateAfterPrack){ - Thread.sleep(waitBeforeFinalResponse); -// st.sendResponse(getFinalResponse()); - } - } else { - logger.info("Waiting for CANCEL, stopping the INVITE processing "); - return ; - } - - if(request.getRequestURI() instanceof SipURI && ("join").equalsIgnoreCase(((SipUri)request.getRequestURI()).getUser())) { - sendJoinMessage = true; - } - if(request.getRequestURI() instanceof SipURI && ("replaces").equalsIgnoreCase(((SipUri)request.getRequestURI()).getUser())) { - sendReplacesMessage = true; - } - } catch (Exception ex) { - logger.error("unexpected exception", ex); - } - } - - private void sendProvisionalResponses(Request request, - ServerTransaction st, Dialog dialog, boolean sendReliably) - throws InterruptedException, ParseException, - InvalidArgumentException, SipException { - RequireHeader requireHeader; - Iterator provisionalResponseIt = provisionalResponsesToSend.iterator(); - while (provisionalResponseIt.hasNext()) { - int provisionalResponseToSend = provisionalResponseIt.next(); - Thread.sleep(getTimeToWaitBetweenProvisionnalResponse()); - logger.info("shootme: Creating provisional response with status code " + provisionalResponseToSend); - Response response = protocolObjects.messageFactory.createResponse( - provisionalResponseToSend, request); - if(response.getStatusCode() == 183) { - response.setReasonPhrase("different" + System.nanoTime()); - } - if(provisionalResponseToSend >= Response.TRYING && provisionalResponseToSend < Response.OK) { - ToHeader toHeader = (ToHeader) response.getHeader(ToHeader.NAME); - if(provisionalResponseToSend != Response.TRYING && toHeader.getTag() == null) { - toHeader.setTag(toTag); // Application is supposed to set. - } - if(sendReliably && provisionalResponseToSend != Response.TRYING) { - provisionalResponsesToSend.remove(0); - provisionalResponseIt = provisionalResponsesToSend.iterator(); - requireHeader = protocolObjects.headerFactory.createRequireHeader("100rel"); - response.addHeader(requireHeader); - Header rseqHeader = protocolObjects.headerFactory.createRSeqHeader(rseqNumber.getAndIncrement()); - response.addHeader(rseqHeader); - Address address = protocolObjects.addressFactory - .createAddress("Shootme "); - contactHeader = protocolObjects.headerFactory.createContactHeader(address); - response.addHeader(contactHeader); - if(isAddRecordRouteForResponses()) { - address = protocolObjects.addressFactory - .createAddress("sip:127.0.0.1:" + myPort +";transport="+protocolObjects.transport); - RecordRouteHeader recordRouteHeader = protocolObjects.headerFactory.createRecordRouteHeader(address); - response.addHeader(recordRouteHeader); - } - dialog.sendReliableProvisionalResponse(response); - break; - } else { - if(provisionalResponseToSend == Response.TRYING) { - provisionalResponsesToSend.remove(0); - provisionalResponseIt = provisionalResponsesToSend.iterator(); - } - Address address = protocolObjects.addressFactory - .createAddress("Shootme "); - contactHeader = protocolObjects.headerFactory.createContactHeader(address); - response.addHeader(contactHeader); - if(isAddRecordRouteForResponses()) { - address = protocolObjects.addressFactory - .createAddress("sip:127.0.0.1:" + myPort +";transport="+protocolObjects.transport); - RecordRouteHeader recordRouteHeader = protocolObjects.headerFactory.createRecordRouteHeader(address); - response.addHeader(recordRouteHeader); - } - - st.sendResponse(response); - } - } - } - } - - public boolean checkProxyAuthorization(Request request) { - // Let Acks go through unchallenged. - ProxyAuthorizationHeader proxyAuthorization= - (ProxyAuthorizationHeader)request.getHeader(ProxyAuthorizationHeader.NAME); - - if (proxyAuthorization==null) { - logger.error("Authentication failed: ProxyAuthorization header missing!"); - return false; - }else{ - - if(nextNonce != null && !proxyAuthorization.getNonce().equals(nextNonce)) { - throw new IllegalArgumentException("Authentication failed: ProxyAuthorization nonce " + proxyAuthorization.getNonce() + " is different from the nextnonce previously generated " + nextNonce); - } - - if(nc > 0 && proxyAuthorization.getNonceCount() != nc) { - throw new IllegalArgumentException("Authentication failed: ProxyAuthorization nonceCount " + proxyAuthorization.getNonceCount() + " is different from the nextnonce previously generated " + nc); - } - - String username=proxyAuthorization.getParameter("username"); - //String password=proxyAuthorization.getParameter("password"); - - try{ - boolean res=dsam.doAuthenticate(username,proxyAuthorization,request); - if (res) logger.info("Authentication passed for user: "+username); - else logger.error("Authentication failed for user: "+username); - return res; - } - catch(Exception e) { - e.printStackTrace(); - return false; - } - } - } - - - public void processBye(Request request, - ServerTransaction serverTransactionId) { - try { - logger.info("shootist: got a bye . ServerTxId = " + serverTransactionId); - if(abortProcessing) { - logger.error("Processing Aborted!"); - return ; - } - this.byeReceived = true; - byeRequestReceived = request; - if (serverTransactionId == null) { - logger.info("shootist: null TID."); - return; - } - - Dialog dialog = serverTransactionId.getDialog(); - logger.info("Dialog State = " + dialog.getState()); - Response response = protocolObjects.messageFactory.createResponse( - byeResponse, request); - serverTransactionId.sendResponse(response); - this.transactionCount++; - logger.info("shootist: Sending " + byeResponse + " to BYE."); - logger.info("Dialog State = " + dialog.getState()); - - } catch (Exception ex) { - ex.printStackTrace(); - } - } - - public void processAck(Request request, - ServerTransaction serverTransactionId) { - try { - logger.info("shootist: got a " + request); - logger.info("shootist: got an ACK. ServerTxId = " + serverTransactionId); - ackReceived = true; - ackRequest = request; - - //we don't count retransmissions - if(serverTransactionId != null) { - ackCount ++; - } - if(testAckViaParam) { - ViaHeader viaHeader = (ViaHeader)request.getHeader(ViaHeader.NAME); - String param = viaHeader.getParameter("testAckViaParam"); - if(param != null) { - abortProcessing = true; - logger.error("the Via Param set in the response shouldn't be present in the ACK"); - return; - } - } - if(sendBye) { - Thread.sleep(timeToWaitBeforeBye ); - if(serverTransactionId != null && serverTransactionId.getDialog() != null) { - Request byeRequest = serverTransactionId.getDialog().createRequest(Request.BYE); - logger.info("BYE created : " + byeRequest); - ClientTransaction ct = sipProvider.getNewClientTransaction(byeRequest); - logger.info("Sending BYE : " + byeRequest); - serverTransactionId.getDialog().sendRequest(ct); - logger.info("Dialog State = " + serverTransactionId.getDialog().getState()); - } - } - if(!joinRequestReceived && sendJoinMessage) { - String fromUser = "join"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = protocolObjects.addressFactory.createSipURI( - fromUser, fromHost); - - String toUser = "join-receiver"; - String toHost = "sip-servlets.com"; - SipURI toAddress = protocolObjects.addressFactory.createSipURI( - toUser, toHost); - - CallIdHeader callIdHeader = (CallIdHeader) request.getHeader(CallIdHeader.NAME); - FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME); - ToHeader toHeader = (ToHeader) request.getHeader(ToHeader.NAME); - JoinHeader joinHeader = (JoinHeader) ((HeaderFactoryExt)protocolObjects.headerFactory).createJoinHeader(callIdHeader.getCallId(), toHeader.getTag(), fromHeader.getTag()); - - sendSipRequest("MESSAGE", fromAddress, toAddress, joinHeader.toString(), null, false); - } - if(!isReplacesRequestReceived() && sendReplacesMessage) { - String fromUser = "replaces"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = protocolObjects.addressFactory.createSipURI( - fromUser, fromHost); - - String toUser = "replaces-receiver"; - String toHost = "sip-servlets.com"; - SipURI toAddress = protocolObjects.addressFactory.createSipURI( - toUser, toHost); - - CallIdHeader callIdHeader = (CallIdHeader) request.getHeader(CallIdHeader.NAME); - FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME); - ToHeader toHeader = (ToHeader) request.getHeader(ToHeader.NAME); - ReplacesHeader replacesHeader = (ReplacesHeader) ((HeaderFactoryExt)protocolObjects.headerFactory).createReplacesHeader(callIdHeader.getCallId(), toHeader.getTag(), fromHeader.getTag()); - - sendSipRequest("MESSAGE", fromAddress, toAddress, replacesHeader.toString(), null, false); - } - if(joinRequestReceived) { - sendBye(); - sendBye(joinDialog); - } - if(isReplacesRequestReceived()) { - sendBye(); - sendBye(replacesDialog); - } - if(sendReinvite && !reinviteSent) { - prackSent = false; - List
headers = new ArrayList
(); - Header reinviteHeader = protocolObjects.headerFactory.createHeader("ReInvite", "true"); - headers.add(reinviteHeader); - String transport = null; - if(ackRequest.getRequestURI() instanceof SipURI) { - transport = ((SipURI)ackRequest.getRequestURI()).getTransportParam(); - } - sendInDialogSipRequest("INVITE", null, null, null, headers, transport); - reinviteSent = true; - return; - } - } catch (Exception ex) { - ex.printStackTrace(); - } - } - public void processResponse(ResponseEvent responseReceivedEvent) { - if(abortProcessing) { - logger.error("Processing aborted"); - return ; - } - Response response = (Response) responseReceivedEvent.getResponse(); - allResponses.add(response); - if(response.getStatusCode() == 491) numberOf491s++; - RecordRouteHeader recordRouteHeader = (RecordRouteHeader)response.getHeader(RecordRouteHeader.NAME); - if(!recordRoutingProxyTesting && recordRouteHeader != null) { - abortProcessing = true; - throw new IllegalArgumentException("we received a record route header in a response !"); - } - ContactHeader contactHeader = (ContactHeader)response.getHeader(ContactHeader.NAME); - if(contactHeader != null && "0.0.0.0".equals(((SipURI)contactHeader.getAddress().getURI()).getHost())) { - abortProcessing = true; - throw new IllegalArgumentException("we received a contact header with 0.0.0.0 in a response !"); - } - - if(response.getStatusCode() >= 400 && response.getStatusCode() < 999) { - this.serverErrorReceived = true; - } - if(response.getStatusCode() == 503) { - this.serviceUnavailableResponse = response; - } - if(response.toString().toLowerCase().contains("info")) { - lastInfoResponseTime = System.currentTimeMillis(); - } - ClientTransaction tid = responseReceivedEvent.getClientTransaction(); - Dialog responseDialog = null; - if(tid != null) { - responseDialog = tid.getDialog(); - } else { - responseDialog = responseReceivedEvent.getDialog(); - } - CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME); - - logger.info("Response received : Status Code = " - + response.getStatusCode() + " " + cseq); - if (tid == null && countRetrans) { - nbRetrans++; - } - // not dropping in PRACK case on REINVITE the ClientTx can be null it seems - if (tid == null && responseDialog == null && !prackSent) { - logger.info("Stray response -- dropping "); - return; - } - logger.info("Dialog = " + responseDialog); - if(responseDialog != null) { - logger.info("Dialog State is " + responseDialog.getState()); - } - if(tid !=null) { - logger.info("transaction state is " + tid.getState()); - } - - try { - if(response.getStatusCode() > 100 && response.getStatusCode() < 200) { - informationalResponse = response; - if(sendCancelOn1xx) { - sendCancel(); - return; - } - } - if(response.getStatusCode() >= 200 && response.getStatusCode() < 700) { - logger.info("final response received : status code " + response.getStatusCode()); - finalResponseReceived = true; - setFinalResponseStatus(response.getStatusCode()); - setFinalResponse(response); - } - if (response.getStatusCode() == Response.OK) { - logger.info("response = " + response); - if (cseq.getMethod().equals(Request.INVITE) && sendAck) { - inviteOkResponse = response; - Request ackRequest = responseDialog.createAck(cseq.getSeqNumber()); - if (useToURIasRequestUri) { - ackRequest.setRequestURI(requestURI); - } - if(timeToWaitBeforeAck > 0) { - Thread.sleep(timeToWaitBeforeAck); - } - logger.info("Sending ACK " + ackRequest); - if(extraRoute) { - Header h = protocolObjects.headerFactory.createHeader("Route", ackRequest.getRequestURI().toString()); - ackRequest.addLast(h); - } - if(!sendSubsequentRequestsThroughSipProvider) { - logger.info("Sending ACK through dialog " + ackRequest); - responseDialog.sendAck(ackRequest); - this.dialog = responseDialog; - } else { - logger.info("Sending ACK through provider " + ackRequest); - sipProvider.sendRequest(ackRequest); - } - ackSent = true; - Thread.sleep(1000); - // If the caller is supposed to send the bye - if(sendReinvite && !reinviteSent) { - List
headers = new ArrayList
(); - Header reinviteHeader = protocolObjects.headerFactory.createHeader("ReInvite", "true"); - headers.add(reinviteHeader); - if(prackSent) { - headers.add(protocolObjects.headerFactory.createHeader(RequireHeader.NAME, "100rel")); - } - prackSent = false; - sendInDialogSipRequest("INVITE", null, null, null, headers, null); - - reinviteSent = true; - return; - } - if(sendBye) { -// Thread.sleep(30000); - sendBye(); - } - if(sendByeAfterTerminatingNotify) { - responseDialog.terminateOnBye(false); - } - } else if(cseq.getMethod().equals(Request.BYE)) { - okToByeReceived = true; - } else if (cseq.getMethod().equals(Request.CANCEL)) { - this.cancelOkReceived = true; -// if (tid.getDialog().getState() == DialogState.CONFIRMED) { -// // oops cancel went in too late. Need to hang up the -// // dialog. -// logger.info("Sending BYE -- cancel went in too late !!"); -// Request byeRequest = dialog.createRequest(Request.BYE); -// ClientTransaction ct = sipProvider -// .getNewClientTransaction(byeRequest); -// tid.getDialog().sendRequest(ct); -// } - } else if (cseq.getMethod().equals(Request.PUBLISH)) { - SIPETagHeader sipTagHeader = (SIPETagHeader)response.getHeader(SIPETag.NAME); - sipETag = sipTagHeader.getETag(); - } else if (cseq.getMethod().equals(Request.PRACK)) { - okToPrackReceived = true; - if (sendUpdateAfterPrack){ - Request updateRequest = dialog.createRequest(Request.UPDATE); - - if (recordRoutingProxyTesting){ - ContactHeader contHdr = (ContactHeader) response.getHeader(ContactHeader.NAME); - SipURI sipUri = (SipURI)contHdr.getAddress().getURI(); - updateRequest.setRequestURI(sipUri); - } - ClientTransaction ct = sipProvider - .getNewClientTransaction(updateRequest); - dialog.sendRequest(ct); - sendUpdate = true; - } - } else if(cseq.getMethod().equals(Request.UPDATE) && sendUpdateAfterUpdate && prackReceived) { - Address address = protocolObjects.addressFactory - .createAddress("Shootme "); - contactHeader = protocolObjects.headerFactory.createContactHeader(address); - setFinalResponse(protocolObjects.messageFactory - .createResponse(finalResponseToSend, inviteRequest)); - ToHeader toHeader = (ToHeader) getFinalResponse().getHeader(ToHeader.NAME); - if(toHeader.getTag() == null) { - toHeader.setTag(toTag); // Application is supposed to set. - } - getFinalResponse().addHeader(contactHeader); - inviteServerTid.sendResponse(getFinalResponse()); - } - } else if (response.getStatusCode() == Response.MOVED_TEMPORARILY) { - // Dialog dies as soon as you get an error response. - this.redirectReceived = true; - if (cseq.getMethod().equals(Request.INVITE)) { - // lookup the contact header - ContactHeader contHdr = (ContactHeader) response - .getHeader(ContactHeader.NAME); - // we can re-use the from header - FromHeader from = ((FromHeader) response - .getHeader(FromHeader.NAME)); - // we use the to-address, but without the tag - ToHeader to = (ToHeader) (response.getHeader(ToHeader.NAME)).clone(); - to.removeParameter("tag"); - // the call-id can be re-used - CallIdHeader callID = ((CallIdHeader) response - .getHeader(CallIdHeader.NAME)); - // we take the next cseq - long seqNo = (((CSeqHeader) response - .getHeader(CSeqHeader.NAME)).getSeqNumber()); - logger.info("seqNo = " + seqNo); - CSeqHeader cseqNew = protocolObjects.headerFactory - .createCSeqHeader(++seqNo, "INVITE"); - // Create ViaHeaders (either use tcp or udp) - ArrayList viaHeaders = new ArrayList(); - ViaHeader viaHeader = protocolObjects.headerFactory - .createViaHeader("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", sipProvider - .getListeningPoint(protocolObjects.transport).getPort(), - protocolObjects.transport, - null); - // add via headers - viaHeaders.add(viaHeader); - // create max forwards - MaxForwardsHeader maxForwardsHeader = protocolObjects.headerFactory - .createMaxForwardsHeader(10); - // create invite Request - SipURI newUri = (SipURI)this.requestURI.clone(); - newUri.setParameter("redirection", "true"); - requestURI = newUri; - Request invRequest = protocolObjects.messageFactory - .createRequest(newUri, - "INVITE", callID, cseqNew, from, to, - viaHeaders, maxForwardsHeader); - // we set the Request URI to the address given - SipURI contactURI = - protocolObjects.addressFactory.createSipURI(null, this.listeningPoint.getIPAddress()); - - contactURI.setPort(this.listeningPoint.getPort()); - contactURI.setTransportParam(protocolObjects.transport); - - Address address = protocolObjects.addressFactory.createAddress(contactURI); - ContactHeader contact = protocolObjects.headerFactory.createContactHeader(address); - invRequest.addHeader(contact); - - // the contacat header in the response contains where to redirect - // the request to -- which in this case happens to be back to the - // same location. - ContactHeader chdr = (ContactHeader)response.getHeader(ContactHeader.NAME); - - SipURI sipUri = (SipURI)chdr.getAddress().getURI(); -// sipUri.setLrParam(); - RouteHeader routeHeader = - protocolObjects.headerFactory.createRouteHeader(chdr.getAddress()); - invRequest.addHeader(routeHeader); - invRequest.setRequestURI(sipUri); - - logger.info("Sending INVITE to " - + contHdr.getAddress().getURI().toString()); - inviteClientTid = sipProvider.getNewClientTransaction(invRequest); - this.transactionCount++; - - logger.info("New TID = " + inviteClientTid); - inviteClientTid.sendRequest(); - logger.info("sendReqeust succeeded " + inviteClientTid); - Dialog dialog = inviteClientTid.getDialog(); - this.dialogCount ++; - this.dialog = dialog; - - - } - } else if (response.getStatusCode() == Response.REQUEST_TERMINATED) { - if(cseq.getMethod().equals(Request.INVITE)){ - this.requestTerminatedReceived = true; - } - } else if(response.getStatusCode() == Response.RINGING && sendUpdateOn180) { - Request updateRequest = dialog.createRequest(Request.UPDATE); - - if (recordRoutingProxyTesting){ - ContactHeader contHdr = (ContactHeader) response.getHeader(ContactHeader.NAME); - SipURI sipUri = (SipURI)contHdr.getAddress().getURI(); - updateRequest.setRequestURI(sipUri); - } - - - ClientTransaction ct = sipProvider - .getNewClientTransaction(updateRequest); - dialog.sendRequest(ct); - sendUpdate = true; - - } else if ((response.getStatusCode() == Response.PROXY_AUTHENTICATION_REQUIRED - || response.getStatusCode() == Response.UNAUTHORIZED) && handleAuthorization ) { - URI uriReq = tid.getRequest().getRequestURI(); - Request authrequest = this.processResponseAuthorization( - response, uriReq); - - if(authrequest == null) { - System.out - .println("INVITE AUTHORIZATION null, stopping there"); - return; - } - inviteClientTid.sendRequest(); - System.out - .println("INVITE AUTHORIZATION sent:\n" + authrequest); - } else if (response.getStatusCode() > Response.TRYING && response.getStatusCode() < Response.OK) { - RequireHeader requireHeader = (RequireHeader) response.getHeader(RequireHeader.NAME); - logger.debug("prackSent ? " + prackSent); - if(requireHeader != null && "100rel".equalsIgnoreCase(requireHeader.getOptionTag().trim()) && !prackSent) { - prackSent = true; - Request prack = responseDialog.createPrack(response); - ClientTransaction ct = sipProvider - .getNewClientTransaction(prack); - responseDialog.sendRequest(ct); - } - } - /** - * end of modified code - */ - } catch (Exception ex) { - logger.error("An unexpected exception occured while processing the response" , ex); - } - - } - - public long getLastInfoResponseTime() { - return lastInfoResponseTime; - } - - public Request processResponseAuthorization(Response response, URI uriReq) { - RecordRouteHeader recordRouteHeader = (RecordRouteHeader)response.getHeader(RecordRouteHeader.NAME); - if(!recordRoutingProxyTesting && recordRouteHeader != null) { - abortProcessing = true; - throw new IllegalArgumentException("we received a record route header in a response !"); - } - Request requestauth = null; - this.authenticationErrorReceived = true; - try { - System.out.println("processResponseAuthorization()"); - - requestauth = (Request) inviteClientTid.getRequest().clone(); - - CSeqHeader cSeq = (CSeqHeader) requestauth.getHeader((CSeqHeader.NAME)); - try { - cSeq.setSeqNumber(cSeq.getSeqNumber() + 1l); - } catch (InvalidArgumentException e) { - logger.error("Cannot increment the Cseq header to the new INVITE request",e); - throw new IllegalArgumentException("Cannot create the INVITE request",e); - } - // non regression test for http://code.google.com/p/sipservlets/issues/detail?id=88 - if((securityUser.equalsIgnoreCase("badUser") || securityPwd.equalsIgnoreCase("badpwd")) && cSeq.getSeqNumber() > 2) { - return null; - } - requestauth.setHeader(cSeq); - requestauth.removeHeader(ViaHeader.NAME); - // Create ViaHeaders - ViaHeader viaHeader = protocolObjects.headerFactory - .createViaHeader("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", sipProvider - .getListeningPoint(protocolObjects.transport).getPort(), protocolObjects.transport, - null); - // add via headers - requestauth.addHeader(viaHeader); - - try { - ClientTransaction retryTran = sipProvider - .getNewClientTransaction(requestauth); - inviteClientTid = retryTran; - - - dialog = retryTran.getDialog(); - if (dialog == null) { - dialog = sipProvider.getNewDialog(retryTran); - } - } catch (TransactionUnavailableException e) { - logger.error("Cannot get a new transaction for the request " + requestauth,e); - throw new IllegalArgumentException("Cannot get a new transaction for the request " + requestauth,e); - } - AuthorizationHeader authorization = new org.mobicents.servlet.sip.catalina.security.authentication.DigestAuthenticator(protocolObjects.headerFactory).getAuthorizationHeader( - ((CSeqHeader) response - .getHeader(CSeqHeader.NAME)).getMethod(), - uriReq.toString(), - "", // TODO: What is this entity-body? - ((WWWAuthenticate) (response - .getHeader(SIPHeaderNames.WWW_AUTHENTICATE))), - securityUser, - securityPwd, - ((WWWAuthenticate) (response - .getHeader(SIPHeaderNames.WWW_AUTHENTICATE))).getNonce(), - 1); - - requestauth.addHeader(authorization); - } catch (ParseException pa) { - System.out - .println("processResponseAuthorization() ParseException:"); - System.out.println(pa.getMessage()); - pa.printStackTrace(); - } catch (Exception ex) { - System.out.println("processResponseAuthorization() Exception:"); - System.out.println(ex.getMessage()); - ex.printStackTrace(); - } - return requestauth; - } - - /** - * @throws SipException - * @throws TransactionUnavailableException - * @throws TransactionDoesNotExistException - * @throws InterruptedException - */ - public void sendBye() throws SipException, - TransactionUnavailableException, TransactionDoesNotExistException, InterruptedException { - if(timeToWaitBeforeBye > 0) { - Thread.sleep(timeToWaitBeforeBye); - } - sendBye(this.dialog); - } - - /** - * @throws SipException - * @throws TransactionUnavailableException - * @throws TransactionDoesNotExistException - */ - public void sendBye(final Dialog dialog) throws SipException, - TransactionUnavailableException, TransactionDoesNotExistException { - Thread th = new Thread(){ - public void run() { - try { - if(sendByeInNewThread) Thread.sleep(600); - Request byeRequest = dialog.createRequest(Request.BYE); - URI uri = ((FromHeader)byeRequest.getHeader(FromHeader.NAME)).getAddress().getURI(); - if(uri.isSipURI()) { - ((SipURI)uri).removeParameter("fromParam"); - } - ClientTransaction ct = sipProvider.getNewClientTransaction(byeRequest); - logger.info("Sending BYE " + byeRequest); - if(!sendSubsequentRequestsThroughSipProvider) { - dialog.sendRequest(ct); - } else { - sipProvider.sendRequest(byeRequest); - } - byeSent = true; - } catch(Exception e) {e.printStackTrace();} - } - }; - if(sendByeInNewThread) { - th.start(); - } else { - th.run(); - } - - } - - public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) { - - logger.info("Transaction Time out"); - } - - - - public SipProvider createProvider() throws Exception { - logger.info("Shootist: createProvider()"); - listeningPoint = protocolObjects.sipStack.createListeningPoint( - "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", myPort, protocolObjects.transport); - this.sipProvider = protocolObjects.sipStack - .createSipProvider(listeningPoint); - return sipProvider; - - } - - public void addListeningPoint(String ipAddress, int port, String transport) throws Exception { - logger.info("Shootist: addListeningPoint()"); - ListeningPoint listeningPoint = protocolObjects.sipStack.createListeningPoint( - "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", port, transport); - sipProvider.addListeningPoint(listeningPoint); - } - - public Request sendSipRequest(String method, URI fromURI, URI toURI, String messageContent, SipURI route, boolean useToURIasRequestUri) throws SipException, ParseException, InvalidArgumentException { - return sendSipRequest(method, fromURI, toURI, messageContent, route, useToURIasRequestUri, null, null, true); - } - - public Request sendSipRequest(String method, URI fromURI, URI toURI, String messageContent, SipURI route, boolean useToURIasRequestUri, String[] headerNames, String[] headerContents, boolean setHeader) throws SipException, ParseException, InvalidArgumentException { - this.useToURIasRequestUri = useToURIasRequestUri; - // create >From Header - Address fromNameAddress = protocolObjects.addressFactory - .createAddress(fromURI); - FromHeader fromHeader = protocolObjects.headerFactory - .createFromHeader(fromNameAddress, Integer.toString(new Random().nextInt(10000000))); - - // create To Header - Address toNameAddress = protocolObjects.addressFactory - .createAddress(toURI); - ToHeader toHeader = protocolObjects.headerFactory.createToHeader( - toNameAddress, null); - - if(toURI instanceof SipURI) { - SipURI toSipUri = (SipURI) toURI; - // create Request URI - this.requestURI = protocolObjects.addressFactory.createSipURI( - toSipUri.getUser(), peerHostPort); - ((SipURI)this.requestURI).setPort(peerPort); - if(setTransport) { - ((SipURI)this.requestURI).setTransportParam(listeningPoint.getTransport()); - } - } - if(useToURIasRequestUri || toURI instanceof TelURL) { - this.requestURI = toURI; - } - - // Create ViaHeaders - - List viaHeaders = new ArrayList(); - ViaHeader viaHeader = protocolObjects.headerFactory - .createViaHeader("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", sipProvider - .getListeningPoint(protocolObjects.transport).getPort(), listeningPoint.getTransport(), - null); - if(rfc5626UseCase != null && (rfc5626UseCase == RFC5626UseCase.B2BUA || rfc5626UseCase == RFC5626UseCase.Proxy)) { - //try to bind to non existing IP - viaHeader = protocolObjects.headerFactory - .createViaHeader("192.192.192.192", sipProvider - .getListeningPoint(protocolObjects.transport).getPort(), listeningPoint.getTransport(), - null); - } - // add via headers - viaHeaders.add(viaHeader); - - // Create ContentTypeHeader -// ContentTypeHeader contentTypeHeader = protocolObjects.headerFactory -// .createContentTypeHeader("application", "sdp"); - - // Create a new CallId header - CallIdHeader callIdHeader = sipProvider.getNewCallId(); - - // Create a new Cseq header - CSeqHeader cSeqHeader = protocolObjects.headerFactory - .createCSeqHeader(1L, method); - - // Create a new MaxForwardsHeader - MaxForwardsHeader maxForwards = protocolObjects.headerFactory - .createMaxForwardsHeader(70); - - // Create the request. - Request request = protocolObjects.messageFactory.createRequest( - requestURI, method, callIdHeader, cSeqHeader, - fromHeader, toHeader, viaHeaders, maxForwards); - // Create contact headers - String host = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; - if(rfc5626UseCase != null && (rfc5626UseCase == RFC5626UseCase.B2BUA || rfc5626UseCase == RFC5626UseCase.Proxy)) { - //try to bind to non existing IP - host = "192.192.192.192"; - } - request.setHeader(protocolObjects.headerFactory.createHeader("REM", "RRRREM")); - URI contactUrl = null; - if(fromURI instanceof SipURI) { - contactUrl = protocolObjects.addressFactory.createSipURI( - ((SipURI)fromURI).getUser(), host); - /** - * either use tcp or udp - */ - ((SipURI)contactUrl).setPort(listeningPoint.getPort()); - if(setTransport) { - ((SipURI)contactUrl).setTransportParam(listeningPoint.getTransport()); - if(rfc5626UseCase == null) { - ((SipURI)contactUrl).setLrParam(); - } - } - if(rfc5626UseCase != null && (rfc5626UseCase == RFC5626UseCase.B2BUA || rfc5626UseCase == RFC5626UseCase.Proxy)) { - ((SipURI)contactUrl).setParameter("ob", null); - } - } else { - contactUrl = fromURI; - } - - // Create the contact name address. - Address contactAddress = protocolObjects.addressFactory - .createAddress(contactUrl); - - // Add the contact address. -// contactAddress.setDisplayName(fromName); - - contactHeader = protocolObjects.headerFactory - .createContactHeader(contactAddress); - if (rfc5626UseCase != null && rfc5626UseCase == RFC5626UseCase.Proxy) { - contactHeader.setParameter("reg-id", "1"); - contactHeader.setParameter("+sip.instance", "\"\""); - } - request.addHeader(contactHeader); - - SipURI uri = protocolObjects.addressFactory.createSipURI(null, "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); - - uri.setLrParam(); - uri.setTransportParam(protocolObjects.transport); - uri.setPort(this.peerPort); - - if(route != null) { - Address address = protocolObjects.addressFactory.createAddress(route); - RouteHeader routeHeader = protocolObjects.headerFactory.createRouteHeader(address); - request.addHeader(routeHeader); - } else if(useDefaultRoute ) { - Address address = protocolObjects.addressFactory.createAddress(uri); - RouteHeader routeHeader = protocolObjects.headerFactory.createRouteHeader(address); - request.addHeader(routeHeader); - } - - // set the message content - if(messageContent != null) { - ContentLengthHeader contentLengthHeader = - protocolObjects.headerFactory.createContentLengthHeader(messageContent.length()); - ContentTypeHeader contentTypeHeader = - protocolObjects.headerFactory.createContentTypeHeader(TEXT_CONTENT_TYPE,PLAIN_UTF8_CONTENT_SUBTYPE); - byte[] contents = messageContent.getBytes(); - request.setContent(contents, contentTypeHeader); - request.setContentLength(contentLengthHeader); - } - - if(headerNames != null) { - for(int q=0; q 0) { - this.peerPort = peerPort; - this.peerHostPort = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":"+ peerPort; - } - this.sendBye = callerSendBye; - allMessagesContent = new ArrayList(); - allSubscriptionStates = new ArrayList(); - finalResponseToSend = Response.OK; - provisionalResponsesToSend = new ArrayList(); - provisionalResponsesToSend.add(Response.TRYING); - provisionalResponsesToSend.add(Response.RINGING); - } - - public void processIOException(IOExceptionEvent exceptionEvent) { - logger.info("IOException happened for " - + exceptionEvent.getHost() + " port = " - + exceptionEvent.getPort()); - - } - - public void processTransactionTerminated( - TransactionTerminatedEvent transactionTerminatedEvent) { - logger.info("Transaction terminated event recieved for " + - transactionTerminatedEvent.getClientTransaction()); - this.transctionTerminatedCount++; - } - - public void processDialogTerminated( - DialogTerminatedEvent dialogTerminatedEvent) { - this.dialogTerminatedCount++; - - } - - public boolean getOkToByeReceived() { - return okToByeReceived; - } - - public boolean getByeReceived() { - return byeReceived; - } - - public void sendCancel() { - sendCancel(false, null); - } - - public void sendCancel(boolean addReason, String reasonText) { - try { - logger.info("Sending cancel"); - - Request cancelRequest = inviteClientTid.createCancel(); - if(addReason) { - ReasonHeader reasonHeader = (ReasonHeader) this.protocolObjects.headerFactory.createReasonHeader("SIP", 200, reasonText); - cancelRequest.addHeader(reasonHeader); - } - ClientTransaction cancelTid = sipProvider - .getNewClientTransaction(cancelRequest); - cancelTid.sendRequest(); - cancelSent = true; - } catch (Exception ex) { - ex.printStackTrace(); - } - } - - /** - * @return the cancelReceived - */ - public boolean isCancelReceived() { - return cancelReceived; - } - - /** - */ - public void setCancelReceived(boolean cancelReceived) { - this.cancelReceived = cancelReceived; - } - - /** - * @return the cancelOkReceived - */ - public boolean isCancelOkReceived() { - return cancelOkReceived; - } - - /** - */ - public void setCancelOkReceived(boolean cancelOkReceived) { - this.cancelOkReceived = cancelOkReceived; - } - - /** - * @return the requestTerminatedReceived - */ - public boolean isRequestTerminatedReceived() { - return requestTerminatedReceived; - } - - /** - * @return the requestTerminatedReceived - */ - public void setRequestTerminatedReceived(boolean requestTerminatedReceived) { - this.requestTerminatedReceived = requestTerminatedReceived; - } - - /** - * @return the waitForCancel - */ - public boolean isWaitForCancel() { - return waitForCancel; - } - - public long getLastRegisterCSeqNumber() { - return lastRegisterCSeqNumber; - } - - /** - * @param waitForCancel the waitForCancel to set - */ - public void setWaitForCancel(boolean waitForCancel) { - this.waitForCancel = waitForCancel; - } - - /** - * @return the ackSent - */ - public boolean isAckSent() { - return ackSent; - } - - public void setAckSent(boolean ackSent) { - this.ackSent = ackSent; - } - - /** - * @return the ackReceived - */ - public boolean isAckReceived() { - return ackReceived; - } - - public void setAckReceived(boolean ackReceived) { - this.ackReceived = ackReceived; - } - - /** - * - * @param transport TODO - * @param messageToSend - * @throws SipException - * @throws InvalidArgumentException - * @throws ParseException - */ - public void sendInDialogSipRequest(String method, String content, String contentType, String subContentType, List
headers, String transport) throws SipException, InvalidArgumentException, ParseException { - - Request message = dialog.createRequest(method); - if(transport !=null) { - ((SipURI)message.getRequestURI()).setTransportParam(transport); - } - - if(content != null) { - ContentLengthHeader contentLengthHeader = - protocolObjects.headerFactory.createContentLengthHeader(content.length()); - ContentTypeHeader contentTypeHeader = - protocolObjects.headerFactory.createContentTypeHeader(contentType,subContentType); - message.setContentLength(contentLengthHeader); - message.setContent(content, contentTypeHeader); - } - - if(headers != null) { - for (Header header : headers) { - message.addHeader(header); - } - } - - addSpecificHeaders(method, message); - message.removeHeader(ViaHeader.NAME); - logger.info("in dialog message = " + message); - - ClientTransaction clientTransaction = sipProvider.getNewClientTransaction(message); - if(method.equals("INVITE")) { - inviteClientTid = clientTransaction; - } - dialog.sendRequest(clientTransaction); - } - - /** - * - * @param messageToSend - * @throws SipException - * @throws InvalidArgumentException - * @throws ParseException - */ - public void sendMessageInDialog(String messageToSend) throws SipException, InvalidArgumentException, ParseException { - Request message = dialog.createRequest(Request.MESSAGE); - ContentLengthHeader contentLengthHeader = - protocolObjects.headerFactory.createContentLengthHeader(messageToSend.length()); - ContentTypeHeader contentTypeHeader = - protocolObjects.headerFactory.createContentTypeHeader(TEXT_CONTENT_TYPE,PLAIN_UTF8_CONTENT_SUBTYPE); - message.setContentLength(contentLengthHeader); - message.setContent(messageToSend, contentTypeHeader); - ClientTransaction clientTransaction = sipProvider.getNewClientTransaction(message); - dialog.sendRequest(clientTransaction); - } - - /** - * - * @param messageToSend - * @throws SipException - * @throws InvalidArgumentException - * @throws ParseException - */ - public void sendMessageNoDialog(String messageToSend) throws SipException, InvalidArgumentException, ParseException { - Request message = dialog.createRequest(Request.MESSAGE); - ContentLengthHeader contentLengthHeader = - protocolObjects.headerFactory.createContentLengthHeader(messageToSend.length()); - ContentTypeHeader contentTypeHeader = - protocolObjects.headerFactory.createContentTypeHeader(TEXT_CONTENT_TYPE,PLAIN_UTF8_CONTENT_SUBTYPE); - message.setContentLength(contentLengthHeader); - message.setContent(messageToSend, contentTypeHeader); - ClientTransaction clientTransaction = sipProvider.getNewClientTransaction(message); - dialog.sendRequest(clientTransaction); - } - - /** - * @return the lastMessageContent - */ - public String getLastMessageContent() { - return lastMessageContent; - } - - /** - * @return the allMessagesContent - */ - public List getAllMessagesContent() { - return allMessagesContent; - } - - /** - * @return the finalResponseReceived - */ - public boolean isFinalResponseReceived() { - return finalResponseReceived; - } - - public boolean isServerErrorReceived() { - return serverErrorReceived; - } - - public void setServerErrorReceived(boolean serverErrorReceived) { - this.serverErrorReceived = serverErrorReceived; - } - - /** - * @return the finalResponseToSend - */ - public int getFinalResponseToSend() { - return finalResponseToSend; - } - - /** - * @param finalResponseToSend the finalResponseToSend to set - */ - public void setFinalResponseToSend(int finalResponseToSend) { - this.finalResponseToSend = finalResponseToSend; - } - - /** - * @return the provisionalResponsesToSend - */ - public List getProvisionalResponsesToSend() { - return provisionalResponsesToSend; - } - - /** - * @param provisionalResponsesToSend the provisionalResponsesToSend to set - */ - public void setProvisionalResponsesToSend( - List provisionalResponsesToSend) { - this.provisionalResponsesToSend = provisionalResponsesToSend; - } - - /** - * @return the allSubscriptionState - */ - public List getAllSubscriptionState() { - return allSubscriptionStates; - } - - /** - * @param byeReceived the byeReceived to set - */ - public void setByeReceived(boolean byeReceived) { - this.byeReceived = byeReceived; - } - - /** - * @param okToByeReceived the okToByeReceived to set - */ - public void setOkToByeReceived(boolean okToByeReceived) { - this.okToByeReceived = okToByeReceived; - } - - public void setSendUpdateOn180(boolean sendUpdateOn180) { - this.sendUpdateOn180 = sendUpdateOn180; - } - - public void setPublishEvent(String publishEvent) { - this.publishEvent = publishEvent; - } - - public void setPublishContentMessage(String publishContentMessage) { - this.publishContentMessage = publishContentMessage; - } - - public void setChallengeRequests(boolean challengeRequests) { - this.challengeRequests = challengeRequests; - } - - /** - * @param timeToWaitBetweenProvisionnalResponse the timeToWaitBetweenProvisionnalResponse to set - */ - public void setTimeToWaitBetweenProvisionnalResponse( - long timeToWaitBetweenProvisionnalResponse) { - this.timeToWaitBetweenProvisionnalResponse = timeToWaitBetweenProvisionnalResponse; - } - - public Response getInviteOkResponse() { - return inviteOkResponse; - } - - /** - * @return the timeToWaitBetweenProvisionnalResponse - */ - public long getTimeToWaitBetweenProvisionnalResponse() { - return timeToWaitBetweenProvisionnalResponse; - } - - public long getTimeToWaitBetweenSubsNotify() { - return timeToWaitBetweenSubsNotify; - } - - public void setTimeToWaitBetweenSubsNotify(long timeToWaitBetweenSubsNotify) { - this.timeToWaitBetweenSubsNotify = timeToWaitBetweenSubsNotify; - } - - /** - * @return the sendBye - */ - public boolean isSendBye() { - return sendBye; - } - - /** - * @param sendBye the sendBye to set - */ - public void setSendBye(boolean sendBye) { - this.sendBye = sendBye; - } - - /** - * @param sendByeBeforeTerminatingNotify the sendByeBeforeTerminatingNotify to set - */ - public void setSendByeBeforeTerminatingNotify( - boolean sendByeBeforeTerminatingNotify) { - this.sendByeBeforeTerminatingNotify = sendByeBeforeTerminatingNotify; - } - - /** - * @return the sendByeBeforeTerminatingNotify - */ - public boolean isSendByeBeforeTerminatingNotify() { - return sendByeBeforeTerminatingNotify; - } - - /** - * @param sendByeAfterTerminatingNotify the sendByeAfterTerminatingNotify to set - */ - public void setSendByeAfterTerminatingNotify( - boolean sendByeAfterTerminatingNotify) { - this.sendByeAfterTerminatingNotify = sendByeAfterTerminatingNotify; - } - - /** - * @return the sendByeAfterTerminatingNotify - */ - public boolean isSendByeAfterTerminatingNotify() { - return sendByeAfterTerminatingNotify; - } - - public boolean isAuthenticationErrorReceived() { - return authenticationErrorReceived; - } - - public void setRespondWithError(int errorCode) { - this.respondWithError = errorCode; - } - - /** - * @param finalResponseStatus the finalResponseStatus to set - */ - public void setFinalResponseStatus(int finalResponseStatus) { - this.finalResponseStatus = finalResponseStatus; - } - - /** - * @return the finalResponseStatus - */ - public int getFinalResponseStatus() { - return finalResponseStatus; - } - - /** - * @param joinRequestReceived the joinRequestReceived to set - */ - public void setJoinRequestReceived(boolean joinRequestReceived) { - this.joinRequestReceived = joinRequestReceived; - } - - /** - * @return the joinRequestReceived - */ - public boolean isJoinRequestReceived() { - return joinRequestReceived; - } - - /** - * @param replacesRequestReceived the replacesRequestReceived to set - */ - public void setReplacesRequestReceived(boolean replacesRequestReceived) { - this.replacesRequestReceived = replacesRequestReceived; - } - - /** - * @return the replacesRequestReceived - */ - public boolean isReplacesRequestReceived() { - return replacesRequestReceived; - } - - /** - * @return the inviteReceived - */ - public boolean isInviteReceived() { - return inviteReceived; - } - - /** - * @return the inviteReceived - */ - public void setInviteReceived(boolean inviteReceived) { - this.inviteReceived = inviteReceived; - } - - - public void setSendReinvite(boolean b) { - sendReinvite = b; - } - - public Request getInviteRequest() { - return inviteRequest; - } - - /** - * @param recordRoutingProxyTesting the recordRoutingProxyTesting to set - */ - public void setRecordRoutingProxyTesting(boolean recordRoutingProxyTesting) { - this.recordRoutingProxyTesting = recordRoutingProxyTesting; - } - - /** - * @return the recordRoutingProxyTesting - */ - public boolean isRecordRoutingProxyTesting() { - return recordRoutingProxyTesting; - } - - /** - * @param sendSubsequentRequestsThroughSipProvider the sendSubsequentRequestsThroughSipProvider to set - */ - public void setSendSubsequentRequestsThroughSipProvider( - boolean sendSubsequentRequestsThroughSipProvider) { - this.sendSubsequentRequestsThroughSipProvider = sendSubsequentRequestsThroughSipProvider; - } - - /** - * @return the sendSubsequentRequestsThroughSipProvider - */ - public boolean isSendSubsequentRequestsThroughSipProvider() { - return sendSubsequentRequestsThroughSipProvider; - } - - /** - * @param testAckViaParam the testAckViaParam to set - */ - public void setTestAckViaParam(boolean testAckViaParam) { - this.testAckViaParam = testAckViaParam; - } - - /** - * @return the testAckViaParam - */ - public boolean isTestAckViaParam() { - return testAckViaParam; - } - - /** - * @return the byeRequestReceived - */ - public Request getByeRequestReceived() { - return byeRequestReceived; - } - - /** - * @return the registerReceived - */ - public Request getRegisterReceived() { - return registerReceived; - } - - /** - * @param timeToWaitBeforeBye the timeToWaitBeforeBye to set - */ - public void setTimeToWaitBeforeBye(long timeToWaitBeforeBye) { - this.timeToWaitBeforeBye = timeToWaitBeforeBye; - } - - /** - * @return the timeToWaitBeforeBye - */ - public long getTimeToWaitBeforeBye() { - return timeToWaitBeforeBye; - } - - /** - * @param sendAck the sendAck to set - */ - public void setSendAck(boolean sendAck) { - this.sendAck = sendAck; - } - - /** - * @return the sendAck - */ - public boolean isSendAck() { - return sendAck; - } - - /** - * @param prackSent the prackSent to set - */ - public void setPrackSent(boolean prackSent) { - this.prackSent = prackSent; - } - - /** - * @return the prackSent - */ - public boolean isPrackSent() { - return prackSent; - } - - /** - * @param okToPrackReceived the okToPrackReceived to set - */ - public void setOkToPrackReceived(boolean okToPrackReceived) { - this.okToPrackReceived = okToPrackReceived; - } - - /** - * @return the okToPrackReceived - */ - public boolean isOkToPrackReceived() { - return okToPrackReceived; - } - - /** - * @param prackReceived the prackReceived to set - */ - public void setPrackReceived(boolean prackReceived) { - this.prackReceived = prackReceived; - } - - /** - * @return the prackReceived - */ - public boolean isPrackReceived() { - return prackReceived; - } - - /** - * @param useDefaultRoute the useDefaultRoute to set - */ - public void setUseDefaultRoute(boolean useDefaultRoute) { - this.useDefaultRoute = useDefaultRoute; - } - - /** - * @return the useDefaultRoute - */ - public boolean isUseDefaultRoute() { - return useDefaultRoute; - } - - /** - * @param messageRequest the messageRequest to set - */ - public void setMessageRequest(Request messageRequest) { - this.messageRequest = messageRequest; - } - - /** - * @return the messageRequest - */ - public Request getMessageRequest() { - return messageRequest; - } - - public void setTransport(boolean b) { - setTransport = b; - } - - /** - * @param finalResponse the finalResponse to set - */ - public void setFinalResponse(Response finalResponse) { - this.finalResponse = finalResponse; - } - - /** - * @return the finalResponse - */ - public Response getFinalResponse() { - return finalResponse; - } - - /** - * @param timeToWaitBeforeAck the timeToWaitBeforeAck to set - */ - public void setTimeToWaitBeforeAck(long timeToWaitBeforeAck) { - this.timeToWaitBeforeAck = timeToWaitBeforeAck; - } - - /** - * @return the timeToWaitBeforeAck - */ - public long getTimeToWaitBeforeAck() { - return timeToWaitBeforeAck; - } - - /** - * @return the serviceUnavailableReceived - */ - public Response getServiceUnavailableResponse() { - return serviceUnavailableResponse; - } - - public void setReferResponseToSend(int referResponseToSend) { - this.referResponseToSend = referResponseToSend; - } - - /** - * @param sendNotifyForRefer the sendNotifyForRefer to set - */ - public void setSendNotifyForRefer(boolean sendNotifyForRefer) { - this.sendNotifyForRefer = sendNotifyForRefer; - } - - /** - * @return the sendNotifyForRefer - */ - public boolean isSendNotifyForRefer() { - return sendNotifyForRefer; - } - - /** - * @param sendNotify the sendNotify to set - */ - public void setSendNotify(boolean sendNotify) { - this.sendNotify = sendNotify; - } - - /** - * @return the sendNotify - */ - public boolean isSendNotify() { - return sendNotify; - } - - /** - * @param informationalResponse the informationalResponse to set - */ - public void setInformationalResponse(Response informationalResponse) { - this.informationalResponse = informationalResponse; - } - - /** - * @return the informationalResponse - */ - public Response getInformationalResponse() { - return informationalResponse; - } - - /** - * @param countRetrans the countRetrans to set - */ - public void setCountRetrans(boolean countRetrans) { - this.countRetrans = countRetrans; - } - - /** - * @return the countRetrans - */ - public boolean isCountRetrans() { - return countRetrans; - } - - /** - * @param nbRetrans the nbRetrans to set - */ - public void setNbRetrans(int nbRetrans) { - this.nbRetrans = nbRetrans; - } - - /** - * @return the nbRetrans - */ - public int getNbRetrans() { - return nbRetrans; - } - - /** - * @param prackRequestReceived the prackRequestReceived to set - */ - public void setPrackRequestReceived(Request prackRequestReceived) { - this.prackRequestReceived = prackRequestReceived; - } - - /** - * @return the prackRequestReceived - */ - public Request getPrackRequestReceived() { - return prackRequestReceived; - } - - public void setMultipleChallengeInResponse(boolean multipleChallengeInResponse) { - this.multipleChallengeInResponse = multipleChallengeInResponse; - } - - /** - * @param disableSequenceNumberValidation the disableSequenceNumberValidation to set - */ - public void setDisableSequenceNumberValidation( - boolean disableSequenceNumberValidation) { - this.disableSequenceNumberValidation = disableSequenceNumberValidation; - } - - /** - * @return the disableSequenceNumberValidation - */ - public boolean isDisableSequenceNumberValidation() { - return disableSequenceNumberValidation; - } - - /** - * @param sendCancelOn1xx the sendCancelOn1xx to set - */ - public void setSendCancelOn1xx(boolean sendCancelOn1xx) { - this.sendCancelOn1xx = sendCancelOn1xx; - } - - /** - * @return the sendCancelOn1xx - */ - public boolean isSendCancelOn1xx() { - return sendCancelOn1xx; - } - - /** - * @param useToURIasRequestUri the useToURIasRequestUri to set - */ - public void setUseToURIasRequestUri(boolean useToURIasRequestUri) { - this.useToURIasRequestUri = useToURIasRequestUri; - } - - /** - * @return the useToURIasRequestUri - */ - public boolean isUseToURIasRequestUri() { - return useToURIasRequestUri; - } - - public void setTestNextNonce(boolean b) { - this.testNextNonce = b; - } - - public void setTestNC(boolean b) { - this.testNC = b; - } - - /** - * @param dropRequest the dropRequest to set - */ - public void setDropRequest(boolean dropRequest) { - this.dropRequest = dropRequest; - } - - /** - * @return the dropRequest - */ - public boolean isDropRequest() { - return dropRequest; - } - - public void setWaitBeforeFinalResponse(long waitBeforeFinalResponse) { - this.waitBeforeFinalResponse = waitBeforeFinalResponse; - } - - public boolean isSendUpdate() { - return sendUpdate; - } - - public boolean isUpdateReceived() { - return updateReceived; - } - - public void setSendUpdateAfterUpdate(boolean sendUpdateAfterUpdate) { - this.sendUpdateAfterUpdate = sendUpdateAfterUpdate; - } - - public boolean isSendUpdateAfterUpdate() { - return sendUpdateAfterUpdate; - } - - public void setSendUpdateAfterPrack(boolean sendUpdateAfterPrack) { - this.sendUpdateAfterPrack = sendUpdateAfterPrack; - } - - public void setSendUpdateAfterProvisionalResponses(boolean sendUpdateAfterProvisonalResponses) { - this.sendUpdateAfterProvisionalResponses = sendUpdateAfterProvisonalResponses; - } - - /** - * @return the ackRequest - */ - public Request getAckRequest() { - return ackRequest; - } - - public void setHandleAuthorization(boolean handleAuthorization) { - this.handleAuthorization = handleAuthorization; - } - - public boolean isHandleAuthorization() { - return handleAuthorization; - } - - public void setUpdateRequest(Request updateRequest) { - this.updateRequest = updateRequest; - } - - public Request getUpdateRequest() { - return updateRequest; - } - - public void setInfoRequest(Request infoRequest) { - this.infoRequest = infoRequest; - } - - public Request getInfoRequest() { - return infoRequest; - } - - public void setOptionsRequest(Request optionsRequest) { - this.optionsRequest = optionsRequest; - } - - public Request getOptionsRequest() { - return this.optionsRequest; - } - - /** - * @param addRecordRouteForResponses the addRecordRouteForResponses to set - */ - public void setAddRecordRouteForResponses(boolean addRecordRouteForResponses) { - this.addRecordRouteForResponses = addRecordRouteForResponses; - } - - /** - * @return the addRecordRouteForResponses - */ - public boolean isAddRecordRouteForResponses() { - return addRecordRouteForResponses; - } - - public void setRFC5626UseCase(RFC5626UseCase rfc5626UseCase) { - this.rfc5626UseCase = rfc5626UseCase; - } - - public void setSecurityUser(String securityUser) { - this.securityUser = securityUser; - } - - public void setSecurityPwd(String securityPwd) { - this.securityPwd = securityPwd; - } - - public void sendProvisionalResponseBeforeChallenge(boolean b) { - sendProvisionalResponseBeforeChallenge = b; - } - - public String getToTag() { - return toTag; - } - - public void setToTag(String toTag) { - this.toTag = toTag; - } - - public int getByeResponse() { - return byeResponse; - } - - public void setByeResponse(int byeResponse) { - this.byeResponse = byeResponse; - } - - /** - * @return the cancelRequest - */ - public Request getCancelRequest() { - return cancelRequest; - } - - /** - * @param cancelRequest the cancelRequest to set - */ - public void setCancelRequest(Request cancelRequest) { - this.cancelRequest = cancelRequest; - } - - /** - * @return the sendNotifyBeforeResponseToSubscribe - */ - public boolean isSendNotifyBeforeResponseToSubscribe() { - return sendNotifyBeforeResponseToSubscribe; - } - - /** - * @param sendNotifyBeforeResponseToSubscribe the sendNotifyBeforeResponseToSubscribe to set - */ - public void setSendNotifyBeforeResponseToSubscribe( - boolean sendNotifyBeforeResponseToSubscribe) { - this.sendNotifyBeforeResponseToSubscribe = sendNotifyBeforeResponseToSubscribe; - } - - public void setCheckSDPNullOnChallengeRequests(boolean checkSDPNullOnChallengeRequests) { - this.checkSDPNullOnChallengeRequests = checkSDPNullOnChallengeRequests; - } -} +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2014, Telestax Inc and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * + * This file incorporates work covered by the following copyright contributed under the GNU LGPL : Copyright 2007-2011 Red Hat. + */ + +package org.mobicents.servlet.sip.testsuite; + +import gov.nist.javax.sip.DialogExt; +import gov.nist.javax.sip.address.SipUri; +import gov.nist.javax.sip.header.HeaderExt; +import gov.nist.javax.sip.header.HeaderFactoryExt; +import gov.nist.javax.sip.header.ParameterNames; +import gov.nist.javax.sip.header.SIPETag; +import gov.nist.javax.sip.header.SIPHeaderNames; +import gov.nist.javax.sip.header.WWWAuthenticate; +import gov.nist.javax.sip.header.extensions.JoinHeader; +import gov.nist.javax.sip.header.extensions.ReplacesHeader; +import gov.nist.javax.sip.header.ims.PathHeader; +import gov.nist.javax.sip.message.MessageExt; + +import gov.nist.javax.sip.stack.SIPTransactionStack; +import gov.nist.javax.sip.message.SIPResponse; +import gov.nist.javax.sip.stack.SIPDialog; +import gov.nist.javax.sip.stack.SIPTransaction; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Random; +import java.util.concurrent.atomic.AtomicInteger; + +import javax.sip.ClientTransaction; +import javax.sip.Dialog; +import javax.sip.DialogTerminatedEvent; +import javax.sip.IOExceptionEvent; +import javax.sip.InvalidArgumentException; +import javax.sip.ListeningPoint; +import javax.sip.RequestEvent; +import javax.sip.ResponseEvent; +import javax.sip.ServerTransaction; +import javax.sip.SipException; +import javax.sip.SipListener; +import javax.sip.SipProvider; +import javax.sip.TransactionAlreadyExistsException; +import javax.sip.TransactionDoesNotExistException; +import javax.sip.TransactionTerminatedEvent; +import javax.sip.TransactionUnavailableException; +import javax.sip.address.Address; +import javax.sip.address.SipURI; +import javax.sip.address.TelURL; +import javax.sip.address.URI; +import javax.sip.header.AllowHeader; +import javax.sip.header.AuthenticationInfoHeader; +import javax.sip.header.AuthorizationHeader; +import javax.sip.header.CSeqHeader; +import javax.sip.header.CallIdHeader; +import javax.sip.header.ContactHeader; +import javax.sip.header.ContentLengthHeader; +import javax.sip.header.ContentTypeHeader; +import javax.sip.header.EventHeader; +import javax.sip.header.ExpiresHeader; +import javax.sip.header.ExtensionHeader; +import javax.sip.header.FromHeader; +import javax.sip.header.Header; +import javax.sip.header.MaxForwardsHeader; +import javax.sip.header.ProxyAuthenticateHeader; +import javax.sip.header.ProxyAuthorizationHeader; +import javax.sip.header.ReasonHeader; +import javax.sip.header.RecordRouteHeader; +import javax.sip.header.ReferToHeader; +import javax.sip.header.RequireHeader; +import javax.sip.header.RouteHeader; +import javax.sip.header.SIPETagHeader; +import javax.sip.header.SIPIfMatchHeader; +import javax.sip.header.SubscriptionStateHeader; +import javax.sip.header.SupportedHeader; +import javax.sip.header.ToHeader; +import javax.sip.header.ViaHeader; +import javax.sip.message.Request; +import javax.sip.message.Response; + +import org.apache.log4j.Logger; + +/** + * This class is a UAC template. Shootist is the guy that shoots and shootme is + * the guy that gets shot. + * + * @author M. Ranganathan + */ + +public class TestSipListener implements SipListener { + private String toTag = Integer.toString(new Random().nextInt(10000000)); + + public List allRequests = new LinkedList(); + public List allResponses = new LinkedList(); + + private static final String PLAIN_UTF8_CONTENT_SUBTYPE = "plain;charset=UTF-8"; + + private static final String TEXT_CONTENT_TYPE = "text"; + + private static final String PIDF_XML_SUBTYPE = "pidf+xml"; + + private static final String APPLICATION_CONTENT_TYPE = "application"; + + private boolean sendBye; + private int byeResponse = 200; + + public int bindings; + + public boolean extraRoute = false; + + private boolean sendJoinMessage; + + private boolean sendReplacesMessage; + + private boolean sendByeBeforeTerminatingNotify; + + private boolean sendByeAfterTerminatingNotify; + + private SipProvider sipProvider; + + public ProtocolObjects protocolObjects; + + private ContactHeader contactHeader; + + private ListeningPoint listeningPoint; + + private ClientTransaction inviteClientTid; + + private ServerTransaction inviteServerTid; + + private Dialog dialog; + + private Dialog joinDialog; + + private Dialog replacesDialog; + + public int myPort; + + private int peerPort; + + private String peerHostPort; + + private int dialogTerminatedCount; + + private int transctionTerminatedCount; + + private int transactionCount; + + private int dialogCount; + + private Request cancelRequest; + + private boolean cancelReceived; + + private boolean cancelOkReceived; + + private boolean ackSent; + + private boolean ackReceived; + + private boolean requestTerminatedReceived; + + private boolean byeReceived; + + private boolean redirectReceived; + + private boolean joinRequestReceived; + + private boolean replacesRequestReceived; + + private boolean okToByeReceived; + + private boolean authenticationErrorReceived; + + private URI requestURI; + + private Request inviteRequest; + + private Request messageRequest; + + private Response finalResponse; + + private Response informationalResponse; + + private boolean cancelSent; + + private boolean waitForCancel; + + private String lastMessageContent; + + private List allMessagesContent; + + private List allSubscriptionStates; + + private boolean finalResponseReceived; + + private int finalResponseToSend = -1; + + public int ackCount = 0; + + public int notifyCount = 0; + + public int numberOf491s = 0; + + private List provisionalResponsesToSend; + + private boolean useToURIasRequestUri; + + private boolean sendUpdateOn180; + + private String publishEvent = "reg"; + + private String sipETag; + + private String publishContentMessage; + + private boolean referReceived; + + private boolean challengeRequests; + private boolean multipleChallengeInResponse; + + private static Logger logger = Logger.getLogger(TestSipListener.class); + + DigestServerAuthenticationMethod dsam; + + private long timeToWaitBetweenProvisionnalResponse = 1000; + + private long timeToWaitBetweenSubsNotify = 1000; + + private boolean byeSent; + + private boolean serverErrorReceived; + + private long lastInfoResponseTime = -1; + + private Integer respondWithError = null; + + private long lastRegisterCSeqNumber = -1; + + private int finalResponseStatus; + + private boolean inviteReceived; + + private boolean sendReinvite; + + private boolean reinviteSent; + + private boolean abortProcessing; + + private boolean recordRoutingProxyTesting; + + public boolean b2buamessagereceived; + + public boolean txTimeoutReceived; + + private boolean sendSubsequentRequestsThroughSipProvider; + + private boolean testAckViaParam; + + private Request byeRequestReceived; + + private Request registerReceived; + + private long timeToWaitBeforeBye = 1000; + private long timeToWaitBeforeAck = 0; + + private boolean sendAck = true; + + private boolean prackSent; + + private boolean prackReceived; + + private Request prackRequestReceived; + + private boolean okToPrackReceived; + + private AtomicInteger rseqNumber = new AtomicInteger(1); + + public boolean sendByeInNewThread = false; + + private boolean useDefaultRoute = true; + + private boolean setTransport=true; + + private Response serviceUnavailableResponse = null; + + private int referResponseToSend = 202; + + private boolean sendNotifyForRefer = true; + + private Response inviteOkResponse; + + private boolean sendNotify = true; + private boolean sendNotifyBeforeResponseToSubscribe = false; + + private boolean countRetrans = false; + private int nbRetrans = 0; + + public Request firstRequest; + public Request lastInvite; + + private boolean disableSequenceNumberValidation = false; + + private boolean sendCancelOn1xx = false; + + private boolean testNextNonce =false; + private boolean testNC =false; + + private String nextNonce = null; + private int nc; + + private boolean dropRequest = false; + + private long waitBeforeFinalResponse = 0; + + private boolean sendUpdate; + + private boolean updateReceived; + + private boolean sendUpdateAfterUpdate = false; + + private boolean sendUpdateAfterPrack = false; + + private boolean sendUpdateAfterProvisionalResponses; + + private Request ackRequest; + + private boolean handleAuthorization = true; + + private Request updateRequest; + + private Request infoRequest; + + private Request optionsRequest; + + private boolean addRecordRouteForResponses; + + private RFC5626UseCase rfc5626UseCase; + + private String securityUser = "user"; + private String securityPwd = "pass"; + + private boolean sendProvisionalResponseBeforeChallenge = false; + + private boolean checkSDPNullOnChallengeRequests; + + class MyEventSource implements Runnable { + private TestSipListener notifier; + private EventHeader eventHeader; + + public MyEventSource(TestSipListener notifier, EventHeader eventHeader ) { + this.notifier = notifier; + this.eventHeader = eventHeader; + } + + public void run() { + try { + for (int i = 0; i < 1; i++) { + + Thread.sleep(timeToWaitBetweenSubsNotify); + Request request = this.notifier.dialog.createRequest(Request.NOTIFY); + SubscriptionStateHeader subscriptionState = protocolObjects.headerFactory + .createSubscriptionStateHeader(SubscriptionStateHeader.ACTIVE); + request.addHeader(subscriptionState); + request.addHeader(eventHeader); + + allSubscriptionStates.add(subscriptionState.getState().toLowerCase()); + // Lets mark our Contact +// ((SipURI)dialog.getLocalParty().getURI()).setParameter("id","not2"); + + ClientTransaction ct = sipProvider.getNewClientTransaction(request); + logger.info("NOTIFY Branch ID " + + ((ViaHeader)request.getHeader(ViaHeader.NAME)).getParameter("branch")); + this.notifier.dialog.sendRequest(ct); + logger.info("Dialog " + dialog); + logger.info("Dialog state after active NOTIFY: " + dialog.getState()); + if(sendByeBeforeTerminatingNotify && !byeSent) { + sendBye(); + } + } + } catch (Throwable ex) { + logger.info(ex.getMessage(), ex); + } + } + } + + public void processRequest(RequestEvent requestReceivedEvent) { + if(abortProcessing) { + logger.error("Processing aborted"); + return ; + } + + + Request request = requestReceivedEvent.getRequest(); + allRequests.add(request); + if(firstRequest == null) firstRequest = request; + ServerTransaction serverTransactionId = requestReceivedEvent + .getServerTransaction(); + + logger.info("\n\nRequest " + request.getMethod() + + " received at " + protocolObjects.sipStack.getStackName() + + " with server transaction id " + serverTransactionId + + " dialog " + requestReceivedEvent.getDialog()); + + if (request.getMethod().equals(Request.INVITE)) { + processInvite(requestReceivedEvent, serverTransactionId); + } + + if (request.getMethod().equals(Request.BYE)) { + processBye(request, serverTransactionId); + } + + if (request.getMethod().equals(Request.ACK)) { + processAck(request, serverTransactionId); + } + + if (request.getMethod().equals(Request.PRACK)) { + processPrack(request, serverTransactionId); + } + + if (request.getMethod().equals(Request.CANCEL)) { + processCancel(requestReceivedEvent, serverTransactionId); + } + + if (request.getMethod().equals(Request.MESSAGE)) { + processMessage(request, serverTransactionId); + } + + if (request.getMethod().equals(Request.REGISTER)) { + processRegister(request, serverTransactionId); + } + + if (request.getMethod().equals(Request.NOTIFY)) { + processNotify(requestReceivedEvent, serverTransactionId); + } + + if (request.getMethod().equals(Request.SUBSCRIBE)) { + processSubscribe(requestReceivedEvent, serverTransactionId); + } + + if (request.getMethod().equals(Request.UPDATE)) { + processUpdate(request, serverTransactionId); + } + + if (request.getMethod().equals(Request.OPTIONS)) { + processOptions(request, serverTransactionId); + } + + if (request.getMethod().equals(Request.INFO)) { + processInfo(request, serverTransactionId); + } + + if (request.getMethod().equals(Request.PUBLISH)) { + processPublish(requestReceivedEvent, serverTransactionId); + } + + if (request.getMethod().equals(Request.REFER)) { + processRefer(requestReceivedEvent, serverTransactionId); + } + } + + private void processPrack(Request request, + ServerTransaction serverTransactionId) { + + try { + prackReceived = true; + prackRequestReceived = request; + ServerTransaction st = serverTransactionId; + if (st == null) { + try { + st = sipProvider.getNewServerTransaction(request); + } catch ( TransactionAlreadyExistsException taex ) { + // This is a retransmission so just return. + return; + } + } + Response response = protocolObjects.messageFactory.createResponse( + 200, request); + Address address = protocolObjects.addressFactory + .createAddress("Shootme "); + contactHeader = protocolObjects.headerFactory.createContactHeader(address); + response.addHeader(contactHeader); + st.sendResponse(response); + + Thread.sleep(200); + + RequireHeader requireHeader = (RequireHeader) request.getHeader(RequireHeader.NAME); + if(provisionalResponsesToSend.size() > 0) { + logger.info("shootme: Creating provisional response with status code " + provisionalResponsesToSend.get(0)); + response = protocolObjects.messageFactory.createResponse( + provisionalResponsesToSend.get(0), inviteRequest); + requireHeader = protocolObjects.headerFactory.createRequireHeader("100rel"); + response.addHeader(requireHeader); + Header rseqHeader = protocolObjects.headerFactory.createRSeqHeader(rseqNumber.getAndIncrement()); + response.addHeader(rseqHeader); + ((MessageExt)response).getToHeader().setTag(((MessageExt) request).getToHeader().getTag()); + address = protocolObjects.addressFactory + .createAddress("Shootme "); + contactHeader = protocolObjects.headerFactory.createContactHeader(address); + response.addHeader(contactHeader); + dialog.sendReliableProvisionalResponse(response); + provisionalResponsesToSend.remove(0); + return; + } + + if(!sendUpdateAfterUpdate && !waitForCancel + // https://github.com/Mobicents/sip-servlets/issues/66 include UPDATE after PRACK + && !sendUpdateAfterPrack) + inviteServerTid.sendResponse(getFinalResponse()); + else { + logger.info("sendUpdateAfterUpdate or Waiting for CANCEL, stopping the PRACK processing and not sending 200 OK to INVITE"); + } + } catch(Exception e) { + logger.error("Unexpected exception while trying to send the 200 to PRACK " + request, e); + } + } + + public void processRefer(RequestEvent requestEvent, + ServerTransaction serverTransactionId) { + try { + SipProvider sipProvider = (SipProvider) requestEvent.getSource(); + Request request = requestEvent.getRequest(); + + logger.info("shootist: got a refer . ServerTxId = " + serverTransactionId); + ServerTransaction st = requestEvent.getServerTransaction(); + if (st == null) { + st = sipProvider.getNewServerTransaction(request); + } + inviteServerTid = st; + Dialog dialog = st.getDialog(); + + this.dialogCount ++; + this.dialog = dialog; + + logger.info("Shootme: dialog = " + dialog); + + Response response = protocolObjects.messageFactory.createResponse( + referResponseToSend, request); + sipETag = Integer.toString(new Random().nextInt(10000000)); + st.sendResponse(response); + this.transactionCount++; + logger.info("shootist: Sending " + referResponseToSend); + + List
headers = new ArrayList
(); + EventHeader eventHeader = (EventHeader) + protocolObjects.headerFactory.createHeader(EventHeader.NAME, "Refer"); + headers.add(eventHeader); + + if(sendNotifyForRefer) { + if(!referReceived) { + referReceived = true; + + SubscriptionStateHeader subscriptionStateHeader = (SubscriptionStateHeader) + protocolObjects.headerFactory.createHeader(SubscriptionStateHeader.NAME, "active;expires=3600"); + headers.add(subscriptionStateHeader); + allMessagesContent.add("SIP/2.0 100 Trying"); + sendInDialogSipRequest(Request.NOTIFY, "SIP/2.0 100 Trying", "message", "sipfrag;version=2.0", headers, null); + Thread.sleep(1000); + headers.remove(subscriptionStateHeader); + subscriptionStateHeader = (SubscriptionStateHeader) + protocolObjects.headerFactory.createHeader(SubscriptionStateHeader.NAME, "terminated;reason=noresource"); + headers.add(subscriptionStateHeader); + if(inviteRequest == null) { + ExtensionHeader extensionHeader = (ExtensionHeader) protocolObjects.headerFactory.createHeader("Out-Of-Dialog", "true"); + headers.add(extensionHeader); + } + allMessagesContent.add("SIP/2.0 200 OK"); + sendInDialogSipRequest(Request.NOTIFY, "SIP/2.0 200 OK", "message", "sipfrag;version=2.0", headers, null); + } else { + SubscriptionStateHeader subscriptionStateHeader = (SubscriptionStateHeader) + protocolObjects.headerFactory.createHeader(SubscriptionStateHeader.NAME, "active;expires=3600"); + headers.add(subscriptionStateHeader); + sendInDialogSipRequest(Request.NOTIFY, "SIP/2.0 100 Subsequent", "message", "sipfrag;version=2.0", headers, null); + } + } + + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + private void processPublish(RequestEvent requestEvent, + ServerTransaction serverTransactionId) { + try { + SipProvider sipProvider = (SipProvider) requestEvent.getSource(); + Request request = requestEvent.getRequest(); + + logger.info("shootist: got a publish . ServerTxId = " + serverTransactionId); + ServerTransaction st = requestEvent.getServerTransaction(); + if (st == null) { + st = sipProvider.getNewServerTransaction(request); + } + inviteServerTid = st; + Dialog dialog = st.getDialog(); + + this.dialogCount ++; + this.dialog = dialog; + + logger.info("Shootme: dialog = " + dialog); + + if(request.getRawContent() != null) { + this.lastMessageContent = new String(request.getRawContent()); + allMessagesContent.add(new String(lastMessageContent)); + } + SIPIfMatchHeader sipIfMatchHeader = (SIPIfMatchHeader) request.getHeader(SIPIfMatchHeader.NAME); + boolean sipIfMatchFound = true; + if(sipIfMatchHeader!= null && sipIfMatchHeader.getETag() != null && !sipIfMatchHeader.getETag().equals(sipETag)) { + sipIfMatchFound = false; + } + if(sipIfMatchFound) { + + Response response = protocolObjects.messageFactory.createResponse( + 200, request); + sipETag = Integer.toString(new Random().nextInt(10000000)); + SIPETagHeader sipTagHeader = protocolObjects.headerFactory.createSIPETagHeader(sipETag); + response.addHeader(sipTagHeader); + response.addHeader(request.getHeader(ExpiresHeader.NAME)); + st.sendResponse(response); + this.transactionCount++; + logger.info("shootist: Sending OK."); + } else { + Response response = protocolObjects.messageFactory.createResponse( + 500, request); + serverTransactionId.sendResponse(response); + this.transactionCount++; + } + + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + + public void processUpdate(Request request, + ServerTransaction serverTransactionId) { + try { + logger.info("shootist: got a update. ServerTxId = " + serverTransactionId); + if (serverTransactionId == null) { + logger.info("shootist: null TID."); + return; + } + + Dialog dialog = serverTransactionId.getDialog(); + logger.info("Dialog State = " + dialog.getState()); + Response response = protocolObjects.messageFactory.createResponse( + 200, request); + serverTransactionId.sendResponse(response); + this.transactionCount++; + logger.info("shootist: Sending OK."); + logger.info("Dialog State = " + dialog.getState()); + updateReceived = true; + updateRequest = request; + if (sendUpdateAfterUpdate) { + Request updateRequest = dialog.createRequest(Request.UPDATE); + + if (recordRoutingProxyTesting){ + ContactHeader contHdr = (ContactHeader) request.getHeader(ContactHeader.NAME); + SipURI sipUri = (SipURI)contHdr.getAddress().getURI(); + updateRequest.setRequestURI(sipUri); + } + + long seqNo = (((CSeqHeader) request.getHeader(CSeqHeader.NAME)).getSeqNumber()); + CSeqHeader cseqNew = protocolObjects.headerFactory.createCSeqHeader(++seqNo, "UPDATE"); + updateRequest.setHeader(cseqNew); + + ClientTransaction ct = sipProvider + .getNewClientTransaction(updateRequest); + ct.sendRequest(); + sendUpdate = true; + if(!prackReceived) { + sendUpdateAfterUpdate = false; + } + } + // https://github.com/Mobicents/sip-servlets/issues/66 send OK if there was an UPDATE after PRACK + if(!sendUpdateAfterUpdate && sendUpdateAfterPrack) + inviteServerTid.sendResponse(getFinalResponse()); + else { + logger.info("sendUpdateAfterUpdate or Waiting for CANCEL, stopping the PRACK processing and not sending 200 OK to INVITE"); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + public void processOptions(Request request, + ServerTransaction serverTransactionId) { + try { + logger.info("shootist: got a OPTIONS. ServerTxId = " + serverTransactionId); + + if (serverTransactionId == null) { + serverTransactionId = sipProvider.getNewServerTransaction(request); + } + if (serverTransactionId == null) { + logger.info("shootist: null TID."); + return; + } + + Dialog dialog = serverTransactionId.getDialog(); + if(dialog != null) { + logger.info("Dialog State = " + dialog.getState()); + } + if(!waitForCancel) { + Response response = protocolObjects.messageFactory.createResponse( + 200, request); + serverTransactionId.sendResponse(response); + this.transactionCount++; + logger.info("shootist: Sending OK."); + if(dialog != null) { + logger.info("Dialog State = " + dialog.getState()); + } + } + this.optionsRequest = request; + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + public void processInfo(Request request, + ServerTransaction serverTransactionId) { + try { + logger.info("shootist: got a info. ServerTxId = " + serverTransactionId); + if (serverTransactionId == null) { + logger.info("shootist: null TID."); + return; + } + + Dialog dialog = serverTransactionId.getDialog(); + logger.info("Dialog State = " + dialog.getState()); + Response response = protocolObjects.messageFactory.createResponse( + 200, request); + serverTransactionId.sendResponse(response); + this.transactionCount++; + logger.info("shootist: Sending OK."); + logger.info("Dialog State = " + dialog.getState()); + infoRequest = request; + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + /** + * Process the invite request. + */ + public void processSubscribe(RequestEvent requestEvent, + ServerTransaction serverTransaction) { + SipProvider sipProvider = (SipProvider) requestEvent.getSource(); + Request request = requestEvent.getRequest(); + try { + logger.info("notifier: got an Subscribe sending OK"); + logger.info("notifier: " + request); + logger.info("notifier : dialog = " + requestEvent.getDialog()); + EventHeader eventHeader = (EventHeader) request.getHeader(EventHeader.NAME); +// this.gotSubscribeRequest = true; + + // Always create a ServerTransaction, best as early as possible in the code + Response response = null; + ServerTransaction st = requestEvent.getServerTransaction(); + if (st == null) { + st = sipProvider.getNewServerTransaction(request); + } + + // Check if it is an initial SUBSCRIBE or a refresh / unsubscribe + boolean isInitial = requestEvent.getDialog() == null; + if ( isInitial ) { + // JvB: need random tags to test forking + String toTag = Integer.toHexString( (int) (Math.random() * Integer.MAX_VALUE) ); + response = protocolObjects.messageFactory.createResponse(202, request); + ToHeader toHeader = (ToHeader) response.getHeader(ToHeader.NAME); + + // Sanity check: to header should not ahve a tag. Else the dialog + // should have matched + toHeader.setTag(toTag); // Application is supposed to set. + + this.dialog = st.getDialog(); + // subscribe dialogs do not terminate on bye. + this.dialog.terminateOnBye(false); + } else { + response = protocolObjects.messageFactory.createResponse(202, request); + this.dialog = st.getDialog(); + // subscribe dialogs do not terminate on bye. + this.dialog.terminateOnBye(false); + } + + // Both 2xx response to SUBSCRIBE and NOTIFY need a Contact + Address address = protocolObjects.addressFactory.createAddress("Notifier "); + ((SipURI)address.getURI()).setPort( sipProvider.getListeningPoint(ListeningPoint.UDP).getPort() ); + ContactHeader contactHeader = protocolObjects.headerFactory.createContactHeader(address); + response.addHeader(contactHeader); + + // Expires header is mandatory in 2xx responses to SUBSCRIBE + ExpiresHeader expires = (ExpiresHeader) request.getHeader( ExpiresHeader.NAME ); + if (expires==null) { + expires = protocolObjects.headerFactory.createExpiresHeader(30); // rather short + } + response.addHeader( expires ); + + /* + * JvB: The SUBSCRIBE MUST be answered first. See RFC3265 3.1.6.2: + * "[...] a NOTIFY message is always sent immediately after any 200- + * class response to a SUBSCRIBE request" + * + * Do this before creating the NOTIFY request below + */ + if(!sendNotifyBeforeResponseToSubscribe) { + logger.info("Sending Response to Subscribe"); + Thread.sleep(waitBeforeFinalResponse); + st.sendResponse(response); + } else { + ((SIPDialog)dialog).setLastResponse((SIPTransaction)st, (SIPResponse)response); + } + //Thread.sleep(1000); // Be kind to implementations + + /* + * NOTIFY requests MUST contain a "Subscription-State" header with a + * value of "active", "pending", or "terminated". The "active" value + * indicates that the subscription has been accepted and has been + * authorized (in most cases; see section 5.2.). The "pending" value + * indicates that the subscription has been received, but that + * policy information is insufficient to accept or deny the + * subscription at this time. The "terminated" value indicates that + * the subscription is not active. + */ + if(sendNotify ) { + Request notifyRequest = dialog.createRequest("NOTIFY"); + + + // Mark the contact header, to check that the remote contact is updated + // ((SipURI)contactHeader.getAddress().getURI()).setParameter("id","not"); + + // Initial state is pending, second time we assume terminated (Expires==0) + SubscriptionStateHeader sstate = protocolObjects.headerFactory.createSubscriptionStateHeader( + expires.getExpires() != 0 ? SubscriptionStateHeader.PENDING : SubscriptionStateHeader.TERMINATED ); + allSubscriptionStates.add(sstate.getState().toLowerCase()); + + + // Need a reason for terminated + if ( sstate.getState().equalsIgnoreCase("terminated") ) { + sstate.setReasonCode( "deactivated" ); + } + + notifyRequest.addHeader(sstate); + notifyRequest.setHeader(eventHeader); + notifyRequest.setHeader(contactHeader); + // notifyRequest.setHeader(routeHeader); + ClientTransaction ct = sipProvider.getNewClientTransaction(notifyRequest); + + if(sstate.getState().equals(SubscriptionStateHeader.TERMINATED)) { + Thread.sleep(timeToWaitBetweenSubsNotify); + } + // Let the other side know that the tx is pending acceptance + // + dialog.sendRequest(ct); + logger.info("NOTIFY Branch ID " + + ((ViaHeader)request.getHeader(ViaHeader.NAME)).getParameter("branch")); + logger.info("Dialog " + dialog); + logger.info("Dialog state after pending NOTIFY: " + dialog.getState()); + + if (expires.getExpires() != 0) { + Thread myEventSource = new Thread(new MyEventSource(this,eventHeader)); + myEventSource.start(); + } + if(sendNotifyBeforeResponseToSubscribe) { + logger.info("Sending Response to Subscribe"); + Thread.sleep(waitBeforeFinalResponse); + st.sendResponse(response); + } + } + } catch (Throwable ex) { + logger.info(ex.getMessage(), ex); + } + } + + public void processNotify(RequestEvent requestEvent, + ServerTransaction serverTransactionId) { + SipProvider provider = (SipProvider) requestEvent.getSource(); + Request notify = requestEvent.getRequest(); + try { + logger.info("subscriber: got a notify count " + this.notifyCount++ ); + if (serverTransactionId == null) { + logger.info("subscriber: null TID."); + serverTransactionId = provider.getNewServerTransaction(notify); + } + Dialog dialog = serverTransactionId.getDialog(); +// if ( dialog != subscriberDialog ) { +// if (forkedDialog == null) { +// forkedDialog = dialog; +// } else { +// AbstractSubsnotifyTestCase.assertTrue("Dialog should be either the subscriber dialog ", +// forkedDialog == dialog); +// } +// } +// +// this.dialogs.add(dialog); + if(dialog != null) { + logger.info("Dialog State = " + dialog.getState()); + } + + Response response = protocolObjects.messageFactory.createResponse(finalResponseToSend, notify); + // SHOULD add a Contact + ContactHeader contact = null; + if(contactHeader != null) { + contact = (ContactHeader) contactHeader.clone(); + } else { + SipURI contactURI = protocolObjects.addressFactory.createSipURI(null, "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); + contactURI.setPort(listeningPoint.getPort()); + Address contactAddress = protocolObjects.addressFactory.createAddress(contactURI); + contact = protocolObjects.headerFactory.createContactHeader(contactAddress); + } + response.addHeader( contact ); + logger.info("Transaction State = " + serverTransactionId.getState()); + serverTransactionId.sendResponse(response); + if(dialog != null) { + logger.info("Dialog State = " + dialog.getState()); + } + SubscriptionStateHeader subscriptionState = (SubscriptionStateHeader) notify + .getHeader(SubscriptionStateHeader.NAME); + + // Subscription is terminated? + String state = subscriptionState.getState(); + allSubscriptionStates.add(state.toLowerCase()); + if(notify.getRawContent() != null) { + this.lastMessageContent = new String(notify.getRawContent()); + allMessagesContent.add(new String(lastMessageContent)); + } + if (state.equalsIgnoreCase(SubscriptionStateHeader.TERMINATED)) { + if(subscriptionState.getReasonCode() == null) { + dialog.delete(); + } + } else if (state.equalsIgnoreCase(SubscriptionStateHeader.ACTIVE)) { + if("reg".equalsIgnoreCase(((EventHeader)notify.getHeader(EventHeader.NAME)).getEventType())) { + if(sendByeBeforeTerminatingNotify) { + dialog.terminateOnBye(false); + sendBye(); + Thread.sleep(1000); + } + logger.info("Subscriber: sending unSUBSCRIBE"); + + // Else we end it ourselves + Request unsubscribe = dialog.createRequest(Request.SUBSCRIBE); + + logger.info( "dialog created:" + unsubscribe ); + // SHOULD add a Contact (done by dialog), lets mark it to test updates + // ((SipURI) dialog.getLocalParty().getURI()).setParameter( "id", "unsub" ); + ExpiresHeader expires = protocolObjects.headerFactory.createExpiresHeader(0); + unsubscribe.addHeader(expires); + // JvB note : stack should do this! + unsubscribe.addHeader(notify.getHeader(EventHeader.NAME)); // copy + // event + // header + logger.info("Sending Unsubscribe : " + unsubscribe); + logger.info("unsubscribe dialog " + dialog); + ClientTransaction ct = sipProvider.getNewClientTransaction(unsubscribe); + dialog.sendRequest(ct); + if(sendByeAfterTerminatingNotify) { + Thread.sleep(1000); + sendBye(); + } + } else if(sendByeBeforeTerminatingNotify) { + sendBye(); + } + } else { + logger.info("Subscriber: state now " + state);// pending + } + + } catch (Exception ex) { + logger.error("Unexpected exception",ex); + } + } + + private void processMessage(Request request, + ServerTransaction serverTransactionId) { + if(request.toString().contains("408 received")) { + txTimeoutReceived = true; + } + ServerTransaction serverTransaction = null; + + messageRequest = request; + try { + + serverTransaction = + (serverTransactionId == null? + sipProvider.getNewServerTransaction(request): + serverTransactionId); + } catch (javax.sip.TransactionAlreadyExistsException ex) { + ex.printStackTrace(); + return; + } catch (javax.sip.TransactionUnavailableException ex1) { + ex1.printStackTrace(); + return; + } + + ContentTypeHeader contentTypeHeader = (ContentTypeHeader) + request.getHeader(ContentTypeHeader.NAME); + boolean sendInvitewithJoin = false; + boolean sendInvitewithReplaces = false; + if(contentTypeHeader != null) { + if(TEXT_CONTENT_TYPE.equals(contentTypeHeader.getContentType())) { + this.lastMessageContent = new String(request.getRawContent()); + allMessagesContent.add(new String(lastMessageContent)); + if(lastMessageContent.indexOf("Join : ") != -1) { + this.lastMessageContent = lastMessageContent.substring("Join : ".length()); + sendInvitewithJoin = true; + } + if(lastMessageContent.indexOf("Replaces : ") != -1) { + this.lastMessageContent = lastMessageContent.substring("Replaces : ".length()); + sendInvitewithReplaces = true; + } + } + } else { + if(request.getHeader("From").toString().contains("b2bua@sip-servlets")) + b2buamessagereceived = true; + } + try { + Response okResponse = protocolObjects.messageFactory.createResponse( + Response.OK, request); + ToHeader toHeader = (ToHeader) okResponse.getHeader(ToHeader.NAME); + if (toHeader.getTag() == null) { + toHeader.setTag(Integer.toString(new Random().nextInt(10000000))); + } +// okResponse.addHeader(contactHeader); + serverTransaction.sendResponse(okResponse); + } catch (Exception ex) { + ex.printStackTrace(); + logger.error("error sending OK response to message", ex); + } + if(sendInvitewithJoin) { + try { + String fromUser = "receiver"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = protocolObjects.addressFactory.createSipURI( + fromUser, fromHost); + + String toUser = "join-receiver"; + String toHost = "sip-servlets.com"; + SipURI toAddress = protocolObjects.addressFactory.createSipURI( + toUser, toHost); + String[] headerNames = new String[] {"Join"}; + String[] headerContents = new String[] {lastMessageContent}; + sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, headerNames, headerContents, true); + } catch (Exception ex) { + ex.printStackTrace(); + logger.error("error sending INVITE with Join", ex); + } + } + if(sendInvitewithReplaces) { + try { + String fromUser = "receiver"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = protocolObjects.addressFactory.createSipURI( + fromUser, fromHost); + + String toUser = "replaces-receiver"; + String toHost = "sip-servlets.com"; + SipURI toAddress = protocolObjects.addressFactory.createSipURI( + toUser, toHost); + String[] headerNames = new String[] {"Replaces"}; + String[] headerContents = new String[] {lastMessageContent}; + sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, headerNames, headerContents, true); + } catch (Exception ex) { + ex.printStackTrace(); + logger.error("error sending INVITE with Join", ex); + } + } + } + + private void processRegister(Request request, + ServerTransaction serverTransactionId) { + + try { + registerReceived = request; + ServerTransaction serverTransaction = serverTransactionId == null? sipProvider.getNewServerTransaction(request) : serverTransactionId; + + System.out.println("challenge Requests ? " + challengeRequests); + lastRegisterCSeqNumber = ((CSeqHeader)request.getHeader("CSeq")).getSeqNumber(); + if(challengeRequests) { + // Verify AUTHORIZATION !!!!!!!!!!!!!!!! + dsam = new DigestServerAuthenticationMethod(); + dsam.initialize(); // it should read values from file, now all static + if ( !checkProxyAuthorization(request) ) { + Response responseauth = protocolObjects.messageFactory.createResponse(Response.PROXY_AUTHENTICATION_REQUIRED,request); + + ProxyAuthenticateHeader proxyAuthenticate = + protocolObjects.headerFactory.createProxyAuthenticateHeader(dsam.getScheme()); + proxyAuthenticate.setParameter("realm",dsam.getRealm(null)); + proxyAuthenticate.setParameter("nonce",dsam.generateNonce()); + //proxyAuthenticateImpl.setParameter("domain",authenticationMethod.getDomain()); + proxyAuthenticate.setParameter("opaque",""); + + proxyAuthenticate.setParameter("algorithm",dsam.getAlgorithm()); + if(testNC) { + proxyAuthenticate.setQop("auth"); + } + responseauth.setHeader(proxyAuthenticate); + // alexander kozlov : Adding the to tag to 407 as well + ToHeader toHeader = (ToHeader) responseauth.getHeader(ToHeader.NAME); + if (toHeader.getTag() == null) { + toHeader.setTag(Integer.toString(new Random().nextInt(10000000))); + } + + if (serverTransaction!=null) + serverTransaction.sendResponse(responseauth); + else + sipProvider.sendResponse(responseauth); + + System.out.println("RequestValidation: 407 PROXY_AUTHENTICATION_REQUIRED replied:\n"+responseauth.toString()); + return; + } else if(multipleChallengeInResponse && lastRegisterCSeqNumber > 2 && lastRegisterCSeqNumber % 2 == 1) { + Response responseauth = protocolObjects.messageFactory.createResponse(Response.PROXY_AUTHENTICATION_REQUIRED,request); + +// ListIterator
proxyAuthHeaders = request.getHeaders(ProxyAuthorizationHeader.NAME); +// while (proxyAuthHeaders.hasNext()) { +// ProxyAuthorizationHeader header = (ProxyAuthorizationHeader) proxyAuthHeaders.next(); +// ProxyAuthenticateHeader proxyAuthenticate = +// protocolObjects.headerFactory.createProxyAuthenticateHeader(dsam.getScheme()); +// proxyAuthenticate.setAlgorithm(header.getAlgorithm()); +// proxyAuthenticate.setNonce(header.getNonce()); +// proxyAuthenticate.setRealm(header.getRealm()); +// proxyAuthenticate.setParameter("username", header.getParameter("username")); +// proxyAuthenticate.setParameter("uri", header.getParameter("uri")); +// proxyAuthenticate.setParameter("response", header.getParameter("response")); +// proxyAuthenticate.setStale(false); +// logger.debug("Adding auth header to challenge response " + proxyAuthenticate); +// responseauth.addLast(proxyAuthenticate); +// } +// + ProxyAuthenticateHeader proxyAuthenticate = + protocolObjects.headerFactory.createProxyAuthenticateHeader(dsam.getScheme()); + proxyAuthenticate.setParameter("realm",dsam.getRealm(null)); + proxyAuthenticate.setParameter("nonce",dsam.generateNonce()); + //proxyAuthenticateImpl.setParameter("domain",authenticationMethod.getDomain()); + proxyAuthenticate.setParameter("opaque",""); + proxyAuthenticate.setStale(true); + + proxyAuthenticate.setParameter("algorithm",dsam.getAlgorithm()); + responseauth.addHeader(proxyAuthenticate); + // alexander kozlov : Adding the to tag to 407 as well + ToHeader toHeader = (ToHeader) responseauth.getHeader(ToHeader.NAME); + if (toHeader.getTag() == null) { + toHeader.setTag(Integer.toString(new Random().nextInt(10000000))); + } + + if (serverTransaction!=null) + serverTransaction.sendResponse(responseauth); + else + sipProvider.sendResponse(responseauth); + + System.out.println("RequestValidation: 407 PROXY_AUTHENTICATION_REQUIRED replied:\n"+responseauth.toString()); + } + } + + Response okResponse = protocolObjects.messageFactory.createResponse( + Response.OK, request); + if(testNextNonce) { + AuthenticationInfoHeader authenticationInfoHeader = protocolObjects.headerFactory.createAuthenticationInfoHeader(""); + nextNonce = dsam.generateNonce(); + authenticationInfoHeader.setNextNonce(nextNonce); + authenticationInfoHeader.removeParameter(ParameterNames.RESPONSE_AUTH); + okResponse.addHeader(authenticationInfoHeader); + } + ToHeader toHeader = (ToHeader) okResponse.getHeader(ToHeader.NAME); + if (toHeader.getTag() == null) { + toHeader.setTag(Integer.toString(new Random().nextInt(10000000))); + } +// okResponse.addHeader(contactHeader); + SupportedHeader supportedHeader = (SupportedHeader) request.getHeader(SupportedHeader.NAME); + PathHeader pathHeader = (PathHeader) request.getHeader(PathHeader.NAME); + contactHeader = (ContactHeader) request.getHeader(ContactHeader.NAME); + if(supportedHeader != null) { + okResponse.addHeader(supportedHeader); + if(((HeaderExt)supportedHeader).getValue().contains("outbound")) { + okResponse.addHeader(protocolObjects.headerFactory.createRequireHeader("outbound")); + contactHeader.setExpires(3600); + okResponse.addHeader(contactHeader); + if(pathHeader != null) { + okResponse.addHeader(pathHeader); + } + } + } + serverTransaction.sendResponse(okResponse); + } catch (Exception ex) { + ex.printStackTrace(); + logger.error("error sending OK response to message", ex); + } + } + + private void processCancel(RequestEvent requestEvent, + ServerTransaction serverTransactionId) { + try { + cancelReceived = true; + Thread.sleep(waitBeforeFinalResponse); + SipProvider sipProvider = (SipProvider) requestEvent.getSource(); + Request request = requestEvent.getRequest(); + setCancelRequest(request); + Response response = protocolObjects.messageFactory.createResponse( + Response.OK, request); + ServerTransaction st = requestEvent.getServerTransaction(); + + if (st == null) { + st = sipProvider.getNewServerTransaction(request); + } + Dialog dialog = st.getDialog(); + logger.info("Shootme: dialog = " + dialog); + st.sendResponse(response); + + response = protocolObjects.messageFactory.createResponse( + Response.REQUEST_TERMINATED, inviteRequest); + inviteServerTid.sendResponse(response); + } catch (Exception ex) { + ex.printStackTrace(); + logger.error("error sending CANCEL responses", ex); + } + } + + /** + * Process the invite request. + */ + public void processInvite(RequestEvent requestEvent, + ServerTransaction serverTransaction) { + inviteReceived = true; + SipProvider sipProvider = (SipProvider) requestEvent.getSource(); + Request request = requestEvent.getRequest(); + inviteRequest = request; + logger.info("shootme: got an Invite " + request); + if(dropRequest) { + logger.warn("dropping " + request); + return; + } + try { + ServerTransaction st = requestEvent.getServerTransaction(); + if (st == null) { + st = sipProvider.getNewServerTransaction(request); + } + inviteServerTid = st; + Dialog dialog = st.getDialog(); + if(request.getHeader(JoinHeader.NAME) != null) { + setJoinRequestReceived(true); + this.joinDialog = dialog; + } else if (request.getHeader(ReplacesHeader.NAME) != null) { + setReplacesRequestReceived(true); + this.replacesDialog = dialog; + } else { + this.dialogCount ++; + this.dialog = dialog; + } + + logger.info("Shootme: dialog = " + dialog); + if(dialog != null) { + logger.info("Shootme: dialog state = " + dialog.getState()); + } + if(dialog != null && disableSequenceNumberValidation) { + ((DialogExt)dialog).disableSequenceNumberValidation(); + } + this.inviteRequest = request; + + boolean sendReliably = false; + RequireHeader requireHeader = (RequireHeader) request.getHeader(RequireHeader.NAME); + if(requireHeader != null && "100rel".equalsIgnoreCase(requireHeader.getOptionTag().trim())) { + sendReliably = true; + } + + if(sendProvisionalResponseBeforeChallenge) { + sendProvisionalResponses(request, st, dialog, sendReliably); + } + if(challengeRequests) { + // Verify AUTHORIZATION !!!!!!!!!!!!!!!! + dsam = new DigestServerAuthenticationMethod(); + dsam.initialize(); // it should read values from file, now all static + if ( !checkProxyAuthorization(request) ) { + Thread.sleep(600); + if(!sendProvisionalResponseBeforeChallenge) { + Response response100 = protocolObjects.messageFactory.createResponse(100,request); + if (st!=null) + st.sendResponse(response100); + else + sipProvider.sendResponse(response100); + + Thread.sleep(600); + } + + Response responseauth = protocolObjects.messageFactory.createResponse(Response.PROXY_AUTHENTICATION_REQUIRED,request); + + ProxyAuthenticateHeader proxyAuthenticate = + protocolObjects.headerFactory.createProxyAuthenticateHeader(dsam.getScheme()); + proxyAuthenticate.setParameter("realm",dsam.getRealm(null)); + proxyAuthenticate.setParameter("nonce",dsam.generateNonce()); + //proxyAuthenticateImpl.setParameter("domain",authenticationMethod.getDomain()); + proxyAuthenticate.setParameter("opaque",""); + proxyAuthenticate.setParameter("stale","FALSE"); + proxyAuthenticate.setParameter("algorithm",dsam.getAlgorithm()); + responseauth.setHeader(proxyAuthenticate); + + if(multipleChallengeInResponse) { + proxyAuthenticate = + protocolObjects.headerFactory.createProxyAuthenticateHeader(dsam.getScheme()); + proxyAuthenticate.setParameter("realm",dsam.getRealm(null)); + proxyAuthenticate.setParameter("nonce",dsam.generateNonce()); + //proxyAuthenticateImpl.setParameter("domain",authenticationMethod.getDomain()); + proxyAuthenticate.setParameter("opaque",""); + proxyAuthenticate.setParameter("stale","true"); + proxyAuthenticate.setParameter("algorithm",dsam.getAlgorithm()); + responseauth.addHeader(proxyAuthenticate); + } + + ToHeader toHeader = (ToHeader) responseauth.getHeader(ToHeader.NAME); + toHeader.setTag(toTag); // Application is supposed to set. + + if(sendProvisionalResponseBeforeChallenge) { + provisionalResponsesToSend.clear(); + toTag = Integer.toString(new Random().nextInt(10000000)); + System.out.println("Resetted toTag to "+toTag); +// this.dialog.delete(); +// ((SIPTransactionStack)this.protocolObjects.sipStack).removeDialog((SIPDialog)dialog); +//// Thread.sleep(10000); +// this.dialog = null; + } + + if (st!=null) + st.sendResponse(responseauth); + else + sipProvider.sendResponse(responseauth); + + + System.out.println("RequestValidation: 407 PROXY_AUTHENTICATION_REQUIRED replied:\n"+responseauth.toString()); + return; + } + if(checkSDPNullOnChallengeRequests) { + //https://code.google.com/p/sipservlets/issues/detail?id=278 + if(request.getContentLength().getContentLength() > 0) { + throw new Exception("SDP should be empty"); + } + } + System.out.println("shootme: got an Invite with Authorization, sending Trying"); + } + if(!sendProvisionalResponseBeforeChallenge) { + sendProvisionalResponses(request, st, dialog, sendReliably); + } + + if (sendUpdateAfterProvisionalResponses) { + Request updateRequest = dialog.createRequest(Request.UPDATE); + + if (recordRoutingProxyTesting){ + ContactHeader contHdr = (ContactHeader) request.getHeader(ContactHeader.NAME); + SipURI sipUri = (SipURI)contHdr.getAddress().getURI(); + updateRequest.setRequestURI(sipUri); + } + + long seqNo = (((CSeqHeader) request.getHeader(CSeqHeader.NAME)).getSeqNumber()); + CSeqHeader cseqNew = protocolObjects.headerFactory.createCSeqHeader(++seqNo, "UPDATE"); + updateRequest.setHeader(cseqNew); + + sipProvider.sendRequest(updateRequest); + sendUpdate = true; + } + + if(respondWithError != null && !sendReliably) { + Response response = protocolObjects.messageFactory.createResponse( + respondWithError, request); + st.sendResponse(response); + return; + } + + + ContactHeader contactHeader = (ContactHeader)request.getHeader(ContactHeader.NAME); + if(contactHeader != null) { + Iterator it = request.getHeaders(ContactHeader.NAME); + int c=0; + while(it.hasNext()) {c++;it.next();} + bindings = c; + } + if(contactHeader != null && "0.0.0.0".equals(((SipURI)contactHeader.getAddress().getURI()).getHost())) { + abortProcessing = true; + throw new IllegalArgumentException("we received a contact header with 0.0.0.0 in an INVITE !"); + } + + if(!waitForCancel) { + Address address = protocolObjects.addressFactory.createAddress("Shootme "); + if(finalResponseToSend == Response.MOVED_TEMPORARILY) { + address = protocolObjects.addressFactory.createAddress("Shootme "); + } + contactHeader = protocolObjects.headerFactory.createContactHeader(address); + setFinalResponse(protocolObjects.messageFactory + .createResponse(finalResponseToSend, request)); + Response response = getFinalResponse(); + logger.debug("created final response " + response); + if(testAckViaParam) { + ViaHeader viaHeader = (ViaHeader)response.getHeader(ViaHeader.NAME); + viaHeader.setParameter("testAckViaParam", "true"); + } + if(testNextNonce) { + AuthenticationInfoHeader authenticationInfoHeader = protocolObjects.headerFactory.createAuthenticationInfoHeader(""); + nextNonce = dsam.generateNonce(); + authenticationInfoHeader.setNextNonce(nextNonce); + authenticationInfoHeader.removeParameter(ParameterNames.RESPONSE_AUTH); + response.addHeader(authenticationInfoHeader); + } + ToHeader toHeader = (ToHeader) response.getHeader(ToHeader.NAME); + if(sendProvisionalResponseBeforeChallenge) { + toHeader.removeParameter("tag"); + } + if(toHeader.getTag() == null) { + logger.debug("setting to Tag " + toTag); + toHeader.setTag(toTag); // Application is supposed to set. + } + getFinalResponse().addHeader(contactHeader); + if(isAddRecordRouteForResponses()) { + address = protocolObjects.addressFactory + .createAddress("sip:127.0.0.1:" + myPort +";transport="+protocolObjects.transport); + RecordRouteHeader recordRouteHeader = protocolObjects.headerFactory.createRecordRouteHeader(address); + response.addHeader(recordRouteHeader); + } + if(!sendReliably) { + Thread.sleep(waitBeforeFinalResponse); + logger.debug("sending back response " + response); + st.sendResponse(response); + } + + if(sendUpdateAfterPrack){ + Thread.sleep(waitBeforeFinalResponse); +// st.sendResponse(getFinalResponse()); + } + } else { + logger.info("Waiting for CANCEL, stopping the INVITE processing "); + return ; + } + + if(request.getRequestURI() instanceof SipURI && ("join").equalsIgnoreCase(((SipUri)request.getRequestURI()).getUser())) { + sendJoinMessage = true; + } + if(request.getRequestURI() instanceof SipURI && ("replaces").equalsIgnoreCase(((SipUri)request.getRequestURI()).getUser())) { + sendReplacesMessage = true; + } + } catch (Exception ex) { + logger.error("unexpected exception", ex); + } + } + + private void sendProvisionalResponses(Request request, + ServerTransaction st, Dialog dialog, boolean sendReliably) + throws InterruptedException, ParseException, + InvalidArgumentException, SipException { + RequireHeader requireHeader; + Iterator provisionalResponseIt = provisionalResponsesToSend.iterator(); + while (provisionalResponseIt.hasNext()) { + int provisionalResponseToSend = provisionalResponseIt.next(); + Thread.sleep(getTimeToWaitBetweenProvisionnalResponse()); + logger.info("shootme: Creating provisional response with status code " + provisionalResponseToSend); + Response response = protocolObjects.messageFactory.createResponse( + provisionalResponseToSend, request); + if(response.getStatusCode() == 183) { + response.setReasonPhrase("different" + System.nanoTime()); + } + if(provisionalResponseToSend >= Response.TRYING && provisionalResponseToSend < Response.OK) { + ToHeader toHeader = (ToHeader) response.getHeader(ToHeader.NAME); + if(provisionalResponseToSend != Response.TRYING && toHeader.getTag() == null) { + toHeader.setTag(toTag); // Application is supposed to set. + } + if(sendReliably && provisionalResponseToSend != Response.TRYING) { + provisionalResponsesToSend.remove(0); + provisionalResponseIt = provisionalResponsesToSend.iterator(); + requireHeader = protocolObjects.headerFactory.createRequireHeader("100rel"); + response.addHeader(requireHeader); + Header rseqHeader = protocolObjects.headerFactory.createRSeqHeader(rseqNumber.getAndIncrement()); + response.addHeader(rseqHeader); + Address address = protocolObjects.addressFactory + .createAddress("Shootme "); + contactHeader = protocolObjects.headerFactory.createContactHeader(address); + response.addHeader(contactHeader); + if(isAddRecordRouteForResponses()) { + address = protocolObjects.addressFactory + .createAddress("sip:127.0.0.1:" + myPort +";transport="+protocolObjects.transport); + RecordRouteHeader recordRouteHeader = protocolObjects.headerFactory.createRecordRouteHeader(address); + response.addHeader(recordRouteHeader); + } + dialog.sendReliableProvisionalResponse(response); + break; + } else { + if(provisionalResponseToSend == Response.TRYING) { + provisionalResponsesToSend.remove(0); + provisionalResponseIt = provisionalResponsesToSend.iterator(); + } + Address address = protocolObjects.addressFactory + .createAddress("Shootme "); + contactHeader = protocolObjects.headerFactory.createContactHeader(address); + response.addHeader(contactHeader); + if(isAddRecordRouteForResponses()) { + address = protocolObjects.addressFactory + .createAddress("sip:127.0.0.1:" + myPort +";transport="+protocolObjects.transport); + RecordRouteHeader recordRouteHeader = protocolObjects.headerFactory.createRecordRouteHeader(address); + response.addHeader(recordRouteHeader); + } + + st.sendResponse(response); + } + } + } + } + + public boolean checkProxyAuthorization(Request request) { + // Let Acks go through unchallenged. + ProxyAuthorizationHeader proxyAuthorization= + (ProxyAuthorizationHeader)request.getHeader(ProxyAuthorizationHeader.NAME); + + if (proxyAuthorization==null) { + logger.error("Authentication failed: ProxyAuthorization header missing!"); + return false; + }else{ + + if(nextNonce != null && !proxyAuthorization.getNonce().equals(nextNonce)) { + throw new IllegalArgumentException("Authentication failed: ProxyAuthorization nonce " + proxyAuthorization.getNonce() + " is different from the nextnonce previously generated " + nextNonce); + } + + if(nc > 0 && proxyAuthorization.getNonceCount() != nc) { + throw new IllegalArgumentException("Authentication failed: ProxyAuthorization nonceCount " + proxyAuthorization.getNonceCount() + " is different from the nextnonce previously generated " + nc); + } + + String username=proxyAuthorization.getParameter("username"); + //String password=proxyAuthorization.getParameter("password"); + + try{ + boolean res=dsam.doAuthenticate(username,proxyAuthorization,request); + if (res) logger.info("Authentication passed for user: "+username); + else logger.error("Authentication failed for user: "+username); + return res; + } + catch(Exception e) { + e.printStackTrace(); + return false; + } + } + } + + + public void processBye(Request request, + ServerTransaction serverTransactionId) { + try { + logger.info("shootist: got a bye . ServerTxId = " + serverTransactionId); + if(abortProcessing) { + logger.error("Processing Aborted!"); + return ; + } + this.byeReceived = true; + byeRequestReceived = request; + if (serverTransactionId == null) { + logger.info("shootist: null TID."); + return; + } + + Dialog dialog = serverTransactionId.getDialog(); + logger.info("Dialog State = " + dialog.getState()); + Response response = protocolObjects.messageFactory.createResponse( + byeResponse, request); + serverTransactionId.sendResponse(response); + this.transactionCount++; + logger.info("shootist: Sending " + byeResponse + " to BYE."); + logger.info("Dialog State = " + dialog.getState()); + + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + public void processAck(Request request, + ServerTransaction serverTransactionId) { + try { + logger.info("shootist: got a " + request); + logger.info("shootist: got an ACK. ServerTxId = " + serverTransactionId); + ackReceived = true; + ackRequest = request; + + //we don't count retransmissions + if(serverTransactionId != null) { + ackCount ++; + } + if(testAckViaParam) { + ViaHeader viaHeader = (ViaHeader)request.getHeader(ViaHeader.NAME); + String param = viaHeader.getParameter("testAckViaParam"); + if(param != null) { + abortProcessing = true; + logger.error("the Via Param set in the response shouldn't be present in the ACK"); + return; + } + } + if(sendBye) { + Thread.sleep(timeToWaitBeforeBye ); + if(serverTransactionId != null && serverTransactionId.getDialog() != null) { + Request byeRequest = serverTransactionId.getDialog().createRequest(Request.BYE); + logger.info("BYE created : " + byeRequest); + ClientTransaction ct = sipProvider.getNewClientTransaction(byeRequest); + logger.info("Sending BYE : " + byeRequest); + serverTransactionId.getDialog().sendRequest(ct); + logger.info("Dialog State = " + serverTransactionId.getDialog().getState()); + } + } + if(!joinRequestReceived && sendJoinMessage) { + String fromUser = "join"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = protocolObjects.addressFactory.createSipURI( + fromUser, fromHost); + + String toUser = "join-receiver"; + String toHost = "sip-servlets.com"; + SipURI toAddress = protocolObjects.addressFactory.createSipURI( + toUser, toHost); + + CallIdHeader callIdHeader = (CallIdHeader) request.getHeader(CallIdHeader.NAME); + FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME); + ToHeader toHeader = (ToHeader) request.getHeader(ToHeader.NAME); + JoinHeader joinHeader = (JoinHeader) ((HeaderFactoryExt)protocolObjects.headerFactory).createJoinHeader(callIdHeader.getCallId(), toHeader.getTag(), fromHeader.getTag()); + + sendSipRequest("MESSAGE", fromAddress, toAddress, joinHeader.toString(), null, false); + } + if(!isReplacesRequestReceived() && sendReplacesMessage) { + String fromUser = "replaces"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = protocolObjects.addressFactory.createSipURI( + fromUser, fromHost); + + String toUser = "replaces-receiver"; + String toHost = "sip-servlets.com"; + SipURI toAddress = protocolObjects.addressFactory.createSipURI( + toUser, toHost); + + CallIdHeader callIdHeader = (CallIdHeader) request.getHeader(CallIdHeader.NAME); + FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME); + ToHeader toHeader = (ToHeader) request.getHeader(ToHeader.NAME); + ReplacesHeader replacesHeader = (ReplacesHeader) ((HeaderFactoryExt)protocolObjects.headerFactory).createReplacesHeader(callIdHeader.getCallId(), toHeader.getTag(), fromHeader.getTag()); + + sendSipRequest("MESSAGE", fromAddress, toAddress, replacesHeader.toString(), null, false); + } + if(joinRequestReceived) { + sendBye(); + sendBye(joinDialog); + } + if(isReplacesRequestReceived()) { + sendBye(); + sendBye(replacesDialog); + } + if(sendReinvite && !reinviteSent) { + prackSent = false; + List
headers = new ArrayList
(); + Header reinviteHeader = protocolObjects.headerFactory.createHeader("ReInvite", "true"); + headers.add(reinviteHeader); + String transport = null; + if(ackRequest.getRequestURI() instanceof SipURI) { + transport = ((SipURI)ackRequest.getRequestURI()).getTransportParam(); + } + sendInDialogSipRequest("INVITE", null, null, null, headers, transport); + reinviteSent = true; + return; + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + public void processResponse(ResponseEvent responseReceivedEvent) { + if(abortProcessing) { + logger.error("Processing aborted"); + return ; + } + Response response = (Response) responseReceivedEvent.getResponse(); + allResponses.add(response); + if(response.getStatusCode() == 491){ + numberOf491s++; + } + RecordRouteHeader recordRouteHeader = (RecordRouteHeader)response.getHeader(RecordRouteHeader.NAME); + if(!recordRoutingProxyTesting && recordRouteHeader != null) { + abortProcessing = true; + throw new IllegalArgumentException("we received a record route header in a response !"); + } + ContactHeader contactHeader = (ContactHeader)response.getHeader(ContactHeader.NAME); + if(contactHeader != null && "0.0.0.0".equals(((SipURI)contactHeader.getAddress().getURI()).getHost())) { + abortProcessing = true; + throw new IllegalArgumentException("we received a contact header with 0.0.0.0 in a response !"); + } + + if(response.getStatusCode() >= 400 && response.getStatusCode() < 999) { + this.serverErrorReceived = true; + } + if(response.getStatusCode() == 503) { + this.serviceUnavailableResponse = response; + } + if(response.toString().toLowerCase().contains("info")) { + lastInfoResponseTime = System.currentTimeMillis(); + } + ClientTransaction tid = responseReceivedEvent.getClientTransaction(); + Dialog responseDialog = null; + if(tid != null) { + responseDialog = tid.getDialog(); + } else { + responseDialog = responseReceivedEvent.getDialog(); + } + CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME); + + logger.info("Response received : Status Code = " + + response.getStatusCode() + " " + cseq); + if (tid == null && countRetrans) { + nbRetrans++; + } + // not dropping in PRACK case on REINVITE the ClientTx can be null it seems + if (tid == null && responseDialog == null && !prackSent) { + logger.info("Stray response -- dropping "); + return; + } + logger.info("Dialog = " + responseDialog); + if(responseDialog != null) { + logger.info("Dialog State is " + responseDialog.getState()); + } + if(tid !=null) { + logger.info("transaction state is " + tid.getState()); + } + + try { + if(response.getStatusCode() > 100 && response.getStatusCode() < 200) { + informationalResponse = response; + if(sendCancelOn1xx) { + sendCancel(); + return; + } + } + if(response.getStatusCode() >= 200 && response.getStatusCode() < 700) { + logger.info("final response received : status code " + response.getStatusCode()); + finalResponseReceived = true; + setFinalResponseStatus(response.getStatusCode()); + setFinalResponse(response); + } + if (response.getStatusCode() == Response.OK) { + logger.info("response = " + response); + if (cseq.getMethod().equals(Request.INVITE) && sendAck) { + inviteOkResponse = response; + Request ackRequest = responseDialog.createAck(cseq.getSeqNumber()); + if (useToURIasRequestUri) { + ackRequest.setRequestURI(requestURI); + } + if(timeToWaitBeforeAck > 0) { + Thread.sleep(timeToWaitBeforeAck); + } + logger.info("Sending ACK " + ackRequest); + if(extraRoute) { + Header h = protocolObjects.headerFactory.createHeader("Route", ackRequest.getRequestURI().toString()); + ackRequest.addLast(h); + } + if(!sendSubsequentRequestsThroughSipProvider) { + logger.info("Sending ACK through dialog " + ackRequest); + responseDialog.sendAck(ackRequest); + this.dialog = responseDialog; + } else { + logger.info("Sending ACK through provider " + ackRequest); + sipProvider.sendRequest(ackRequest); + } + ackSent = true; + Thread.sleep(1000); + // If the caller is supposed to send the bye + if(sendReinvite && !reinviteSent) { + List
headers = new ArrayList
(); + Header reinviteHeader = protocolObjects.headerFactory.createHeader("ReInvite", "true"); + headers.add(reinviteHeader); + if(prackSent) { + headers.add(protocolObjects.headerFactory.createHeader(RequireHeader.NAME, "100rel")); + } + prackSent = false; + sendInDialogSipRequest("INVITE", null, null, null, headers, null); + + reinviteSent = true; + return; + } + if(sendBye) { +// Thread.sleep(30000); + sendBye(); + } + if(sendByeAfterTerminatingNotify) { + responseDialog.terminateOnBye(false); + } + } else if(cseq.getMethod().equals(Request.BYE)) { + okToByeReceived = true; + } else if (cseq.getMethod().equals(Request.CANCEL)) { + this.cancelOkReceived = true; +// if (tid.getDialog().getState() == DialogState.CONFIRMED) { +// // oops cancel went in too late. Need to hang up the +// // dialog. +// logger.info("Sending BYE -- cancel went in too late !!"); +// Request byeRequest = dialog.createRequest(Request.BYE); +// ClientTransaction ct = sipProvider +// .getNewClientTransaction(byeRequest); +// tid.getDialog().sendRequest(ct); +// } + } else if (cseq.getMethod().equals(Request.PUBLISH)) { + SIPETagHeader sipTagHeader = (SIPETagHeader)response.getHeader(SIPETag.NAME); + sipETag = sipTagHeader.getETag(); + } else if (cseq.getMethod().equals(Request.PRACK)) { + okToPrackReceived = true; + if (sendUpdateAfterPrack){ + Request updateRequest = dialog.createRequest(Request.UPDATE); + + if (recordRoutingProxyTesting){ + ContactHeader contHdr = (ContactHeader) response.getHeader(ContactHeader.NAME); + SipURI sipUri = (SipURI)contHdr.getAddress().getURI(); + updateRequest.setRequestURI(sipUri); + } + ClientTransaction ct = sipProvider + .getNewClientTransaction(updateRequest); + dialog.sendRequest(ct); + sendUpdate = true; + } + } else if(cseq.getMethod().equals(Request.UPDATE) && sendUpdateAfterUpdate && prackReceived) { + Address address = protocolObjects.addressFactory + .createAddress("Shootme "); + contactHeader = protocolObjects.headerFactory.createContactHeader(address); + setFinalResponse(protocolObjects.messageFactory + .createResponse(finalResponseToSend, inviteRequest)); + ToHeader toHeader = (ToHeader) getFinalResponse().getHeader(ToHeader.NAME); + if(toHeader.getTag() == null) { + toHeader.setTag(toTag); // Application is supposed to set. + } + getFinalResponse().addHeader(contactHeader); + inviteServerTid.sendResponse(getFinalResponse()); + } + } else if (response.getStatusCode() == Response.MOVED_TEMPORARILY) { + // Dialog dies as soon as you get an error response. + this.redirectReceived = true; + if (cseq.getMethod().equals(Request.INVITE)) { + // lookup the contact header + ContactHeader contHdr = (ContactHeader) response + .getHeader(ContactHeader.NAME); + // we can re-use the from header + FromHeader from = ((FromHeader) response + .getHeader(FromHeader.NAME)); + // we use the to-address, but without the tag + ToHeader to = (ToHeader) (response.getHeader(ToHeader.NAME)).clone(); + to.removeParameter("tag"); + // the call-id can be re-used + CallIdHeader callID = ((CallIdHeader) response + .getHeader(CallIdHeader.NAME)); + // we take the next cseq + long seqNo = (((CSeqHeader) response + .getHeader(CSeqHeader.NAME)).getSeqNumber()); + logger.info("seqNo = " + seqNo); + CSeqHeader cseqNew = protocolObjects.headerFactory + .createCSeqHeader(++seqNo, "INVITE"); + // Create ViaHeaders (either use tcp or udp) + ArrayList viaHeaders = new ArrayList(); + ViaHeader viaHeader = protocolObjects.headerFactory + .createViaHeader("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", sipProvider + .getListeningPoint(protocolObjects.transport).getPort(), + protocolObjects.transport, + null); + // add via headers + viaHeaders.add(viaHeader); + // create max forwards + MaxForwardsHeader maxForwardsHeader = protocolObjects.headerFactory + .createMaxForwardsHeader(10); + // create invite Request + SipURI newUri = (SipURI)this.requestURI.clone(); + newUri.setParameter("redirection", "true"); + requestURI = newUri; + Request invRequest = protocolObjects.messageFactory + .createRequest(newUri, + "INVITE", callID, cseqNew, from, to, + viaHeaders, maxForwardsHeader); + // we set the Request URI to the address given + SipURI contactURI = + protocolObjects.addressFactory.createSipURI(null, this.listeningPoint.getIPAddress()); + + contactURI.setPort(this.listeningPoint.getPort()); + contactURI.setTransportParam(protocolObjects.transport); + + Address address = protocolObjects.addressFactory.createAddress(contactURI); + ContactHeader contact = protocolObjects.headerFactory.createContactHeader(address); + invRequest.addHeader(contact); + + // the contacat header in the response contains where to redirect + // the request to -- which in this case happens to be back to the + // same location. + ContactHeader chdr = (ContactHeader)response.getHeader(ContactHeader.NAME); + + SipURI sipUri = (SipURI)chdr.getAddress().getURI(); +// sipUri.setLrParam(); + RouteHeader routeHeader = + protocolObjects.headerFactory.createRouteHeader(chdr.getAddress()); + invRequest.addHeader(routeHeader); + invRequest.setRequestURI(sipUri); + + logger.info("Sending INVITE to " + + contHdr.getAddress().getURI().toString()); + inviteClientTid = sipProvider.getNewClientTransaction(invRequest); + this.transactionCount++; + + logger.info("New TID = " + inviteClientTid); + inviteClientTid.sendRequest(); + logger.info("sendReqeust succeeded " + inviteClientTid); + Dialog dialog = inviteClientTid.getDialog(); + this.dialogCount ++; + this.dialog = dialog; + + + } + } else if (response.getStatusCode() == Response.REQUEST_TERMINATED) { + if(cseq.getMethod().equals(Request.INVITE)){ + this.requestTerminatedReceived = true; + } + } else if(response.getStatusCode() == Response.RINGING && sendUpdateOn180) { + Request updateRequest = dialog.createRequest(Request.UPDATE); + + if (recordRoutingProxyTesting){ + ContactHeader contHdr = (ContactHeader) response.getHeader(ContactHeader.NAME); + SipURI sipUri = (SipURI)contHdr.getAddress().getURI(); + updateRequest.setRequestURI(sipUri); + } + + + ClientTransaction ct = sipProvider + .getNewClientTransaction(updateRequest); + dialog.sendRequest(ct); + sendUpdate = true; + + } else if ((response.getStatusCode() == Response.PROXY_AUTHENTICATION_REQUIRED + || response.getStatusCode() == Response.UNAUTHORIZED) && handleAuthorization ) { + URI uriReq = tid.getRequest().getRequestURI(); + Request authrequest = this.processResponseAuthorization( + response, uriReq); + + if(authrequest == null) { + System.out + .println("INVITE AUTHORIZATION null, stopping there"); + return; + } + inviteClientTid.sendRequest(); + System.out + .println("INVITE AUTHORIZATION sent:\n" + authrequest); + } else if (response.getStatusCode() > Response.TRYING && response.getStatusCode() < Response.OK) { + RequireHeader requireHeader = (RequireHeader) response.getHeader(RequireHeader.NAME); + logger.debug("prackSent ? " + prackSent); + if(requireHeader != null && "100rel".equalsIgnoreCase(requireHeader.getOptionTag().trim()) && !prackSent) { + prackSent = true; + Request prack = responseDialog.createPrack(response); + ClientTransaction ct = sipProvider + .getNewClientTransaction(prack); + responseDialog.sendRequest(ct); + } + } + /** + * end of modified code + */ + } catch (Exception ex) { + logger.error("An unexpected exception occured while processing the response" , ex); + } + + } + + public long getLastInfoResponseTime() { + return lastInfoResponseTime; + } + + public Request processResponseAuthorization(Response response, URI uriReq) { + RecordRouteHeader recordRouteHeader = (RecordRouteHeader)response.getHeader(RecordRouteHeader.NAME); + if(!recordRoutingProxyTesting && recordRouteHeader != null) { + abortProcessing = true; + throw new IllegalArgumentException("we received a record route header in a response !"); + } + Request requestauth = null; + this.authenticationErrorReceived = true; + try { + System.out.println("processResponseAuthorization()"); + + requestauth = (Request) inviteClientTid.getRequest().clone(); + + CSeqHeader cSeq = (CSeqHeader) requestauth.getHeader((CSeqHeader.NAME)); + try { + cSeq.setSeqNumber(cSeq.getSeqNumber() + 1l); + } catch (InvalidArgumentException e) { + logger.error("Cannot increment the Cseq header to the new INVITE request",e); + throw new IllegalArgumentException("Cannot create the INVITE request",e); + } + // non regression test for http://code.google.com/p/sipservlets/issues/detail?id=88 + if((securityUser.equalsIgnoreCase("badUser") || securityPwd.equalsIgnoreCase("badpwd")) && cSeq.getSeqNumber() > 2) { + return null; + } + requestauth.setHeader(cSeq); + requestauth.removeHeader(ViaHeader.NAME); + // Create ViaHeaders + ViaHeader viaHeader = protocolObjects.headerFactory + .createViaHeader("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", sipProvider + .getListeningPoint(protocolObjects.transport).getPort(), protocolObjects.transport, + null); + // add via headers + requestauth.addHeader(viaHeader); + + try { + ClientTransaction retryTran = sipProvider + .getNewClientTransaction(requestauth); + inviteClientTid = retryTran; + + + dialog = retryTran.getDialog(); + if (dialog == null) { + dialog = sipProvider.getNewDialog(retryTran); + } + } catch (TransactionUnavailableException e) { + logger.error("Cannot get a new transaction for the request " + requestauth,e); + throw new IllegalArgumentException("Cannot get a new transaction for the request " + requestauth,e); + } + AuthorizationHeader authorization = new org.mobicents.servlet.sip.catalina.security.authentication.DigestAuthenticator(protocolObjects.headerFactory).getAuthorizationHeader( + ((CSeqHeader) response + .getHeader(CSeqHeader.NAME)).getMethod(), + uriReq.toString(), + "", // TODO: What is this entity-body? + ((WWWAuthenticate) (response + .getHeader(SIPHeaderNames.WWW_AUTHENTICATE))), + securityUser, + securityPwd, + ((WWWAuthenticate) (response + .getHeader(SIPHeaderNames.WWW_AUTHENTICATE))).getNonce(), + 1); + + requestauth.addHeader(authorization); + } catch (ParseException pa) { + System.out + .println("processResponseAuthorization() ParseException:"); + System.out.println(pa.getMessage()); + pa.printStackTrace(); + } catch (Exception ex) { + System.out.println("processResponseAuthorization() Exception:"); + System.out.println(ex.getMessage()); + ex.printStackTrace(); + } + return requestauth; + } + + /** + * @throws SipException + * @throws TransactionUnavailableException + * @throws TransactionDoesNotExistException + * @throws InterruptedException + */ + public void sendBye() throws SipException, + TransactionUnavailableException, TransactionDoesNotExistException, InterruptedException { + if(timeToWaitBeforeBye > 0) { + Thread.sleep(timeToWaitBeforeBye); + } + sendBye(this.dialog); + } + + /** + * @throws SipException + * @throws TransactionUnavailableException + * @throws TransactionDoesNotExistException + */ + public void sendBye(final Dialog dialog) throws SipException, + TransactionUnavailableException, TransactionDoesNotExistException { + Thread th = new Thread(){ + public void run() { + try { + if(getFinalResponseStatus() >= 500 && getFinalResponseStatus() < 600) { + logger.info("Not Sending BYE as last response final status was " + getFinalResponseStatus()); + } + if(sendByeInNewThread) Thread.sleep(600); + Request byeRequest = dialog.createRequest(Request.BYE); + URI uri = ((FromHeader)byeRequest.getHeader(FromHeader.NAME)).getAddress().getURI(); + if(uri.isSipURI()) { + ((SipURI)uri).removeParameter("fromParam"); + } + ClientTransaction ct = sipProvider.getNewClientTransaction(byeRequest); + logger.info("Sending BYE " + byeRequest); + if(!sendSubsequentRequestsThroughSipProvider) { + dialog.sendRequest(ct); + } else { + sipProvider.sendRequest(byeRequest); + } + byeSent = true; + } catch(Exception e) {e.printStackTrace();} + } + }; + if(sendByeInNewThread) { + th.start(); + } else { + th.run(); + } + + } + + public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) { + + logger.info("Transaction Time out"); + } + + + + public SipProvider createProvider() throws Exception { + logger.info("Shootist: createProvider()"); + listeningPoint = protocolObjects.sipStack.createListeningPoint( + "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", myPort, protocolObjects.transport); + this.sipProvider = protocolObjects.sipStack + .createSipProvider(listeningPoint); + return sipProvider; + + } + + public void addListeningPoint(String ipAddress, int port, String transport) throws Exception { + logger.info("Shootist: addListeningPoint()"); + ListeningPoint listeningPoint = protocolObjects.sipStack.createListeningPoint( + "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", port, transport); + sipProvider.addListeningPoint(listeningPoint); + } + + public Request sendSipRequest(String method, URI fromURI, URI toURI, String messageContent, SipURI route, boolean useToURIasRequestUri) throws SipException, ParseException, InvalidArgumentException { + return sendSipRequest(method, fromURI, toURI, messageContent, route, useToURIasRequestUri, null, null, true); + } + + public Request sendSipRequest(String method, URI fromURI, URI toURI, String messageContent, SipURI route, boolean useToURIasRequestUri, String[] headerNames, String[] headerContents, boolean setHeader) throws SipException, ParseException, InvalidArgumentException { + this.useToURIasRequestUri = useToURIasRequestUri; + // create >From Header + Address fromNameAddress = protocolObjects.addressFactory + .createAddress(fromURI); + FromHeader fromHeader = protocolObjects.headerFactory + .createFromHeader(fromNameAddress, Integer.toString(new Random().nextInt(10000000))); + + // create To Header + Address toNameAddress = protocolObjects.addressFactory + .createAddress(toURI); + ToHeader toHeader = protocolObjects.headerFactory.createToHeader( + toNameAddress, null); + if (toURI.toString().contains("receiverWithTag")) { + toHeader.setTag("123456"); + } + + if(toURI instanceof SipURI) { + SipURI toSipUri = (SipURI) toURI; + // create Request URI + this.requestURI = protocolObjects.addressFactory.createSipURI( + toSipUri.getUser(), peerHostPort); + ((SipURI)this.requestURI).setPort(peerPort); + if(setTransport) { + ((SipURI)this.requestURI).setTransportParam(listeningPoint.getTransport()); + } + } + if(useToURIasRequestUri || toURI instanceof TelURL) { + this.requestURI = toURI; + } + + // Create ViaHeaders + + List viaHeaders = new ArrayList(); + ViaHeader viaHeader = protocolObjects.headerFactory + .createViaHeader("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", sipProvider + .getListeningPoint(protocolObjects.transport).getPort(), listeningPoint.getTransport(), + null); + if(rfc5626UseCase != null && (rfc5626UseCase == RFC5626UseCase.B2BUA || rfc5626UseCase == RFC5626UseCase.Proxy)) { + //try to bind to non existing IP + viaHeader = protocolObjects.headerFactory + .createViaHeader("192.192.192.192", sipProvider + .getListeningPoint(protocolObjects.transport).getPort(), listeningPoint.getTransport(), + null); + } + // add via headers + viaHeaders.add(viaHeader); + + // Create ContentTypeHeader +// ContentTypeHeader contentTypeHeader = protocolObjects.headerFactory +// .createContentTypeHeader("application", "sdp"); + + // Create a new CallId header + CallIdHeader callIdHeader = sipProvider.getNewCallId(); + + // Create a new Cseq header + CSeqHeader cSeqHeader = protocolObjects.headerFactory + .createCSeqHeader(1L, method); + + // Create a new MaxForwardsHeader + MaxForwardsHeader maxForwards = protocolObjects.headerFactory + .createMaxForwardsHeader(70); + + // Create the request. + Request request = protocolObjects.messageFactory.createRequest( + requestURI, method, callIdHeader, cSeqHeader, + fromHeader, toHeader, viaHeaders, maxForwards); + // Create contact headers + String host = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; + if(rfc5626UseCase != null && (rfc5626UseCase == RFC5626UseCase.B2BUA || rfc5626UseCase == RFC5626UseCase.Proxy)) { + //try to bind to non existing IP + host = "192.192.192.192"; + } + request.setHeader(protocolObjects.headerFactory.createHeader("REM", "RRRREM")); + URI contactUrl = null; + if(fromURI instanceof SipURI) { + contactUrl = protocolObjects.addressFactory.createSipURI( + ((SipURI)fromURI).getUser(), host); + /** + * either use tcp or udp + */ + ((SipURI)contactUrl).setPort(listeningPoint.getPort()); + if(setTransport) { + ((SipURI)contactUrl).setTransportParam(listeningPoint.getTransport()); + if(rfc5626UseCase == null) { + ((SipURI)contactUrl).setLrParam(); + } + } + if(rfc5626UseCase != null && (rfc5626UseCase == RFC5626UseCase.B2BUA || rfc5626UseCase == RFC5626UseCase.Proxy)) { + ((SipURI)contactUrl).setParameter("ob", null); + } + } else { + contactUrl = fromURI; + } + + // Create the contact name address. + Address contactAddress = protocolObjects.addressFactory + .createAddress(contactUrl); + + // Add the contact address. +// contactAddress.setDisplayName(fromName); + + contactHeader = protocolObjects.headerFactory + .createContactHeader(contactAddress); + if (rfc5626UseCase != null && rfc5626UseCase == RFC5626UseCase.Proxy) { + contactHeader.setParameter("reg-id", "1"); + contactHeader.setParameter("+sip.instance", "\"\""); + } + request.addHeader(contactHeader); + + SipURI uri = protocolObjects.addressFactory.createSipURI(null, "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); + + uri.setLrParam(); + uri.setTransportParam(protocolObjects.transport); + uri.setPort(this.peerPort); + + if(route != null) { + Address address = protocolObjects.addressFactory.createAddress(route); + RouteHeader routeHeader = protocolObjects.headerFactory.createRouteHeader(address); + request.addHeader(routeHeader); + } else if(useDefaultRoute ) { + Address address = protocolObjects.addressFactory.createAddress(uri); + RouteHeader routeHeader = protocolObjects.headerFactory.createRouteHeader(address); + request.addHeader(routeHeader); + } + + // set the message content + if(messageContent != null) { + ContentLengthHeader contentLengthHeader = + protocolObjects.headerFactory.createContentLengthHeader(messageContent.length()); + ContentTypeHeader contentTypeHeader = + protocolObjects.headerFactory.createContentTypeHeader(TEXT_CONTENT_TYPE,PLAIN_UTF8_CONTENT_SUBTYPE); + byte[] contents = messageContent.getBytes(); + request.setContent(contents, contentTypeHeader); + request.setContentLength(contentLengthHeader); + } + + if(headerNames != null) { + for(int q=0; q 0) { + this.peerPort = peerPort; + this.peerHostPort = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":"+ peerPort; + } + this.sendBye = callerSendBye; + allMessagesContent = new ArrayList(); + allSubscriptionStates = new ArrayList(); + finalResponseToSend = Response.OK; + provisionalResponsesToSend = new ArrayList(); + provisionalResponsesToSend.add(Response.TRYING); + provisionalResponsesToSend.add(Response.RINGING); + } + + public void processIOException(IOExceptionEvent exceptionEvent) { + logger.info("IOException happened for " + + exceptionEvent.getHost() + " port = " + + exceptionEvent.getPort()); + + } + + public void processTransactionTerminated( + TransactionTerminatedEvent transactionTerminatedEvent) { + logger.info("Transaction terminated event recieved for " + + transactionTerminatedEvent.getClientTransaction()); + this.transctionTerminatedCount++; + } + + public void processDialogTerminated( + DialogTerminatedEvent dialogTerminatedEvent) { + this.dialogTerminatedCount++; + + } + + public boolean getOkToByeReceived() { + return okToByeReceived; + } + + public boolean getByeReceived() { + return byeReceived; + } + + public void sendCancel() { + sendCancel(false, null); + } + + public void sendCancel(boolean addReason, String reasonText) { + try { + logger.info("Sending cancel"); + + Request cancelRequest = inviteClientTid.createCancel(); + if(addReason) { + ReasonHeader reasonHeader = (ReasonHeader) this.protocolObjects.headerFactory.createReasonHeader("SIP", 200, reasonText); + cancelRequest.addHeader(reasonHeader); + } + ClientTransaction cancelTid = sipProvider + .getNewClientTransaction(cancelRequest); + cancelTid.sendRequest(); + cancelSent = true; + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + /** + * @return the cancelReceived + */ + public boolean isCancelReceived() { + return cancelReceived; + } + + /** + */ + public void setCancelReceived(boolean cancelReceived) { + this.cancelReceived = cancelReceived; + } + + /** + * @return the cancelOkReceived + */ + public boolean isCancelOkReceived() { + return cancelOkReceived; + } + + /** + */ + public void setCancelOkReceived(boolean cancelOkReceived) { + this.cancelOkReceived = cancelOkReceived; + } + + /** + * @return the requestTerminatedReceived + */ + public boolean isRequestTerminatedReceived() { + return requestTerminatedReceived; + } + + /** + * @return the requestTerminatedReceived + */ + public void setRequestTerminatedReceived(boolean requestTerminatedReceived) { + this.requestTerminatedReceived = requestTerminatedReceived; + } + + /** + * @return the waitForCancel + */ + public boolean isWaitForCancel() { + return waitForCancel; + } + + public long getLastRegisterCSeqNumber() { + return lastRegisterCSeqNumber; + } + + /** + * @param waitForCancel the waitForCancel to set + */ + public void setWaitForCancel(boolean waitForCancel) { + this.waitForCancel = waitForCancel; + } + + /** + * @return the ackSent + */ + public boolean isAckSent() { + return ackSent; + } + + public void setAckSent(boolean ackSent) { + this.ackSent = ackSent; + } + + /** + * @return the ackReceived + */ + public boolean isAckReceived() { + return ackReceived; + } + + public void setAckReceived(boolean ackReceived) { + this.ackReceived = ackReceived; + } + + /** + * + * @param transport TODO + * @param messageToSend + * @throws SipException + * @throws InvalidArgumentException + * @throws ParseException + */ + public void sendInDialogSipRequest(String method, String content, String contentType, String subContentType, List
headers, String transport) throws SipException, InvalidArgumentException, ParseException { + + Request message = dialog.createRequest(method); + if(transport !=null) { + ((SipURI)message.getRequestURI()).setTransportParam(transport); + } + + if(content != null) { + ContentLengthHeader contentLengthHeader = + protocolObjects.headerFactory.createContentLengthHeader(content.length()); + ContentTypeHeader contentTypeHeader = + protocolObjects.headerFactory.createContentTypeHeader(contentType,subContentType); + message.setContentLength(contentLengthHeader); + message.setContent(content, contentTypeHeader); + } + + if(headers != null) { + for (Header header : headers) { + message.addHeader(header); + } + } + + addSpecificHeaders(method, message); + message.removeHeader(ViaHeader.NAME); + logger.info("in dialog message = " + message); + + ClientTransaction clientTransaction = sipProvider.getNewClientTransaction(message); + if(method.equals("INVITE")) { + inviteClientTid = clientTransaction; + } + dialog.sendRequest(clientTransaction); + } + + /** + * + * @param messageToSend + * @throws SipException + * @throws InvalidArgumentException + * @throws ParseException + */ + public void sendMessageInDialog(String messageToSend) throws SipException, InvalidArgumentException, ParseException { + Request message = dialog.createRequest(Request.MESSAGE); + ContentLengthHeader contentLengthHeader = + protocolObjects.headerFactory.createContentLengthHeader(messageToSend.length()); + ContentTypeHeader contentTypeHeader = + protocolObjects.headerFactory.createContentTypeHeader(TEXT_CONTENT_TYPE,PLAIN_UTF8_CONTENT_SUBTYPE); + message.setContentLength(contentLengthHeader); + message.setContent(messageToSend, contentTypeHeader); + ClientTransaction clientTransaction = sipProvider.getNewClientTransaction(message); + dialog.sendRequest(clientTransaction); + } + + /** + * + * @param messageToSend + * @throws SipException + * @throws InvalidArgumentException + * @throws ParseException + */ + public void sendMessageNoDialog(String messageToSend) throws SipException, InvalidArgumentException, ParseException { + Request message = dialog.createRequest(Request.MESSAGE); + ContentLengthHeader contentLengthHeader = + protocolObjects.headerFactory.createContentLengthHeader(messageToSend.length()); + ContentTypeHeader contentTypeHeader = + protocolObjects.headerFactory.createContentTypeHeader(TEXT_CONTENT_TYPE,PLAIN_UTF8_CONTENT_SUBTYPE); + message.setContentLength(contentLengthHeader); + message.setContent(messageToSend, contentTypeHeader); + ClientTransaction clientTransaction = sipProvider.getNewClientTransaction(message); + dialog.sendRequest(clientTransaction); + } + + /** + * @return the lastMessageContent + */ + public String getLastMessageContent() { + return lastMessageContent; + } + + /** + * @return the allMessagesContent + */ + public List getAllMessagesContent() { + return allMessagesContent; + } + + /** + * @return the finalResponseReceived + */ + public boolean isFinalResponseReceived() { + return finalResponseReceived; + } + + public boolean isServerErrorReceived() { + return serverErrorReceived; + } + + public void setServerErrorReceived(boolean serverErrorReceived) { + this.serverErrorReceived = serverErrorReceived; + } + + /** + * @return the finalResponseToSend + */ + public int getFinalResponseToSend() { + return finalResponseToSend; + } + + /** + * @param finalResponseToSend the finalResponseToSend to set + */ + public void setFinalResponseToSend(int finalResponseToSend) { + this.finalResponseToSend = finalResponseToSend; + } + + /** + * @return the provisionalResponsesToSend + */ + public List getProvisionalResponsesToSend() { + return provisionalResponsesToSend; + } + + /** + * @param provisionalResponsesToSend the provisionalResponsesToSend to set + */ + public void setProvisionalResponsesToSend( + List provisionalResponsesToSend) { + this.provisionalResponsesToSend = provisionalResponsesToSend; + } + + /** + * @return the allSubscriptionState + */ + public List getAllSubscriptionState() { + return allSubscriptionStates; + } + + /** + * @param byeReceived the byeReceived to set + */ + public void setByeReceived(boolean byeReceived) { + this.byeReceived = byeReceived; + } + + /** + * @param okToByeReceived the okToByeReceived to set + */ + public void setOkToByeReceived(boolean okToByeReceived) { + this.okToByeReceived = okToByeReceived; + } + + public void setSendUpdateOn180(boolean sendUpdateOn180) { + this.sendUpdateOn180 = sendUpdateOn180; + } + + public void setPublishEvent(String publishEvent) { + this.publishEvent = publishEvent; + } + + public void setPublishContentMessage(String publishContentMessage) { + this.publishContentMessage = publishContentMessage; + } + + public void setChallengeRequests(boolean challengeRequests) { + this.challengeRequests = challengeRequests; + } + + /** + * @param timeToWaitBetweenProvisionnalResponse the timeToWaitBetweenProvisionnalResponse to set + */ + public void setTimeToWaitBetweenProvisionnalResponse( + long timeToWaitBetweenProvisionnalResponse) { + this.timeToWaitBetweenProvisionnalResponse = timeToWaitBetweenProvisionnalResponse; + } + + public Response getInviteOkResponse() { + return inviteOkResponse; + } + + /** + * @return the timeToWaitBetweenProvisionnalResponse + */ + public long getTimeToWaitBetweenProvisionnalResponse() { + return timeToWaitBetweenProvisionnalResponse; + } + + public long getTimeToWaitBetweenSubsNotify() { + return timeToWaitBetweenSubsNotify; + } + + public void setTimeToWaitBetweenSubsNotify(long timeToWaitBetweenSubsNotify) { + this.timeToWaitBetweenSubsNotify = timeToWaitBetweenSubsNotify; + } + + /** + * @return the sendBye + */ + public boolean isSendBye() { + return sendBye; + } + + /** + * @param sendBye the sendBye to set + */ + public void setSendBye(boolean sendBye) { + this.sendBye = sendBye; + } + + /** + * @param sendByeBeforeTerminatingNotify the sendByeBeforeTerminatingNotify to set + */ + public void setSendByeBeforeTerminatingNotify( + boolean sendByeBeforeTerminatingNotify) { + this.sendByeBeforeTerminatingNotify = sendByeBeforeTerminatingNotify; + } + + /** + * @return the sendByeBeforeTerminatingNotify + */ + public boolean isSendByeBeforeTerminatingNotify() { + return sendByeBeforeTerminatingNotify; + } + + /** + * @param sendByeAfterTerminatingNotify the sendByeAfterTerminatingNotify to set + */ + public void setSendByeAfterTerminatingNotify( + boolean sendByeAfterTerminatingNotify) { + this.sendByeAfterTerminatingNotify = sendByeAfterTerminatingNotify; + } + + /** + * @return the sendByeAfterTerminatingNotify + */ + public boolean isSendByeAfterTerminatingNotify() { + return sendByeAfterTerminatingNotify; + } + + public boolean isAuthenticationErrorReceived() { + return authenticationErrorReceived; + } + + public void setRespondWithError(int errorCode) { + this.respondWithError = errorCode; + } + + /** + * @param finalResponseStatus the finalResponseStatus to set + */ + public void setFinalResponseStatus(int finalResponseStatus) { + this.finalResponseStatus = finalResponseStatus; + } + + /** + * @return the finalResponseStatus + */ + public int getFinalResponseStatus() { + return finalResponseStatus; + } + + /** + * @param joinRequestReceived the joinRequestReceived to set + */ + public void setJoinRequestReceived(boolean joinRequestReceived) { + this.joinRequestReceived = joinRequestReceived; + } + + /** + * @return the joinRequestReceived + */ + public boolean isJoinRequestReceived() { + return joinRequestReceived; + } + + /** + * @param replacesRequestReceived the replacesRequestReceived to set + */ + public void setReplacesRequestReceived(boolean replacesRequestReceived) { + this.replacesRequestReceived = replacesRequestReceived; + } + + /** + * @return the replacesRequestReceived + */ + public boolean isReplacesRequestReceived() { + return replacesRequestReceived; + } + + /** + * @return the inviteReceived + */ + public boolean isInviteReceived() { + return inviteReceived; + } + + /** + * @return the inviteReceived + */ + public void setInviteReceived(boolean inviteReceived) { + this.inviteReceived = inviteReceived; + } + + + public void setSendReinvite(boolean b) { + sendReinvite = b; + } + + public Request getInviteRequest() { + return inviteRequest; + } + + /** + * @param recordRoutingProxyTesting the recordRoutingProxyTesting to set + */ + public void setRecordRoutingProxyTesting(boolean recordRoutingProxyTesting) { + this.recordRoutingProxyTesting = recordRoutingProxyTesting; + } + + /** + * @return the recordRoutingProxyTesting + */ + public boolean isRecordRoutingProxyTesting() { + return recordRoutingProxyTesting; + } + + /** + * @param sendSubsequentRequestsThroughSipProvider the sendSubsequentRequestsThroughSipProvider to set + */ + public void setSendSubsequentRequestsThroughSipProvider( + boolean sendSubsequentRequestsThroughSipProvider) { + this.sendSubsequentRequestsThroughSipProvider = sendSubsequentRequestsThroughSipProvider; + } + + /** + * @return the sendSubsequentRequestsThroughSipProvider + */ + public boolean isSendSubsequentRequestsThroughSipProvider() { + return sendSubsequentRequestsThroughSipProvider; + } + + /** + * @param testAckViaParam the testAckViaParam to set + */ + public void setTestAckViaParam(boolean testAckViaParam) { + this.testAckViaParam = testAckViaParam; + } + + /** + * @return the testAckViaParam + */ + public boolean isTestAckViaParam() { + return testAckViaParam; + } + + /** + * @return the byeRequestReceived + */ + public Request getByeRequestReceived() { + return byeRequestReceived; + } + + /** + * @return the registerReceived + */ + public Request getRegisterReceived() { + return registerReceived; + } + + /** + * @param timeToWaitBeforeBye the timeToWaitBeforeBye to set + */ + public void setTimeToWaitBeforeBye(long timeToWaitBeforeBye) { + this.timeToWaitBeforeBye = timeToWaitBeforeBye; + } + + /** + * @return the timeToWaitBeforeBye + */ + public long getTimeToWaitBeforeBye() { + return timeToWaitBeforeBye; + } + + /** + * @param sendAck the sendAck to set + */ + public void setSendAck(boolean sendAck) { + this.sendAck = sendAck; + } + + /** + * @return the sendAck + */ + public boolean isSendAck() { + return sendAck; + } + + /** + * @param prackSent the prackSent to set + */ + public void setPrackSent(boolean prackSent) { + this.prackSent = prackSent; + } + + /** + * @return the prackSent + */ + public boolean isPrackSent() { + return prackSent; + } + + /** + * @param okToPrackReceived the okToPrackReceived to set + */ + public void setOkToPrackReceived(boolean okToPrackReceived) { + this.okToPrackReceived = okToPrackReceived; + } + + /** + * @return the okToPrackReceived + */ + public boolean isOkToPrackReceived() { + return okToPrackReceived; + } + + /** + * @param prackReceived the prackReceived to set + */ + public void setPrackReceived(boolean prackReceived) { + this.prackReceived = prackReceived; + } + + /** + * @return the prackReceived + */ + public boolean isPrackReceived() { + return prackReceived; + } + + /** + * @param useDefaultRoute the useDefaultRoute to set + */ + public void setUseDefaultRoute(boolean useDefaultRoute) { + this.useDefaultRoute = useDefaultRoute; + } + + /** + * @return the useDefaultRoute + */ + public boolean isUseDefaultRoute() { + return useDefaultRoute; + } + + /** + * @param messageRequest the messageRequest to set + */ + public void setMessageRequest(Request messageRequest) { + this.messageRequest = messageRequest; + } + + /** + * @return the messageRequest + */ + public Request getMessageRequest() { + return messageRequest; + } + + public void setTransport(boolean b) { + setTransport = b; + } + + /** + * @param finalResponse the finalResponse to set + */ + public void setFinalResponse(Response finalResponse) { + this.finalResponse = finalResponse; + } + + /** + * @return the finalResponse + */ + public Response getFinalResponse() { + return finalResponse; + } + + /** + * @param timeToWaitBeforeAck the timeToWaitBeforeAck to set + */ + public void setTimeToWaitBeforeAck(long timeToWaitBeforeAck) { + this.timeToWaitBeforeAck = timeToWaitBeforeAck; + } + + /** + * @return the timeToWaitBeforeAck + */ + public long getTimeToWaitBeforeAck() { + return timeToWaitBeforeAck; + } + + /** + * @return the serviceUnavailableReceived + */ + public Response getServiceUnavailableResponse() { + return serviceUnavailableResponse; + } + + public void setReferResponseToSend(int referResponseToSend) { + this.referResponseToSend = referResponseToSend; + } + + /** + * @param sendNotifyForRefer the sendNotifyForRefer to set + */ + public void setSendNotifyForRefer(boolean sendNotifyForRefer) { + this.sendNotifyForRefer = sendNotifyForRefer; + } + + /** + * @return the sendNotifyForRefer + */ + public boolean isSendNotifyForRefer() { + return sendNotifyForRefer; + } + + /** + * @param sendNotify the sendNotify to set + */ + public void setSendNotify(boolean sendNotify) { + this.sendNotify = sendNotify; + } + + /** + * @return the sendNotify + */ + public boolean isSendNotify() { + return sendNotify; + } + + /** + * @param informationalResponse the informationalResponse to set + */ + public void setInformationalResponse(Response informationalResponse) { + this.informationalResponse = informationalResponse; + } + + /** + * @return the informationalResponse + */ + public Response getInformationalResponse() { + return informationalResponse; + } + + /** + * @param countRetrans the countRetrans to set + */ + public void setCountRetrans(boolean countRetrans) { + this.countRetrans = countRetrans; + } + + /** + * @return the countRetrans + */ + public boolean isCountRetrans() { + return countRetrans; + } + + /** + * @param nbRetrans the nbRetrans to set + */ + public void setNbRetrans(int nbRetrans) { + this.nbRetrans = nbRetrans; + } + + /** + * @return the nbRetrans + */ + public int getNbRetrans() { + return nbRetrans; + } + + /** + * @param prackRequestReceived the prackRequestReceived to set + */ + public void setPrackRequestReceived(Request prackRequestReceived) { + this.prackRequestReceived = prackRequestReceived; + } + + /** + * @return the prackRequestReceived + */ + public Request getPrackRequestReceived() { + return prackRequestReceived; + } + + public void setMultipleChallengeInResponse(boolean multipleChallengeInResponse) { + this.multipleChallengeInResponse = multipleChallengeInResponse; + } + + /** + * @param disableSequenceNumberValidation the disableSequenceNumberValidation to set + */ + public void setDisableSequenceNumberValidation( + boolean disableSequenceNumberValidation) { + this.disableSequenceNumberValidation = disableSequenceNumberValidation; + } + + /** + * @return the disableSequenceNumberValidation + */ + public boolean isDisableSequenceNumberValidation() { + return disableSequenceNumberValidation; + } + + /** + * @param sendCancelOn1xx the sendCancelOn1xx to set + */ + public void setSendCancelOn1xx(boolean sendCancelOn1xx) { + this.sendCancelOn1xx = sendCancelOn1xx; + } + + /** + * @return the sendCancelOn1xx + */ + public boolean isSendCancelOn1xx() { + return sendCancelOn1xx; + } + + /** + * @param useToURIasRequestUri the useToURIasRequestUri to set + */ + public void setUseToURIasRequestUri(boolean useToURIasRequestUri) { + this.useToURIasRequestUri = useToURIasRequestUri; + } + + /** + * @return the useToURIasRequestUri + */ + public boolean isUseToURIasRequestUri() { + return useToURIasRequestUri; + } + + public void setTestNextNonce(boolean b) { + this.testNextNonce = b; + } + + public void setTestNC(boolean b) { + this.testNC = b; + } + + /** + * @param dropRequest the dropRequest to set + */ + public void setDropRequest(boolean dropRequest) { + this.dropRequest = dropRequest; + } + + /** + * @return the dropRequest + */ + public boolean isDropRequest() { + return dropRequest; + } + + public void setWaitBeforeFinalResponse(long waitBeforeFinalResponse) { + this.waitBeforeFinalResponse = waitBeforeFinalResponse; + } + + public boolean isSendUpdate() { + return sendUpdate; + } + + public boolean isUpdateReceived() { + return updateReceived; + } + + public void setSendUpdateAfterUpdate(boolean sendUpdateAfterUpdate) { + this.sendUpdateAfterUpdate = sendUpdateAfterUpdate; + } + + public boolean isSendUpdateAfterUpdate() { + return sendUpdateAfterUpdate; + } + + public void setSendUpdateAfterPrack(boolean sendUpdateAfterPrack) { + this.sendUpdateAfterPrack = sendUpdateAfterPrack; + } + + public void setSendUpdateAfterProvisionalResponses(boolean sendUpdateAfterProvisonalResponses) { + this.sendUpdateAfterProvisionalResponses = sendUpdateAfterProvisonalResponses; + } + + /** + * @return the ackRequest + */ + public Request getAckRequest() { + return ackRequest; + } + + public void setHandleAuthorization(boolean handleAuthorization) { + this.handleAuthorization = handleAuthorization; + } + + public boolean isHandleAuthorization() { + return handleAuthorization; + } + + public void setUpdateRequest(Request updateRequest) { + this.updateRequest = updateRequest; + } + + public Request getUpdateRequest() { + return updateRequest; + } + + public void setInfoRequest(Request infoRequest) { + this.infoRequest = infoRequest; + } + + public Request getInfoRequest() { + return infoRequest; + } + + public void setOptionsRequest(Request optionsRequest) { + this.optionsRequest = optionsRequest; + } + + public Request getOptionsRequest() { + return this.optionsRequest; + } + + /** + * @param addRecordRouteForResponses the addRecordRouteForResponses to set + */ + public void setAddRecordRouteForResponses(boolean addRecordRouteForResponses) { + this.addRecordRouteForResponses = addRecordRouteForResponses; + } + + /** + * @return the addRecordRouteForResponses + */ + public boolean isAddRecordRouteForResponses() { + return addRecordRouteForResponses; + } + + public void setRFC5626UseCase(RFC5626UseCase rfc5626UseCase) { + this.rfc5626UseCase = rfc5626UseCase; + } + + public void setSecurityUser(String securityUser) { + this.securityUser = securityUser; + } + + public void setSecurityPwd(String securityPwd) { + this.securityPwd = securityPwd; + } + + public void sendProvisionalResponseBeforeChallenge(boolean b) { + sendProvisionalResponseBeforeChallenge = b; + } + + public String getToTag() { + return toTag; + } + + public void setToTag(String toTag) { + this.toTag = toTag; + } + + public int getByeResponse() { + return byeResponse; + } + + public void setByeResponse(int byeResponse) { + this.byeResponse = byeResponse; + } + + /** + * @return the cancelRequest + */ + public Request getCancelRequest() { + return cancelRequest; + } + + /** + * @param cancelRequest the cancelRequest to set + */ + public void setCancelRequest(Request cancelRequest) { + this.cancelRequest = cancelRequest; + } + + /** + * @return the sendNotifyBeforeResponseToSubscribe + */ + public boolean isSendNotifyBeforeResponseToSubscribe() { + return sendNotifyBeforeResponseToSubscribe; + } + + /** + * @param sendNotifyBeforeResponseToSubscribe the sendNotifyBeforeResponseToSubscribe to set + */ + public void setSendNotifyBeforeResponseToSubscribe( + boolean sendNotifyBeforeResponseToSubscribe) { + this.sendNotifyBeforeResponseToSubscribe = sendNotifyBeforeResponseToSubscribe; + } + + public void setCheckSDPNullOnChallengeRequests(boolean checkSDPNullOnChallengeRequests) { + this.checkSDPNullOnChallengeRequests = checkSDPNullOnChallengeRequests; + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/address/AddressTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/address/AddressTest.java index 1382835d9f..6ba3e9521c 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/address/AddressTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/address/AddressTest.java @@ -23,6 +23,7 @@ package org.mobicents.servlet.sip.testsuite.address; import javax.servlet.sip.Address; +import javax.servlet.sip.URI; import org.mobicents.servlet.sip.message.SipFactoryImpl; @@ -70,4 +71,20 @@ public void testDifferent() throws Exception { assertFalse(uri2 + " is the same as " + uri1, uri2.equals(uri1)); } } + + // test for https://telestax.zendesk.com/tickets/31631 + public void testParameter() throws Exception { + Address address = address(""); +// address.setParameter("webrtc", "yes"); +// System.out.println(address.toString()); +// assertEquals(";webrtc=yes", address.toString()); + address.getURI().setParameter("webrtc", "yes"); +// uri.setParameter("webrtc", "yes"); +// address.setURI(uri); +// assertEquals(";webrtc=yes", address.toString()); + assertEquals("", address.toString()); + System.out.println(address.toString()); + System.out.println(address.getURI().toString()); + + } } \ No newline at end of file diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/address/SipFactoryTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/address/SipFactoryTest.java index 814a9a0dd8..03b7eee0f9 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/address/SipFactoryTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/address/SipFactoryTest.java @@ -24,6 +24,7 @@ import javax.servlet.sip.Parameterable; import javax.servlet.sip.ServletParseException; +import javax.servlet.sip.SipURI; import org.mobicents.servlet.sip.message.SipFactoryImpl; @@ -33,6 +34,9 @@ public class SipFactoryTest extends junit.framework.TestCase { private SipFactoryImpl sipFactory; + int[] arrayToDecode = new int[]{83, 73, 80, 47, 50, 46, 48, 32, 50, 48, 48, 32, 67, 97, 110, 99, 101, 108, 105, 110, 103, 13, 10, 84, 111, 58, 32, 60, 115, 105, 112, 58, 43, 49, 53, 49, 50, 51, 56, 56, 52, 49, 49, 53, 64, 53, 52, 46, 56, 51, 46, 49, 57, 54, 46, 50, 51, 56, 62, 59, 116, 97, 103, 61, 51, 49, 50, 52, 50, 51, 56, 13, 10, 86, 105, 97, 58, 32, 83, 73, 80, 47, 50, 46, 48, 47, 85, 68, 80, 32, 49, 48, 46, 49, 54, 53, 46, 49, 51, 55, 46, 49, 55, 58, 53, 48, 54, 53, 59, 98, 114, 97, 110, 99, 104, 61, 122, 57, 104, 71, 52, 98, 75, 49, 115, 97, 110, 115, 97, 121, 49, 57, 50, 56, 53, 52, 52, 48, 50, 55, 114, 100, 98, 50, 55, 49, 52, 50, 54, 50, 55, 52, 52, 122, 115, 100, 95, 48, 13, 10, 86, 105, 97, 58, 32, 83, 73, 80, 47, 50, 46, 48, 47, 85, 68, 80, 32, 49, 48, 46, 49, 54, 53, 46, 49, 51, 55, 46, 49, 55, 58, 53, 48, 54, 48, 59, 98, 114, 97, 110, 99, 104, 61, 122, 57, 104, 71, 52, 98, 75, 49, 115, 97, 110, 115, 97, 121, 49, 57, 50, 56, 53, 52, 52, 48, 50, 55, 114, 100, 98, 50, 55, 49, 52, 50, 54, 50, 55, 52, 52, 95, 48, 13, 10, 86, 105, 97, 58, 32, 83, 73, 80, 47, 50, 46, 48, 47, 85, 68, 80, 32, 54, 52, 46, 49, 51, 54, 46, 49, 55, 51, 46, 51, 49, 58, 53, 48, 54, 48, 59, 98, 114, 97, 110, 99, 104, 61, 122, 57, 104, 71, 52, 98, 75, 49, 115, 97, 110, 115, 97, 121, 49, 57, 50, 56, 53, 52, 52, 48, 50, 55, 114, 100, 98, 50, 55, 49, 52, 50, 13, 10, 67, 83, 101, 113, 58, 32, 49, 32, 67, 65, 78, 67, 69, 76, 13, 10, 67, 97, 108, 108, 45, 73, 68, 58, 32, 54, 50, 55, 52, 52, 53, 56, 55, 55, 45, 48, 45, 50, 52, 51, 49, 53, 51, 50, 56, 54, 48, 64, 54, 52, 46, 49, 51, 54, 46, 49, 55, 51, 46, 50, 50, 54, 13, 10, 70, 114, 111, 109, 58, 32, 60, 115, 105, 112, 58, 43, 51, 49, 54, 53, 51, 53, 55, 49, 50, 57, 50, 64, 54, 52, 46, 49, 51, 54, 46, 49, 55, 51, 46, 51, 49, 62, 59, 116, 97, 103, 61, 115, 97, 110, 115, 97, 121, 49, 57, 50, 56, 53, 52, 52, 48, 50, 55, 114, 100, 98, 50, 55, 49, 52, 50, 13, 10, 83, 101, 114, 118, 101, 114, 58, 32, 84, 101, 108, 83, 99, 97, 108, 101, 32, 82, 101, 115, 116, 99, 111, 109, 109, 32, 55, 46, 51, 46, 49, 46, 49, 49, 53, 55, 13, 10, 67, 111, 110, 116, 101, 110, 116, 45, 76, 101, 110, 103, 116, 104, 58, 32, 48, 13, 10, 13, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int[] arrayToDecode2 = new int[]{83, 73, 80, 47, 50, 46, 48, 32, 50, 48, 48, 32, 79, 75, 13, 10, 84, 111, 58, 32, 60, 115, 105, 112, 58, 43, 49, 53, 49, 50, 51, 56, 56, 52, 49, 49, 53, 64, 53, 52, 46, 56, 51, 46, 49, 57, 54, 46, 50, 51, 56, 62, 59, 116, 97, 103, 61, 51, 51, 54, 51, 51, 53, 52, 50, 95, 97, 53, 56, 100, 51, 100, 53, 52, 95, 53, 55, 97, 53, 98, 48, 56, 97, 95, 100, 102, 53, 49, 54, 101, 102, 55, 13, 10, 86, 105, 97, 58, 32, 83, 73, 80, 47, 50, 46, 48, 47, 85, 68, 80, 32, 49, 48, 46, 49, 54, 53, 46, 49, 51, 55, 46, 49, 55, 58, 53, 48, 54, 53, 59, 98, 114, 97, 110, 99, 104, 61, 122, 57, 104, 71, 52, 98, 75, 49, 115, 97, 110, 115, 97, 121, 49, 57, 50, 56, 53, 52, 52, 48, 50, 55, 114, 100, 98, 50, 55, 49, 52, 50, 54, 50, 55, 52, 52, 122, 115, 100, 95, 48, 13, 10, 86, 105, 97, 58, 32, 83, 73, 80, 47, 50, 46, 48, 47, 85, 68, 80, 32, 49, 48, 46, 49, 54, 53, 46, 49, 51, 55, 46, 49, 55, 58, 53, 48, 54, 48, 59, 98, 114, 97, 110, 99, 104, 61, 122, 57, 104, 71, 52, 98, 75, 49, 115, 97, 110, 115, 97, 121, 49, 57, 50, 56, 53, 52, 52, 48, 50, 55, 114, 100, 98, 50, 55, 49, 52, 50, 54, 50, 55, 52, 52, 95, 48, 13, 10, 86, 105, 97, 58, 32, 83, 73, 80, 47, 50, 46, 48, 47, 85, 68, 80, 32, 54, 52, 46, 49, 51, 54, 46, 49, 55, 51, 46, 51, 49, 58, 53, 48, 54, 48, 59, 98, 114, 97, 110, 99, 104, 61, 122, 57, 104, 71, 52, 98, 75, 49, 115, 97, 110, 115, 97, 121, 49, 57, 50, 56, 53, 52, 52, 48, 50, 55, 114, 100, 98, 50, 55, 49, 52, 50, 13, 10, 82, 101, 99, 111, 114, 100, 45, 82, 111, 117, 116, 101, 58, 32, 60, 115, 105, 112, 58, 49, 48, 46, 49, 54, 53, 46, 49, 51, 55, 46, 49, 55, 58, 53, 48, 54, 53, 59, 116, 114, 97, 110, 115, 112, 111, 114, 116, 61, 117, 100, 112, 59, 108, 114, 59, 110, 111, 100, 101, 95, 104, 111, 115, 116, 61, 49, 48, 46, 49, 51, 55, 46, 51, 56, 46, 49, 50, 54, 59, 110, 111, 100, 101, 95, 112, 111, 114, 116, 61, 53, 48, 56, 48, 59, 118, 101, 114, 115, 105, 111, 110, 61, 48, 62, 13, 10, 82, 101, 99, 111, 114, 100, 45, 82, 111, 117, 116, 101, 58, 32, 60, 115, 105, 112, 58, 49, 48, 46, 49, 54, 53, 46, 49, 51, 55, 46, 49, 55, 58, 53, 48, 54, 48, 59, 116, 114, 97, 110, 115, 112, 111, 114, 116, 61, 117, 100, 112, 59, 108, 114, 59, 110, 111, 100, 101, 95, 104, 111, 115, 116, 61, 49, 48, 46, 49, 51, 55, 46, 51, 56, 46, 49, 50, 54, 59, 110, 111, 100, 101, 95, 112, 111, 114, 116, 61, 53, 48, 56, 48, 59, 118, 101, 114, 115, 105, 111, 110, 61, 48, 62, 13, 10, 82, 101, 99, 111, 114, 100, 45, 82, 111, 117, 116, 101, 58, 32, 60, 115, 105, 112, 58, 115, 97, 110, 115, 97, 121, 49, 57, 50, 56, 53, 52, 52, 48, 50, 55, 114, 100, 98, 50, 55, 49, 52, 50, 64, 54, 52, 46, 49, 51, 54, 46, 49, 55, 51, 46, 51, 49, 58, 53, 48, 54, 48, 59, 108, 114, 59, 116, 114, 97, 110, 115, 112, 111, 114, 116, 61, 117, 100, 112, 62, 13, 10, 67, 83, 101, 113, 58, 32, 49, 32, 73, 78, 86, 73, 84, 69, 13, 10, 67, 97, 108, 108, 45, 73, 68, 58, 32, 54, 50, 55, 52, 52, 53, 56, 55, 55, 45, 48, 45, 50, 52, 51, 49, 53, 51, 50, 56, 54, 48, 64, 54, 52, 46, 49, 51, 54, 46, 49, 55, 51, 46, 50, 50, 54, 13, 10, 70, 114, 111, 109, 58, 32, 60, 115, 105, 112, 58, 43, 51, 49, 54, 53, 51, 53, 55, 49, 50, 57, 50, 64, 54, 52, 46, 49, 51, 54, 46, 49, 55, 51, 46, 51, 49, 62, 59, 116, 97, 103, 61, 115, 97, 110, 115, 97, 121, 49, 57, 50, 56, 53, 52, 52, 48, 50, 55, 114, 100, 98, 50, 55, 49, 52, 50, 13, 10, 83, 101, 114, 118, 101, 114, 58, 32, 84, 101, 108, 83, 99, 97, 108, 101, 32, 82, 101, 115, 116, 99, 111, 109, 109, 32, 55, 46, 51, 46, 49, 46, 49, 49, 53, 55, 13, 10, 67, 111, 110, 116, 97, 99, 116, 58, 32, 60, 115, 105, 112, 58, 53, 52, 46, 56, 51, 46, 49, 57, 54, 46, 50, 51, 56, 58, 53, 48, 54, 48, 62, 13, 10, 67, 111, 110, 116, 101, 110, 116, 45, 84, 121, 112, 101, 58, 32, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 115, 100, 112, 13, 10, 67, 111, 110, 116, 101, 110, 116, 45, 76, 101, 110, 103, 116, 104, 58, 32, 51, 54, 52, 13, 10, 13, 10, 118, 61, 48, 13, 10, 111, 61, 45, 32, 49, 52, 52, 51, 56, 48, 53, 57, 48, 48, 51, 53, 54, 32, 49, 32, 73, 78, 32, 73, 80, 52, 32, 50, 51, 46, 50, 51, 46, 50, 50, 56, 46, 50, 51, 56, 13, 10, 115, 61, 77, 111, 98, 105, 99, 101, 110, 116, 115, 32, 77, 101, 100, 105, 97, 32, 83, 101, 114, 118, 101, 114, 13, 10, 99, 61, 73, 78, 32, 73, 80, 52, 32, 50, 51, 46, 50, 51, 46, 50, 50, 56, 46, 50, 51, 56, 13, 10, 116, 61, 48, 32, 48, 13, 10, 109, 61, 97, 117, 100, 105, 111, 32, 54, 53, 51, 52, 52, 32, 82, 84, 80, 47, 65, 86, 80, 32, 56, 32, 48, 32, 49, 56, 32, 49, 48, 49, 13, 10, 99, 61, 73, 78, 32, 73, 80, 52, 32, 50, 51, 46, 50, 51, 46, 50, 50, 56, 46, 50, 51, 56, 13, 10, 97, 61, 115, 101, 110, 100, 114, 101, 99, 118, 13, 10, 97, 61, 114, 116, 99, 112, 58, 54, 53, 51, 52, 53, 32, 73, 78, 32, 73, 80, 52, 32, 49, 48, 46, 49, 51, 55, 46, 51, 56, 46, 49, 50, 54, 13, 10, 97, 61, 112, 116, 105, 109, 101, 58, 50, 48, 13, 10, 97, 61, 114, 116, 112, 109, 97, 112, 58, 48, 32, 112, 99, 109, 117, 47, 56, 48, 48, 48, 13, 10, 97, 61, 114, 116, 112, 109, 97, 112, 58, 49, 48, 49, 32, 116, 101, 108, 101, 112, 104, 111, 110, 101, 45, 101, 118, 101, 110, 116, 47, 56, 48, 48, 48, 13, 10, 97, 61, 114, 116, 112, 109, 97, 112, 58, 49, 56, 32, 103, 55, 50, 57, 47, 56, 48, 48, 48, 13, 10, 97, 61, 114, 116, 112, 109, 97, 112, 58, 56, 32, 112, 99, 109, 97, 47, 56, 48, 48, 48, 13, 10, 97, 61, 115, 115, 114, 99, 58, 49, 48, 50, 48, 57, 57, 56, 50, 56, 57, 32, 99, 110, 97, 109, 101, 58, 104, 80, 88, 109, 77, 105, 48, 79, 121, 81, 120, 84, 68, 68, 100, 55, 10, 0, 0, 0, 0, 0, 0, 0}; + int[] arrayToDecode3 = new int[]{83, 73, 80, 47, 50, 46, 48, 32, 50, 48, 48, 32, 79, 75, 13, 10, 84, 111, 58, 32, 60, 115, 105, 112, 58, 43, 49, 53, 49, 50, 57, 49, 48, 56, 48, 50, 52, 64, 53, 52, 46, 56, 51, 46, 49, 57, 54, 46, 50, 51, 56, 62, 59, 116, 97, 103, 61, 55, 56, 56, 57, 50, 55, 54, 55, 95, 97, 53, 56, 100, 51, 100, 53, 52, 95, 53, 55, 97, 53, 98, 48, 56, 97, 95, 50, 98, 51, 57, 52, 57, 56, 56, 13, 10, 86, 105, 97, 58, 32, 83, 73, 80, 47, 50, 46, 48, 47, 85, 68, 80, 32, 49, 48, 46, 49, 54, 53, 46, 49, 51, 55, 46, 49, 55, 58, 53, 48, 54, 53, 59, 98, 114, 97, 110, 99, 104, 61, 122, 57, 104, 71, 52, 98, 75, 49, 115, 97, 110, 115, 97, 121, 49, 57, 50, 56, 49, 49, 57, 54, 50, 56, 114, 100, 98, 50, 54, 48, 56, 49, 54, 50, 55, 51, 49, 122, 115, 100, 95, 48, 13, 10, 86, 105, 97, 58, 32, 83, 73, 80, 47, 50, 46, 48, 47, 85, 68, 80, 32, 49, 48, 46, 49, 54, 53, 46, 49, 51, 55, 46, 49, 55, 58, 53, 48, 54, 48, 59, 98, 114, 97, 110, 99, 104, 61, 122, 57, 104, 71, 52, 98, 75, 49, 115, 97, 110, 115, 97, 121, 49, 57, 50, 56, 49, 49, 57, 54, 50, 56, 114, 100, 98, 50, 54, 48, 56, 49, 54, 50, 55, 51, 49, 95, 48, 13, 10, 86, 105, 97, 58, 32, 83, 73, 80, 47, 50, 46, 48, 47, 85, 68, 80, 32, 54, 52, 46, 49, 51, 54, 46, 49, 55, 51, 46, 51, 49, 58, 53, 48, 54, 48, 59, 98, 114, 97, 110, 99, 104, 61, 122, 57, 104, 71, 52, 98, 75, 49, 115, 97, 110, 115, 97, 121, 49, 57, 50, 56, 49, 49, 57, 54, 50, 56, 114, 100, 98, 50, 54, 48, 56, 49, 13, 10, 82, 101, 99, 111, 114, 100, 45, 82, 111, 117, 116, 101, 58, 32, 60, 115, 105, 112, 58, 49, 48, 46, 49, 54, 53, 46, 49, 51, 55, 46, 49, 55, 58, 53, 48, 54, 53, 59, 116, 114, 97, 110, 115, 112, 111, 114, 116, 61, 117, 100, 112, 59, 108, 114, 59, 110, 111, 100, 101, 95, 104, 111, 115, 116, 61, 49, 48, 46, 49, 51, 55, 46, 51, 56, 46, 49, 50, 54, 59, 110, 111, 100, 101, 95, 112, 111, 114, 116, 61, 53, 48, 56, 48, 59, 118, 101, 114, 115, 105, 111, 110, 61, 48, 62, 13, 10, 82, 101, 99, 111, 114, 100, 45, 82, 111, 117, 116, 101, 58, 32, 60, 115, 105, 112, 58, 49, 48, 46, 49, 54, 53, 46, 49, 51, 55, 46, 49, 55, 58, 53, 48, 54, 48, 59, 116, 114, 97, 110, 115, 112, 111, 114, 116, 61, 117, 100, 112, 59, 108, 114, 59, 110, 111, 100, 101, 95, 104, 111, 115, 116, 61, 49, 48, 46, 49, 51, 55, 46, 51, 56, 46, 49, 50, 54, 59, 110, 111, 100, 101, 95, 112, 111, 114, 116, 61, 53, 48, 56, 48, 59, 118, 101, 114, 115, 105, 111, 110, 61, 48, 62, 13, 10, 82, 101, 99, 111, 114, 100, 45, 82, 111, 117, 116, 101, 58, 32, 60, 115, 105, 112, 58, 115, 97, 110, 115, 97, 121, 49, 57, 50, 56, 49, 49, 57, 54, 50, 56, 114, 100, 98, 50, 54, 48, 56, 49, 64, 54, 52, 46, 49, 51, 54, 46, 49, 55, 51, 46, 51, 49, 58, 53, 48, 54, 48, 59, 108, 114, 59, 116, 114, 97, 110, 115, 112, 111, 114, 116, 61, 117, 100, 112, 62, 13, 10, 67, 83, 101, 113, 58, 32, 49, 32, 73, 78, 86, 73, 84, 69, 13, 10, 67, 97, 108, 108, 45, 73, 68, 58, 32, 54, 50, 55, 51, 49, 54, 48, 50, 49, 45, 48, 45, 50, 52, 50, 57, 52, 54, 57, 50, 55, 48, 64, 54, 52, 46, 49, 51, 54, 46, 49, 55, 51, 46, 50, 50, 54, 13, 10, 70, 114, 111, 109, 58, 32, 60, 115, 105, 112, 58, 82, 101, 115, 116, 114, 105, 99, 116, 101, 100, 64, 54, 52, 46, 49, 51, 54, 46, 49, 55, 51, 46, 51, 49, 62, 59, 116, 97, 103, 61, 115, 97, 110, 115, 97, 121, 49, 57, 50, 56, 49, 49, 57, 54, 50, 56, 114, 100, 98, 50, 54, 48, 56, 49, 13, 10, 83, 101, 114, 118, 101, 114, 58, 32, 84, 101, 108, 83, 99, 97, 108, 101, 32, 82, 101, 115, 116, 99, 111, 109, 109, 32, 55, 46, 51, 46, 49, 46, 49, 49, 53, 55, 13, 10, 67, 111, 110, 116, 97, 99, 116, 58, 32, 60, 115, 105, 112, 58, 53, 52, 46, 56, 51, 46, 49, 57, 54, 46, 50, 51, 56, 58, 53, 48, 54, 48, 62, 13, 10, 67, 111, 110, 116, 101, 110, 116, 45, 84, 121, 112, 101, 58, 32, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 115, 100, 112, 13, 10, 67, 111, 110, 116, 101, 110, 116, 45, 76, 101, 110, 103, 116, 104, 58, 32, 51, 52, 48, 13, 10, 13, 10, 118, 61, 48, 13, 10, 111, 61, 45, 32, 49, 52, 52, 51, 56, 48, 51, 56, 51, 54, 54, 49, 54, 32, 49, 32, 73, 78, 32, 73, 80, 52, 32, 50, 51, 46, 50, 51, 46, 50, 50, 56, 46, 50, 51, 56, 13, 10, 115, 61, 77, 111, 98, 105, 99, 101, 110, 116, 115, 32, 77, 101, 100, 105, 97, 32, 83, 101, 114, 118, 101, 114, 13, 10, 99, 61, 73, 78, 32, 73, 80, 52, 32, 50, 51, 46, 50, 51, 46, 50, 50, 56, 46, 50, 51, 56, 13, 10, 116, 61, 48, 32, 48, 13, 10, 109, 61, 97, 117, 100, 105, 111, 32, 54, 53, 51, 56, 48, 32, 82, 84, 80, 47, 65, 86, 80, 32, 48, 32, 49, 56, 32, 49, 48, 49, 13, 10, 99, 61, 73, 78, 32, 73, 80, 52, 32, 50, 51, 46, 50, 51, 46, 50, 50, 56, 46, 50, 51, 56, 13, 10, 97, 61, 115, 101, 110, 100, 114, 101, 99, 118, 13, 10, 97, 61, 114, 116, 99, 112, 58, 54, 53, 51, 56, 49, 32, 73, 78, 32, 73, 80, 52, 32, 49, 48, 46, 49, 51, 55, 46, 51, 56, 46, 49, 50, 54, 13, 10, 97, 61, 112, 116, 105, 109, 101, 58, 50, 48, 13, 10, 97, 61, 114, 116, 112, 109, 97, 112, 58, 48, 32, 112, 99, 109, 117, 47, 56, 48, 48, 48, 13, 10, 97, 61, 114, 116, 112, 109, 97, 112, 58, 49, 48, 49, 32, 116, 101, 108, 101, 112, 104, 111, 110, 101, 45, 101, 118, 101, 110, 116, 47, 56, 48, 48, 48, 13, 10, 97, 61, 114, 116, 112, 109, 97, 112, 58, 49, 56, 32, 103, 55, 50, 57, 47, 56, 48, 48, 48, 13, 10, 97, 61, 115, 115, 114, 99, 58, 50, 55, 49, 49, 54, 55, 49, 55, 52, 50, 32, 99, 110, 97, 109, 101, 58, 107, 49, 101, 109, 119, 104, 103, 76, 102, 55, 111, 102, 81, 103, 105, 85, 10, 0}; public void setUp() { sipFactory = new SipFactoryImpl(); sipFactory.initialize("gov.nist", true); @@ -48,5 +52,9 @@ public void testSessionExpires() throws ServletParseException { Parameterable p = sipFactory.createParameterable("3600"); p.setParameter("refresher", "uac"); System.out.println(p.toString()); + sipFactory.createURI("sip:proxy@localhost"); + for (int i = 0; i < arrayToDecode3.length; i++) { + System.out.print((char)arrayToDecode3[i]); + } } } \ No newline at end of file diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/address/SipURITest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/address/SipURITest.java index d1d044f8e3..14141e283d 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/address/SipURITest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/address/SipURITest.java @@ -1,161 +1,161 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.address; - -import javax.servlet.sip.ServletParseException; -import javax.servlet.sip.SipURI; -import javax.servlet.sip.URI; -import org.junit.Assert; - -import org.mobicents.servlet.sip.message.SipFactoryImpl; -import org.mobicents.servlet.sip.startup.StaticServiceHolder; - -/** - * Tests from RFC3261 §19.1.4 URI Comparison - */ -public class SipURITest extends junit.framework.TestCase { - - static String[][] equal = { - {"sip:%61lice@atlanta.com;transport=TCP", "sip:alice@AtlanTa.CoM;Transport=tcp"}, - {"sip:carol@chicago.com", "sip:carol@chicago.com;newparam=5"}, - {"sip:carol@chicago.com", "sip:carol@chicago.com;lr"}, - {"sip:carol@chicago.com;security=on", "sip:carol@chicago.com;newparam=5"}, - {"sip:alice@atlanta.com?subject=project%20x&priority=urgent", "sip:alice@atlanta.com?priority=urgent&subject=project%20x"}, - {"sip:carol@chicago.com", "sip:carol@chicago.com;security=on"}, - {"sip:carol@chicago.com;security=on", "sip:carol@chicago.com"}, - {"sip:[0:0:0:0:0:0:0:1%1]:5070;transport=udp", "sip:[0:0:0:0:0:0:0:1%1]:5070;transport=udp"} - }; - - static String[][] different = { - {"sip:alice@atlanta.com", "sip:ALICE@atlanta.com"}, - {"sip:bob@biloxi.com", "sip:bob@biloxi.com:5060"}, - {"sip:bob@biloxi.com", "sip:bob@biloxi.com;transport=tcp"}, - {"sip:carol@chicago.com;newparam=6", "sip:carol@chicago.com;newparam=5"}, - {"sip:carol@chicago.com", "sip:carol@chicago.com?Subject=next%20meeting"}, - {"sip:carol@chicago.com?Subject=next%20meeting", "sip:carol@chicago.com?Subject=another%20meeting"}, - {"sip:carol@chicago.com;security=off", "sip:carol@chicago.com;security=on"} - }; - - private SipFactoryImpl sipFactory; - - public void setUp() { - sipFactory = new SipFactoryImpl(); - sipFactory.initialize("gov.nist", true); - } - - private SipURI sipUri(String uri) throws Exception { - return (SipURI) sipFactory.createURI(uri); - } - - public void testEqual() throws Exception { - for (int i = 0; i < equal.length; i++) { - SipURI uri1 = sipUri(equal[i][0]); - SipURI uri2 = sipUri(equal[i][1]); - assertTrue(uri1 + " is different as " + uri2, uri1.equals(uri2)); - assertTrue(uri2 + " is different as " + uri1, uri2.equals(uri1)); - } - } - - public void testDifferent() throws Exception { - for (int i = 0; i < different.length; i++) { - SipURI uri1 = sipUri(different[i][0]); - SipURI uri2 = sipUri(different[i][1]); - assertFalse(uri1 + " is the same as " + uri2, uri1.equals(uri2)); - assertFalse(uri2 + " is the same as " + uri1, uri2.equals(uri1)); - } - } - - public void testEscaping() throws Exception { - SipURI uri1 = sipUri("sip:alice@atlanta.com;transport=TCP?Subject=SIP%20Servlets"); - assertTrue(uri1.getUser() + " is different as alice" , uri1.getUser().equals("alice")); - assertTrue(uri1.toString() + " is different as sip:alice@atlanta.com;transport=TCP?Subject=SIP%20Servlets" , uri1.toString().equals("sip:alice@atlanta.com;transport=TCP?Subject=SIP%20Servlets")); - uri1 = sipUri("sip:alice@example.com;transport=tcp?Subject=SIP%20Servlets"); - assertTrue(uri1.getHeader("Subject") + " is different as SIP Servlets" , uri1.getHeader("Subject").equals("SIP Servlets")); - assertTrue(uri1.toString() + " is different as sip:alice@example.com;transport=tcp?Subject=SIP%20Servlets" , uri1.toString().equals("sip:alice@example.com;transport=tcp?Subject=SIP%20Servlets")); -// uri1 = sipUri("sip:annc@ms.example.net;play=file://fs.example.net//clips/my-intro.dvi;content-type=video/mpeg%3bencode%3d314M-25/625-50"); -// SipURI uri2 = sipUri("sip:annc@ms.example.net;play=file://fs.example.net//clips/my-intro.dvi;content-type=video/mpeg;encode=314M-25/625-50"); -// assertTrue(uri1.getParameter("content-type") + " is different as video/mpeg;encode=314M-25/625-50" , uri1.getParameter("content-type").equals("video/mpeg;encode=314M-25/625-50")); -// assertTrue(uri1.toString() + " is different as sip:annc@ms.example.net;play=file://fs.example.net//clips/my-intro.dvi;content-type=video/mpeg%3bencode%3d314M-25/625-50" , uri1.equals(uri2)); - } - - public void testNullUser() throws Exception { - SipURI uri1 = sipUri("sip:atlanta.com;transport=TCP?Subject=SIP%20Servlets"); - assertNotNull(uri1); - assertNull(uri1.getUser()); - assertNotNull(uri1.getHost()); - assertEquals("TCP", uri1.getTransportParam()); - assertTrue(uri1.getHeader("Subject") + " is different as SIP Servlets" , uri1.getHeader("Subject").equals("SIP Servlets")); - } - - public void testParams() throws Exception { - URI uri = sipFactory.createURI("sip:" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - System.out.println(uri); - uri.setParameter("Key", "val"); - System.out.println(uri); - String s = uri.toString(); - assertEquals("sip:" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080;Key=val", s); - } - - // Non regression for https://github.com/Mobicents/sip-servlets/issues/46 - public void testNullValueParam() throws Exception { - try { - URI uri = sipFactory.createURI("sip:" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - uri.setParameter("orig", null); - Assert.fail("NPE expected"); - } catch (Exception e) { - //we are expecting NPE - } - } - - // Non regression for https://github.com/Mobicents/sip-servlets/issues/46 - public void testemptyValueParam() throws Exception { - String initialURI = "sip:" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"; - URI uri = sipFactory.createURI(initialURI); - uri.setParameter("orig2", ""); - String encodedURI = uri.toString(); - Assert.assertEquals(initialURI + ";orig2", encodedURI); - } - - /** - * - * Non regression for https://github.com/RestComm/sip-servlets/issues/114 - * @throws Exception - */ - public void testOneCharParam() throws Exception { - URI uri = sipFactory.createURI("sip:" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); - System.out.println(uri); - uri.setParameter("Key", "v"); - System.out.println(uri); - String s = uri.toString(); - assertEquals("sip:" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080;Key=v", s); - } - - public void testBrackets() throws Exception { - try { - String uriString = ""; - sipFactory.createURI(uriString); - fail(uriString + " should throw a ServletParseException because the angle brackets are not allowed"); - } catch (ServletParseException e) { - } - } -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite.address; + +import javax.servlet.sip.ServletParseException; +import javax.servlet.sip.SipURI; +import javax.servlet.sip.URI; +import org.junit.Assert; + +import org.mobicents.servlet.sip.message.SipFactoryImpl; +import org.mobicents.servlet.sip.startup.StaticServiceHolder; + +/** + * Tests from RFC3261 §19.1.4 URI Comparison + */ +public class SipURITest extends junit.framework.TestCase { + + static String[][] equal = { + {"sip:%61lice@atlanta.com;transport=TCP", "sip:alice@AtlanTa.CoM;Transport=tcp"}, + {"sip:carol@chicago.com", "sip:carol@chicago.com;newparam=5"}, + {"sip:carol@chicago.com", "sip:carol@chicago.com;lr"}, + {"sip:carol@chicago.com;security=on", "sip:carol@chicago.com;newparam=5"}, + {"sip:alice@atlanta.com?subject=project%20x&priority=urgent", "sip:alice@atlanta.com?priority=urgent&subject=project%20x"}, + {"sip:carol@chicago.com", "sip:carol@chicago.com;security=on"}, + {"sip:carol@chicago.com;security=on", "sip:carol@chicago.com"}, + {"sip:[0:0:0:0:0:0:0:1%1]:5070;transport=udp", "sip:[0:0:0:0:0:0:0:1%1]:5070;transport=udp"} + }; + + static String[][] different = { + {"sip:alice@atlanta.com", "sip:ALICE@atlanta.com"}, + {"sip:bob@biloxi.com", "sip:bob@biloxi.com:5060"}, + {"sip:bob@biloxi.com", "sip:bob@biloxi.com;transport=tcp"}, + {"sip:carol@chicago.com;newparam=6", "sip:carol@chicago.com;newparam=5"}, + {"sip:carol@chicago.com", "sip:carol@chicago.com?Subject=next%20meeting"}, + {"sip:carol@chicago.com?Subject=next%20meeting", "sip:carol@chicago.com?Subject=another%20meeting"}, + {"sip:carol@chicago.com;security=off", "sip:carol@chicago.com;security=on"} + }; + + private SipFactoryImpl sipFactory; + + public void setUp() { + sipFactory = new SipFactoryImpl(); + sipFactory.initialize("gov.nist", true); + } + + private SipURI sipUri(String uri) throws Exception { + return (SipURI) sipFactory.createURI(uri); + } + + public void testEqual() throws Exception { + for (int i = 0; i < equal.length; i++) { + SipURI uri1 = sipUri(equal[i][0]); + SipURI uri2 = sipUri(equal[i][1]); + assertTrue(uri1 + " is different as " + uri2, uri1.equals(uri2)); + assertTrue(uri2 + " is different as " + uri1, uri2.equals(uri1)); + } + } + + public void testDifferent() throws Exception { + for (int i = 0; i < different.length; i++) { + SipURI uri1 = sipUri(different[i][0]); + SipURI uri2 = sipUri(different[i][1]); + assertFalse(uri1 + " is the same as " + uri2, uri1.equals(uri2)); + assertFalse(uri2 + " is the same as " + uri1, uri2.equals(uri1)); + } + } + + public void testEscaping() throws Exception { + SipURI uri1 = sipUri("sip:alice@atlanta.com;transport=TCP?Subject=SIP%20Servlets"); + assertTrue(uri1.getUser() + " is different as alice" , uri1.getUser().equals("alice")); + assertTrue(uri1.toString() + " is different as sip:alice@atlanta.com;transport=TCP?Subject=SIP%20Servlets" , uri1.toString().equals("sip:alice@atlanta.com;transport=TCP?Subject=SIP%20Servlets")); + uri1 = sipUri("sip:alice@example.com;transport=tcp?Subject=SIP%20Servlets"); + assertTrue(uri1.getHeader("Subject") + " is different as SIP Servlets" , uri1.getHeader("Subject").equals("SIP Servlets")); + assertTrue(uri1.toString() + " is different as sip:alice@example.com;transport=tcp?Subject=SIP%20Servlets" , uri1.toString().equals("sip:alice@example.com;transport=tcp?Subject=SIP%20Servlets")); +// uri1 = sipUri("sip:annc@ms.example.net;play=file://fs.example.net//clips/my-intro.dvi;content-type=video/mpeg%3bencode%3d314M-25/625-50"); +// SipURI uri2 = sipUri("sip:annc@ms.example.net;play=file://fs.example.net//clips/my-intro.dvi;content-type=video/mpeg;encode=314M-25/625-50"); +// assertTrue(uri1.getParameter("content-type") + " is different as video/mpeg;encode=314M-25/625-50" , uri1.getParameter("content-type").equals("video/mpeg;encode=314M-25/625-50")); +// assertTrue(uri1.toString() + " is different as sip:annc@ms.example.net;play=file://fs.example.net//clips/my-intro.dvi;content-type=video/mpeg%3bencode%3d314M-25/625-50" , uri1.equals(uri2)); + } + + public void testNullUser() throws Exception { + SipURI uri1 = sipUri("sip:atlanta.com;transport=TCP?Subject=SIP%20Servlets"); + assertNotNull(uri1); + assertNull(uri1.getUser()); + assertNotNull(uri1.getHost()); + assertEquals("TCP", uri1.getTransportParam()); + assertTrue(uri1.getHeader("Subject") + " is different as SIP Servlets" , uri1.getHeader("Subject").equals("SIP Servlets")); + } + + public void testParams() throws Exception { + URI uri = sipFactory.createURI("sip:" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); + System.out.println(uri); + uri.setParameter("Key", "val"); + System.out.println(uri); + String s = uri.toString(); + assertEquals("sip:" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080;Key=val", s); + } + + // Non regression for https://github.com/Mobicents/sip-servlets/issues/46 + public void testNullValueParam() throws Exception { + try { + URI uri = sipFactory.createURI("sip:" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); + uri.setParameter("orig", null); + Assert.fail("NPE expected"); + } catch (Exception e) { + //we are expecting NPE + } + } + + // Non regression for https://github.com/Mobicents/sip-servlets/issues/46 + public void testemptyValueParam() throws Exception { + String initialURI = "sip:" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"; + URI uri = sipFactory.createURI(initialURI); + uri.setParameter("orig2", ""); + String encodedURI = uri.toString(); + Assert.assertEquals(initialURI + ";orig2", encodedURI); + } + + /** + * + * Non regression for https://github.com/RestComm/sip-servlets/issues/114 + * @throws Exception + */ + public void testOneCharParam() throws Exception { + URI uri = sipFactory.createURI("sip:" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080"); + System.out.println(uri); + uri.setParameter("Key", "v"); + System.out.println(uri); + String s = uri.toString(); + assertEquals("sip:" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080;Key=v", s); + } + + public void testBrackets() throws Exception { + try { + String uriString = ""; + sipFactory.createURI(uriString); + fail(uriString + " should throw a ServletParseException because the angle brackets are not allowed"); + } catch (ServletParseException e) { + } + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/annotations/AnnotationTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/annotations/AnnotationTest.java index b0bbb432bd..8b9a5cced8 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/annotations/AnnotationTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/annotations/AnnotationTest.java @@ -1,140 +1,156 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.annotations; - -import java.util.EventObject; -import java.util.Hashtable; - -import javax.sip.DialogTerminatedEvent; -import javax.sip.IOExceptionEvent; -import javax.sip.RequestEvent; -import javax.sip.ResponseEvent; -import javax.sip.SipListener; -import javax.sip.SipProvider; -import javax.sip.TimeoutEvent; -import javax.sip.TransactionTerminatedEvent; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; - -public class AnnotationTest extends SipServletTestCase implements SipListener { - - private static transient Logger logger = Logger.getLogger(AnnotationTest.class); - - protected Hashtable providerTable = new Hashtable(); - - private Tracker tracker; - - public AnnotationTest(String name) { - super(name); - } - - @Override - public void setUp() throws Exception { - //init(); - tracker = new Tracker(); - super.setUp(); - } - - public void testSecurity() { - tracker.init(); - try { - for(int q=0; q<10; q++) - { - if(tracker.receivedInvite) break; - Thread.sleep(1111); - } - if(!tracker.receivedInvite) - fail("Didnt receive notification that the scenario is complete."); - } catch (InterruptedException e) { - fail("Test failed: " + e); - e.printStackTrace(); - } - } - - @Override - public void tearDown() throws Exception { - tracker.destroy(); - super.tearDown(); - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/annotated-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/annotations/annotated-servlet-dar.properties"; - } - - public void init() { - - } - - private SipListener getSipListener(EventObject sipEvent) { - SipProvider source = (SipProvider) sipEvent.getSource(); - SipListener listener = (SipListener) providerTable.get(source); - if (listener == null) - throw new RuntimeException("Unexpected null listener"); - return listener; - } - - public void processRequest(RequestEvent requestEvent) { - getSipListener(requestEvent).processRequest(requestEvent); - - } - - public void processResponse(ResponseEvent responseEvent) { - getSipListener(responseEvent).processResponse(responseEvent); - - } - - public void processTimeout(TimeoutEvent timeoutEvent) { - getSipListener(timeoutEvent).processTimeout(timeoutEvent); - } - - public void processIOException(IOExceptionEvent exceptionEvent) { - fail("unexpected exception"); - - } - - public void processTransactionTerminated( - TransactionTerminatedEvent transactionTerminatedEvent) { - getSipListener(transactionTerminatedEvent) - .processTransactionTerminated(transactionTerminatedEvent); - - } - - public void processDialogTerminated( - DialogTerminatedEvent dialogTerminatedEvent) { - getSipListener(dialogTerminatedEvent).processDialogTerminated( - dialogTerminatedEvent); - - } -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite.annotations; + +import java.util.EventObject; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; + +import javax.sip.DialogTerminatedEvent; +import javax.sip.IOExceptionEvent; +import javax.sip.RequestEvent; +import javax.sip.ResponseEvent; +import javax.sip.SipListener; +import javax.sip.SipProvider; +import javax.sip.TimeoutEvent; +import javax.sip.TransactionTerminatedEvent; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; + +public class AnnotationTest extends SipServletTestCase implements SipListener { + + private static transient Logger logger = Logger.getLogger(AnnotationTest.class); + + protected Hashtable providerTable = new Hashtable(); + + private Tracker tracker; + + public AnnotationTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void setUp() throws Exception { + //init(); + tracker = new Tracker(); + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + } + + public void testSecurity() { + tracker.init(); + Map params = new HashMap(); + params.put("testPort", String.valueOf(tracker.getMyPort())); + params.put("servletContainerPort", String.valueOf(containerPort)); + deployApplication(params); + try { + for(int q=0; q<10; q++) + { + if(tracker.receivedInvite) break; + Thread.sleep(1111); + } + if(!tracker.receivedInvite) + fail("Didnt receive notification that the scenario is complete."); + } catch (InterruptedException e) { + fail("Test failed: " + e); + e.printStackTrace(); + } + } + + @Override + public void tearDown() throws Exception { + tracker.destroy(); + super.tearDown(); + } + + @Override + public void deployApplication() { + assertTrue(tomcat.deployContext( + projectHome + "/sip-servlets-test-suite/applications/annotated-servlet/src/main/sipapp", + "sip-test-context", "sip-test")); + } + + public void deployApplication(Map params) { + SipStandardContext ctx = deployApplication(projectHome + "/sip-servlets-test-suite/applications/annotated-servlet/src/main/sipapp", + params, null); + assertTrue(ctx.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/annotations/annotated-servlet-dar.properties"; + } + + public void init() { + + } + + private SipListener getSipListener(EventObject sipEvent) { + SipProvider source = (SipProvider) sipEvent.getSource(); + SipListener listener = (SipListener) providerTable.get(source); + if (listener == null) + throw new RuntimeException("Unexpected null listener"); + return listener; + } + + public void processRequest(RequestEvent requestEvent) { + getSipListener(requestEvent).processRequest(requestEvent); + + } + + public void processResponse(ResponseEvent responseEvent) { + getSipListener(responseEvent).processResponse(responseEvent); + + } + + public void processTimeout(TimeoutEvent timeoutEvent) { + getSipListener(timeoutEvent).processTimeout(timeoutEvent); + } + + public void processIOException(IOExceptionEvent exceptionEvent) { + fail("unexpected exception"); + + } + + public void processTransactionTerminated( + TransactionTerminatedEvent transactionTerminatedEvent) { + getSipListener(transactionTerminatedEvent) + .processTransactionTerminated(transactionTerminatedEvent); + + } + + public void processDialogTerminated( + DialogTerminatedEvent dialogTerminatedEvent) { + getSipListener(dialogTerminatedEvent).processDialogTerminated( + dialogTerminatedEvent); + + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/annotations/Tracker.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/annotations/Tracker.java index 7e6b61049a..eafb65b2e2 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/annotations/Tracker.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/annotations/Tracker.java @@ -48,12 +48,13 @@ import javax.sip.message.MessageFactory; import javax.sip.message.Request; import javax.sip.message.Response; +import org.mobicents.servlet.sip.NetworkPortAssigner; public class Tracker implements SipListener { private MessageFactory messageFactory; private SipStack sipStack; - private static final int myPort = 5058; + private int myPort; protected ServerTransaction inviteTid; private Dialog dialog; public static final boolean callerSendsBye = true; @@ -176,9 +177,9 @@ public void init() { // Your code will limp at 32 but it is best for debugging. properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "32"); properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", - "logs/cutmedebug.txt"); + "target/logs/cutmedebug.txt"); properties.setProperty("gov.nist.javax.sip.SERVER_LOG", - "logs/cutmelog.txt"); + "target/logs/cutmelog.txt"); try { // Create SipStack object @@ -199,6 +200,7 @@ public void init() { // headerFactory = sipFactory.createHeaderFactory(); // addressFactory = sipFactory.createAddressFactory(); messageFactory = sipFactory.createMessageFactory(); + myPort = NetworkPortAssigner.retrieveNextPort(); ListeningPoint lp = sipStack.createListeningPoint("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", myPort, "udp"); @@ -266,4 +268,10 @@ public void destroy() { sipStack.stop(); } + + public int getMyPort() { + return myPort; + } + + } diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/b2bua/B2BUASessionCallbackTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/b2bua/B2BUASessionCallbackTest.java index be641b0793..9bc85c2dfc 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/b2bua/B2BUASessionCallbackTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/b2bua/B2BUASessionCallbackTest.java @@ -23,7 +23,9 @@ package org.mobicents.servlet.sip.testsuite.b2bua; import java.io.File; +import java.util.HashMap; import java.util.ListIterator; +import java.util.Map; import javax.sip.ListeningPoint; import javax.sip.SipProvider; @@ -34,6 +36,7 @@ import javax.sip.header.UserAgentHeader; import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; import org.mobicents.servlet.sip.SipServletTestCase; import org.mobicents.servlet.sip.testsuite.ProtocolObjects; import org.mobicents.servlet.sip.testsuite.TestSipListener; @@ -82,12 +85,12 @@ protected String getDarConfigurationFile() { } @Override - protected void setUp() throws Exception { + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); super.setUp(); - tomcat.addSipConnector(serverName, sipIpAddress, 5070, ListeningPoint.TCP); + tomcat.addSipConnector(serverName, sipIpAddress, containerPort, ListeningPoint.TCP); tomcat.startTomcat(); - deployApplication(); senderProtocolObjects = new ProtocolObjects("forward-udp-sender", "gov.nist", TRANSPORT_UDP, AUTODIALOG, null, null, null); @@ -99,10 +102,12 @@ protected void setUp() throws Exception { public void testCallForwardingCallerSendByeDoubleCallback() throws Exception { File testResult = new File("b2buaSessionDoubleCallbackTest"); testResult.delete(); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); SipProvider senderProvider = sender.createProvider(); - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); SipProvider receiverProvider = receiver.createProvider(); receiverProvider.addSipListener(receiver); @@ -110,6 +115,15 @@ public void testCallForwardingCallerSendByeDoubleCallback() throws Exception { senderProtocolObjects.start(); receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(receiverPort)); + params.put( "senderPort", String.valueOf(senderPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params + , null); String fromName = "forward-tcp-sender"; String fromSipAddress = "sip-servlets.com"; @@ -141,7 +155,7 @@ public void testCallForwardingCallerSendByeDoubleCallback() throws Exception { while (contactHeaderIt.hasNext()) { ContactHeader contactHeader = (ContactHeader) contactHeaderIt .next(); - assertTrue(contactHeader.toString().trim().startsWith("Contact: \"callforwardingB2BUA\" ;test")); + assertTrue(contactHeader.toString().trim().startsWith("Contact: \"callforwardingB2BUA\" ;test")); i++; } assertEquals(1, i); diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/b2bua/B2BUASetCallIdTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/b2bua/B2BUASetCallIdTest.java new file mode 100644 index 0000000000..8adb3ea9d4 --- /dev/null +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/b2bua/B2BUASetCallIdTest.java @@ -0,0 +1,168 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2014, Telestax Inc and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + */ + +package org.mobicents.servlet.sip.testsuite.b2bua; + +import java.util.HashMap; +import java.util.ListIterator; +import java.util.Map; + +import javax.sip.ListeningPoint; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import javax.sip.header.AllowHeader; +import javax.sip.header.CallIdHeader; +import javax.sip.header.ContactHeader; +import javax.sip.header.Header; +import javax.sip.header.UserAgentHeader; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.catalina.SipStandardManager; +import org.mobicents.servlet.sip.startup.SipContextConfig; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +/** + * Testing system header modification, in particular callId. + * + * @author Filip Olsson + * + */ +public class B2BUASetCallIdTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(B2BUASetCallIdTest.class); + + private static final String TRANSPORT_UDP = "udp"; + private static final String TRANSPORT_TCP = "tcp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 15000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + TestSipListener receiver; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + SipStandardManager sipStandardManager = null; + + public B2BUASetCallIdTest(String name) { + super(name); + startTomcatOnStartup = false; + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + sipStandardManager = new SipStandardManager(); + SipStandardContext context = new SipStandardContext(); + context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp"); + context.setName("sip-test-context"); + context.setPath("/sip-test"); + context.addLifecycleListener(new SipContextConfig()); + context.setManager(sipStandardManager); + boolean success = tomcat.deployContext( + context); + assertTrue(success); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/callcontroller/call-forwarding-b2bua-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + tomcat.addSipConnector(serverName, sipIpAddress, containerPort, ListeningPoint.TCP); + tomcat.startTomcat(); + + senderProtocolObjects = new ProtocolObjects("forward-udp-sender", + "gov.nist", TRANSPORT_UDP, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects("forward-tcp-receiver", + "gov.nist", TRANSPORT_TCP, AUTODIALOG, null, null, null); + + } + + private static final String B2BUACALL_ID="f81d4fae-7dec-11d0-a765-00a0c91e6bf6@foo.bar.com"; + + public void testSetCallIdWithHelper() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(receiverPort)); + params.put( "senderPort", String.valueOf(senderPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params + , null); + + String fromName = "forward-tcp-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "forward-receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[] {UserAgentHeader.NAME, "extension-header", AllowHeader.NAME, "P-SetCallId"}, new String[] {"TestSipListener UA", "extension-sip-listener", "INVITE, CANCEL, BYE, ACK, OPTIONS", B2BUACALL_ID}, true); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + CallIdHeader receiverCallIdHeader = (CallIdHeader)receiver.getInviteRequest().getHeader(CallIdHeader.NAME); + CallIdHeader senderCallIdHeader = (CallIdHeader)sender.getInviteRequest().getHeader(CallIdHeader.NAME); + + assertFalse(receiverCallIdHeader.getCallId().equals(senderCallIdHeader.getCallId())); + assertEquals(B2BUACALL_ID, receiverCallIdHeader.getCallId()); + + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + sender = null; + receiver = null; + logger.info("Test completed"); + super.tearDown(); + } + + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/b2bua/B2BUASetCallIdWithFactoryTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/b2bua/B2BUASetCallIdWithFactoryTest.java new file mode 100644 index 0000000000..cc2bdf6e4e --- /dev/null +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/b2bua/B2BUASetCallIdWithFactoryTest.java @@ -0,0 +1,166 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2014, Telestax Inc and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + */ + +package org.mobicents.servlet.sip.testsuite.b2bua; + +import java.util.HashMap; +import java.util.Map; + +import javax.sip.ListeningPoint; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import javax.sip.header.AllowHeader; +import javax.sip.header.CallIdHeader; +import javax.sip.header.UserAgentHeader; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.catalina.SipStandardManager; +import org.mobicents.servlet.sip.startup.SipContextConfig; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +/** + * Testing system header modification, in particular callId. + * + * @author Filip Olsson + * + */ +public class B2BUASetCallIdWithFactoryTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(B2BUASetCallIdWithFactoryTest.class); + + private static final String TRANSPORT_UDP = "udp"; + private static final String TRANSPORT_TCP = "tcp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 15000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + TestSipListener receiver; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + SipStandardManager sipStandardManager = null; + + public B2BUASetCallIdWithFactoryTest(String name) { + super(name); + startTomcatOnStartup = false; + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + sipStandardManager = new SipStandardManager(); + SipStandardContext context = new SipStandardContext(); + context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp"); + context.setName("sip-test-context"); + context.setPath("/sip-test"); + context.addLifecycleListener(new SipContextConfig()); + context.setManager(sipStandardManager); + boolean success = tomcat.deployContext( + context); + assertTrue(success); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/callcontroller/call-forwarding-b2bua-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + tomcat.addSipConnector(serverName, sipIpAddress, containerPort, ListeningPoint.TCP); + tomcat.startTomcat(); + + senderProtocolObjects = new ProtocolObjects("forward-udp-sender", + "gov.nist", TRANSPORT_UDP, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects("forward-tcp-receiver", + "gov.nist", TRANSPORT_TCP, AUTODIALOG, null, null, null); + + } + + private static final String B2BUACALL_ID="f81d4fae-7dec-11d0-a765-00a0c91e6bf6@foo.bar.com"; + + public void testSetCallIdWithFactory() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(receiverPort)); + params.put( "senderPort", String.valueOf(senderPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params + , null); + + String fromName = "forward-tcp-sender-factory"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "forward-receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[] {UserAgentHeader.NAME, "extension-header", AllowHeader.NAME, "P-SetCallId"}, new String[] {"TestSipListener UA", "extension-sip-listener", "INVITE, CANCEL, BYE, ACK, OPTIONS", B2BUACALL_ID}, true); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + CallIdHeader receiverCallIdHeader = (CallIdHeader)receiver.getInviteRequest().getHeader(CallIdHeader.NAME); + CallIdHeader senderCallIdHeader = (CallIdHeader)sender.getInviteRequest().getHeader(CallIdHeader.NAME); + + assertFalse(receiverCallIdHeader.getCallId().equals(senderCallIdHeader.getCallId())); + assertEquals(B2BUACALL_ID, receiverCallIdHeader.getCallId()); + + } + + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + sender = null; + receiver = null; + logger.info("Test completed"); + super.tearDown(); + } + + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/b2bua/B2BUASipUnitTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/b2bua/B2BUASipUnitTest.java index 8cea7bd2e0..958bc3c080 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/b2bua/B2BUASipUnitTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/b2bua/B2BUASipUnitTest.java @@ -1,208 +1,234 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.b2bua; - -import java.util.Properties; - -import javax.sip.SipProvider; -import javax.sip.address.SipURI; -import javax.sip.message.Response; - -import org.apache.log4j.Logger; -import org.cafesip.sipunit.SipCall; -import org.cafesip.sipunit.SipPhone; -import org.cafesip.sipunit.SipStack; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class B2BUASipUnitTest extends SipServletTestCase { - private static final Logger logger = Logger.getLogger(B2BUASipUnitTest.class); - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; -// private static final int TIMEOUT = 100000000; - SipStack sipStackA; - SipStack sipStackB; - - SipPhone sipPhoneA; - SipPhone sipPhoneB; - - TestSipListener sender; - TestSipListener receiver; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - - public B2BUASipUnitTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/b2bua-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/b2bua/b2bua-sip-servlet-dar.properties"; - } - - public void setupPhones(String a, String b) throws Exception { - Properties properties1 = new Properties(); - //properties1.setProperty("javax.sip.IP_ADDRESS", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); - String transport = "udp"; - String peerHostPort1 = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070"; - properties1.setProperty("javax.sip.OUTBOUND_PROXY", peerHostPort1 + "/" - + transport); - properties1.setProperty("javax.sip.STACK_NAME", "sender"); - properties1.setProperty("sipunit.BINDADDR", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); - properties1.setProperty("gov.nist.javax.sip.DEBUG_LOG", - "logs/b2buadebug1.txt"); - properties1.setProperty("gov.nist.javax.sip.SERVER_LOG", - "logs/b2bualog1.xml"); - properties1.setProperty("gov.nist.javax.sip.TRACE_LEVEL", - "32"); - - Properties properties2 = new Properties(); - // properties2.setProperty("javax.sip.IP_ADDRESS", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); - String peerHostPort2 = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070"; - properties2.setProperty("javax.sip.OUTBOUND_PROXY", peerHostPort2 + "/" - + transport); - properties2.setProperty("javax.sip.STACK_NAME", "receiver"); - properties2.setProperty("sipunit.BINDADDR", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); - properties2.setProperty("gov.nist.javax.sip.DEBUG_LOG", - "logs/b2buadebug2.txt"); - properties2.setProperty("gov.nist.javax.sip.SERVER_LOG", - "logs/b2bualog2.xml"); - properties2.setProperty("gov.nist.javax.sip.TRACE_LEVEL", - "32"); - - sipStackA = new SipStack(SipStack.PROTOCOL_UDP , 5058, properties1); - sipPhoneA = sipStackA.createSipPhone("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", SipStack.PROTOCOL_UDP, 5070, a); - - sipStackB = new SipStack(SipStack.PROTOCOL_UDP , 5059, properties2); - sipPhoneB = sipStackB.createSipPhone("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", SipStack.PROTOCOL_UDP, 5070, b); - } - - public void testB2BUASipUnit() throws Exception { - setupPhones("sip:sender@nist.gov", "sip:aa@nist.gov"); - SipCall callA = sipPhoneA.createSipCall(); - SipCall callB = sipPhoneB.createSipCall(); - - callB.listenForIncomingCall(); - Thread.sleep(300); - callA.initiateOutgoingCall("sip:receiver@nist.gov", null); - - assertTrue(callB.waitForIncomingCall(TIMEOUT)); - - assertTrue(callB.sendIncomingCallResponse(Response.RINGING, "Ringing", 0)); - assertTrue(callA.waitOutgoingCallResponse(TIMEOUT)); - - assertTrue(callB.sendIncomingCallResponse(Response.OK, "OK", 0)); - assertTrue(callB.waitForAck(TIMEOUT)); - - assertTrue(callA.waitOutgoingCallResponse(TIMEOUT)); - assertNotNull(callA.findMostRecentResponse(Response.OK)); - //sipunit doesn't succeed to send the ACK since it tries to do it with - //Dialog.createRequest(Request.ACK) - //assertTrue(callA.sendInviteOkAck()); - callA.sendInviteOkAck(); - - assertTrue(callA.disconnect()); - assertTrue(callB.waitForDisconnect(TIMEOUT)); - assertTrue(callB.respondToDisconnect()); - - sipPhoneA.dispose(); - sipPhoneB.dispose(); - sipStackA.dispose(); - sipStackB.dispose(); - Thread.sleep(TIMEOUT); - } - - public void testB2BUASipUnitCancelNoResponse() throws Exception { - setupPhones("sip:sender@nist.gov", "sip:aa@nist.gov"); - SipCall callA = sipPhoneA.createSipCall(); - SipCall callB = sipPhoneB.createSipCall(); - - callB.listenForIncomingCall(); - Thread.sleep(300); - callA.initiateOutgoingCall("sip:cancel-no-response@nist.gov", null); - //sipunit doesn't succeed to send the ACK since it tries to do it with - //Dialog.createRequest(Request.ACK) - //assertTrue(callA.sendInviteOkAck()); - callA.sendInviteOkAck(); - - sipPhoneA.dispose(); - sipPhoneB.dispose(); - sipStackA.dispose(); - sipStackB.dispose(); - Thread.sleep(TIMEOUT); - } - - public void testB2BUASipUnitGenerateResponses() throws Exception { - senderProtocolObjects = new ProtocolObjects("generateResponses", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - receiverProtocolObjects = new ProtocolObjects("aa", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - String fromName = "generateResponses"; - String fromSipAddress = "nist.gov"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "nist.gov"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - sender.setTimeToWaitBeforeBye(TIMEOUT); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5059, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - //checking numbers of ACK received see http://forums.java.net/jive/thread.jspa?messageID=277840 - assertEquals(1,receiver.ackCount); - Thread.sleep(TIMEOUT); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - } -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.b2bua; + +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import javax.sip.message.Response; + +import org.apache.log4j.Logger; +import org.cafesip.sipunit.SipCall; +import org.cafesip.sipunit.SipPhone; +import org.cafesip.sipunit.SipStack; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.PhoneCloseable; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.StackCloseable; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class B2BUASipUnitTest extends SipServletTestCase { + + private static final Logger logger = Logger.getLogger(B2BUASipUnitTest.class); + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 15000; +// private static final int TIMEOUT = 100000000; + SipStack sipStackA; + SipStack sipStackB; + + SipPhone sipPhoneA; + SipPhone sipPhoneB; + + TestSipListener sender; + TestSipListener receiver; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + + public B2BUASipUnitTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + assertTrue(tomcat.deployContext( + projectHome + "/sip-servlets-test-suite/applications/b2bua-sip-servlet/src/main/sipapp", + "sip-test-context", "sip-test")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/b2bua/b2bua-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + } + + public void setupPhones(String a, String b) throws Exception { + Properties properties1 = new Properties(); + //properties1.setProperty("javax.sip.IP_ADDRESS", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); + String transport = "udp"; + String peerHostPort1 = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + containerPort; + properties1.setProperty("javax.sip.OUTBOUND_PROXY", peerHostPort1 + "/" + + transport); + properties1.setProperty("javax.sip.STACK_NAME", "sender"); + properties1.setProperty("sipunit.BINDADDR", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); + properties1.setProperty("gov.nist.javax.sip.DEBUG_LOG", + "target/logs/b2buadebug1.txt"); + properties1.setProperty("gov.nist.javax.sip.SERVER_LOG", + "target/logs/b2bualog1.xml"); + properties1.setProperty("gov.nist.javax.sip.TRACE_LEVEL", + "32"); + + Properties properties2 = new Properties(); + // properties2.setProperty("javax.sip.IP_ADDRESS", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); + String peerHostPort2 = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + containerPort; + properties2.setProperty("javax.sip.OUTBOUND_PROXY", peerHostPort2 + "/" + + transport); + properties2.setProperty("javax.sip.STACK_NAME", "receiver"); + properties2.setProperty("sipunit.BINDADDR", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); + properties2.setProperty("gov.nist.javax.sip.DEBUG_LOG", + "target/logs/b2buadebug2.txt"); + properties2.setProperty("gov.nist.javax.sip.SERVER_LOG", + "target/logs/b2bualog2.xml"); + properties2.setProperty("gov.nist.javax.sip.TRACE_LEVEL", + "32"); + + int aPort = NetworkPortAssigner.retrieveNextPort(); + sipStackA = new SipStack(SipStack.PROTOCOL_UDP, aPort, properties1); + sipPhoneA = sipStackA.createSipPhone("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", SipStack.PROTOCOL_UDP, containerPort, a); + + int bPort = NetworkPortAssigner.retrieveNextPort(); + sipStackB = new SipStack(SipStack.PROTOCOL_UDP, bPort, properties2); + sipPhoneB = sipStackB.createSipPhone("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", SipStack.PROTOCOL_UDP, containerPort, b); + testResources.add(new PhoneCloseable(sipPhoneA)); + testResources.add(new PhoneCloseable(sipPhoneB)); + testResources.add(new StackCloseable(sipStackA)); + testResources.add(new StackCloseable(sipStackB)); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(bPort)); + params.put("senderPort", String.valueOf(aPort)); + SipStandardContext deployApplication = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/b2bua-sip-servlet/src/main/sipapp", + params, null); + } + + public void testB2BUASipUnit() throws Exception { + setupPhones("sip:sender@nist.gov", "sip:aa@nist.gov"); + SipCall callA = sipPhoneA.createSipCall(); + SipCall callB = sipPhoneB.createSipCall(); + + callB.listenForIncomingCall(); + Thread.sleep(300); + callA.initiateOutgoingCall("sip:receiver@nist.gov", null); + + assertTrue(callB.waitForIncomingCall(TIMEOUT)); + + assertTrue(callB.sendIncomingCallResponse(Response.RINGING, "Ringing", 0)); + assertTrue(callA.waitOutgoingCallResponse(TIMEOUT)); + + assertTrue(callB.sendIncomingCallResponse(Response.OK, "OK", 0)); + assertTrue(callB.waitForAck(TIMEOUT)); + + assertTrue(callA.waitOutgoingCallResponse(TIMEOUT)); + assertNotNull(callA.findMostRecentResponse(Response.OK)); + //sipunit doesn't succeed to send the ACK since it tries to do it with + //Dialog.createRequest(Request.ACK) + //assertTrue(callA.sendInviteOkAck()); + callA.sendInviteOkAck(); + + assertTrue(callA.disconnect()); + assertTrue(callB.waitForDisconnect(TIMEOUT)); + assertTrue(callB.respondToDisconnect()); + + } + + public void testB2BUASipUnitCancelNoResponse() throws Exception { + setupPhones("sip:sender@nist.gov", "sip:aa@nist.gov"); + SipCall callA = sipPhoneA.createSipCall(); + SipCall callB = sipPhoneB.createSipCall(); + + callB.listenForIncomingCall(); + Thread.sleep(300); + callA.initiateOutgoingCall("sip:cancel-no-response@nist.gov", null); + //sipunit doesn't succeed to send the ACK since it tries to do it with + //Dialog.createRequest(Request.ACK) + //assertTrue(callA.sendInviteOkAck()); + callA.sendInviteOkAck(); + } + + public void testB2BUASipUnitGenerateResponses() throws Exception { + senderProtocolObjects = new ProtocolObjects("generateResponses", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects("aa", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + String fromName = "generateResponses"; + String fromSipAddress = "nist.gov"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "nist.gov"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + sender.setTimeToWaitBeforeBye(TIMEOUT); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + testResources.add(senderProtocolObjects); + receiverProtocolObjects.start(); + testResources.add(receiverProtocolObjects); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + SipStandardContext deployApplication = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/b2bua-sip-servlet/src/main/sipapp", + params, null); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + //checking numbers of ACK received see http://forums.java.net/jive/thread.jspa?messageID=277840 + assertEquals(1, receiver.ackCount); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + + logger.info("Test completed"); + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/b2bua/B2BUATcpUdpTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/b2bua/B2BUATcpUdpTest.java index 864cb09632..2c7f7167bb 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/b2bua/B2BUATcpUdpTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/b2bua/B2BUATcpUdpTest.java @@ -16,10 +16,11 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ - package org.mobicents.servlet.sip.testsuite.b2bua; +import java.util.HashMap; import java.util.ListIterator; +import java.util.Map; import javax.sip.ListeningPoint; import javax.sip.SipProvider; @@ -28,9 +29,11 @@ import javax.sip.header.CallIdHeader; import javax.sip.header.ContactHeader; import javax.sip.header.Header; +import javax.sip.header.ReasonHeader; import javax.sip.header.UserAgentHeader; import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; import org.mobicents.servlet.sip.SipServletTestCase; import org.mobicents.servlet.sip.catalina.SipStandardManager; import org.mobicents.servlet.sip.startup.SipContextConfig; @@ -40,319 +43,419 @@ /** * Testing B2BUA bridge between udp and tcp transports - * - * @author Filip Olsson + * + * @author Filip Olsson * */ public class B2BUATcpUdpTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(B2BUATcpUdpTest.class); - private static final String TRANSPORT_UDP = "udp"; - private static final String TRANSPORT_TCP = "tcp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 15000; + private static transient Logger logger = Logger.getLogger(B2BUATcpUdpTest.class); + + private static final String TRANSPORT_UDP = "udp"; + private static final String TRANSPORT_TCP = "tcp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 15000; // private static final int TIMEOUT = 100000000; - - TestSipListener sender; - TestSipListener receiver; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - SipStandardManager sipStandardManager = null; - - public B2BUATcpUdpTest(String name) { - super(name); - startTomcatOnStartup = false; - autoDeployOnStartup = false; - } - - @Override - public void deployApplication() { - sipStandardManager = new SipStandardManager(); - SipStandardContext context = new SipStandardContext(); + + TestSipListener sender; + TestSipListener receiver; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + SipStandardManager sipStandardManager = null; + + public B2BUATcpUdpTest(String name) { + super(name); + startTomcatOnStartup = false; + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + sipStandardManager = new SipStandardManager(); + SipStandardContext context = new SipStandardContext(); context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp"); context.setName("sip-test-context"); - context.setPath("/sip-test"); + context.setPath("/sip-test"); context.addLifecycleListener(new SipContextConfig()); context.setManager(sipStandardManager); boolean success = tomcat.deployContext( context); - assertTrue(success); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/callcontroller/call-forwarding-b2bua-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - tomcat.addSipConnector(serverName, sipIpAddress, 5070, ListeningPoint.TCP); - tomcat.startTomcat(); - deployApplication(); - - senderProtocolObjects = new ProtocolObjects("forward-udp-sender", - "gov.nist", TRANSPORT_UDP, AUTODIALOG, null, null, null); - receiverProtocolObjects = new ProtocolObjects("forward-tcp-receiver", - "gov.nist", TRANSPORT_TCP, AUTODIALOG, null, null, null); - - } - - public void testCallForwardingCallerSendBye() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-tcp-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "forward-receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[] {UserAgentHeader.NAME, "extension-header", AllowHeader.NAME}, new String[] {"TestSipListener UA", "extension-sip-listener", "INVITE, CANCEL, BYE, ACK, OPTIONS"}, true); - Thread.sleep(TIMEOUT); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - CallIdHeader receiverCallIdHeader = (CallIdHeader)receiver.getInviteRequest().getHeader(CallIdHeader.NAME); - CallIdHeader senderCallIdHeader = (CallIdHeader)sender.getInviteRequest().getHeader(CallIdHeader.NAME); - ListIterator userAgentHeaderIt = receiver.getInviteRequest().getHeaders(UserAgentHeader.NAME); - ListIterator allowHeaderIt = receiver.getInviteRequest().getHeaders(AllowHeader.NAME); - int i = 0; - while (userAgentHeaderIt.hasNext()) { - UserAgentHeader userAgentHeader = (UserAgentHeader) userAgentHeaderIt - .next(); - assertTrue(userAgentHeader.toString().trim().endsWith("CallForwardingB2BUASipServlet")); - i++; - } - assertEquals(1, i); - ListIterator contactHeaderIt = receiver.getInviteRequest().getHeaders(ContactHeader.NAME); - i = 0; - while (contactHeaderIt.hasNext()) { - ContactHeader contactHeader = (ContactHeader) contactHeaderIt - .next(); - assertTrue(contactHeader.toString().trim().startsWith("Contact: \"callforwardingB2BUA\" ;test")); - i++; - } - assertEquals(1, i); - ListIterator
extensionHeaderIt = receiver.getInviteRequest().getHeaders("extension-header"); - i = 0; - while (extensionHeaderIt.hasNext()) { - extensionHeaderIt.next(); - i++; - } - assertEquals(2, i); - userAgentHeaderIt = receiver.getByeRequestReceived().getHeaders(UserAgentHeader.NAME); - i = 0; - while (userAgentHeaderIt.hasNext()) { - UserAgentHeader userAgentHeader = (UserAgentHeader) userAgentHeaderIt - .next(); - assertTrue(userAgentHeader.toString().trim().endsWith("CallForwardingB2BUASipServlet")); - i++; - } - assertEquals(1, i); - i = 0; - while (allowHeaderIt.hasNext()) { - allowHeaderIt.next(); - i++; - } - assertEquals(5, i); - contactHeaderIt = receiver.getByeRequestReceived().getHeaders(ContactHeader.NAME); - i = 0; - while (contactHeaderIt.hasNext()) { - ContactHeader contactHeader = (ContactHeader) contactHeaderIt - .next(); - i++; - } - assertEquals(0, i); - assertFalse(receiverCallIdHeader.getCallId().equals(senderCallIdHeader.getCallId())); - extensionHeaderIt = receiver.getByeRequestReceived().getHeaders("extension-header"); - i = 0; - while (extensionHeaderIt.hasNext()) { - extensionHeaderIt.next(); - i++; - } - assertEquals(2, i); - } - - public void testCallForwardingREGISTERCheckContact() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-tcp-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "forward-receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("REGISTER", fromAddress, toAddress, null, null, false, new String[] {UserAgentHeader.NAME, "extension-header"}, new String[] {"TestSipListener UA", "extension-sip-listener"}, true); - Thread.sleep(TIMEOUT); - ListIterator userAgentHeaderIt = receiver.getRegisterReceived().getHeaders(UserAgentHeader.NAME); - int i = 0; - while (userAgentHeaderIt.hasNext()) { - UserAgentHeader userAgentHeader = (UserAgentHeader) userAgentHeaderIt - .next(); - assertTrue(userAgentHeader.toString().trim().endsWith("CallForwardingB2BUASipServlet")); - i++; - } - assertEquals(1, i); - ListIterator contactHeaderIt = receiver.getRegisterReceived().getHeaders(ContactHeader.NAME); - assertTrue(contactHeaderIt.hasNext()); - assertTrue(contactHeaderIt.next().toString().trim().startsWith("Contact: ")); - assertTrue(contactHeaderIt.hasNext()); - assertTrue(contactHeaderIt.next().toString().trim().startsWith("Contact: \"callforwardingB2BUA\" ;test")); - ListIterator
extensionHeaderIt = receiver.getRegisterReceived().getHeaders("extension-header"); - i = 0; - while (extensionHeaderIt.hasNext()) { - extensionHeaderIt.next(); - i++; - } - assertEquals(2, i); - } - - - public void testCallForwardingCalleeSendByeTCPSender() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); -// receiver.setTransport(false); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-udp-sender-tcp-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - receiver.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - CallIdHeader receiverCallIdHeader = (CallIdHeader)sender.getInviteRequest().getHeader(CallIdHeader.NAME); - CallIdHeader senderCallIdHeader = (CallIdHeader)receiver.getInviteRequest().getHeader(CallIdHeader.NAME); - assertFalse(receiverCallIdHeader.getCallId().equals(senderCallIdHeader.getCallId())); - } - - public void testCallForwardingCalleeSendBye() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-tcp-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getOkToByeReceived()); - assertTrue(sender.getByeReceived()); - CallIdHeader receiverCallIdHeader = (CallIdHeader)receiver.getInviteRequest().getHeader(CallIdHeader.NAME); - CallIdHeader senderCallIdHeader = (CallIdHeader)sender.getInviteRequest().getHeader(CallIdHeader.NAME); - assertFalse(receiverCallIdHeader.getCallId().equals(senderCallIdHeader.getCallId())); - } - - public void testCancelCallForwarding() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-tcp-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - receiver.setWaitForCancel(true); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(500); - sender.sendCancel(); - Thread.sleep(TIMEOUT); - assertTrue(sender.isCancelOkReceived()); - assertTrue(sender.isRequestTerminatedReceived()); - assertTrue(receiver.isCancelReceived()); - CallIdHeader receiverCallIdHeader = (CallIdHeader)receiver.getInviteRequest().getHeader(CallIdHeader.NAME); - CallIdHeader senderCallIdHeader = (CallIdHeader)sender.getInviteRequest().getHeader(CallIdHeader.NAME); - assertFalse(receiverCallIdHeader.getCallId().equals(senderCallIdHeader.getCallId())); - Thread.sleep(TIMEOUT*2); - assertEquals(0, sipStandardManager.getActiveSipApplicationSessions()); - assertEquals(0, sipStandardManager.getActiveSipSessions()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - sender = null; - receiver = null; - logger.info("Test completed"); - super.tearDown(); - } - + assertTrue(success); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/callcontroller/call-forwarding-b2bua-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + tomcat.addSipConnector(serverName, sipIpAddress, containerPort, ListeningPoint.TCP); + tomcat.startTomcat(); + + senderProtocolObjects = new ProtocolObjects("forward-udp-sender", + "gov.nist", TRANSPORT_UDP, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects("forward-tcp-receiver", + "gov.nist", TRANSPORT_TCP, AUTODIALOG, null, null, null); + + } + + public void testCallForwardingCallerSendBye() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + SipStandardContext deployApplication = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params, null); + sipStandardManager = (SipStandardManager) deployApplication.getSipManager(); + + String fromName = "forward-tcp-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "forward-receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[]{UserAgentHeader.NAME, "extension-header", AllowHeader.NAME}, new String[]{"TestSipListener UA", "extension-sip-listener", "INVITE, CANCEL, BYE, ACK, OPTIONS"}, true); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + CallIdHeader receiverCallIdHeader = (CallIdHeader) receiver.getInviteRequest().getHeader(CallIdHeader.NAME); + CallIdHeader senderCallIdHeader = (CallIdHeader) sender.getInviteRequest().getHeader(CallIdHeader.NAME); + ListIterator userAgentHeaderIt = receiver.getInviteRequest().getHeaders(UserAgentHeader.NAME); + ListIterator allowHeaderIt = receiver.getInviteRequest().getHeaders(AllowHeader.NAME); + int i = 0; + while (userAgentHeaderIt.hasNext()) { + UserAgentHeader userAgentHeader = (UserAgentHeader) userAgentHeaderIt + .next(); + assertTrue(userAgentHeader.toString().trim().endsWith("CallForwardingB2BUASipServlet")); + i++; + } + assertEquals(1, i); + ListIterator contactHeaderIt = receiver.getInviteRequest().getHeaders(ContactHeader.NAME); + i = 0; + while (contactHeaderIt.hasNext()) { + ContactHeader contactHeader = (ContactHeader) contactHeaderIt + .next(); + assertTrue(contactHeader.toString().trim().startsWith("Contact: \"callforwardingB2BUA\" ;test")); + i++; + } + assertEquals(1, i); + ListIterator
extensionHeaderIt = receiver.getInviteRequest().getHeaders("extension-header"); + i = 0; + while (extensionHeaderIt.hasNext()) { + extensionHeaderIt.next(); + i++; + } + assertEquals(2, i); + userAgentHeaderIt = receiver.getByeRequestReceived().getHeaders(UserAgentHeader.NAME); + i = 0; + while (userAgentHeaderIt.hasNext()) { + UserAgentHeader userAgentHeader = (UserAgentHeader) userAgentHeaderIt + .next(); + assertTrue(userAgentHeader.toString().trim().endsWith("CallForwardingB2BUASipServlet")); + i++; + } + assertEquals(1, i); + i = 0; + while (allowHeaderIt.hasNext()) { + allowHeaderIt.next(); + i++; + } + assertEquals(5, i); + contactHeaderIt = receiver.getByeRequestReceived().getHeaders(ContactHeader.NAME); + i = 0; + while (contactHeaderIt.hasNext()) { + ContactHeader contactHeader = (ContactHeader) contactHeaderIt + .next(); + i++; + } + assertEquals(0, i); + assertFalse(receiverCallIdHeader.getCallId().equals(senderCallIdHeader.getCallId())); + extensionHeaderIt = receiver.getByeRequestReceived().getHeaders("extension-header"); + i = 0; + while (extensionHeaderIt.hasNext()) { + extensionHeaderIt.next(); + i++; + } + assertEquals(2, i); + } + + public void testCallForwardingREGISTERCheckContact() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params, null); + + String fromName = "forward-tcp-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "forward-receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("REGISTER", fromAddress, toAddress, null, null, false, new String[]{UserAgentHeader.NAME, "extension-header"}, new String[]{"TestSipListener UA", "extension-sip-listener"}, true); + Thread.sleep(TIMEOUT); + ListIterator userAgentHeaderIt = receiver.getRegisterReceived().getHeaders(UserAgentHeader.NAME); + int i = 0; + while (userAgentHeaderIt.hasNext()) { + UserAgentHeader userAgentHeader = (UserAgentHeader) userAgentHeaderIt + .next(); + assertTrue(userAgentHeader.toString().trim().endsWith("CallForwardingB2BUASipServlet")); + i++; + } + assertEquals(1, i); + ListIterator contactHeaderIt = receiver.getRegisterReceived().getHeaders(ContactHeader.NAME); + assertTrue(contactHeaderIt.hasNext()); + assertTrue(contactHeaderIt.next().toString().trim().startsWith("Contact: ")); + assertTrue(contactHeaderIt.hasNext()); + assertTrue(contactHeaderIt.next().toString().trim().startsWith("Contact: \"callforwardingB2BUA\" ;test")); + ListIterator
extensionHeaderIt = receiver.getRegisterReceived().getHeaders("extension-header"); + i = 0; + while (extensionHeaderIt.hasNext()) { + extensionHeaderIt.next(); + i++; + } + assertEquals(2, i); + } + + public void testCallForwardingCalleeSendByeTCPSender() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params, null); + + String fromName = "forward-udp-sender-tcp-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + receiver.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + CallIdHeader receiverCallIdHeader = (CallIdHeader) sender.getInviteRequest().getHeader(CallIdHeader.NAME); + CallIdHeader senderCallIdHeader = (CallIdHeader) receiver.getInviteRequest().getHeader(CallIdHeader.NAME); + assertFalse(receiverCallIdHeader.getCallId().equals(senderCallIdHeader.getCallId())); + } + + public void testCallForwardingCalleeSendBye() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params, null); + + String fromName = "forward-tcp-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getOkToByeReceived()); + assertTrue(sender.getByeReceived()); + CallIdHeader receiverCallIdHeader = (CallIdHeader) receiver.getInviteRequest().getHeader(CallIdHeader.NAME); + CallIdHeader senderCallIdHeader = (CallIdHeader) sender.getInviteRequest().getHeader(CallIdHeader.NAME); + assertFalse(receiverCallIdHeader.getCallId().equals(senderCallIdHeader.getCallId())); + } + + public void testCancelCallForwarding() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + SipStandardContext deployApplication = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params, null); + sipStandardManager = (SipStandardManager) deployApplication.getSipManager(); + + String fromName = "forward-tcp-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + receiver.setWaitForCancel(true); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(500); + sender.sendCancel(); + Thread.sleep(TIMEOUT); + assertTrue(sender.isCancelOkReceived()); + assertTrue(sender.isRequestTerminatedReceived()); + assertTrue(receiver.isCancelReceived()); + CallIdHeader receiverCallIdHeader = (CallIdHeader) receiver.getInviteRequest().getHeader(CallIdHeader.NAME); + CallIdHeader senderCallIdHeader = (CallIdHeader) sender.getInviteRequest().getHeader(CallIdHeader.NAME); + assertFalse(receiverCallIdHeader.getCallId().equals(senderCallIdHeader.getCallId())); + Thread.sleep(TIMEOUT * 2); + assertEquals(0, sipStandardManager.getActiveSipApplicationSessions()); + assertEquals(0, sipStandardManager.getActiveSipSessions()); + } + + public void testCancelCallForwarding487RequestTerminatedReasonHeader() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + SipStandardContext deployApplication = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params, null); + sipStandardManager = (SipStandardManager) deployApplication.getSipManager(); + + String fromName = "forward-tcp-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + receiver.setWaitForCancel(true); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(500); + sender.sendCancel(); + Thread.sleep(TIMEOUT); + assertTrue(sender.isCancelOkReceived()); + assertTrue(sender.isRequestTerminatedReceived()); + assertTrue(receiver.isCancelReceived()); + assertTrue(sender.getFinalResponse().getHeader(ReasonHeader.NAME).toString().contains("487 request terminated reason")); + CallIdHeader receiverCallIdHeader = (CallIdHeader) receiver.getInviteRequest().getHeader(CallIdHeader.NAME); + CallIdHeader senderCallIdHeader = (CallIdHeader) sender.getInviteRequest().getHeader(CallIdHeader.NAME); + assertFalse(receiverCallIdHeader.getCallId().equals(senderCallIdHeader.getCallId())); + Thread.sleep(TIMEOUT * 2); + assertEquals(0, sipStandardManager.getActiveSipApplicationSessions()); + assertEquals(0, sipStandardManager.getActiveSipSessions()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + sender = null; + receiver = null; + logger.info("Test completed"); + super.tearDown(); + } } diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/b2bua/forking/B2BUASipServletForkingTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/b2bua/forking/B2BUASipServletForkingTest.java index 534ae1bff9..829a0ec845 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/b2bua/forking/B2BUASipServletForkingTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/b2bua/forking/B2BUASipServletForkingTest.java @@ -1,220 +1,270 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.b2bua.forking; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Properties; - -import javax.sip.SipProvider; - -import org.apache.catalina.deploy.ApplicationParameter; -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.catalina.SipStandardService; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; -import org.mobicents.servlet.sip.testsuite.proxy.Shootist; -import org.mobicents.servlet.sip.testsuite.simple.forking.Proxy; -import org.mobicents.servlet.sip.testsuite.simple.forking.Shootme; - -public class B2BUASipServletForkingTest extends SipServletTestCase { - private static transient Logger logger = Logger.getLogger(B2BUASipServletForkingTest.class); - private static final int TIMEOUT = 40000; -// private static final int TIMEOUT = 100000000; - - public B2BUASipServletForkingTest(String name) { - super(name); - startTomcatOnStartup = false; - autoDeployOnStartup = false; - addSipConnectorOnStartup = false; - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - public SipStandardContext deployApplication(String name, String value) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(name); - applicationParameter.setValue(value); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - return context; - } - - public SipStandardContext deployApplication(Map params) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - for (Entry param : params.entrySet()) { - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(param.getKey()); - applicationParameter.setValue(param.getValue()); - context.addApplicationParameter(applicationParameter); - } - assertTrue(tomcat.deployContext(context)); - return context; - } - - public SipStandardContext deployApplicationServletListenerTest() { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName("testServletListener"); - applicationParameter.setValue("true"); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - return context; - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/callcontroller/call-forwarding-b2bua-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - } - - // non regression test for Issue 2354 http://code.google.com/p/mobicents/issues/detail?id=2354 - public void testB2BUAForking() throws Exception { - Shootme shootme1 = new Shootme(5080, true, 1500); - SipProvider shootmeProvider = shootme1.createProvider(); - shootmeProvider.addSipListener(shootme1); - Shootme shootme2 = new Shootme(5081, true, 2500); - SipProvider shootme2Provider = shootme2.createProvider(); - shootme2Provider.addSipListener(shootme2); - Proxy proxy = new Proxy(5070,2); - SipProvider provider = proxy.createSipProvider(); - provider.addSipListener(proxy); - Shootist shootist = new Shootist(true, "5060"); - shootist.pauseBeforeBye = 20000; - shootist.setFromHost("sip-servlets.com"); - - sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, 5060, listeningPointTransport); - tomcat.startTomcat(); - Map params= new HashMap(); - params.put("route", "sip:" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070"); - params.put("timeToWaitForBye", "20000"); - params.put("dontSetRURI", "true"); - SipStandardContext sipContext = deployApplication(params); - shootist.init("forward-sender-forking-pending", false, null); - Thread.sleep(TIMEOUT); - proxy.stop(); - shootme1.stop(); - shootme2.stop(); - shootist.stop(); - assertTrue(shootme1.isAckSeen()); - assertTrue(shootme1.checkBye()); - assertTrue(shootme2.isAckSeen()); - assertTrue(shootme2.checkBye()); - assertEquals(0, sipContext.getSipManager().getActiveSipSessions()); - assertEquals(0, sipContext.getSipManager().getActiveSipApplicationSessions()); - - } - - public void testB2BUAForkingWithCANCEL() throws Exception { - Shootme shootme1 = new Shootme(5080, true, 2500); - SipProvider shootmeProvider = shootme1.createProvider(); - shootmeProvider.addSipListener(shootme1); - Shootme shootme2 = new Shootme(5081, true, 1500); - SipProvider shootme2Provider = shootme2.createProvider(); - shootme2Provider.addSipListener(shootme2); - shootme2.setWaitForCancel(true); - Proxy proxy = new Proxy(5070,2); - SipProvider provider = proxy.createSipProvider(); - provider.addSipListener(proxy); - Shootist shootist = new Shootist(true, "5060"); - shootist.pauseBeforeBye = 20000; - shootist.setFromHost("sip-servlets.com"); - - sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, 5060, listeningPointTransport); - tomcat.startTomcat(); - Map params= new HashMap(); - params.put("route", "sip:" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070"); - params.put("timeToWaitForBye", "20000"); - params.put("dontSetRURI", "true"); - SipStandardContext sipContext = deployApplication(params); - shootist.init("forward-sender-forking-pending", false, null); - Thread.sleep(TIMEOUT); - proxy.stop(); - shootme1.stop(); - shootme2.stop(); - shootist.stop(); -// assertTrue(shootme1.isAckSeen()); - assertTrue(shootme1.checkBye()); -// assertTrue(shootme2.isAckSeen()); -// assertTrue(shootme2.checkBye()); - assertEquals(0, sipContext.getSipManager().getActiveSipSessions()); - assertEquals(0, sipContext.getSipManager().getActiveSipApplicationSessions()); - - } - - @Override - protected Properties getSipStackProperties() { - Properties sipStackProperties = new Properties(); - sipStackProperties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", - "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", - "32"); - sipStackProperties.setProperty(SipStandardService.DEBUG_LOG_STACK_PROP, - tomcatBasePath + "/" + "mss-jsip-" + getName() +"-debug.txt"); - sipStackProperties.setProperty(SipStandardService.SERVER_LOG_STACK_PROP, - tomcatBasePath + "/" + "mss-jsip-" + getName() +"-messages.xml"); - sipStackProperties.setProperty("javax.sip.STACK_NAME", "mss-" + getName()); - sipStackProperties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT" , "off"); - sipStackProperties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.THREAD_POOL_SIZE", "64"); - sipStackProperties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.MAX_FORK_TIME_SECONDS", "5"); - sipStackProperties.setProperty(SipStandardService.LOOSE_DIALOG_VALIDATION, "true"); - sipStackProperties.setProperty(SipStandardService.PASS_INVITE_NON_2XX_ACK_TO_LISTENER, "true"); - return sipStackProperties; - } - - @Override - protected void tearDown() throws Exception { - logger.info("Test completed"); - super.tearDown(); - } -} \ No newline at end of file +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.b2bua.forking; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Properties; + +import javax.sip.SipProvider; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.catalina.SipStandardService; +import org.mobicents.servlet.sip.core.session.MobicentsSipSession; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.proxy.Shootist; +import org.mobicents.servlet.sip.testsuite.simple.forking.Proxy; +import org.mobicents.servlet.sip.testsuite.simple.forking.Shootme; + +public class B2BUASipServletForkingTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(B2BUASipServletForkingTest.class); + private static final int TIMEOUT = 40000; +// private static final int TIMEOUT = 100000000; + + public B2BUASipServletForkingTest(String name) { + super(name); + startTomcatOnStartup = false; + autoDeployOnStartup = false; + addSipConnectorOnStartup = false; + } + + @Override + public void deployApplication() { + assertTrue(tomcat.deployContext( + projectHome + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + "sip-test-context", "sip-test")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/callcontroller/call-forwarding-b2bua-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + } + + // non regression test for Issue https://telestax.atlassian.net/browse/RES-4 + public void testB2BUAForkingCrossed180() throws Exception { + + // ShootMe-1 : 5091 + // ShootMe-2 : 5092 + // Proxy (forks to Shootme clients) : 5090 + // Container running B2BUA app : 5060 + // Shootist (initiates the call) : 5089 + + + int shootme1Port = NetworkPortAssigner.retrieveNextPort(); + //force ringing to come after shootme2,but 200ok before shootme 2 + Shootme shootme1 = new Shootme(shootme1Port, true, 1000,1500); + SipProvider shootmeProvider = shootme1.createProvider(); + shootmeProvider.addSipListener(shootme1); + + int shootme2Port = NetworkPortAssigner.retrieveNextPort(); + //send 180 inmediately,but 200 ok after shootme1 + Shootme shootme2 = new Shootme(shootme2Port, true, 2500); + SipProvider shootme2Provider = shootme2.createProvider(); + shootme2Provider.addSipListener(shootme2); + + int proxyPort = NetworkPortAssigner.retrieveNextPort(); + Proxy proxy = new Proxy(proxyPort, new int[]{shootme1Port, shootme2Port}); + SipProvider provider = proxy.createSipProvider(); + provider.addSipListener(proxy); + + int shootistPort = NetworkPortAssigner.retrieveNextPort(); + int listeningPort = NetworkPortAssigner.retrieveNextPort(); + Shootist shootist = new Shootist(true, shootistPort, String.valueOf(listeningPort)); + shootist.pauseBeforeBye = 20000; + shootist.setFromHost("sip-servlets.com"); + + sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, listeningPort, listeningPointTransport); + tomcat.startTomcat(); + Map params = new HashMap(); + params.put("timeToWaitForBye", "20000"); + params.put("dontSetRURI", "true"); + params.put("servletContainerPort", String.valueOf(proxyPort)); + params.put("testPort", String.valueOf(shootme1Port)); + params.put("senderPort", String.valueOf(shootistPort)); + SipStandardContext sipContext = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params, null); + + shootist.init("forward-sender-forking-pending", false, null); + Thread.sleep(TIMEOUT); + proxy.stop(); + shootme1.stop(); + shootme2.stop(); + shootist.stop(); + assertTrue(shootme1.isAckSeen()); + assertTrue(shootme1.checkBye()); + assertTrue(shootme2.isAckSeen()); + assertTrue(shootme2.checkBye()); + + Iterator sipSessionsIter = sipContext.getSipManager().getAllSipSessions(); + while (sipSessionsIter.hasNext()) { + MobicentsSipSession sipSession = (MobicentsSipSession) sipSessionsIter.next(); + String msg = String.format("SipSession in memory, key [%s], state [%s], hasParent [%s], hasDerivedSessions [%s]", sipSession.getKey(), sipSession.getState(), sipSession.getParentSession() != null, sipSession.getDerivedSipSessions().hasNext()); + logger.error(msg); + Iterator iter = sipSession.getDerivedSipSessions(); + while (iter.hasNext()) { + MobicentsSipSession derivedSipSession = iter.next(); + msg = String.format("Derived sip session [%s], state [%s}",derivedSipSession.getKey(), derivedSipSession.getState()); + logger.error(msg); + } + } + + assertEquals(0, sipContext.getSipManager().getActiveSipSessions()); + assertEquals(0, sipContext.getSipManager().getActiveSipApplicationSessions()); + + } + + // non regression test for Issue 2354 http://code.google.com/p/mobicents/issues/detail?id=2354 + public void testB2BUAForking() throws Exception { + int shootme1Port = NetworkPortAssigner.retrieveNextPort(); + //force shootme1 to send 180 first + Shootme shootme1 = new Shootme(shootme1Port, true,100, 1500); + SipProvider shootmeProvider = shootme1.createProvider(); + shootmeProvider.addSipListener(shootme1); + int shootme2Port = NetworkPortAssigner.retrieveNextPort(); + //force shootme2 to send 180 second + Shootme shootme2 = new Shootme(shootme2Port, true, 300, 2500); + SipProvider shootme2Provider = shootme2.createProvider(); + shootme2Provider.addSipListener(shootme2); + int proxyPort = NetworkPortAssigner.retrieveNextPort(); + Proxy proxy = new Proxy(proxyPort, new int[]{shootme1Port, shootme2Port}); + SipProvider provider = proxy.createSipProvider(); + provider.addSipListener(proxy); + int shootistPort = NetworkPortAssigner.retrieveNextPort(); + int listeningPort = NetworkPortAssigner.retrieveNextPort(); + Shootist shootist = new Shootist(true, shootistPort, String.valueOf(listeningPort)); + shootist.pauseBeforeBye = 20000; + shootist.setFromHost("sip-servlets.com"); + + sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, listeningPort, listeningPointTransport); + tomcat.startTomcat(); + Map params = new HashMap(); + params.put("timeToWaitForBye", "20000"); + params.put("dontSetRURI", "true"); + params.put("servletContainerPort", String.valueOf(proxyPort)); + params.put("testPort", String.valueOf(shootme1Port)); + params.put("senderPort", String.valueOf(shootistPort)); + SipStandardContext sipContext = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params, null); + + shootist.init("forward-sender-forking-pending", false, null); + Thread.sleep(TIMEOUT); + proxy.stop(); + shootme1.stop(); + shootme2.stop(); + shootist.stop(); + assertTrue(shootme1.isAckSeen()); + assertTrue(shootme1.checkBye()); + assertTrue(shootme2.isAckSeen()); + assertTrue(shootme2.checkBye()); + assertEquals(0, sipContext.getSipManager().getActiveSipSessions()); + assertEquals(0, sipContext.getSipManager().getActiveSipApplicationSessions()); + + } + + public void testB2BUAForkingWithCANCEL() throws Exception { + int shootme1Port = NetworkPortAssigner.retrieveNextPort(); + Shootme shootme1 = new Shootme(shootme1Port, true, 2500); + SipProvider shootmeProvider = shootme1.createProvider(); + shootmeProvider.addSipListener(shootme1); + int shootme2Port = NetworkPortAssigner.retrieveNextPort(); + Shootme shootme2 = new Shootme(shootme2Port, true, 1500); + SipProvider shootme2Provider = shootme2.createProvider(); + shootme2Provider.addSipListener(shootme2); + shootme2.setWaitForCancel(true); + int proxyPort = NetworkPortAssigner.retrieveNextPort(); + Proxy proxy = new Proxy(proxyPort, new int[]{shootme1Port, shootme2Port}); + SipProvider provider = proxy.createSipProvider(); + provider.addSipListener(proxy); + int shootistPort = NetworkPortAssigner.retrieveNextPort(); + int listeningPort = NetworkPortAssigner.retrieveNextPort(); + Shootist shootist = new Shootist(true, shootistPort, String.valueOf(listeningPort)); + shootist.pauseBeforeBye = 20000; + shootist.setFromHost("sip-servlets.com"); + + sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, listeningPort, listeningPointTransport); + tomcat.startTomcat(); + Map params = new HashMap(); + params.put("timeToWaitForBye", "20000"); + params.put("dontSetRURI", "true"); + params.put("servletContainerPort", String.valueOf(proxyPort)); + params.put("testPort", String.valueOf(shootme1Port)); + params.put("senderPort", String.valueOf(shootistPort)); + SipStandardContext sipContext = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params, null); + + shootist.init("forward-sender-forking-pending", false, null); + Thread.sleep(TIMEOUT); + proxy.stop(); + shootme1.stop(); + shootme2.stop(); + shootist.stop(); +// assertTrue(shootme1.isAckSeen()); + assertTrue(shootme1.checkBye()); +// assertTrue(shootme2.isAckSeen()); +// assertTrue(shootme2.checkBye()); + assertEquals(0, sipContext.getSipManager().getActiveSipSessions()); + assertEquals(0, sipContext.getSipManager().getActiveSipApplicationSessions()); + + } + + @Override + protected Properties getSipStackProperties() { + Properties sipStackProperties = new Properties(); + sipStackProperties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", + "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", + "32"); + sipStackProperties.setProperty(SipStandardService.DEBUG_LOG_STACK_PROP, + tomcatBasePath + "/" + "mss-jsip-" + getName() + "-debug.txt"); + sipStackProperties.setProperty(SipStandardService.SERVER_LOG_STACK_PROP, + tomcatBasePath + "/" + "mss-jsip-" + getName() + "-messages.xml"); + sipStackProperties.setProperty("javax.sip.STACK_NAME", "mss-" + getName()); + sipStackProperties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", "off"); + sipStackProperties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.THREAD_POOL_SIZE", "64"); + sipStackProperties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.MAX_FORK_TIME_SECONDS", "5"); + sipStackProperties.setProperty(SipStandardService.LOOSE_DIALOG_VALIDATION, "true"); + sipStackProperties.setProperty(SipStandardService.PASS_INVITE_NON_2XX_ACK_TO_LISTENER, "true"); + return sipStackProperties; + } + + @Override + protected void tearDown() throws Exception { + logger.info("Test completed"); + super.tearDown(); + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/b2bua/prack/CallForwardingB2BUAPrackTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/b2bua/prack/CallForwardingB2BUAPrackTest.java index d1d7269fdf..e415c6c014 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/b2bua/prack/CallForwardingB2BUAPrackTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/b2bua/prack/CallForwardingB2BUAPrackTest.java @@ -1,257 +1,360 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.b2bua.prack; - -import gov.nist.javax.sip.message.RequestExt; - -import javax.sip.SipProvider; -import javax.sip.address.SipURI; -import javax.sip.header.ViaHeader; -import javax.sip.message.Request; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class CallForwardingB2BUAPrackTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(CallForwardingB2BUAPrackTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 20000; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender; - TestSipListener receiver; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - - public CallForwardingB2BUAPrackTest(String name) { - super(name); - startTomcatOnStartup = false; - autoDeployOnStartup = false; - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", - "sip-test-context", - "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/callcontroller/call-forwarding-b2bua-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects = new ProtocolObjects("forward-sender", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - receiverProtocolObjects = new ProtocolObjects("receiver", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - } - - public void testCallForwardingCallerSendBye() throws Exception { - tomcat.startTomcat(); - deployApplication(); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - String[] headerNames = new String[]{"require"}; - String[] headerValues = new String[]{"100rel"}; - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, headerNames, headerValues, true); - Thread.sleep(TIMEOUT); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - } - - // non regression test for https://github.com/Mobicents/sip-servlets/issues/66 - public void testCallForwardingCallerPrackUpdateSendBye() throws Exception { - tomcat.startTomcat(); - deployApplication(); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - String[] headerNames = new String[]{"require"}; - String[] headerValues = new String[]{"100rel"}; - -// sender.setSendUpdateOn180(true); -// receiver.setTimeToWaitBeforeAck(5000); - sender.setSendUpdateAfterPrack(true); - sender.setTimeToWaitBeforeBye(1000); - receiver.setSendUpdateAfterPrack(true); - receiver.setWaitBeforeFinalResponse(3000); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, headerNames, headerValues, true); - Thread.sleep(TIMEOUT); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - assertEquals(4, ((RequestExt)receiver.getByeRequestReceived()).getCSeqHeader().getSeqNumber()); - } - - public void testCallForwardingCalleeSendBye() throws Exception { - tomcat.startTomcat(); - deployApplication(); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, true); - receiver.setTimeToWaitBetweenProvisionnalResponse(1000); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - String[] headerNames = new String[]{"require"}; - String[] headerValues = new String[]{"100rel"}; - - for (int i = 0; i < 3; i++) { - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, headerNames, headerValues, true); - } - Thread.sleep(TIMEOUT * 5); - assertTrue(receiver.getOkToByeReceived()); - assertTrue(sender.getByeReceived()); - - if(sender.getAllMessagesContent() != null) { - assertFalse(sender.getAllMessagesContent().contains("KO")); - } - } - - public void testCallForwardingCallerSendByeAnyLocalAddress() throws Exception { - tomcat.removeConnector(sipConnector); - sipIpAddress = "0.0.0.0"; - tomcat.addSipConnector(serverName, sipIpAddress, 5070, listeningPointTransport); - tomcat.startTomcat(); - deployApplication(); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - String[] headerNames = new String[]{"require"}; - String[] headerValues = new String[]{"100rel"}; - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, headerNames, headerValues, true); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isPrackReceived()); - Request prackReceived = receiver.getPrackRequestReceived(); - assertNotNull(prackReceived); - ViaHeader via= ((RequestExt)prackReceived).getTopmostViaHeader(); - assertNotNull(via); - assertFalse(via.getHost().equals("0.0.0.0")); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite.b2bua.prack; + +import gov.nist.javax.sip.message.RequestExt; +import java.util.HashMap; +import java.util.Map; + +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import javax.sip.header.ViaHeader; +import javax.sip.message.Request; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class CallForwardingB2BUAPrackTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(CallForwardingB2BUAPrackTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 20000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + TestSipListener receiver; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + + public CallForwardingB2BUAPrackTest(String name) { + super(name); + startTomcatOnStartup = false; + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + assertTrue(tomcat.deployContext( + projectHome + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + "sip-test-context", + "sip-test")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/callcontroller/call-forwarding-b2bua-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects("forward-sender", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects("receiver", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + } + + public void testCallForwardingCallerSendBye() throws Exception { + tomcat.startTomcat(); + + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(receiverPort)); + params.put( "senderPort", String.valueOf(senderPort)); + SipStandardContext deployApplication = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params + , null); + + + String fromName = "forward-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + String[] headerNames = new String[]{"require"}; + String[] headerValues = new String[]{"100rel"}; + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, headerNames, headerValues, true); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + } + + // non regression test for https://github.com/Mobicents/sip-servlets/issues/66 + public void testCallForwardingCallerPrackUpdateSendBye() throws Exception { + tomcat.startTomcat(); + + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(receiverPort)); + params.put( "senderPort", String.valueOf(senderPort)); + SipStandardContext deployApplication = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params + , null); + + String fromName = "forward-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + String[] headerNames = new String[]{"require"}; + String[] headerValues = new String[]{"100rel"}; + +// sender.setSendUpdateOn180(true); +// receiver.setTimeToWaitBeforeAck(5000); + sender.setSendUpdateAfterPrack(true); + sender.setTimeToWaitBeforeBye(1000); + receiver.setSendUpdateAfterPrack(true); + receiver.setWaitBeforeFinalResponse(3000); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, headerNames, headerValues, true); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + assertEquals(4, ((RequestExt)receiver.getByeRequestReceived()).getCSeqHeader().getSeqNumber()); + } + + // non regression test for https://github.com/RestComm/sip-servlets/issues/362 + public void testCallForwardingCallerPrackUpdateFromBPartySendBye() throws Exception { + tomcat.startTomcat(); + + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(receiverPort)); + params.put( "senderPort", String.valueOf(senderPort)); + SipStandardContext deployApplication = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params + , null); + + String fromName = "forward-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + String[] headerNames = new String[]{"require"}; + String[] headerValues = new String[]{"100rel"}; + +// sender.setSendUpdateOn180(true); +// receiver.setTimeToWaitBeforeAck(5000); + sender.setSendUpdateAfterPrack(true); + sender.setTimeToWaitBeforeBye(1000); + receiver.setSendUpdateAfterPrack(true); + //this will actually cuase the issue, by forcing receiver to send counter UPDATE + receiver.setSendUpdateAfterUpdate(true); + receiver.setWaitBeforeFinalResponse(3000); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, headerNames, headerValues, true); + Thread.sleep(TIMEOUT); + assertTrue(sender.isUpdateReceived()); + assertTrue(receiver.isUpdateReceived()); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + assertEquals(4, ((RequestExt)receiver.getByeRequestReceived()).getCSeqHeader().getSeqNumber()); + } + + public void testCallForwardingCalleeSendBye() throws Exception { + tomcat.startTomcat(); + + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, true); + receiver.setTimeToWaitBetweenProvisionnalResponse(1000); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(receiverPort)); + params.put( "senderPort", String.valueOf(senderPort)); + SipStandardContext deployApplication = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params + , null); + + String fromName = "forward-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + String[] headerNames = new String[]{"require"}; + String[] headerValues = new String[]{"100rel"}; + + for (int i = 0; i < 3; i++) { + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, headerNames, headerValues, true); + } + Thread.sleep(TIMEOUT * 5); + assertTrue(receiver.getOkToByeReceived()); + assertTrue(sender.getByeReceived()); + + if(sender.getAllMessagesContent() != null) { + assertFalse(sender.getAllMessagesContent().contains("KO")); + } + } + + public void testCallForwardingCallerSendByeAnyLocalAddress() throws Exception { + tomcat.removeConnector(sipConnector); + sipIpAddress = "0.0.0.0"; + tomcat.addSipConnector(serverName, sipIpAddress, containerPort, listeningPointTransport); + tomcat.startTomcat(); + + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(receiverPort)); + params.put( "senderPort", String.valueOf(senderPort)); + SipStandardContext deployApplication = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params + , null); + + String fromName = "forward-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + String[] headerNames = new String[]{"require"}; + String[] headerValues = new String[]{"100rel"}; + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, headerNames, headerValues, true); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isPrackReceived()); + Request prackReceived = receiver.getPrackRequestReceived(); + assertNotNull(prackReceived); + ViaHeader via= ((RequestExt)prackReceived).getTopmostViaHeader(); + assertNotNull(via); + assertFalse(via.getHost().equals("0.0.0.0")); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/CallBlockingTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/CallBlockingTest.java index fe8d77ecea..2bf8c19eab 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/CallBlockingTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/CallBlockingTest.java @@ -1,110 +1,132 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.callcontroller; - -import java.util.Properties; - -import javax.sip.message.Response; - -import org.apache.log4j.Logger; -import org.cafesip.sipunit.SipCall; -import org.cafesip.sipunit.SipPhone; -import org.cafesip.sipunit.SipStack; -import org.mobicents.servlet.sip.SipUnitServletTestCase; - -public class CallBlockingTest extends SipUnitServletTestCase { - - private static transient Logger logger = Logger.getLogger(CallBlockingTest.class); - - private SipStack sipStackSender; - private SipPhone sipPhoneSender; - - private static final int TIMEOUT = 20000; - - public CallBlockingTest(String name) { - super(name); - } - - @Override - public void setUp() throws Exception { - super.setUp(); - } - - @Override - public void tearDown() throws Exception { - sipPhoneSender.dispose(); - sipStackSender.dispose(); - super.tearDown(); - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/call-blocking-servlet/src/main/sipapp", - "sip-test-context", - "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/callcontroller/call-blocking-servlet-dar.properties"; - } - - public SipStack makeStack(String transport, int port) throws Exception { - Properties properties = new Properties(); - String peerHostPort1 = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070"; - properties.setProperty("javax.sip.OUTBOUND_PROXY", peerHostPort1 + "/" - + "udp"); - properties.setProperty("javax.sip.STACK_NAME", "UAC_" + transport + "_" - + port); - properties.setProperty("sipunit.BINDADDR", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); - properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", - "logs/simplesipservlettest_debug_port" + port + ".txt"); - properties.setProperty("gov.nist.javax.sip.SERVER_LOG", - "logs/simplesipservlettest_log_port" + port + ".txt"); - - return new SipStack(transport, port, properties); - } - - public void setupPhone() throws Exception { - sipStackSender = makeStack(SipStack.PROTOCOL_UDP, 5080); - sipPhoneSender = sipStackSender.createSipPhone("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", - SipStack.PROTOCOL_UDP, 5070, "sip:blocked-sender@sip-servlets.com"); - } - - public void init() throws Exception { - setupPhone(); - } - - // Check if we receive a FORBIDDEN response for our invite - public void testCallBlockingInvite() throws Exception { - init(); - SipCall sender = sipPhoneSender.createSipCall(); - assertTrue(sender.initiateOutgoingCall("sip:receiver@sip-servlets.com", null)); - assertTrue(sender.waitOutgoingCallResponse(TIMEOUT)); - assertResponseReceived(Response.FORBIDDEN, sender); - } -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.callcontroller; + +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import javax.sip.message.Response; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.cafesip.sipunit.SipCall; +import org.cafesip.sipunit.SipPhone; +import org.cafesip.sipunit.SipStack; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipUnitServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; + +public class CallBlockingTest extends SipUnitServletTestCase { + + private static transient Logger logger = Logger.getLogger(CallBlockingTest.class); + + private SipStack sipStackSender; + private SipPhone sipPhoneSender; + + private static final int TIMEOUT = 20000; + + public CallBlockingTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + autoDeployOnStartup = false; + } + + @Override + public void tearDown() throws Exception { + sipPhoneSender.dispose(); + sipStackSender.dispose(); + super.tearDown(); + } + + @Override + public void deployApplication() { + assertTrue(tomcat.deployContext( + projectHome + "/sip-servlets-test-suite/applications/call-blocking-servlet/src/main/sipapp", + "sip-test-context", + "sip-test")); + } + + private void deployCallBlocking(Map params) { + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-blocking-servlet/src/main/sipapp", + "call-blocking", + params, + null); + assertTrue(ctx.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/callcontroller/call-blocking-servlet-dar.properties"; + } + + public SipStack makeStack(String transport, int port) throws Exception { + Properties properties = new Properties(); + String peerHostPort1 = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + containerPort; + properties.setProperty("javax.sip.OUTBOUND_PROXY", peerHostPort1 + "/" + + "udp"); + properties.setProperty("javax.sip.STACK_NAME", "UAC_" + transport + "_" + + port); + properties.setProperty("sipunit.BINDADDR", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); + properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", + "target/logs/simplesipservlettest_debug_port" + port + ".txt"); + properties.setProperty("gov.nist.javax.sip.SERVER_LOG", + "target/logs/simplesipservlettest_log_port" + port + ".txt"); + + return new SipStack(transport, port, properties); + } + + public void setupPhone() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sipStackSender = makeStack(SipStack.PROTOCOL_UDP, senderPort); + sipPhoneSender = sipStackSender.createSipPhone("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", + SipStack.PROTOCOL_UDP, containerPort, "sip:blocked-sender@sip-servlets.com"); + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployCallBlocking(params); + } + + public void init() throws Exception { + setupPhone(); + } + + // Check if we receive a FORBIDDEN response for our invite + public void testCallBlockingInvite() throws Exception { + init(); + SipCall sender = sipPhoneSender.createSipCall(); + assertTrue(sender.initiateOutgoingCall("sip:receiver@sip-servlets.com", null)); + assertTrue(sender.waitOutgoingCallResponse(TIMEOUT)); + assertResponseReceived(Response.FORBIDDEN, sender); + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/CallControllerCancelTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/CallControllerCancelTest.java index d6f2a69069..058aaada79 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/CallControllerCancelTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/CallControllerCancelTest.java @@ -1,131 +1,151 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.callcontroller; - -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class CallControllerCancelTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(CallControllerCancelTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 20000; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender; - TestSipListener receiver; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - - public CallControllerCancelTest(String name) { - super(name); - } - - public void deployApplication() { - deployCallBlocking(); - deployCallForwarding(); - } - - private void deployCallBlocking() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/call-blocking-servlet/src/main/sipapp", - "call-blocking-context", - "call-blocking")); - } - - private void deployCallForwarding() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", - "call-forwarding-b2bua-context", - "call-forwarding-b2bua")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/callcontroller/call-controller-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects = new ProtocolObjects("forward-sender", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - receiverProtocolObjects = new ProtocolObjects("forward-receiver", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - } - - public void testCancelCallForwarding() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, true); - receiver.setWaitForCancel(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(500); - sender.sendCancel(); - Thread.sleep(TIMEOUT); - assertTrue(sender.isCancelOkReceived()); - assertTrue(sender.isRequestTerminatedReceived()); - assertTrue(receiver.isCancelReceived()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite.callcontroller; + +import java.util.HashMap; +import java.util.Map; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class CallControllerCancelTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(CallControllerCancelTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 20000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + TestSipListener receiver; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + + public CallControllerCancelTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + public void deployApplication() { + + } + + private void deployCallBlocking(Map params) { + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-blocking-servlet/src/main/sipapp", + "call-blocking", + params, + null); + assertTrue(ctx.getAvailable()); + } + + private void deployCallForwarding(Map params) { + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + "call-forwarding-b2bua", + params, + null); + assertTrue(ctx.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/callcontroller/call-controller-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects("forward-sender", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects("forward-receiver", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + } + + public void testCancelCallForwarding() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, true); + receiver.setWaitForCancel(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployCallBlocking(params); + deployCallForwarding(params); + + String fromName = "forward-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(500); + sender.sendCancel(); + Thread.sleep(TIMEOUT); + assertTrue(sender.isCancelOkReceived()); + assertTrue(sender.isRequestTerminatedReceived()); + assertTrue(receiver.isCancelReceived()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/CallControllerJunitTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/CallControllerJunitTest.java index b641a6b87e..f9d5a90c1b 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/CallControllerJunitTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/CallControllerJunitTest.java @@ -1,210 +1,244 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.callcontroller; - -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class CallControllerJunitTest extends SipServletTestCase { - - private static final String TO_NAME = "receiver"; - private static final String FROM_NAME = "forward-sender"; - - private static final String FROM_DOMAIN = "sip-servlets.com"; - private String toDomain; - - private static transient Logger logger = Logger.getLogger(CallControllerJunitTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 30000; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender; - TestSipListener receiver; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - - public CallControllerJunitTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - deployCallBlocking(); - deployCallForwarding(); - } - - private void deployCallBlocking() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/call-blocking-servlet/src/main/sipapp", - "call-blocking-context", - "call-blocking")); - } - - private void deployCallForwarding() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", - "call-forwarding-b2bua-context", - "call-forwarding-b2bua")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/callcontroller/call-controller-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - autoDeployOnStartup = false; - super.setUp(); - toDomain = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090"; - senderProtocolObjects = new ProtocolObjects(FROM_NAME, - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - receiverProtocolObjects = new ProtocolObjects(TO_NAME, - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - } - - public void testCallForwardingCallerSendBye() throws Exception { - deployCallBlocking(); - deployCallForwarding(); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = FROM_NAME; - String fromSipAddress = FROM_DOMAIN; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = toDomain; - String toUser = TO_NAME; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); - Thread.sleep(TIMEOUT); - //checking numbers of ACK received see http://forums.java.net/jive/thread.jspa?messageID=277840 - assertEquals(1,receiver.ackCount); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - } - - public void testCallForwardingCalleeSendBye() throws Exception { - deployCallBlocking(); - deployCallForwarding(); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, true); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = FROM_NAME; - String fromSipAddress = toDomain; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = FROM_DOMAIN; - String toUser = TO_NAME; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getOkToByeReceived()); - assertTrue(sender.getByeReceived()); - } - - public void testCancelCallForwarding() throws Exception { - deployCallBlocking(); - deployCallForwarding(); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, true); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = FROM_NAME; - String fromSipAddress = FROM_DOMAIN; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = toDomain; - String toUser = TO_NAME; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); - Thread.sleep(500); - sender.sendCancel(); - Thread.sleep(TIMEOUT); - assertTrue(sender.isCancelOkReceived()); - assertTrue(sender.isRequestTerminatedReceived()); - assertTrue(receiver.isCancelReceived()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite.callcontroller; + +import java.util.HashMap; +import java.util.Map; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class CallControllerJunitTest extends SipServletTestCase { + + private static final String TO_NAME = "receiver"; + private static final String FROM_NAME = "forward-sender"; + + private static final String FROM_DOMAIN = "sip-servlets.com"; + private String toDomain; + + private static transient Logger logger = Logger.getLogger(CallControllerJunitTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 30000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + TestSipListener receiver; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + + public CallControllerJunitTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + private void deployCallBlocking(Map params) { + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-blocking-servlet/src/main/sipapp", + "call-blocking", + params, + null); + assertTrue(ctx.getAvailable()); + } + + private void deployCallForwarding(Map params) { + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + "call-forwarding-b2bua", + params, + null); + assertTrue(ctx.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/callcontroller/call-controller-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + autoDeployOnStartup = false; + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects(FROM_NAME, + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects(TO_NAME, + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + } + + public void testCallForwardingCallerSendBye() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + toDomain = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + receiverPort; + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployCallBlocking(params); + deployCallForwarding(params); + + String fromName = FROM_NAME; + String fromSipAddress = FROM_DOMAIN; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = toDomain; + String toUser = TO_NAME; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); + Thread.sleep(TIMEOUT); + //checking numbers of ACK received see http://forums.java.net/jive/thread.jspa?messageID=277840 + assertEquals(1,receiver.ackCount); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + } + + public void testCallForwardingCalleeSendBye() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, true); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + toDomain = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + receiverPort; + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployCallBlocking(params); + deployCallForwarding(params); + + String fromName = FROM_NAME; + String fromSipAddress = toDomain; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = FROM_DOMAIN; + String toUser = TO_NAME; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getOkToByeReceived()); + assertTrue(sender.getByeReceived()); + } + + public void testCancelCallForwarding() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, true); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + toDomain = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + receiverPort; + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployCallBlocking(params); + deployCallForwarding(params); + + String fromName = FROM_NAME; + String fromSipAddress = FROM_DOMAIN; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = toDomain; + String toUser = TO_NAME; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); + Thread.sleep(500); + sender.sendCancel(); + Thread.sleep(TIMEOUT); + assertTrue(sender.isCancelOkReceived()); + assertTrue(sender.isRequestTerminatedReceived()); + assertTrue(receiver.isCancelReceived()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/CallControllerSipUnitTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/CallControllerSipUnitTest.java index 837eecc7b4..4b15cd584e 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/CallControllerSipUnitTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/CallControllerSipUnitTest.java @@ -1,205 +1,231 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.callcontroller; - -import java.util.Properties; - -import javax.sip.message.Response; - -import org.apache.log4j.Logger; -import org.cafesip.sipunit.SipCall; -import org.cafesip.sipunit.SipPhone; -import org.cafesip.sipunit.SipStack; -import org.mobicents.servlet.sip.SipUnitServletTestCase; - -public class CallControllerSipUnitTest extends SipUnitServletTestCase { - - private static transient Logger logger = Logger.getLogger(CallControllerSipUnitTest.class); - - private SipStack sipStackSender; - private SipPhone sipPhoneSender; - - private SipStack sipStackReceiver; - private SipPhone sipPhoneReceiver; - - private static final int TIMEOUT = 30000; - private static final int TIMEOUT_FORBIDDEN = 40000; -// private static final int TIMEOUT = 1000000; - - public CallControllerSipUnitTest(String name) { - super(name); - } - - @Override - public void setUp() throws Exception { - autoDeployOnStartup = false; - super.setUp(); - } - - @Override - public void tearDown() throws Exception { - Thread.sleep(1000); - sipPhoneSender.dispose(); - sipPhoneReceiver.dispose(); - sipStackSender.dispose(); - sipStackReceiver.dispose(); - super.tearDown(); - } - - @Override - public void deployApplication() { - deployCallBlocking(); - deployCallForwarding(); - } - - private void deployCallBlocking() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/call-blocking-servlet/src/main/sipapp", - "call-blocking-context", - "call-blocking")); - } - - private void deployCallForwarding() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", - "call-forwarding-b2bua-context", - "call-forwarding-b2bua")); - } - - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/callcontroller/call-controller-servlet-dar.properties"; - } - - public SipStack makeStack(String transport, int port) throws Exception { - Properties properties = new Properties(); - String peerHostPort1 = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070"; - properties.setProperty("javax.sip.OUTBOUND_PROXY", peerHostPort1 + "/" - + "udp"); - properties.setProperty("javax.sip.STACK_NAME", "UAC_" + transport + "_" - + port); - properties.setProperty("sipunit.BINDADDR", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); - properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", - "logs/callforwarding_debug_" + port + ".txt"); - properties.setProperty("gov.nist.javax.sip.SERVER_LOG", - "logs/callforwarding_server_" + port + ".xml"); - properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "32"); - - return new SipStack(transport, port, properties); - } - - public void setupPhone(String fromAddress, String toAddress) { - try { - sipStackSender = makeStack(SipStack.PROTOCOL_UDP, 5080); - sipPhoneSender = sipStackSender.createSipPhone("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", - SipStack.PROTOCOL_UDP, 5070, fromAddress); - sipStackReceiver = makeStack(SipStack.PROTOCOL_UDP, 5090); - sipPhoneReceiver = sipStackReceiver.createSipPhone("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", - SipStack.PROTOCOL_UDP, 5070, toAddress); - } catch (Exception e) { - e.printStackTrace(); - } - } - - - // Check if we receive a FORBIDDEN response for our invite - public void testCallBlockingInvite() throws Exception { - deployCallBlocking(); - setupPhone("sip:blocked-sender@sip-servlets.com", "sip:receiver@sip-servlets.com"); - SipCall sender = sipPhoneSender.createSipCall(); - assertTrue(sender.initiateOutgoingCall("sip:receiver@sip-servlets.com", null)); - int trial = 0; - while(findResponse(sender, Response.FORBIDDEN) == null && trial < 5) { - assertTrue(sender.waitOutgoingCallResponse(TIMEOUT_FORBIDDEN)); - trial ++; - } - } - - // - public void testCallForwarding() throws Exception { - deployCallForwarding(); - setupPhone("sip:forward-sender@sip-servlets.com", "sip:forward-receiver@sip-servlets.com"); - - SipCall sender = sipPhoneSender.createSipCall(); - SipCall receiver = sipPhoneReceiver.createSipCall(); - - receiver.listenForIncomingCall(); - Thread.sleep(300); - sender.initiateOutgoingCall("sip:receiver@sip-servlets.com", null); - - assertTrue(receiver.waitForIncomingCall(TIMEOUT)); - assertTrue(receiver.sendIncomingCallResponse(Response.OK, "OK", 0)); - assertTrue(sender.waitOutgoingCallResponse(TIMEOUT)); - assertTrue(receiver.waitForAck(TIMEOUT)); - -// assertTrue(sender.sendInviteOkAck()); - sender.sendInviteOkAck(); - assertTrue(sender.disconnect()); - assertTrue(receiver.waitForDisconnect(TIMEOUT)); - assertTrue(receiver.respondToDisconnect()); - } - - // - public void testCallForwardingBothDeployed() throws Exception { - deployCallBlocking(); - deployCallForwarding(); - setupPhone("sip:forward-sender@sip-servlets.com", "sip:forward-receiver@sip-servlets.com"); - - SipCall sender = sipPhoneSender.createSipCall(); - SipCall receiver = sipPhoneReceiver.createSipCall(); - - receiver.listenForIncomingCall(); - Thread.sleep(300); - sender.initiateOutgoingCall("sip:receiver@sip-servlets.com", null); - - assertTrue(receiver.waitForIncomingCall(TIMEOUT)); - assertTrue(receiver.sendIncomingCallResponse(Response.OK, "OK", 0)); - assertTrue(receiver.waitForAck(TIMEOUT)); - assertTrue(sender.waitOutgoingCallResponse(TIMEOUT)); - //sipunit doesn't succeed to send the ACK since it tries to do it with - //Dialog.createRequest(Request.ACK) -// assertTrue(sender.sendInviteOkAck()); - sender.sendInviteOkAck(); - assertTrue(sender.disconnect()); - assertTrue(receiver.waitForDisconnect(TIMEOUT)); - assertTrue(receiver.respondToDisconnect()); - } - - // Check if we receive a FORBIDDEN response for our invite - public void testCallBlockingBothDeployed() throws Exception { - deployCallBlocking(); - deployCallForwarding(); - setupPhone("sip:blocked-sender@sip-servlets.com", "sip:receiver@sip-servlets.com"); - SipCall sender = sipPhoneSender.createSipCall(); - assertTrue(sender.initiateOutgoingCall("sip:receiver@sip-servlets.com", null)); - int trial = 0; - while(findResponse(sender, Response.FORBIDDEN) == null && trial < 5) { - assertTrue(sender.waitOutgoingCallResponse(TIMEOUT_FORBIDDEN)); - trial ++; - } - } -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.callcontroller; + +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import javax.sip.message.Response; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.cafesip.sipunit.SipCall; +import org.cafesip.sipunit.SipPhone; +import org.cafesip.sipunit.SipStack; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipUnitServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; + +public class CallControllerSipUnitTest extends SipUnitServletTestCase { + + private static transient Logger logger = Logger.getLogger(CallControllerSipUnitTest.class); + + private SipStack sipStackSender; + private SipPhone sipPhoneSender; + + private SipStack sipStackReceiver; + private SipPhone sipPhoneReceiver; + private int senderPort; + private int receiverPort; + + private static final int TIMEOUT = 30000; + private static final int TIMEOUT_FORBIDDEN = 40000; +// private static final int TIMEOUT = 1000000; + + public CallControllerSipUnitTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void setUp() throws Exception { + autoDeployOnStartup = false; + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + } + + @Override + public void tearDown() throws Exception { + Thread.sleep(1000); + sipPhoneSender.dispose(); + sipPhoneReceiver.dispose(); + sipStackSender.dispose(); + sipStackReceiver.dispose(); + super.tearDown(); + } + + @Override + public void deployApplication() { + } + + private void deployCallBlocking(Map params) { + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-blocking-servlet/src/main/sipapp", + "call-blocking", + params, + null); + assertTrue(ctx.getAvailable()); + } + + private void deployCallForwarding(Map params) { + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + "call-forwarding-b2bua", + params, + null); + assertTrue(ctx.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/callcontroller/call-controller-servlet-dar.properties"; + } + + public SipStack makeStack(String transport, int port) throws Exception { + Properties properties = new Properties(); + String peerHostPort1 = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + containerPort; + properties.setProperty("javax.sip.OUTBOUND_PROXY", peerHostPort1 + "/" + + "udp"); + properties.setProperty("javax.sip.STACK_NAME", "UAC_" + transport + "_" + + port); + properties.setProperty("sipunit.BINDADDR", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); + properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", + "target/logs/callforwarding_debug_" + port + ".txt"); + properties.setProperty("gov.nist.javax.sip.SERVER_LOG", + "target/logs/callforwarding_server_" + port + ".xml"); + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "32"); + + return new SipStack(transport, port, properties); + } + + public void setupPhone(String fromAddress, String toAddress) { + try { + senderPort = NetworkPortAssigner.retrieveNextPort(); + sipStackSender = makeStack(SipStack.PROTOCOL_UDP, senderPort); + sipPhoneSender = sipStackSender.createSipPhone("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", + SipStack.PROTOCOL_UDP, containerPort, fromAddress); + receiverPort = NetworkPortAssigner.retrieveNextPort(); + sipStackReceiver = makeStack(SipStack.PROTOCOL_UDP, receiverPort); + sipPhoneReceiver = sipStackReceiver.createSipPhone("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", + SipStack.PROTOCOL_UDP, containerPort, toAddress); + } catch (Exception e) { + e.printStackTrace(); + } + } + + // Check if we receive a FORBIDDEN response for our invite + public void testCallBlockingInvite() throws Exception { + setupPhone("sip:blocked-sender@sip-servlets.com", "sip:receiver@sip-servlets.com"); + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployCallBlocking(params); + SipCall sender = sipPhoneSender.createSipCall(); + assertTrue(sender.initiateOutgoingCall("sip:receiver@sip-servlets.com", null)); + int trial = 0; + while (findResponse(sender, Response.FORBIDDEN) == null && trial < 5) { + assertTrue(sender.waitOutgoingCallResponse(TIMEOUT_FORBIDDEN)); + trial++; + } + } + + // + public void testCallForwarding() throws Exception { + setupPhone("sip:forward-sender@sip-servlets.com", "sip:forward-receiver@sip-servlets.com"); + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployCallForwarding(params); + + SipCall sender = sipPhoneSender.createSipCall(); + SipCall receiver = sipPhoneReceiver.createSipCall(); + + receiver.listenForIncomingCall(); + Thread.sleep(300); + sender.initiateOutgoingCall("sip:receiver@sip-servlets.com", null); + + assertTrue(receiver.waitForIncomingCall(TIMEOUT)); + assertTrue(receiver.sendIncomingCallResponse(Response.OK, "OK", 0)); + assertTrue(sender.waitOutgoingCallResponse(TIMEOUT)); + assertTrue(receiver.waitForAck(TIMEOUT)); + +// assertTrue(sender.sendInviteOkAck()); + sender.sendInviteOkAck(); + assertTrue(sender.disconnect()); + assertTrue(receiver.waitForDisconnect(TIMEOUT)); + assertTrue(receiver.respondToDisconnect()); + } + + // + public void testCallForwardingBothDeployed() throws Exception { + setupPhone("sip:forward-sender@sip-servlets.com", "sip:forward-receiver@sip-servlets.com"); + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployCallBlocking(params); + deployCallForwarding(params); + + SipCall sender = sipPhoneSender.createSipCall(); + SipCall receiver = sipPhoneReceiver.createSipCall(); + + receiver.listenForIncomingCall(); + Thread.sleep(300); + sender.initiateOutgoingCall("sip:receiver@sip-servlets.com", null); + + assertTrue(receiver.waitForIncomingCall(TIMEOUT)); + assertTrue(receiver.sendIncomingCallResponse(Response.OK, "OK", 0)); + assertTrue(receiver.waitForAck(TIMEOUT)); + assertTrue(sender.waitOutgoingCallResponse(TIMEOUT)); + //sipunit doesn't succeed to send the ACK since it tries to do it with + //Dialog.createRequest(Request.ACK) +// assertTrue(sender.sendInviteOkAck()); + sender.sendInviteOkAck(); + assertTrue(sender.disconnect()); + assertTrue(receiver.waitForDisconnect(TIMEOUT)); + assertTrue(receiver.respondToDisconnect()); + } + + // Check if we receive a FORBIDDEN response for our invite + public void testCallBlockingBothDeployed() throws Exception { + setupPhone("sip:blocked-sender@sip-servlets.com", "sip:receiver@sip-servlets.com"); + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployCallBlocking(params); + deployCallForwarding(params); + SipCall sender = sipPhoneSender.createSipCall(); + assertTrue(sender.initiateOutgoingCall("sip:receiver@sip-servlets.com", null)); + int trial = 0; + while (findResponse(sender, Response.FORBIDDEN) == null && trial < 5) { + assertTrue(sender.waitOutgoingCallResponse(TIMEOUT_FORBIDDEN)); + trial++; + } + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/CallForwardingB2BUAJunitTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/CallForwardingB2BUAJunitTest.java index 006cec7f1d..58d2d4b59d 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/CallForwardingB2BUAJunitTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/CallForwardingB2BUAJunitTest.java @@ -1,707 +1,887 @@ -/* - * TeleStax, Open Source Cloud Communications Copyright 2012. - * and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ -package org.mobicents.servlet.sip.testsuite.callcontroller; - -import gov.nist.javax.sip.message.MessageExt; - -import java.util.Iterator; -import java.util.Properties; - -import javax.sip.ListeningPoint; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; -import javax.sip.message.Request; - -import org.apache.catalina.deploy.ApplicationParameter; -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.catalina.SipStandardService; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class CallForwardingB2BUAJunitTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(CallForwardingB2BUAJunitTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender; - TestSipListener receiver; - TestSipListener receiver2; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - ProtocolObjects receiver2ProtocolObjects; - - public CallForwardingB2BUAJunitTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName("checkOriginalRequestMapSize"); - applicationParameter.setValue("true"); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/callcontroller/call-forwarding-b2bua-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects = new ProtocolObjects("forward-sender", - "gov.nist", TRANSPORT, AUTODIALOG, null, "32", "true"); - receiverProtocolObjects = new ProtocolObjects("receiver", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - receiver2ProtocolObjects = new ProtocolObjects("receiver2", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - } - - public void testCallForwardingCallerSendBye() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - sender.setTimeToWaitBeforeBye(TIMEOUT*2); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isAckReceived()); - Thread.sleep(TIMEOUT*3); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertEquals(1, sender.getAllMessagesContent().size()); - assertTrue(sender.getAllMessagesContent().contains("sipApplicationSessionReadyToBeInvalidated")); - } - - public void testCallForwardingToItself() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-myself"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - sender.setTimeToWaitBeforeBye(TIMEOUT*2); - Thread.sleep(TIMEOUT*2); - assertTrue(receiver.isAckReceived()); - Thread.sleep(TIMEOUT*4); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertEquals(2, sender.getAllMessagesContent().size()); - assertTrue(sender.getAllMessagesContent().contains("sipApplicationSessionReadyToBeInvalidated")); - } - - /* - * non regression test for Issue 2419 - */ - public void testCallForwardingCallerSendByeLinkedRequest() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "useLinkedRequest"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - sender.setTimeToWaitBeforeBye(TIMEOUT*2); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isAckReceived()); - Thread.sleep(TIMEOUT*3); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertEquals(1, sender.getAllMessagesContent().size()); - assertTrue(sender.getAllMessagesContent().contains("sipApplicationSessionReadyToBeInvalidated")); - } - - public void testCallForwardingCallerSendByeUseSameCallID() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-sender-factory-same-callID"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setTimeToWaitBeforeBye(TIMEOUT*2); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isAckReceived()); - Thread.sleep(TIMEOUT*3); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertEquals(1, sender.getAllMessagesContent().size()); - assertTrue(sender.getAllMessagesContent().contains("sipApplicationSessionReadyToBeInvalidated")); - assertEquals(((MessageExt)sender.getInviteRequest()).getCallIdHeader().getCallId(), ((MessageExt)receiver.getInviteRequest()).getCallIdHeader().getCallId()); - } - - // Non regression test for http://code.google.com/p/sipservlets/issues/detail?id=126 - public void testCallForwardingCallerSendByeUseSameCallIDOriginalSessionTerminated() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-sender-factory-same-callID-kill-original-session"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - //receiver.setTimeToWaitBeforeBye(TIMEOUT*2); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isAckReceived()); - Thread.sleep(TIMEOUT*2); - assertTrue(receiver.getOkToByeReceived()); - - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertEquals(1, sender.getAllMessagesContent().size()); - assertTrue(sender.getAllMessagesContent().contains("sipApplicationSessionReadyToBeInvalidated")); - assertEquals(((MessageExt)sender.getInviteRequest()).getCallIdHeader().getCallId(), ((MessageExt)receiver.getInviteRequest()).getCallIdHeader().getCallId()); - } - - public void testCallForwardingCalleeSendBye() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - receiver.setTimeToWaitBeforeBye(TIMEOUT*2); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT*4); - assertTrue(receiver.getOkToByeReceived()); - assertTrue(sender.getByeReceived()); - } - - public void testCallForwardingCheckContact() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "checkContact"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setTimeToWaitBeforeBye(TIMEOUT*2); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[] {"Contact"}, new String[] {";+sip.instance=\"\""}, true); - Thread.sleep(TIMEOUT*3); - assertEquals(200, sender.getFinalResponseStatus()); - } - - public void testCancelCallForwarding() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - receiver.setWaitForCancel(true); - String fromName = "forward-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(1500); - sender.sendCancel(); - Thread.sleep(TIMEOUT); - assertTrue(sender.isCancelOkReceived()); - assertTrue(sender.isRequestTerminatedReceived()); - assertTrue(receiver.isCancelReceived()); - } - - public void testCallForwardingCallerSendByePendingMessages() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-pending-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setTimeToWaitBeforeAck(6000); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT*4); - assertTrue(sender.isAckSent()); - assertTrue(receiver.isAckReceived()); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - } - - public void testCallForwardingCallerUseSipFactory() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "factory-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setTimeToWaitBeforeBye(TIMEOUT*2); - sender.setTimeToWaitBeforeAck(6000); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT*4); - assertTrue(sender.isAckSent()); - assertTrue(receiver.isAckReceived()); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - } - - public void testCallForwardingUpdateCallerSendBye() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "testSipAppSessionReadyToBeInvalidated"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT * 3); - sender.sendInDialogSipRequest(Request.UPDATE, null, null, null, null, null); - sender.sendInDialogSipRequest(Request.UPDATE, null, null, null, null, null); - Thread.sleep(TIMEOUT * 4); - sender.sendInDialogSipRequest(Request.BYE, null, null, null, null, null); - Thread.sleep(TIMEOUT * 6); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertEquals(0, sender.getAllMessagesContent().size()); - } - - // non regression test for Issue 1550 http://code.google.com/p/mobicents/issues/detail?id=1550 - // IllegalStateException: Cannot create a response - not a server transaction gov.nist.javax.sip.stack.SIPClientTransaction - public void testCallForwardingLinkedRequestCallerSendBye() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "useLinkedRequest-pending"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT * 3); - assertEquals(200, sender.getFinalResponseStatus()); - sender.setFinalResponse(null); - sender.setFinalResponseStatus(-1); - sender.sendInDialogSipRequest(Request.UPDATE, null, null, null, null, null); - receiver.sendInDialogSipRequest(Request.UPDATE, null, null, null, null, null); - Thread.sleep(TIMEOUT * 4); - assertEquals(200, receiver.getFinalResponseStatus()); - assertEquals(200, sender.getFinalResponseStatus()); - sender.sendInDialogSipRequest(Request.BYE, null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - } - - // non regression test for issue 1716 http://code.google.com/p/mobicents/issues/detail?id=1716 - // The same response is routed to SipServlet twice - public void testCallForwardingCallerCheckRetransmissionIsNotAForkedResponse() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "factory-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setTimeToWaitBeforeBye(TIMEOUT*2); - sender.setTimeToWaitBeforeAck(4000); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[] {"Require"}, new String[] {"Nothing"}, false); - Thread.sleep(TIMEOUT*4); - assertTrue(sender.isAckSent()); - assertTrue(receiver.isAckReceived()); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - } - - - public void testCallForwardingCaller2ConnectorsPortIssue() throws Exception { - - senderProtocolObjects = new ProtocolObjects("forward-sender", - "gov.nist", ListeningPoint.TCP, AUTODIALOG, null, "32", "true"); - receiverProtocolObjects = new ProtocolObjects("receiver", - "gov.nist", ListeningPoint.TCP, AUTODIALOG, null, null, null); - - sender = new TestSipListener(5080, 5071, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - tomcat.removeConnector(sipConnector); - - tomcat.addSipConnector(serverName, sipIpAddress, 5071, ListeningPoint.TCP); - tomcat.addSipConnector(serverName, sipIpAddress, 5070, ListeningPoint.TCP); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "2-connectors-port-issue-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "2-connectors-port-issue-receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("REGISTER", fromAddress, fromAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertEquals(200, sender.getFinalResponseStatus()); - - receiver.sendSipRequest("REGISTER", toAddress, toAddress, null, null, false); - sender.setTimeToWaitBeforeBye(TIMEOUT*2); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckReceived()); - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - } - - /* - * Non regression test for https://github.com/Mobicents/sip-servlets/issues/56 - */ - public void testCallForwardingCallerReInvite3rdLeg() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - - receiver2 = new TestSipListener(5091, 5070, receiver2ProtocolObjects, false); - SipProvider receiver2Provider = receiver2.createProvider(); - - receiverProvider.addSipListener(receiver); - receiver2Provider.addSipListener(receiver2); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - receiver2ProtocolObjects.start(); - - String fromName = "forward-sender-3rd-leg-factory"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - sender.setTimeToWaitBeforeBye(TIMEOUT*2); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isAckReceived()); - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertTrue(receiver2.isAckReceived()); - Thread.sleep(TIMEOUT*3); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver2.getByeReceived()); -// Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); -// while (allMessagesIterator.hasNext()) { -// String message = (String) allMessagesIterator.next(); -// logger.info(message); -// } -// assertEquals(1, sender.getAllMessagesContent().size()); -// assertTrue(sender.getAllMessagesContent().contains("sipApplicationSessionReadyToBeInvalidated")); - } - - @Override - protected Properties getSipStackProperties() { - Properties sipStackProperties = new Properties(); - sipStackProperties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", - "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", - "32"); - sipStackProperties.setProperty(SipStandardService.DEBUG_LOG_STACK_PROP, - tomcatBasePath + "/" + "mss-jsip-" + getName() +"-debug.txt"); - sipStackProperties.setProperty(SipStandardService.SERVER_LOG_STACK_PROP, - tomcatBasePath + "/" + "mss-jsip-" + getName() +"-messages.xml"); - sipStackProperties.setProperty("javax.sip.STACK_NAME", "mss-" + getName()); - sipStackProperties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", "off"); - sipStackProperties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.THREAD_POOL_SIZE", "64"); - sipStackProperties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.MAX_FORK_TIME_SECONDS", "1"); - sipStackProperties.setProperty(SipStandardService.LOOSE_DIALOG_VALIDATION, "true"); - sipStackProperties.setProperty(SipStandardService.PASS_INVITE_NON_2XX_ACK_TO_LISTENER, "true"); - return sipStackProperties; - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - receiver2ProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * TeleStax, Open Source Cloud Communications Copyright 2012. + * and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.callcontroller; + +import gov.nist.javax.sip.message.MessageExt; +import java.util.HashMap; + +import java.util.Iterator; +import java.util.Map; +import java.util.Properties; + +import javax.sip.ListeningPoint; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import javax.sip.message.Request; +import static junit.framework.Assert.assertTrue; + +import org.apache.catalina.deploy.ApplicationParameter; +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.catalina.SipStandardManager; +import org.mobicents.servlet.sip.catalina.SipStandardService; +import org.mobicents.servlet.sip.startup.SipContextConfig; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class CallForwardingB2BUAJunitTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(CallForwardingB2BUAJunitTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + TestSipListener receiver; + TestSipListener receiver2; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + ProtocolObjects receiver2ProtocolObjects; + + public CallForwardingB2BUAJunitTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + SipStandardContext context = new SipStandardContext(); + context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp"); + context.setName("sip-test-context"); + context.setPath("sip-test"); + context.addLifecycleListener(new SipContextConfig()); + context.setManager(new SipStandardManager()); + ApplicationParameter applicationParameter = new ApplicationParameter(); + applicationParameter.setName("checkOriginalRequestMapSize"); + applicationParameter.setValue("true"); + context.addApplicationParameter(applicationParameter); + assertTrue(tomcat.deployContext(context)); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/callcontroller/call-forwarding-b2bua-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects("forward-sender", + "gov.nist", TRANSPORT, AUTODIALOG, null, "32", "true"); + receiverProtocolObjects = new ProtocolObjects("receiver", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + receiver2ProtocolObjects = new ProtocolObjects("receiver2", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + } + + public void testCallForwardingCallerSendBye() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params, null); + assertTrue(ctx.getAvailable()); + + String fromName = "forward-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + sender.setTimeToWaitBeforeBye(TIMEOUT * 2); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isAckReceived()); + Thread.sleep(TIMEOUT * 4); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertEquals(1, sender.getAllMessagesContent().size()); + assertTrue(sender.getAllMessagesContent().contains("sipApplicationSessionReadyToBeInvalidated")); + } + + public void testCallForwardingToItself() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params, null); + assertTrue(ctx.getAvailable()); + + String fromName = "forward-myself"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + sender.setTimeToWaitBeforeBye(TIMEOUT * 2); + Thread.sleep(TIMEOUT * 2); + assertTrue(receiver.isAckReceived()); + Thread.sleep(TIMEOUT * 4); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertEquals(2, sender.getAllMessagesContent().size()); + assertTrue(sender.getAllMessagesContent().contains("sipApplicationSessionReadyToBeInvalidated")); + } + + /* + * non regression test for Issue 2419 + */ + public void testCallForwardingCallerSendByeLinkedRequest() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params, null); + assertTrue(ctx.getAvailable()); + + String fromName = "forward-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "useLinkedRequest"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + sender.setTimeToWaitBeforeBye(TIMEOUT * 2); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isAckReceived()); + Thread.sleep(TIMEOUT * 3); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertEquals(1, sender.getAllMessagesContent().size()); + assertTrue(sender.getAllMessagesContent().contains("sipApplicationSessionReadyToBeInvalidated")); + } + + public void testCallForwardingCallerSendByeUseSameCallID() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params, null); + assertTrue(ctx.getAvailable()); + + + String fromName = "forward-sender-factory-same-callID"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setTimeToWaitBeforeBye(TIMEOUT * 2); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isAckReceived()); + Thread.sleep(TIMEOUT * 3); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertEquals(1, sender.getAllMessagesContent().size()); + assertTrue(sender.getAllMessagesContent().contains("sipApplicationSessionReadyToBeInvalidated")); + assertEquals(((MessageExt) sender.getInviteRequest()).getCallIdHeader().getCallId(), ((MessageExt) receiver.getInviteRequest()).getCallIdHeader().getCallId()); + } + + // Non regression test for http://code.google.com/p/sipservlets/issues/detail?id=126 + public void testCallForwardingCallerSendByeUseSameCallIDOriginalSessionTerminated() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, true); + SipProvider receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params, null); + assertTrue(ctx.getAvailable()); + + + String fromName = "forward-sender-factory-same-callID-kill-original-session"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + //receiver.setTimeToWaitBeforeBye(TIMEOUT*2); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isAckReceived()); + Thread.sleep(TIMEOUT * 2); + assertTrue(receiver.getOkToByeReceived()); + + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertEquals(1, sender.getAllMessagesContent().size()); + assertTrue(sender.getAllMessagesContent().contains("sipApplicationSessionReadyToBeInvalidated")); + assertEquals(((MessageExt) sender.getInviteRequest()).getCallIdHeader().getCallId(), ((MessageExt) receiver.getInviteRequest()).getCallIdHeader().getCallId()); + } + + public void testCallForwardingCalleeSendBye() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, true); + SipProvider receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params, null); + assertTrue(ctx.getAvailable()); + + + String fromName = "forward-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + receiver.setTimeToWaitBeforeBye(TIMEOUT * 2); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT * 4); + assertTrue(receiver.getOkToByeReceived()); + assertTrue(sender.getByeReceived()); + } + + public void testCallForwardingCheckContact() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params, null); + assertTrue(ctx.getAvailable()); + + + String fromName = "forward-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "checkContact"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setTimeToWaitBeforeBye(TIMEOUT * 2); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[]{"Contact"}, new String[]{";+sip.instance=\"\""}, true); + Thread.sleep(TIMEOUT * 3); + assertEquals(200, sender.getFinalResponseStatus()); + } + + public void testCancelCallForwarding() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params, null); + assertTrue(ctx.getAvailable()); + + + receiver.setWaitForCancel(true); + String fromName = "forward-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(1500); + sender.sendCancel(); + Thread.sleep(TIMEOUT); + assertTrue(sender.isCancelOkReceived()); + assertTrue(sender.isRequestTerminatedReceived()); + assertTrue(receiver.isCancelReceived()); + } + + public void testCallForwardingCallerSendByePendingMessages() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params, null); + assertTrue(ctx.getAvailable()); + + + String fromName = "forward-pending-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setTimeToWaitBeforeAck(6000); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT * 4); + assertTrue(sender.isAckSent()); + assertTrue(receiver.isAckReceived()); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + } + + public void testCallForwardingCallerUseSipFactory() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params, null); + assertTrue(ctx.getAvailable()); + + + String fromName = "factory-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setTimeToWaitBeforeBye(TIMEOUT * 2); + sender.setTimeToWaitBeforeAck(6000); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT * 4); + assertTrue(sender.isAckSent()); + assertTrue(receiver.isAckReceived()); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + } + + public void testCallForwardingUpdateCallerSendBye() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params, null); + assertTrue(ctx.getAvailable()); + + + String fromName = "forward-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "testSipAppSessionReadyToBeInvalidated"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT * 3); + sender.sendInDialogSipRequest(Request.UPDATE, null, null, null, null, null); + sender.sendInDialogSipRequest(Request.UPDATE, null, null, null, null, null); + Thread.sleep(TIMEOUT * 4); + sender.sendInDialogSipRequest(Request.BYE, null, null, null, null, null); + Thread.sleep(TIMEOUT * 6); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertEquals(0, sender.getAllMessagesContent().size()); + } + + // non regression test for Issue 1550 http://code.google.com/p/mobicents/issues/detail?id=1550 + // IllegalStateException: Cannot create a response - not a server transaction gov.nist.javax.sip.stack.SIPClientTransaction + public void testCallForwardingLinkedRequestCallerSendBye() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params, null); + assertTrue(ctx.getAvailable()); + + + String fromName = "forward-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "useLinkedRequest-pending"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT * 3); + assertEquals(200, sender.getFinalResponseStatus()); + sender.setFinalResponse(null); + sender.setFinalResponseStatus(-1); + sender.sendInDialogSipRequest(Request.UPDATE, null, null, null, null, null); + receiver.sendInDialogSipRequest(Request.UPDATE, null, null, null, null, null); + Thread.sleep(TIMEOUT * 4); + assertEquals(200, receiver.getFinalResponseStatus()); + assertEquals(200, sender.getFinalResponseStatus()); + sender.sendInDialogSipRequest(Request.BYE, null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + } + + // non regression test for issue 1716 http://code.google.com/p/mobicents/issues/detail?id=1716 + // The same response is routed to SipServlet twice + public void testCallForwardingCallerCheckRetransmissionIsNotAForkedResponse() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params, null); + assertTrue(ctx.getAvailable()); + + + String fromName = "factory-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setTimeToWaitBeforeBye(TIMEOUT * 2); + sender.setTimeToWaitBeforeAck(4000); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[]{"Require"}, new String[]{"Nothing"}, false); + Thread.sleep(TIMEOUT * 4); + assertTrue(sender.isAckSent()); + assertTrue(receiver.isAckReceived()); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + } + + public void testCallForwardingCaller2ConnectorsPortIssue() throws Exception { + + senderProtocolObjects = new ProtocolObjects("forward-sender", + "gov.nist", ListeningPoint.TCP, AUTODIALOG, null, "32", "true"); + receiverProtocolObjects = new ProtocolObjects("receiver", + "gov.nist", ListeningPoint.TCP, AUTODIALOG, null, null, null); + + int cont2Port = NetworkPortAssigner.retrieveNextPort(); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, cont2Port, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + tomcat.removeConnector(sipConnector); + + tomcat.addSipConnector(serverName, sipIpAddress, cont2Port, ListeningPoint.TCP); + tomcat.addSipConnector(serverName, sipIpAddress, containerPort, ListeningPoint.TCP); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params, null); + assertTrue(ctx.getAvailable()); + + + String fromName = "2-connectors-port-issue-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "2-connectors-port-issue-receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("REGISTER", fromAddress, fromAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertEquals(200, sender.getFinalResponseStatus()); + + receiver.sendSipRequest("REGISTER", toAddress, toAddress, null, null, false); + sender.setTimeToWaitBeforeBye(TIMEOUT * 2); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckReceived()); + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + } + + /* + * Non regression test for https://github.com/Mobicents/sip-servlets/issues/56 + */ + public void testCallForwardingCallerReInvite3rdLeg() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + int receiver2Port = NetworkPortAssigner.retrieveNextPort(); + receiver2 = new TestSipListener(receiver2Port, containerPort, receiver2ProtocolObjects, false); + SipProvider receiver2Provider = receiver2.createProvider(); + + receiverProvider.addSipListener(receiver); + receiver2Provider.addSipListener(receiver2); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + receiver2ProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params, null); + assertTrue(ctx.getAvailable()); + + + String fromName = "forward-sender-3rd-leg-factory"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + sender.setTimeToWaitBeforeBye(TIMEOUT * 2); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isAckReceived()); + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver2.isAckReceived()); + Thread.sleep(TIMEOUT * 3); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver2.getByeReceived()); +// Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); +// while (allMessagesIterator.hasNext()) { +// String message = (String) allMessagesIterator.next(); +// logger.info(message); +// } +// assertEquals(1, sender.getAllMessagesContent().size()); +// assertTrue(sender.getAllMessagesContent().contains("sipApplicationSessionReadyToBeInvalidated")); + } + + @Override + protected Properties getSipStackProperties() { + Properties sipStackProperties = new Properties(); + sipStackProperties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", + "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", + "32"); + sipStackProperties.setProperty(SipStandardService.DEBUG_LOG_STACK_PROP, + tomcatBasePath + "/" + "mss-jsip-" + getName() + "-debug.txt"); + sipStackProperties.setProperty(SipStandardService.SERVER_LOG_STACK_PROP, + tomcatBasePath + "/" + "mss-jsip-" + getName() + "-messages.xml"); + sipStackProperties.setProperty("javax.sip.STACK_NAME", "mss-" + getName()); + sipStackProperties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", "off"); + sipStackProperties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.THREAD_POOL_SIZE", "64"); + sipStackProperties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.MAX_FORK_TIME_SECONDS", "1"); + sipStackProperties.setProperty(SipStandardService.LOOSE_DIALOG_VALIDATION, "true"); + sipStackProperties.setProperty(SipStandardService.PASS_INVITE_NON_2XX_ACK_TO_LISTENER, "true"); + return sipStackProperties; + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + receiver2ProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/CallForwardingJunitTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/CallForwardingJunitTest.java index e9a5d47ffa..4a207db1dd 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/CallForwardingJunitTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/CallForwardingJunitTest.java @@ -1,119 +1,134 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.callcontroller; - -import java.text.ParseException; - -import javax.sip.InvalidArgumentException; -import javax.sip.SipException; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class CallForwardingJunitTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(CallForwardingJunitTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender; - TestSipListener receiver; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - - public CallForwardingJunitTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/call-forwarding-servlet/src/main/sipapp", - "sip-test-context", - "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/callcontroller/call-forwarding-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects = new ProtocolObjects("forward-sender", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - receiverProtocolObjects = new ProtocolObjects("receiver", "gov.nist", - TRANSPORT, AUTODIALOG, null, null, null); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, -1, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - } - - public void testCallForwarding() throws InterruptedException, ParseException, SipException, InvalidArgumentException { - String fromName = "forward-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.callcontroller; + +import java.text.ParseException; +import java.util.HashMap; +import java.util.Map; + +import javax.sip.InvalidArgumentException; +import javax.sip.SipException; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class CallForwardingJunitTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(CallForwardingJunitTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + TestSipListener receiver; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + + public CallForwardingJunitTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + assertTrue(tomcat.deployContext( + projectHome + "/sip-servlets-test-suite/applications/call-forwarding-servlet/src/main/sipapp", + "sip-test-context", + "sip-test")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/callcontroller/call-forwarding-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects("forward-sender", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects("receiver", "gov.nist", + TRANSPORT, AUTODIALOG, null, null, null); + + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-servlet/src/main/sipapp", + params, null); + assertTrue(ctx.getAvailable()); + } + + public void testCallForwarding() throws InterruptedException, ParseException, SipException, InvalidArgumentException { + String fromName = "forward-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/CallForwardingSipUnitTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/CallForwardingSipUnitTest.java index bd3a5d5f0a..cb66a48930 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/CallForwardingSipUnitTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/CallForwardingSipUnitTest.java @@ -1,137 +1,152 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.callcontroller; - -import java.util.Properties; - -import javax.sip.message.Response; - -import org.apache.log4j.Logger; -import org.cafesip.sipunit.SipCall; -import org.cafesip.sipunit.SipPhone; -import org.cafesip.sipunit.SipStack; -import org.mobicents.servlet.sip.SipServletTestCase; - -public class CallForwardingSipUnitTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(CallForwardingSipUnitTest.class); - - private SipStack sipStackSender; - private SipPhone sipPhoneSender; - - private SipStack sipStackReceiver; - private SipPhone sipPhoneReceiver; - - private static final int TIMEOUT = 5000; -// private static final int TIMEOUT = 1000000; - - public CallForwardingSipUnitTest(String name) { - super(name); - } - - @Override - public void setUp() throws Exception { - super.setUp(); - SipStack.setTraceEnabled(true); - } - - @Override - public void tearDown() throws Exception { - sipPhoneSender.dispose(); - sipStackSender.dispose(); - sipPhoneReceiver.dispose(); - sipStackReceiver.dispose(); - super.tearDown(); - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", - "sip-test-context", - "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/callcontroller/call-forwarding-b2bua-servlet-dar.properties"; - } - - public SipStack makeStack(String transport, int port) throws Exception { - Properties properties = new Properties(); - String peerHostPort1 = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070"; - properties.setProperty("javax.sip.OUTBOUND_PROXY", peerHostPort1 + "/" - + "udp"); - properties.setProperty("javax.sip.STACK_NAME", "UAC_" + transport + "_" - + port); - properties.setProperty("sipunit.BINDADDR", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); - properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", - "logs/callforwarding_debug_" + port + ".txt"); - properties.setProperty("gov.nist.javax.sip.SERVER_LOG", - "logs/callforwarding_server_" + port + ".txt"); - properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", - "32"); - - return new SipStack(transport, port, properties); - } - - public void setupPhone() throws Exception { - sipStackSender = makeStack(SipStack.PROTOCOL_UDP, 5080); - sipPhoneSender = sipStackSender.createSipPhone("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", - SipStack.PROTOCOL_UDP, 5070, "sip:forward-sender@sip-servlets.com"); - sipStackReceiver = makeStack(SipStack.PROTOCOL_UDP, 5090); - sipPhoneReceiver = sipStackReceiver.createSipPhone("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", - SipStack.PROTOCOL_UDP, 5070, "sip:forward-receiver@sip-servlets.com"); - } - - public void init() throws Exception { - setupPhone(); - } - - // Check if we receive the forwarded call for our invite - public void testCallForwarding() throws Exception { - init(); - - SipCall sender = sipPhoneSender.createSipCall(); - SipCall receiver = sipPhoneReceiver.createSipCall(); - - receiver.listenForIncomingCall(); - Thread.sleep(300); - sender.initiateOutgoingCall("sip:receiver@sip-servlets.com", null); - - assertTrue(receiver.waitForIncomingCall(TIMEOUT)); - assertTrue(receiver.sendIncomingCallResponse(Response.OK, "OK", 0)); - assertTrue(sender.waitOutgoingCallResponse(TIMEOUT)); - assertTrue(receiver.waitForAck(TIMEOUT)); - //sipunit doesn't succeed to send the ACK since it tries to do it with - //Dialog.createRequest(Request.ACK) - //assertTrue(sender.sendInviteOkAck()); - sender.sendInviteOkAck(); - assertTrue(sender.disconnect()); - assertTrue(receiver.waitForDisconnect(TIMEOUT)); - assertTrue(receiver.respondToDisconnect()); - } -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite.callcontroller; + +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import javax.sip.message.Response; + +import org.apache.log4j.Logger; +import org.cafesip.sipunit.SipCall; +import org.cafesip.sipunit.SipPhone; +import org.cafesip.sipunit.SipStack; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; + +public class CallForwardingSipUnitTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(CallForwardingSipUnitTest.class); + + private SipStack sipStackSender; + private SipPhone sipPhoneSender; + + private SipStack sipStackReceiver; + private SipPhone sipPhoneReceiver; + + private static final int TIMEOUT = 5000; +// private static final int TIMEOUT = 1000000; + + public CallForwardingSipUnitTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + SipStack.setTraceEnabled(true); + } + + @Override + public void tearDown() throws Exception { + sipPhoneSender.dispose(); + sipStackSender.dispose(); + sipPhoneReceiver.dispose(); + sipStackReceiver.dispose(); + super.tearDown(); + } + + @Override + public void deployApplication() { + assertTrue(tomcat.deployContext( + projectHome + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + "sip-test-context", + "sip-test")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/callcontroller/call-forwarding-b2bua-servlet-dar.properties"; + } + + public SipStack makeStack(String transport, int port) throws Exception { + Properties properties = new Properties(); + String peerHostPort1 = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + containerPort; + properties.setProperty("javax.sip.OUTBOUND_PROXY", peerHostPort1 + "/" + + "udp"); + properties.setProperty("javax.sip.STACK_NAME", "UAC_" + transport + "_" + + port); + properties.setProperty("sipunit.BINDADDR", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); + properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", + "target/logs/callforwarding_debug_" + port + ".txt"); + properties.setProperty("gov.nist.javax.sip.SERVER_LOG", + "target/logs/callforwarding_server_" + port + ".txt"); + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", + "32"); + + return new SipStack(transport, port, properties); + } + + public void setupPhone() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sipStackSender = makeStack(SipStack.PROTOCOL_UDP, senderPort); + sipPhoneSender = sipStackSender.createSipPhone("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", + SipStack.PROTOCOL_UDP, containerPort, "sip:forward-sender@sip-servlets.com"); + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + sipStackReceiver = makeStack(SipStack.PROTOCOL_UDP, receiverPort); + sipPhoneReceiver = sipStackReceiver.createSipPhone("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", + SipStack.PROTOCOL_UDP, containerPort, "sip:forward-receiver@sip-servlets.com"); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params, null); + } + + public void init() throws Exception { + setupPhone(); + } + + // Check if we receive the forwarded call for our invite + public void testCallForwarding() throws Exception { + init(); + + SipCall sender = sipPhoneSender.createSipCall(); + SipCall receiver = sipPhoneReceiver.createSipCall(); + + receiver.listenForIncomingCall(); + Thread.sleep(300); + sender.initiateOutgoingCall("sip:receiver@sip-servlets.com", null); + + assertTrue(receiver.waitForIncomingCall(TIMEOUT)); + assertTrue(receiver.sendIncomingCallResponse(Response.OK, "OK", 0)); + assertTrue(sender.waitOutgoingCallResponse(TIMEOUT)); + assertTrue(receiver.waitForAck(TIMEOUT)); + //sipunit doesn't succeed to send the ACK since it tries to do it with + //Dialog.createRequest(Request.ACK) + //assertTrue(sender.sendInviteOkAck()); + sender.sendInviteOkAck(); + assertTrue(sender.disconnect()); + assertTrue(receiver.waitForDisconnect(TIMEOUT)); + assertTrue(receiver.respondToDisconnect()); + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/MultiHomeB2BUATest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/MultiHomeB2BUATest.java index b3ad47c95c..65ae03491f 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/MultiHomeB2BUATest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/callcontroller/MultiHomeB2BUATest.java @@ -1,180 +1,218 @@ -/* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2014, Telestax Inc and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - */ - - -package org.mobicents.servlet.sip.testsuite.callcontroller; - -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class MultiHomeB2BUATest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(MultiHomeB2BUATest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender; - TestSipListener receiver; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - - public MultiHomeB2BUATest(String name) { - super(name); - this.sipIpAddress = "0.0.0.0"; - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", - "sip-test-context", - "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/callcontroller/call-forwarding-b2bua-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects = new ProtocolObjects("forward-sender", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - receiverProtocolObjects = new ProtocolObjects("receiver", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - } - - public void testCallForwardingCallerSendBye() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - } - - public void testCallForwardingCalleeSendBye() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getOkToByeReceived()); - assertTrue(sender.getByeReceived()); - } - - /* - * https://code.google.com/p/sipservlets/issues/detail?id=267 - */ - public void testCancelCallForwarding() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - receiver.setWaitForCancel(true); - String fromName = "forward-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(1500); - sender.sendCancel(); - Thread.sleep(TIMEOUT); - assertTrue(sender.isCancelOkReceived()); - assertTrue(sender.isRequestTerminatedReceived()); - assertTrue(receiver.isCancelReceived()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2014, Telestax Inc and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + */ + + +package org.mobicents.servlet.sip.testsuite.callcontroller; + +import java.util.HashMap; +import java.util.Map; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class MultiHomeB2BUATest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(MultiHomeB2BUATest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + TestSipListener receiver; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + + public MultiHomeB2BUATest(String name) { + super(name); + this.sipIpAddress = "0.0.0.0"; + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + assertTrue(tomcat.deployContext( + projectHome + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + "sip-test-context", + "sip-test")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/callcontroller/call-forwarding-b2bua-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects("forward-sender", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects("receiver", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + } + + public void testCallForwardingCallerSendBye() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(receiverPort)); + params.put( "senderPort", String.valueOf(senderPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params + , null); + + String fromName = "forward-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + } + + public void testCallForwardingCalleeSendBye() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(receiverPort)); + params.put( "senderPort", String.valueOf(senderPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params + , null); + + String fromName = "forward-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getOkToByeReceived()); + assertTrue(sender.getByeReceived()); + } + + /* + * https://code.google.com/p/sipservlets/issues/detail?id=267 + */ + public void testCancelCallForwarding() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(receiverPort)); + params.put( "senderPort", String.valueOf(senderPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params + , null); + + receiver.setWaitForCancel(true); + String fromName = "forward-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(1500); + sender.sendCancel(); + Thread.sleep(TIMEOUT); + assertTrue(sender.isCancelOkReceived()); + assertTrue(sender.isRequestTerminatedReceived()); + assertTrue(receiver.isCancelReceived()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/click2call/Click2CallBasicTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/click2call/Click2CallBasicTest.java index 1de5fd1879..369e87e8c4 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/click2call/Click2CallBasicTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/click2call/Click2CallBasicTest.java @@ -23,15 +23,19 @@ import java.io.InputStream; import java.net.URL; +import java.util.HashMap; +import java.util.Map; import java.util.Properties; import javax.sip.message.Response; import org.apache.catalina.Wrapper; +import org.apache.catalina.deploy.ApplicationParameter; import org.apache.log4j.Logger; import org.cafesip.sipunit.SipCall; import org.cafesip.sipunit.SipPhone; import org.cafesip.sipunit.SipStack; +import org.mobicents.servlet.sip.NetworkPortAssigner; import org.mobicents.servlet.sip.SipServletTestCase; import org.mobicents.servlet.sip.catalina.SipStandardManager; import org.mobicents.servlet.sip.startup.SipContextConfig; @@ -61,16 +65,17 @@ public class Click2CallBasicTest extends SipServletTestCase { public Click2CallBasicTest(String name) { super(name); + autoDeployOnStartup = false; } @Override public void setUp() throws Exception { if (firstTime) { + containerPort = NetworkPortAssigner.retrieveNextPort(); super.setUp(); - CLICK2DIAL_URL = "http://" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":8080/click2call/call"; - RESOURCE_LEAK_URL = "http://" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":8080/click2call/index.html"; + CLICK2DIAL_URL = "http://" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + httpContainerPort + "/click2call/call"; + RESOURCE_LEAK_URL = "http://" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + httpContainerPort+"/click2call/index.html"; EXPIRATION_TIME_PARAMS = "?expirationTime"; - CLICK2DIAL_PARAMS = "?from=sip:from@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5056&to=sip:to@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5057"; } firstTime = true; } @@ -98,12 +103,22 @@ public void tearDown() throws Exception { @Override public void deployApplication() { - + } + + public SipStandardContext deployApplication(Map params) { context = new SipStandardContext(); context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/click-to-call-servlet/src/main/sipapp"); context.setName("click2call-context"); context.setPath("/click2call"); context.addLifecycleListener(new SipContextConfig()); + if (params != null) { + for (Map.Entry param : params.entrySet()) { + ApplicationParameter applicationParameter = new ApplicationParameter(); + applicationParameter.setName(param.getKey()); + applicationParameter.setValue(param.getValue()); + context.addApplicationParameter(applicationParameter); + } + } manager = new SipStandardManager(); context.setManager(manager); @@ -118,6 +133,8 @@ public void deployApplication() { context.addServletMapping("/", "default"); assertTrue(tomcat.deployContext(context)); + + return context; } @Override @@ -130,16 +147,16 @@ protected String getDarConfigurationFile() { public SipStack makeStack(String transport, int port) throws Exception { Properties properties = new Properties(); - String peerHostPort1 = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070"; + String peerHostPort1 = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + containerPort; properties.setProperty("javax.sip.OUTBOUND_PROXY", peerHostPort1 + "/" + "udp"); properties.setProperty("javax.sip.STACK_NAME", "UAC_" + transport + "_" + port); properties.setProperty("sipunit.BINDADDR", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", - "logs/simplesipservlettest_debug_port" + port + ".txt"); + "target/logs/simplesipservlettest_debug_port" + port + ".txt"); properties.setProperty("gov.nist.javax.sip.SERVER_LOG", - "logs/simplesipservlettest_log_port" + port + ".xml"); + "target/logs/simplesipservlettest_log_port" + port + ".xml"); properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "32"); return new SipStack(transport, port, properties); @@ -149,13 +166,22 @@ public void setupPhones() throws Exception { sipStackReceivers = new SipStack[receiversCount]; sipPhoneReceivers = new SipPhone[receiversCount]; - sipStackReceivers[0] = makeStack(SipStack.PROTOCOL_UDP, 5057); + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + sipStackReceivers[0] = makeStack(SipStack.PROTOCOL_UDP, receiverPort); sipPhoneReceivers[0] = sipStackReceivers[0].createSipPhone("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", - SipStack.PROTOCOL_UDP, 5070, "sip:to@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); + SipStack.PROTOCOL_UDP, containerPort, "sip:to@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); - sipStackReceivers[1] = makeStack(SipStack.PROTOCOL_UDP, 5056); + int receiver2Port = NetworkPortAssigner.retrieveNextPort(); + sipStackReceivers[1] = makeStack(SipStack.PROTOCOL_UDP, receiver2Port); sipPhoneReceivers[1] = sipStackReceivers[1].createSipPhone("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", - SipStack.PROTOCOL_UDP, 5070, "sip:from@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); + SipStack.PROTOCOL_UDP, containerPort, "sip:from@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); + + CLICK2DIAL_PARAMS = "?from=sip:from@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + receiver2Port + "&to=sip:to@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + receiverPort; + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(receiver2Port)); + deployApplication(params); } public void init() throws Exception { @@ -216,7 +242,7 @@ public void testClickToCallNoConvergedSession() */ public void testClickToCallHttpSessionLeak() throws Exception { - + deployApplication(new HashMap()); final int sessionsNumber = manager.getActiveSessions(); logger.info("Trying to reach url : " + RESOURCE_LEAK_URL); @@ -241,7 +267,7 @@ public void testClickToCallHttpSessionLeak() */ public void testClickToCallExpirationTime() throws Exception { - + deployApplication(new HashMap()); logger.info("Trying to reach url : " + CLICK2DIAL_URL + EXPIRATION_TIME_PARAMS); URL url = new URL(CLICK2DIAL_URL + EXPIRATION_TIME_PARAMS); diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/ApplicationRouterDirectionOptionalParameterTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/ApplicationRouterDirectionOptionalParameterTest.java index 8f68ded53b..f0a23dba30 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/ApplicationRouterDirectionOptionalParameterTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/ApplicationRouterDirectionOptionalParameterTest.java @@ -19,11 +19,12 @@ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ - package org.mobicents.servlet.sip.testsuite.composition; import java.io.InputStream; import java.net.URL; +import java.util.HashMap; +import java.util.Map; import java.util.Properties; import javax.sip.message.Response; @@ -32,152 +33,172 @@ import org.cafesip.sipunit.SipCall; import org.cafesip.sipunit.SipPhone; import org.cafesip.sipunit.SipStack; +import org.mobicents.servlet.sip.NetworkPortAssigner; import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; public class ApplicationRouterDirectionOptionalParameterTest extends SipServletTestCase { - private String CLICK2DIAL_URL; - private String CLICK2DIAL_PARAMS; - private static transient Logger logger = Logger.getLogger(ApplicationRouterDirectionOptionalParameterTest.class); - - private SipStack[] sipStackReceivers; - - private SipPhone[] sipPhoneReceivers; - - private static final int timeout = 10000; - - private static final int receiversCount = 2; - - // Don't restart the server for this set of tests. - private static boolean firstTime = true; - - public ApplicationRouterDirectionOptionalParameterTest(String name) { - super(name); - } - - @Override - public void setUp() throws Exception { - if (firstTime) { - super.setUp(); - CLICK2DIAL_URL = "http://" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":8080/click2call/call"; - CLICK2DIAL_PARAMS = "?from=sip:from@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5056&to=sip:to@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5057"; - } - firstTime = true; - } - - @Override - public void tearDown() throws Exception { - for (SipPhone sp : sipPhoneReceivers) { - if(sp != null) { - sp.dispose(); - } - } - for (SipStack ss : sipStackReceivers) { - if(ss != null) { - ss.dispose(); - } - } - super.tearDown(); - } - - @Override - public void deployApplication() { - assertTrue(tomcat - .deployContext( - projectHome - + "/sip-servlets-test-suite/applications/click-to-call-servlet/src/main/sipapp", - "click2call-context", "/click2call")); - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/location-service-servlet/src/main/sipapp", - "location-service-context", - "location-service")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/composition/c2c-direction.properties"; - } - - public SipStack makeStack(String transport, int port) throws Exception { - Properties properties = new Properties(); - String peerHostPort1 = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070"; - properties.setProperty("javax.sip.OUTBOUND_PROXY", peerHostPort1 + "/" - + "udp"); - properties.setProperty("javax.sip.STACK_NAME", "UAC_" + transport + "_" - + port); - properties.setProperty("sipunit.BINDADDR", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); - properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", - "logs/simplesipservlettest_debug_port" + port + ".txt"); - properties.setProperty("gov.nist.javax.sip.SERVER_LOG", - "logs/simplesipservlettest_log_port" + port + ".xml"); - properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", - "32"); - return new SipStack(transport, port, properties); - } - - public void setupPhones() throws Exception { - sipStackReceivers = new SipStack[receiversCount]; - sipPhoneReceivers = new SipPhone[receiversCount]; - - sipStackReceivers[0] = makeStack(SipStack.PROTOCOL_UDP, 5057); - sipPhoneReceivers[0] = sipStackReceivers[0].createSipPhone("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", - SipStack.PROTOCOL_UDP, 5070, "sip:to@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); - - sipStackReceivers[1] = makeStack(SipStack.PROTOCOL_UDP, 5056); - sipPhoneReceivers[1] = sipStackReceivers[1].createSipPhone("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", - SipStack.PROTOCOL_UDP, 5070, "sip:from@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); - } - - public void init() throws Exception { - setupPhones(); - } - - public void testClickToCallOutDirection() - throws Exception { - init(); - SipCall[] receiverCalls = new SipCall[receiversCount]; - - receiverCalls[0] = sipPhoneReceivers[0].createSipCall(); - receiverCalls[1] = sipPhoneReceivers[1].createSipCall(); - - receiverCalls[0].listenForIncomingCall(); - receiverCalls[1].listenForIncomingCall(); - - logger.info("Trying to reach url : " + CLICK2DIAL_URL - + CLICK2DIAL_PARAMS); - - URL url = new URL(CLICK2DIAL_URL + CLICK2DIAL_PARAMS); - InputStream in = url.openConnection().getInputStream(); - - byte[] buffer = new byte[10000]; - int len = in.read(buffer); - String httpResponse = ""; - for (int q = 0; q < len; q++) - httpResponse += (char) buffer[q]; - logger.info("Received the follwing HTTP response: " + httpResponse); - - receiverCalls[0].waitForIncomingCall(timeout); - - assertTrue(receiverCalls[0].sendIncomingCallResponse(Response.RINGING, - "Ringing", 0)); - assertTrue(receiverCalls[0].sendIncomingCallResponse(Response.OK, "OK", - 0)); - - receiverCalls[1].waitForIncomingCall(timeout); - - assertTrue(receiverCalls[1].sendIncomingCallResponse(Response.RINGING, - "Ringing", 0)); - assertTrue(receiverCalls[1].sendIncomingCallResponse(Response.OK, "OK", - 0)); - - assertTrue(receiverCalls[1].waitForAck(timeout)); - assertTrue(receiverCalls[0].waitForAck(timeout)); - - assertTrue(receiverCalls[0].disconnect()); - assertTrue(receiverCalls[1].waitForDisconnect(timeout)); - assertTrue(receiverCalls[1].respondToDisconnect()); - } + private String CLICK2DIAL_URL; + private String CLICK2DIAL_PARAMS; + private static transient Logger logger = Logger.getLogger(ApplicationRouterDirectionOptionalParameterTest.class); + + private SipStack[] sipStackReceivers; + + private SipPhone[] sipPhoneReceivers; + + private static final int timeout = 10000; + + private static final int receiversCount = 2; + + // Don't restart the server for this set of tests. + private static boolean firstTime = true; + + public ApplicationRouterDirectionOptionalParameterTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void setUp() throws Exception { + if (firstTime) { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + CLICK2DIAL_URL = "http://" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + httpContainerPort + "/click2call/call"; + } + firstTime = true; + } + + @Override + public void tearDown() throws Exception { + for (SipPhone sp : sipPhoneReceivers) { + if (sp != null) { + sp.dispose(); + } + } + for (SipStack ss : sipStackReceivers) { + if (ss != null) { + ss.dispose(); + } + } + super.tearDown(); + } + + @Override + public void deployApplication() { + } + + public SipStandardContext deployApplication(Map params) { + + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/click-to-call-servlet/src/main/sipapp", + "click2call", + params, null); + assertTrue(ctx.getAvailable()); + + ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/location-service-servlet/src/main/sipapp", + "location-service", + params, null); + assertTrue(ctx.getAvailable()); + return ctx; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/composition/c2c-direction.properties"; + } + + public SipStack makeStack(String transport, int port) throws Exception { + Properties properties = new Properties(); + String peerHostPort1 = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + containerPort; + properties.setProperty("javax.sip.OUTBOUND_PROXY", peerHostPort1 + "/" + + "udp"); + properties.setProperty("javax.sip.STACK_NAME", "UAC_" + transport + "_" + + port); + properties.setProperty("sipunit.BINDADDR", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); + properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", + "target/logs/simplesipservlettest_debug_port" + port + ".txt"); + properties.setProperty("gov.nist.javax.sip.SERVER_LOG", + "target/logs/simplesipservlettest_log_port" + port + ".xml"); + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", + "32"); + return new SipStack(transport, port, properties); + } + + public void setupPhones() throws Exception { + sipStackReceivers = new SipStack[receiversCount]; + sipPhoneReceivers = new SipPhone[receiversCount]; + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + sipStackReceivers[0] = makeStack(SipStack.PROTOCOL_UDP, receiverPort); + sipPhoneReceivers[0] = sipStackReceivers[0].createSipPhone("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", + SipStack.PROTOCOL_UDP, containerPort, "sip:to@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); + + int receiver2Port = NetworkPortAssigner.retrieveNextPort(); + sipStackReceivers[1] = makeStack(SipStack.PROTOCOL_UDP, receiver2Port); + sipPhoneReceivers[1] = sipStackReceivers[1].createSipPhone("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", + SipStack.PROTOCOL_UDP, containerPort, "sip:from@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); + + CLICK2DIAL_PARAMS = "?from=sip:from@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + receiver2Port + "&to=sip:to@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + receiverPort; + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(receiver2Port)); + deployApplication(params); + } + + public void init() throws Exception { + setupPhones(); + } + + public void testClickToCallOutDirection() + throws Exception { + init(); + SipCall[] receiverCalls = new SipCall[receiversCount]; + + receiverCalls[0] = sipPhoneReceivers[0].createSipCall(); + receiverCalls[1] = sipPhoneReceivers[1].createSipCall(); + + receiverCalls[0].listenForIncomingCall(); + receiverCalls[1].listenForIncomingCall(); + + logger.info("Trying to reach url : " + CLICK2DIAL_URL + + CLICK2DIAL_PARAMS); + + URL url = new URL(CLICK2DIAL_URL + CLICK2DIAL_PARAMS); + InputStream in = url.openConnection().getInputStream(); + + byte[] buffer = new byte[10000]; + int len = in.read(buffer); + String httpResponse = ""; + for (int q = 0; q < len; q++) { + httpResponse += (char) buffer[q]; + } + logger.info("Received the follwing HTTP response: " + httpResponse); + + receiverCalls[0].waitForIncomingCall(timeout); + + assertTrue(receiverCalls[0].sendIncomingCallResponse(Response.RINGING, + "Ringing", 0)); + assertTrue(receiverCalls[0].sendIncomingCallResponse(Response.OK, "OK", + 0)); + + receiverCalls[1].waitForIncomingCall(timeout); + + assertTrue(receiverCalls[1].sendIncomingCallResponse(Response.RINGING, + "Ringing", 0)); + assertTrue(receiverCalls[1].sendIncomingCallResponse(Response.OK, "OK", + 0)); + + assertTrue(receiverCalls[1].waitForAck(timeout)); + assertTrue(receiverCalls[0].waitForAck(timeout)); + + assertTrue(receiverCalls[0].disconnect()); + assertTrue(receiverCalls[1].waitForDisconnect(timeout)); + assertTrue(receiverCalls[1].respondToDisconnect()); + } } diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/B2BUACompositionJunitTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/B2BUACompositionJunitTest.java index 085448d084..d3fd8e5e16 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/B2BUACompositionJunitTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/B2BUACompositionJunitTest.java @@ -1,240 +1,276 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.composition; - -import javax.sip.ListeningPoint; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class B2BUACompositionJunitTest extends SipServletTestCase { - - private static final String TO_NAME = "forward-receiver"; - private static final String FROM_NAME = "composition"; - - private static final String FROM_DOMAIN = "sip-servlets.com"; - private String TO_DOMAIN; - - private static transient Logger logger = Logger.getLogger(B2BUACompositionJunitTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender; - TestSipListener receiver; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - - public B2BUACompositionJunitTest(String name) { - super(name); - autoDeployOnStartup = false; - startTomcatOnStartup = false; - } - - @Override - public void deployApplication() { - deployB2BUA(); - deployCallForwarding(); - } - - private void deployB2BUA() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/b2bua-sip-servlet/src/main/sipapp", - "b2bua-context", - "b2bua")); - } - - private void deployCallForwarding() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", - "call-forwarding-b2bua-context", - "call-forwarding-b2bua")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/composition/b2bua-composition-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - TO_DOMAIN = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090"; - tomcat.addSipConnector(serverName, sipIpAddress, 5070, ListeningPoint.TCP); - tomcat.startTomcat(); - - senderProtocolObjects = new ProtocolObjects(FROM_NAME, - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - receiverProtocolObjects = new ProtocolObjects(TO_NAME, - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - } - - public void testCallForwardingCallerSendBye() throws Exception { - deployB2BUA(); - deployCallForwarding(); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5059, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = FROM_NAME; - String fromSipAddress = FROM_DOMAIN; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = TO_DOMAIN; - String toUser = TO_NAME; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); - Thread.sleep(TIMEOUT); - //checking numbers of ACK received see http://forums.java.net/jive/thread.jspa?messageID=277840 - assertEquals(1,receiver.ackCount); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - } - - public void testCallForwardingCalleeSendBye() throws Exception { - deployB2BUA(); - deployCallForwarding(); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5059, 5070, receiverProtocolObjects, true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = FROM_NAME; - String fromSipAddress = TO_DOMAIN; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = FROM_DOMAIN; - String toUser = TO_NAME; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getOkToByeReceived()); - assertTrue(sender.getByeReceived()); - } - - public void testCancelCallForwarding() throws Exception { - deployB2BUA(); - deployCallForwarding(); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5059, 5070, receiverProtocolObjects, true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = FROM_NAME; - String fromSipAddress = FROM_DOMAIN; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = TO_DOMAIN; - String toUser = TO_NAME; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); - Thread.sleep(500); - sender.sendCancel(); - Thread.sleep(TIMEOUT); - assertTrue(sender.isCancelOkReceived()); - assertTrue(sender.isRequestTerminatedReceived()); - assertTrue(receiver.isCancelReceived()); - } - - public void testRegisterComposition() throws Exception { - deployB2BUA(); - deployCallForwarding(); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5059, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = FROM_NAME; - String fromSipAddress = FROM_DOMAIN; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = TO_DOMAIN; - String toUser = TO_NAME; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("REGISTER", fromAddress, fromAddress, null, null, true); - Thread.sleep(TIMEOUT); - assertNotNull(receiver.getRegisterReceived()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.composition; + +import java.util.HashMap; +import java.util.Map; +import javax.sip.ListeningPoint; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class B2BUACompositionJunitTest extends SipServletTestCase { + + private static final String TO_NAME = "forward-receiver"; + private static final String FROM_NAME = "composition"; + + private static final String FROM_DOMAIN = "sip-servlets.com"; + private String TO_DOMAIN; + + private static transient Logger logger = Logger.getLogger(B2BUACompositionJunitTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + TestSipListener receiver; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + + public B2BUACompositionJunitTest(String name) { + super(name); + autoDeployOnStartup = false; + startTomcatOnStartup = false; + } + + @Override + public void deployApplication() { + + } + + private void deployB2BUA(Map params) { + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/b2bua-sip-servlet/src/main/sipapp", + "b2bua", + params, null); + assertTrue(ctx.getAvailable()); + } + + private void deployCallForwarding(Map params) { + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + "call-forwarding-b2bua", + params, null); + assertTrue(ctx.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/composition/b2bua-composition-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + tomcat.addSipConnector(serverName, sipIpAddress, containerPort, ListeningPoint.TCP); + tomcat.startTomcat(); + + senderProtocolObjects = new ProtocolObjects(FROM_NAME, + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects(TO_NAME, + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + } + + public void testCallForwardingCallerSendBye() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + TO_DOMAIN = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + receiverPort; + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployB2BUA(params); + deployCallForwarding(params); + + String fromName = FROM_NAME; + String fromSipAddress = FROM_DOMAIN; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = TO_DOMAIN; + String toUser = TO_NAME; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); + Thread.sleep(TIMEOUT); + //checking numbers of ACK received see http://forums.java.net/jive/thread.jspa?messageID=277840 + assertEquals(1, receiver.ackCount); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + } + + public void testCallForwardingCalleeSendBye() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + TO_DOMAIN = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + receiverPort; + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployB2BUA(params); + deployCallForwarding(params); + + String fromName = FROM_NAME; + String fromSipAddress = TO_DOMAIN; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = FROM_DOMAIN; + String toUser = TO_NAME; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getOkToByeReceived()); + assertTrue(sender.getByeReceived()); + } + + public void testCancelCallForwarding() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + TO_DOMAIN = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + receiverPort; + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployB2BUA(params); + deployCallForwarding(params); + + String fromName = FROM_NAME; + String fromSipAddress = FROM_DOMAIN; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = TO_DOMAIN; + String toUser = TO_NAME; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); + Thread.sleep(500); + sender.sendCancel(); + Thread.sleep(TIMEOUT); + assertTrue(sender.isCancelOkReceived()); + assertTrue(sender.isRequestTerminatedReceived()); + assertTrue(receiver.isCancelReceived()); + } + + public void testRegisterComposition() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + TO_DOMAIN = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + receiverPort; + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployB2BUA(params); + deployCallForwarding(params); + + String fromName = FROM_NAME; + String fromSipAddress = FROM_DOMAIN; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = TO_DOMAIN; + String toUser = TO_NAME; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("REGISTER", fromAddress, fromAddress, null, null, true); + Thread.sleep(TIMEOUT); + assertNotNull(receiver.getRegisterReceived()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/LocationServiceB2BUACompositionTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/LocationServiceB2BUACompositionTest.java index a8acd543c8..c6b89cb2f0 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/LocationServiceB2BUACompositionTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/LocationServiceB2BUACompositionTest.java @@ -19,113 +19,127 @@ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ - package org.mobicents.servlet.sip.testsuite.composition; +import java.util.HashMap; +import java.util.Map; import javax.sip.SipProvider; import javax.sip.address.SipURI; +import static junit.framework.Assert.assertTrue; import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; import org.mobicents.servlet.sip.testsuite.ProtocolObjects; import org.mobicents.servlet.sip.testsuite.TestSipListener; public class LocationServiceB2BUACompositionTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(LocationServiceB2BUACompositionTest.class); - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 20000; + private static transient Logger logger = Logger.getLogger(LocationServiceB2BUACompositionTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 20000; // private static final int TIMEOUT = 100000000; - - TestSipListener sender; - TestSipListener receiver; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - - public LocationServiceB2BUACompositionTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - deployCallForwarding(); - deployLocationService(); - } - - private void deployCallForwarding() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", - "call-forwarding-b2bua-context", - "call-forwarding-b2bua")); - } - - private void deployLocationService() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/location-service-servlet/src/main/sipapp", - "location-service-context", - "location-service")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/composition/location-b2bua-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects = new ProtocolObjects("sender", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - receiverProtocolObjects = new ProtocolObjects("receiver", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - } - - public void testLocationServiceCallForwardingCallerSendBye() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - receiver.setWaitBeforeFinalResponse(2000); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-sender"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "proxy-b2bua"; - String toHost = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); - Thread.sleep(TIMEOUT); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - } - - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } + TestSipListener sender; + TestSipListener receiver; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + + public LocationServiceB2BUACompositionTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + + } + + private void deployCallForwarding(Map params) { + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + "call-forwarding-b2bua", + params, null); + assertTrue(ctx.getAvailable()); + } + + private void deployLocationService(Map params) { + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/location-service-servlet/src/main/sipapp", + "location-servicea", + params, null); + assertTrue(ctx.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/composition/location-b2bua-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects("sender", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects("receiver", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + } + + public void testLocationServiceCallForwardingCallerSendBye() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + receiver.setWaitBeforeFinalResponse(2000); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployCallForwarding(params); + deployLocationService(params); + + String fromName = "forward-sender"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "proxy-b2bua"; + String toHost = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + containerPort; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } } diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/LocationServiceB2BUAStaticServerAddressTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/LocationServiceB2BUAStaticServerAddressTest.java index 103774638f..efe6414d99 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/LocationServiceB2BUAStaticServerAddressTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/LocationServiceB2BUAStaticServerAddressTest.java @@ -19,198 +19,207 @@ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ - package org.mobicents.servlet.sip.testsuite.composition; import gov.nist.javax.sip.header.Contact; import gov.nist.javax.sip.header.Via; import java.io.File; +import java.util.HashMap; +import java.util.Map; import javax.sip.SipProvider; import javax.sip.address.SipURI; +import static junit.framework.Assert.assertTrue; import org.apache.catalina.connector.Connector; import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; import org.mobicents.servlet.sip.SipServletTestCase; import org.mobicents.servlet.sip.UDPPacketForwarder; import org.mobicents.servlet.sip.catalina.SipProtocolHandler; +import org.mobicents.servlet.sip.startup.SipStandardContext; import org.mobicents.servlet.sip.testsuite.ProtocolObjects; import org.mobicents.servlet.sip.testsuite.TestSipListener; public class LocationServiceB2BUAStaticServerAddressTest extends SipServletTestCase { - - private String HOST; - private static final int MSS_PORT = 5070; + private String HOST; - private static final int IP_LOAD_BALANCER_PORT = 5005; + private static int IP_LOAD_BALANCER_PORT = 5005; - private static transient Logger logger = Logger.getLogger(LocationServiceB2BUAStaticServerAddressTest.class); + private static transient Logger logger = Logger.getLogger(LocationServiceB2BUAStaticServerAddressTest.class); - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 20000; + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 20000; // private static final int TIMEOUT = 100000000; - - TestSipListener sender; - TestSipListener receiver; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - UDPPacketForwarder ipBalancer; - - public LocationServiceB2BUAStaticServerAddressTest(String name) { - super(name); - startTomcatOnStartup = false; - addSipConnectorOnStartup = false; - autoDeployOnStartup = false; - } - - @Override - public void deployApplication() { - deployCallForwarding(); - deployLocationService(); - } - - private void deployCallForwarding() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", - "call-forwarding-b2bua-context", - "call-forwarding-b2bua")); - } - - private void deployLocationService() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/location-service-servlet/src/main/sipapp", - "location-service-context", - "location-service")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/composition/location-b2bua-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - HOST = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; - - Connector udpSipConnector = null; - try { - udpSipConnector = new Connector( - SipProtocolHandler.class.getName()); - } catch (Exception e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } - - SipProtocolHandler udpProtocolHandler = (SipProtocolHandler) udpSipConnector - .getProtocolHandler(); - try { - udpProtocolHandler.setPort(MSS_PORT); - udpProtocolHandler.setIpAddress(HOST); - - udpProtocolHandler.setSignalingTransport("udp"); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - tomcat.getSipService().setSipStackProperties(null); - udpProtocolHandler.setUseStaticAddress(true); - udpProtocolHandler.setStaticServerAddress(HOST); - udpProtocolHandler.setStaticServerPort(IP_LOAD_BALANCER_PORT); - tomcat.getSipService().addConnector(udpSipConnector); - try { - tomcat.startTomcat(); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - deployApplication(); - senderProtocolObjects = new ProtocolObjects("sender", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - receiverProtocolObjects = new ProtocolObjects("receiver", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - } - - public void testLocationServiceCallForwardingCallerSendBye() throws Exception { - try { - new File("proxy-b2bua.failure.flag").delete(); - new File("proxy-b2bua.case.flag").delete(); - new File("proxy-b2bua.case.flag").createNewFile(); - assertFalse(new File("proxy-b2bua.failure.flag").exists()); - - sender = new TestSipListener(5080, IP_LOAD_BALANCER_PORT, senderProtocolObjects, true); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, IP_LOAD_BALANCER_PORT, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - receiver.setWaitBeforeFinalResponse(2000); - SipProvider receiverProvider = receiver.createProvider(); - - ipBalancer = new UDPPacketForwarder(IP_LOAD_BALANCER_PORT, MSS_PORT, HOST); - ipBalancer.start(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-sender"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "proxy-b2bua"; - String toHost = HOST+":"+MSS_PORT; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); - Thread.sleep(TIMEOUT); - int byes = 0; - - assertTrue( - receiver.getByeRequestReceived().getHeader(Via.NAME).toString().contains(":"+IP_LOAD_BALANCER_PORT)); - - for(String message:ipBalancer.sipMessageWithoutRetrans) { - if(message.contains("BYE ")) { - byes++; - } - } - assertEquals(1, byes); - - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - Contact contact = (Contact) sender.getInviteOkResponse().getHeader(Contact.NAME); - SipURI sipURI = (SipURI) contact.getAddress().getURI(); - assertTrue(sipURI.getPort() == IP_LOAD_BALANCER_PORT); - assertFalse(new File("proxy-b2bua.failure.flag").exists()); - - - } finally { - new File("proxy-b2bua.case.flag").delete(); - new File("proxy-b2bua.failure.flag").delete(); - } - } - - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - ipBalancer.stop(); - logger.info("Test completed"); - super.tearDown(); - } + TestSipListener sender; + TestSipListener receiver; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + UDPPacketForwarder ipBalancer; + + public LocationServiceB2BUAStaticServerAddressTest(String name) { + super(name); + startTomcatOnStartup = false; + addSipConnectorOnStartup = false; + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + private void deployCallForwarding(Map params) { + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + "call-forwarding-b2bua", + params, null); + assertTrue(ctx.getAvailable()); + } + + private void deployLocationService(Map params) { + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/location-service-servlet/src/main/sipapp", + "location-servicea", + params, null); + assertTrue(ctx.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/composition/location-b2bua-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + IP_LOAD_BALANCER_PORT = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + HOST = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; + + Connector udpSipConnector = null; + try { + udpSipConnector = new Connector( + SipProtocolHandler.class.getName()); + } catch (Exception e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + + SipProtocolHandler udpProtocolHandler = (SipProtocolHandler) udpSipConnector + .getProtocolHandler(); + try { + udpProtocolHandler.setPort(containerPort); + udpProtocolHandler.setIpAddress(HOST); + + udpProtocolHandler.setSignalingTransport("udp"); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + tomcat.getSipService().setSipStackProperties(null); + udpProtocolHandler.setUseStaticAddress(true); + udpProtocolHandler.setStaticServerAddress(HOST); + udpProtocolHandler.setStaticServerPort(IP_LOAD_BALANCER_PORT); + tomcat.getSipService().addConnector(udpSipConnector); + try { + tomcat.startTomcat(); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + senderProtocolObjects = new ProtocolObjects("sender", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects("receiver", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + } + + public void testLocationServiceCallForwardingCallerSendBye() throws Exception { + try { + new File("proxy-b2bua.failure.flag").delete(); + new File("proxy-b2bua.case.flag").delete(); + new File("proxy-b2bua.case.flag").createNewFile(); + assertFalse(new File("proxy-b2bua.failure.flag").exists()); + + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, IP_LOAD_BALANCER_PORT, senderProtocolObjects, true); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, IP_LOAD_BALANCER_PORT, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + receiver.setWaitBeforeFinalResponse(2000); + SipProvider receiverProvider = receiver.createProvider(); + + ipBalancer = new UDPPacketForwarder(IP_LOAD_BALANCER_PORT, containerPort, HOST); + ipBalancer.start(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployCallForwarding(params); + deployLocationService(params); + + String fromName = "forward-sender"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "proxy-b2bua"; + String toHost = HOST + ":" + containerPort; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); + Thread.sleep(TIMEOUT); + int byes = 0; + + assertTrue( + receiver.getByeRequestReceived().getHeader(Via.NAME).toString().contains(":" + IP_LOAD_BALANCER_PORT)); + + for (String message : ipBalancer.sipMessageWithoutRetrans) { + if (message.contains("BYE ")) { + byes++; + } + } + assertEquals(1, byes); + + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + Contact contact = (Contact) sender.getInviteOkResponse().getHeader(Contact.NAME); + SipURI sipURI = (SipURI) contact.getAddress().getURI(); + assertTrue(sipURI.getPort() == IP_LOAD_BALANCER_PORT); + assertFalse(new File("proxy-b2bua.failure.flag").exists()); + + } finally { + new File("proxy-b2bua.case.flag").delete(); + new File("proxy-b2bua.failure.flag").delete(); + } + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + ipBalancer.stop(); + logger.info("Test completed"); + super.tearDown(); + } } diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/NoApplicationDeployedJunitTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/NoApplicationDeployedJunitTest.java index 47cfdfe1a2..7ddb14f5d1 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/NoApplicationDeployedJunitTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/NoApplicationDeployedJunitTest.java @@ -19,13 +19,13 @@ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ - package org.mobicents.servlet.sip.testsuite.composition; import javax.sip.SipProvider; import javax.sip.address.SipURI; import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; import org.mobicents.servlet.sip.SipServletTestCase; import org.mobicents.servlet.sip.testsuite.ProtocolObjects; import org.mobicents.servlet.sip.testsuite.TestSipListener; @@ -36,138 +36,144 @@ */ public class NoApplicationDeployedJunitTest extends SipServletTestCase { - private static transient Logger logger = Logger.getLogger(NoApplicationDeployedJunitTest.class); + private static transient Logger logger = Logger.getLogger(NoApplicationDeployedJunitTest.class); - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; // private static final int TIMEOUT = 100000000; - - TestSipListener sender; - TestSipListener receiver; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - - /** - * @param name - */ - public NoApplicationDeployedJunitTest(String name) { - super(name); - startTomcatOnStartup = false; - initTomcatOnStartup = false; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - senderProtocolObjects = new ProtocolObjects("sender", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - receiverProtocolObjects = new ProtocolObjects("receiver", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - } - - @Override - protected void deployApplication() { - // test to deploy nothing - - } - - @Override - protected String getDarConfigurationFile() { - return null; - } - - public void testNoMatchingAppDeployedCallerSendBye() throws Exception { - System.setProperty("javax.servlet.sip.dar", "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/composition/dummy-dar.properties"); - super.tomcat.initTomcat(tomcatBasePath, null); - tomcat.addSipConnector(serverName, sipIpAddress, 5070, listeningPointTransport); - super.tomcat.startTomcat(); - - sender = new TestSipListener(5080, 5090, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "sender"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "1"; - String toHost = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - SipURI routeAddress = senderProtocolObjects.addressFactory.createSipURI( - null, "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); - routeAddress.setPort(5070); - routeAddress.setLrParam(); - routeAddress.setTransportParam(senderProtocolObjects.transport); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, routeAddress, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - } - - public void testNoAppDeployedCallerSendBye() throws Exception { - System.setProperty("javax.servlet.sip.dar", "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/composition/empty-dar.properties"); - super.tomcat.initTomcat(tomcatBasePath, null); - tomcat.addSipConnector(serverName, sipIpAddress, 5070, listeningPointTransport); - super.tomcat.startTomcat(); - - sender = new TestSipListener(5080, 5090, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "sender"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "1"; - String toHost = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - SipURI routeAddress = senderProtocolObjects.addressFactory.createSipURI( - null, "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); - routeAddress.setPort(5070); - routeAddress.setLrParam(); - routeAddress.setTransportParam(senderProtocolObjects.transport); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, routeAddress, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } + + TestSipListener sender; + TestSipListener receiver; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + + /** + * @param name + */ + public NoApplicationDeployedJunitTest(String name) { + super(name); + startTomcatOnStartup = false; + initTomcatOnStartup = false; + autoDeployOnStartup = false; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + senderProtocolObjects = new ProtocolObjects("sender", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects("receiver", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + } + + @Override + protected void deployApplication() { + // test to deploy nothing + + } + + @Override + protected String getDarConfigurationFile() { + return null; + } + + public void testNoMatchingAppDeployedCallerSendBye() throws Exception { + System.setProperty("javax.servlet.sip.dar", "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/composition/dummy-dar.properties"); + super.tomcat.initTomcat(tomcatBasePath, null); + tomcat.addSipConnector(serverName, sipIpAddress, containerPort, listeningPointTransport); + super.tomcat.startTomcat(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, receiverPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + String fromName = "sender"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "1"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + SipURI routeAddress = senderProtocolObjects.addressFactory.createSipURI( + null, "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); + routeAddress.setPort(containerPort); + routeAddress.setLrParam(); + routeAddress.setTransportParam(senderProtocolObjects.transport); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, routeAddress, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + } + + public void testNoAppDeployedCallerSendBye() throws Exception { + System.setProperty("javax.servlet.sip.dar", "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/composition/empty-dar.properties"); + super.tomcat.initTomcat(tomcatBasePath, null); + tomcat.addSipConnector(serverName, sipIpAddress, containerPort, listeningPointTransport); + super.tomcat.startTomcat(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, receiverPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + String fromName = "sender"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "1"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + SipURI routeAddress = senderProtocolObjects.addressFactory.createSipURI( + null, "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); + routeAddress.setPort(containerPort); + routeAddress.setLrParam(); + routeAddress.setTransportParam(senderProtocolObjects.transport); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, routeAddress, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } } diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/ProxyB2BUACompositionTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/ProxyB2BUACompositionTest.java index 92717bb7a8..394a0be402 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/ProxyB2BUACompositionTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/ProxyB2BUACompositionTest.java @@ -19,248 +19,355 @@ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ - package org.mobicents.servlet.sip.testsuite.composition; +import gov.nist.javax.sip.message.RequestExt; +import java.util.HashMap; +import java.util.Map; + import javax.sip.SipProvider; import javax.sip.address.SipURI; +import static junit.framework.Assert.assertTrue; import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; import org.mobicents.servlet.sip.testsuite.ProtocolObjects; import org.mobicents.servlet.sip.testsuite.TestSipListener; public class ProxyB2BUACompositionTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(ProxyB2BUACompositionTest.class); - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; + private static transient Logger logger = Logger.getLogger(ProxyB2BUACompositionTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; // private static final int TIMEOUT = 100000000; - - TestSipListener sender; - TestSipListener receiver; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - - public ProxyB2BUACompositionTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - deployCallForwarding(); - deployLocationService(); - } - - private void deployCallForwarding() { - tomcat.getSipService().setDialogPendingRequestChecking(true); - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", - "call-forwarding-b2bua-context", - "call-forwarding-b2bua")); - } - - private void deployLocationService() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/speed-dial-servlet/src/main/sipapp", - "location-service-context", - "location-service")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/composition/proxy-b2bua-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects = new ProtocolObjects("sender", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - receiverProtocolObjects = new ProtocolObjects("receiver", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - } - - public void testSpeedDialLocationServiceCallerSendBye() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - sender.setRecordRoutingProxyTesting(true); - sender.sendByeInNewThread = true; - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "sender"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "b2bua"; - String toHost = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.b2buamessagereceived); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - } - - public void testSpeedDialLocationServiceCallerReInviteSendBye() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - sender.setRecordRoutingProxyTesting(true); - sender.sendByeInNewThread = true; - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-pending-sender"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "b2bua"; - String toHost = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.b2buamessagereceived); - assertEquals(200, sender.getFinalResponseStatus()); - sender.setFinalResponseStatus(-1); - - receiver.sendInDialogSipRequest("INVITE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertEquals(200, receiver.getFinalResponseStatus()); - - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertEquals(200, sender.getFinalResponseStatus()); - - sender.sendInDialogSipRequest("BYE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - } - - public void test491Response() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - sender.setRecordRoutingProxyTesting(true); - sender.sendByeInNewThread = true; - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-pending-sender"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "b2bua"; - String toHost = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.b2buamessagereceived); - assertEquals(200, sender.getFinalResponseStatus()); - sender.setFinalResponseStatus(-1); - Thread.sleep(3000); - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - - try { - Thread.sleep(300); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertEquals(1, sender.numberOf491s); - } - - public void test491ResponseTough() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - sender.setRecordRoutingProxyTesting(true); - sender.sendByeInNewThread = true; - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-pending-sender"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "b2bua"; - String toHost = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.b2buamessagereceived); - assertEquals(200, sender.getFinalResponseStatus()); - sender.setFinalResponseStatus(-1); - Thread.sleep(3000); - receiver.sendInDialogSipRequest("INVITE", null, null, null, null, null); - receiver.sendInDialogSipRequest("INVITE", null, null, null, null, null); - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - sender.sendInDialogSipRequest("BYE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertEquals(2, sender.numberOf491s); - assertEquals(2, receiver.numberOf491s); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } + TestSipListener sender; + TestSipListener receiver; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + + public ProxyB2BUACompositionTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + private void deployCallForwarding(Map params) { + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + "call-forwarding-b2bua", + params, null); + assertTrue(ctx.getAvailable()); + } + + private void deployLocationService(Map params) { + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/speed-dial-servlet/src/main/sipapp", + "location-servicea", + params, null); + assertTrue(ctx.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/composition/proxy-b2bua-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects("sender", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects("receiver", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + } + + public void testSpeedDialLocationServiceCallerSendBye() throws Exception { + + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + sender.setRecordRoutingProxyTesting(true); + sender.sendByeInNewThread = true; + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployCallForwarding(params); + deployLocationService(params); + + String fromName = "sender"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "b2bua"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.b2buamessagereceived); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + } + + public void testSpeedDialLocationServiceCallerReInviteSendBye() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + sender.setRecordRoutingProxyTesting(true); + sender.sendByeInNewThread = true; + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployCallForwarding(params); + deployLocationService(params); + + String fromName = "forward-pending-changeFromTo-sender"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "b2bua"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.b2buamessagereceived); + assertEquals(200, sender.getFinalResponseStatus()); + sender.setFinalResponseStatus(-1); + + receiver.sendInDialogSipRequest("INVITE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertEquals(200, receiver.getFinalResponseStatus()); + + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertEquals(200, sender.getFinalResponseStatus()); + + sender.sendInDialogSipRequest("BYE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + } + + /** + * Non regression test for changing From and To Headers + * https://telestax.zendesk.com/tickets/31838 Test both at the Proxy and + * B2BUA side + * + * @throws Exception + */ + public void testSpeedDialLocationServiceCallerReInviteChangeToFromHeadersSendBye() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + sender.setRecordRoutingProxyTesting(true); + sender.sendByeInNewThread = true; + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployCallForwarding(params); + deployLocationService(params); + + String fromName = "forward-pending-sender"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "b2bua"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.b2buamessagereceived); + assertEquals(200, sender.getFinalResponseStatus()); + sender.setFinalResponseStatus(-1); + + receiver.sendInDialogSipRequest("INVITE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertEquals(200, receiver.getFinalResponseStatus()); + + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertEquals(200, sender.getFinalResponseStatus()); + assertEquals("sip:fromchanged@sip-servlets.com", ((RequestExt) receiver.getInviteRequest()).getFromHeader().getAddress().getURI().toString().trim()); + assertEquals("sip:tochanged@sip-servlets.com", ((RequestExt) receiver.getInviteRequest()).getToHeader().getAddress().getURI().toString().trim()); + + sender.sendInDialogSipRequest("BYE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + } + + public void test491Response() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + sender.setRecordRoutingProxyTesting(true); + sender.sendByeInNewThread = true; + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployCallForwarding(params); + deployLocationService(params); + + String fromName = "forward-pending-sender"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "b2bua"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.b2buamessagereceived); + assertEquals(200, sender.getFinalResponseStatus()); + sender.setFinalResponseStatus(-1); + Thread.sleep(3000); + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + + try { + Thread.sleep(300); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertEquals(1, sender.numberOf491s); + } + + public void test491ResponseTough() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + sender.setRecordRoutingProxyTesting(true); + sender.sendByeInNewThread = true; + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployCallForwarding(params); + deployLocationService(params); + + String fromName = "forward-pending-sender"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "b2bua"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.b2buamessagereceived); + assertEquals(200, sender.getFinalResponseStatus()); + sender.setFinalResponseStatus(-1); + Thread.sleep(3000); + receiver.sendInDialogSipRequest("INVITE", null, null, null, null, null); + receiver.sendInDialogSipRequest("INVITE", null, null, null, null, null); + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + sender.sendInDialogSipRequest("BYE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertEquals(2, sender.numberOf491s); + assertEquals(2, receiver.numberOf491s); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } } diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/SameSipSessionB2BUACompositionJunitTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/SameSipSessionB2BUACompositionJunitTest.java index 23508dd458..81036f350b 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/SameSipSessionB2BUACompositionJunitTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/SameSipSessionB2BUACompositionJunitTest.java @@ -1,180 +1,202 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.composition; - -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; -/** - * Non regression test for Issue 790 : - * 1 SipSession should not be used in 2 different app session (http://code.google.com/p/mobicents/issues/detail?id=790) - * @author jean.deruelle@gmail.com - * - */ -public class SameSipSessionB2BUACompositionJunitTest extends SipServletTestCase { - - private static final String TO_NAME = "receiver"; - private static final String FROM_NAME = "samesipsession"; - private static final String CANCEL_FROM_NAME = "cancel-samesipsession"; - private static final String ERROR_FROM_NAME = "error-samesipsession"; - - private static final String FROM_DOMAIN = "sip-servlets.com"; - private String TO_DOMAIN; - - private static transient Logger logger = Logger.getLogger(SameSipSessionB2BUACompositionJunitTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender; - ProtocolObjects senderProtocolObjects; - - public SameSipSessionB2BUACompositionJunitTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - deployCallForwarding(); - } - - private void deployCallForwarding() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", - "call-forwarding-b2bua-context", - "call-forwarding-b2bua")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/composition/samesipsession-composition-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - autoDeployOnStartup = false; - super.setUp(); - TO_DOMAIN = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070"; - - senderProtocolObjects = new ProtocolObjects(FROM_NAME, - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - } - - public void testSameSipSessionCallerSendBye() throws Exception { - deployCallForwarding(); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - - String fromName = FROM_NAME; - String fromSipAddress = FROM_DOMAIN; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = TO_DOMAIN; - String toUser = TO_NAME; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); - Thread.sleep(TIMEOUT); - //checking numbers of ACK received see http://forums.java.net/jive/thread.jspa?messageID=277840 - assertTrue(sender.getOkToByeReceived()); - } - - public void testSameSipSessionCancel() throws Exception { - deployCallForwarding(); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - - String fromName = CANCEL_FROM_NAME; - String fromSipAddress = FROM_DOMAIN; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = TO_DOMAIN; - String toUser = TO_NAME; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); - Thread.sleep(100); - sender.sendCancel(); - Thread.sleep(TIMEOUT); - assertTrue(sender.isCancelOkReceived()); - assertTrue(sender.isRequestTerminatedReceived()); - } - - public void testSameSipSessionErrorResponse() throws Exception { - deployCallForwarding(); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - - String fromName = ERROR_FROM_NAME; - String fromSipAddress = FROM_DOMAIN; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = TO_DOMAIN; - String toUser = TO_NAME; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); - Thread.sleep(TIMEOUT); - assertTrue(sender.isFinalResponseReceived()); - assertEquals(500, sender.getFinalResponseStatus()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.composition; + +import java.util.HashMap; +import java.util.Map; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +/** + * Non regression test for Issue 790 : 1 SipSession should not be used in 2 + * different app session + * (http://code.google.com/p/mobicents/issues/detail?id=790) + * + * @author jean.deruelle@gmail.com + * + */ +public class SameSipSessionB2BUACompositionJunitTest extends SipServletTestCase { + + private static final String TO_NAME = "receiver"; + private static final String FROM_NAME = "samesipsession"; + private static final String CANCEL_FROM_NAME = "cancel-samesipsession"; + private static final String ERROR_FROM_NAME = "error-samesipsession"; + + private static final String FROM_DOMAIN = "sip-servlets.com"; + private String TO_DOMAIN; + + private static transient Logger logger = Logger.getLogger(SameSipSessionB2BUACompositionJunitTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + ProtocolObjects senderProtocolObjects; + + public SameSipSessionB2BUACompositionJunitTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + private void deployCallForwarding(Map params) { + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + "call-forwarding-b2bua", + params, null); + assertTrue(ctx.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/composition/samesipsession-composition-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + autoDeployOnStartup = false; + super.setUp(); + TO_DOMAIN = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + containerPort; + + senderProtocolObjects = new ProtocolObjects(FROM_NAME, + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + } + + public void testSameSipSessionCallerSendBye() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployCallForwarding(params); + + String fromName = FROM_NAME; + String fromSipAddress = FROM_DOMAIN; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = TO_DOMAIN; + String toUser = TO_NAME; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); + Thread.sleep(TIMEOUT); + //checking numbers of ACK received see http://forums.java.net/jive/thread.jspa?messageID=277840 + assertTrue(sender.getOkToByeReceived()); + } + + public void testSameSipSessionCancel() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployCallForwarding(params); + + String fromName = CANCEL_FROM_NAME; + String fromSipAddress = FROM_DOMAIN; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = TO_DOMAIN; + String toUser = TO_NAME; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); + Thread.sleep(100); + sender.sendCancel(); + Thread.sleep(TIMEOUT); + assertTrue(sender.isCancelOkReceived()); + assertTrue(sender.isRequestTerminatedReceived()); + } + + public void testSameSipSessionErrorResponse() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployCallForwarding(params); + + String fromName = ERROR_FROM_NAME; + String fromSipAddress = FROM_DOMAIN; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = TO_DOMAIN; + String toUser = TO_NAME; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); + Thread.sleep(TIMEOUT); + assertTrue(sender.isFinalResponseReceived()); + assertEquals(500, sender.getFinalResponseStatus()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/SpeedDialLocationServiceJunitTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/SpeedDialLocationServiceJunitTest.java index c5fd4fb278..190fd0a24f 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/SpeedDialLocationServiceJunitTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/SpeedDialLocationServiceJunitTest.java @@ -1,256 +1,306 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.composition; - -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class SpeedDialLocationServiceJunitTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(SpeedDialLocationServiceJunitTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender; - TestSipListener receiver; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - - public SpeedDialLocationServiceJunitTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - deploySpeedDial(); - deployLocationService(); - } - - private void deploySpeedDial() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/speed-dial-servlet/src/main/sipapp", - "speed-dial-context", - "speed-dial")); - } - - private void deployLocationService() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/location-service-servlet/src/main/sipapp", - "location-service-context", - "location-service")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/composition/speeddial-locationservice-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects = new ProtocolObjects("sender", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - receiverProtocolObjects = new ProtocolObjects("receiver", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - } - - public void testSpeedDialLocationServiceCallerSendBye() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "sender"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "1"; - String toHost = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - } - - public void testSpeedDialLocationServiceErrorResponse() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - receiver.setRespondWithError(408); - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "sender-expect-408"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "1"; - String toHost = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isServerErrorReceived()); - } - - public void testSpeedDialLocationServiceCalleeSendBye() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, true); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "sender"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "1"; - String toHost = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getOkToByeReceived()); - assertTrue(sender.getByeReceived()); - } - - public void testCancelSpeedDialLocationService() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, true); - receiver.setRecordRoutingProxyTesting(true); - receiver.setWaitForCancel(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "sender"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "1"; - String toHost = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(500); - sender.sendCancel(); - Thread.sleep(TIMEOUT); - assertTrue(sender.isCancelOkReceived()); - assertTrue(sender.isRequestTerminatedReceived()); - assertTrue(receiver.isCancelReceived()); - } - - public void testRemoteAddrPortAndTransport() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "remote"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "1"; - String toHost = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.composition; + +import java.util.HashMap; +import java.util.Map; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class SpeedDialLocationServiceJunitTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(SpeedDialLocationServiceJunitTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + TestSipListener receiver; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + + public SpeedDialLocationServiceJunitTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + private void deploySpeedDial(Map params) { + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/speed-dial-servlet/src/main/sipapp", + "speed-dial", + params, null); + assertTrue(ctx.getAvailable()); + } + + private void deployLocationService(Map params) { + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/location-service-servlet/src/main/sipapp", + "location-service", + params, null); + assertTrue(ctx.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/composition/speeddial-locationservice-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects("sender", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects("receiver", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + } + + public void testSpeedDialLocationServiceCallerSendBye() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deploySpeedDial(params); + deployLocationService(params); + + String fromName = "sender"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "1"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + } + + public void testSpeedDialLocationServiceErrorResponse() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + receiver.setRespondWithError(408); + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deploySpeedDial(params); + deployLocationService(params); + + String fromName = "sender-expect-408"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "1"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isServerErrorReceived()); + } + + public void testSpeedDialLocationServiceCalleeSendBye() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deploySpeedDial(params); + deployLocationService(params); + + String fromName = "sender"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "1"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getOkToByeReceived()); + assertTrue(sender.getByeReceived()); + } + + public void testCancelSpeedDialLocationService() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + receiver.setWaitForCancel(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deploySpeedDial(params); + deployLocationService(params); + + String fromName = "sender"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "1"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(500); + sender.sendCancel(); + Thread.sleep(TIMEOUT); + assertTrue(sender.isCancelOkReceived()); + assertTrue(sender.isRequestTerminatedReceived()); + assertTrue(receiver.isCancelReceived()); + } + + public void testRemoteAddrPortAndTransport() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deploySpeedDial(params); + deployLocationService(params); + + String fromName = "remote"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "1"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/SpeedDialLocationServiceStaticServerAddressTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/SpeedDialLocationServiceStaticServerAddressTest.java index 93198d828d..51222838d8 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/SpeedDialLocationServiceStaticServerAddressTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/SpeedDialLocationServiceStaticServerAddressTest.java @@ -19,357 +19,407 @@ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ - package org.mobicents.servlet.sip.testsuite.composition; +import java.util.HashMap; import java.util.ListIterator; +import java.util.Map; import javax.sip.SipProvider; import javax.sip.address.SipURI; import javax.sip.header.ViaHeader; import javax.sip.message.Request; import javax.sip.message.Response; +import static junit.framework.Assert.assertTrue; import org.apache.catalina.connector.Connector; import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; import org.mobicents.servlet.sip.SipServletTestCase; import org.mobicents.servlet.sip.UDPPacketForwarder; import org.mobicents.servlet.sip.catalina.SipProtocolHandler; +import org.mobicents.servlet.sip.startup.SipStandardContext; import org.mobicents.servlet.sip.testsuite.ProtocolObjects; import org.mobicents.servlet.sip.testsuite.TestSipListener; public class SpeedDialLocationServiceStaticServerAddressTest extends SipServletTestCase { - - private static final int IPLB_ADDRESS_EXTERNAL = 5005; - private static final int IPLB_ADDRESS_INTERNAL = 5115; - private static transient Logger logger = Logger.getLogger(SpeedDialLocationServiceStaticServerAddressTest.class); + private static final int IPLB_ADDRESS_EXTERNAL = 5005; + private static final int IPLB_ADDRESS_INTERNAL = 5115; + + private static transient Logger logger = Logger.getLogger(SpeedDialLocationServiceStaticServerAddressTest.class); - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 20000; + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 20000; // private static final int TIMEOUT = 100000000; - - TestSipListener sender; - TestSipListener receiver; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - - UDPPacketForwarder ipBalancerExternal; - UDPPacketForwarder ipBalancerInternal; - - public SpeedDialLocationServiceStaticServerAddressTest(String name) { - super(name); - startTomcatOnStartup = false; - addSipConnectorOnStartup = false; - autoDeployOnStartup = false; - } - - @Override - public void deployApplication() { - deploySpeedDial(); - deployLocationService(); - } - - private void deploySpeedDial() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/speed-dial-servlet/src/main/sipapp", - "speed-dial-context", - "speed-dial")); - } - - private void deployLocationService() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/location-service-servlet/src/main/sipapp", - "location-service-context", - "location-service")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/composition/speeddial-locationservice-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - Connector udpSipConnector = null; - try { - udpSipConnector = new Connector( - SipProtocolHandler.class.getName()); - } catch (Exception e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } - - SipProtocolHandler udpProtocolHandler = (SipProtocolHandler) udpSipConnector - .getProtocolHandler(); - try { - udpProtocolHandler.setPort(5070); - udpProtocolHandler.setIpAddress("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); - - udpProtocolHandler.setSignalingTransport("udp"); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - tomcat.getSipService().setSipStackProperties(null); - udpProtocolHandler.setUseStaticAddress(true); - udpProtocolHandler.setStaticServerAddress("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); - udpProtocolHandler.setStaticServerPort(IPLB_ADDRESS_EXTERNAL); - tomcat.getSipService().addConnector(udpSipConnector); - tomcat.getSipService().setOutboundProxy(System.getProperty("org.mobicents.testsuite.testhostaddr")+":"+IPLB_ADDRESS_INTERNAL); - //tomcat.getSipService().setOutboundProxy(outboundProxy) - try { - tomcat.startTomcat(); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - deployApplication(); - - senderProtocolObjects = new ProtocolObjects("sender", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - receiverProtocolObjects = new ProtocolObjects("receiver", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - } - - private void startLoadBalancer() { - ipBalancerExternal = new UDPPacketForwarder(IPLB_ADDRESS_EXTERNAL, 5070, "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); - ipBalancerExternal.start(); - ipBalancerInternal = new UDPPacketForwarder(IPLB_ADDRESS_INTERNAL, 5090, "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); - ipBalancerInternal.start(); - } - - public void testSpeedDialLocationServiceCallerSendBye() throws Exception { - sender = new TestSipListener(5080, 5005, senderProtocolObjects, true); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5005, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - startLoadBalancer(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "sender"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "1"; - String toHost = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - assertTrue(ipBalancerInternal.sipMessageWithoutRetrans.size()>0); - } - - public void testSpeedDialLocationServiceErrorResponse() throws Exception { - sender = new TestSipListener(5080, 5005, senderProtocolObjects, true); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5005, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - startLoadBalancer(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - receiver.setRespondWithError(408); - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "sender-expect-408"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "1"; - String toHost = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isServerErrorReceived()); - } - - public void testSpeedDialLocationServiceCalleeSendBye() throws Exception { - sender = new TestSipListener(5080, 5005, senderProtocolObjects, false); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5005, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - receiver.setWaitBeforeFinalResponse(2000); - SipProvider receiverProvider = receiver.createProvider(); - - startLoadBalancer(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "sender"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "1"; - String toHost = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(7000); - receiver.sendInDialogSipRequest("INVITE", null, null, null, null, null); - Thread.sleep(7000); - receiver.sendInDialogSipRequest("INVITE", null, null, null, null, null); - Thread.sleep(7000); - receiver.sendInDialogSipRequest("INVITE", null, null, null, null, null); - Thread.sleep(7000); - receiver.sendInDialogSipRequest("INVITE", null, null, null, null, null); - Thread.sleep(7000); - receiver.sendInDialogSipRequest("BYE", null, null, null, null, null); - Thread.sleep(7000); - int count = 0; - ListIterator viaHeaders = sender.getInviteRequest().getHeaders(ViaHeader.NAME); - while(viaHeaders.hasNext()) {viaHeaders.next(); count++;} - - - assertEquals(3, count); // must see exactly 3 via headers in the callee->caller direction - //TODO: review this assertTrue(ipBalancerExternal.sipMessageWithoutRetrans.size()<=27); // More than 26 messages means the something that should be bypassing is going through it - assertTrue(receiver.isAckReceived()); // is the ACK working in the callee->caller direction - assertTrue(sender.isAckReceived()); // is the ACK working in the caller->callee direction - assertTrue(ipBalancerExternal.sipMessageWithoutRetrans.size()>0); - assertTrue(ipBalancerInternal.sipMessageWithoutRetrans.size()>0); - assertTrue(receiver.getOkToByeReceived()); - assertTrue(sender.getByeReceived()); - - for(Request r : receiver.allRequests) { - ViaHeader via = (ViaHeader) r.getHeader(ViaHeader.NAME); - assertEquals(IPLB_ADDRESS_EXTERNAL, via.getPort()); - } - for(Request r : sender.allRequests) { - ViaHeader via = (ViaHeader) r.getHeader(ViaHeader.NAME); - assertEquals(IPLB_ADDRESS_EXTERNAL, via.getPort()); - } - - for(Response message : sender.allResponses) { - if(message.getStatusCode()>200) { - fail("We don't expect errors. This is error: " + message); - } - } - for(Response message : receiver.allResponses) { - if(message.getStatusCode()>200) { - fail("We don't expect errors. This is error: " + message); - } - } - } - - public void testCancelSpeedDialLocationService() throws Exception { - sender = new TestSipListener(5080, 5005, senderProtocolObjects, false); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - startLoadBalancer(); - - receiver = new TestSipListener(5090, 5005, receiverProtocolObjects, true); - receiver.setRecordRoutingProxyTesting(true); - receiver.setWaitForCancel(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "sender"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "1"; - String toHost = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(500); - sender.sendCancel(); - Thread.sleep(TIMEOUT); - assertTrue(sender.isCancelOkReceived()); - assertTrue(sender.isRequestTerminatedReceived()); - assertTrue(receiver.isCancelReceived()); - assertTrue(ipBalancerInternal.sipMessageWithoutRetrans.size()>0); - assertTrue(ipBalancerExternal.sipMessageWithoutRetrans.size()>0); - } - - public void testRemoteAddrPortAndTransport() throws Exception { - startLoadBalancer(); - sender = new TestSipListener(5080, 5005, senderProtocolObjects, true); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - - - receiver = new TestSipListener(5090, 5005, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - receiver.setWaitBeforeFinalResponse(2000); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "remote"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "1"; - String toHost = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - ipBalancerExternal.stop(); - ipBalancerInternal.stop(); - logger.info("Test completed"); - super.tearDown(); - } + TestSipListener sender; + TestSipListener receiver; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + + UDPPacketForwarder ipBalancerExternal; + UDPPacketForwarder ipBalancerInternal; + + public SpeedDialLocationServiceStaticServerAddressTest(String name) { + super(name); + startTomcatOnStartup = false; + addSipConnectorOnStartup = false; + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + private void deploySpeedDial(Map params) { + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/speed-dial-servlet/src/main/sipapp", + "speed-dial", + params, null); + assertTrue(ctx.getAvailable()); + } + + private void deployLocationService(Map params) { + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/location-service-servlet/src/main/sipapp", + "location-service", + params, null); + assertTrue(ctx.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/composition/speeddial-locationservice-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + Connector udpSipConnector = null; + try { + udpSipConnector = new Connector( + SipProtocolHandler.class.getName()); + } catch (Exception e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + + SipProtocolHandler udpProtocolHandler = (SipProtocolHandler) udpSipConnector + .getProtocolHandler(); + try { + udpProtocolHandler.setPort(containerPort); + udpProtocolHandler.setIpAddress("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); + + udpProtocolHandler.setSignalingTransport("udp"); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + tomcat.getSipService().setSipStackProperties(null); + udpProtocolHandler.setUseStaticAddress(true); + udpProtocolHandler.setStaticServerAddress("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); + udpProtocolHandler.setStaticServerPort(IPLB_ADDRESS_EXTERNAL); + tomcat.getSipService().addConnector(udpSipConnector); + tomcat.getSipService().setOutboundProxy(System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + IPLB_ADDRESS_INTERNAL); + //tomcat.getSipService().setOutboundProxy(outboundProxy) + try { + tomcat.startTomcat(); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + deployApplication(); + + senderProtocolObjects = new ProtocolObjects("sender", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects("receiver", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + } + + private void startLoadBalancer(int receiverPort) { + ipBalancerExternal = new UDPPacketForwarder(IPLB_ADDRESS_EXTERNAL, containerPort, "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); + ipBalancerExternal.start(); + ipBalancerInternal = new UDPPacketForwarder(IPLB_ADDRESS_INTERNAL, receiverPort, "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); + ipBalancerInternal.start(); + } + + public void testSpeedDialLocationServiceCallerSendBye() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, IPLB_ADDRESS_EXTERNAL, senderProtocolObjects, true); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, IPLB_ADDRESS_EXTERNAL, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + startLoadBalancer(receiverPort); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deploySpeedDial(params); + deployLocationService(params); + + String fromName = "sender"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "1"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + assertTrue(ipBalancerInternal.sipMessageWithoutRetrans.size() > 0); + } + + public void testSpeedDialLocationServiceErrorResponse() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, IPLB_ADDRESS_EXTERNAL, senderProtocolObjects, true); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, IPLB_ADDRESS_EXTERNAL, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + startLoadBalancer(receiverPort); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + receiver.setRespondWithError(408); + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deploySpeedDial(params); + deployLocationService(params); + + String fromName = "sender-expect-408"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "1"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isServerErrorReceived()); + } + + public void testSpeedDialLocationServiceCalleeSendBye() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, IPLB_ADDRESS_EXTERNAL, senderProtocolObjects, false); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, IPLB_ADDRESS_EXTERNAL, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + receiver.setWaitBeforeFinalResponse(2000); + SipProvider receiverProvider = receiver.createProvider(); + + startLoadBalancer(receiverPort); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deploySpeedDial(params); + deployLocationService(params); + + String fromName = "sender"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "1"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(7000); + receiver.sendInDialogSipRequest("INVITE", null, null, null, null, null); + Thread.sleep(7000); + receiver.sendInDialogSipRequest("INVITE", null, null, null, null, null); + Thread.sleep(7000); + receiver.sendInDialogSipRequest("INVITE", null, null, null, null, null); + Thread.sleep(7000); + receiver.sendInDialogSipRequest("INVITE", null, null, null, null, null); + Thread.sleep(7000); + receiver.sendInDialogSipRequest("BYE", null, null, null, null, null); + Thread.sleep(7000); + int count = 0; + ListIterator viaHeaders = sender.getInviteRequest().getHeaders(ViaHeader.NAME); + while (viaHeaders.hasNext()) { + viaHeaders.next(); + count++; + } + + assertEquals(3, count); // must see exactly 3 via headers in the callee->caller direction + //TODO: review this assertTrue(ipBalancerExternal.sipMessageWithoutRetrans.size()<=27); // More than 26 messages means the something that should be bypassing is going through it + assertTrue(receiver.isAckReceived()); // is the ACK working in the callee->caller direction + assertTrue(sender.isAckReceived()); // is the ACK working in the caller->callee direction + assertTrue(ipBalancerExternal.sipMessageWithoutRetrans.size() > 0); + assertTrue(ipBalancerInternal.sipMessageWithoutRetrans.size() > 0); + assertTrue(receiver.getOkToByeReceived()); + assertTrue(sender.getByeReceived()); + + for (Request r : receiver.allRequests) { + ViaHeader via = (ViaHeader) r.getHeader(ViaHeader.NAME); + assertEquals(IPLB_ADDRESS_EXTERNAL, via.getPort()); + } + for (Request r : sender.allRequests) { + ViaHeader via = (ViaHeader) r.getHeader(ViaHeader.NAME); + assertEquals(IPLB_ADDRESS_EXTERNAL, via.getPort()); + } + + for (Response message : sender.allResponses) { + if (message.getStatusCode() > 200) { + fail("We don't expect errors. This is error: " + message); + } + } + for (Response message : receiver.allResponses) { + if (message.getStatusCode() > 200) { + fail("We don't expect errors. This is error: " + message); + } + } + } + + public void testCancelSpeedDialLocationService() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, IPLB_ADDRESS_EXTERNAL, senderProtocolObjects, true); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, IPLB_ADDRESS_EXTERNAL, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + receiver.setWaitForCancel(true); + SipProvider receiverProvider = receiver.createProvider(); + + startLoadBalancer(receiverPort); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deploySpeedDial(params); + deployLocationService(params); + + String fromName = "sender"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "1"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(500); + sender.sendCancel(); + Thread.sleep(TIMEOUT); + assertTrue(sender.isCancelOkReceived()); + assertTrue(sender.isRequestTerminatedReceived()); + assertTrue(receiver.isCancelReceived()); + assertTrue(ipBalancerInternal.sipMessageWithoutRetrans.size() > 0); + assertTrue(ipBalancerExternal.sipMessageWithoutRetrans.size() > 0); + } + + public void testRemoteAddrPortAndTransport() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, IPLB_ADDRESS_EXTERNAL, senderProtocolObjects, true); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, IPLB_ADDRESS_EXTERNAL, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + receiver.setWaitBeforeFinalResponse(2000); + SipProvider receiverProvider = receiver.createProvider(); + + startLoadBalancer(receiverPort); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deploySpeedDial(params); + deployLocationService(params); + + String fromName = "remote"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "1"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + ipBalancerExternal.stop(); + ipBalancerInternal.stop(); + logger.info("Test completed"); + super.tearDown(); + } } diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/SpeedDial_LocationServiceTwice_JunitTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/SpeedDial_LocationServiceTwice_JunitTest.java index 321e564d51..b3ada43fb0 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/SpeedDial_LocationServiceTwice_JunitTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/composition/SpeedDial_LocationServiceTwice_JunitTest.java @@ -1,304 +1,351 @@ -/* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2014, Telestax Inc and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - * - * This file incorporates work covered by the following copyright contributed under the GNU LGPL : Copyright 2007-2011 Red Hat. - */ - -package org.mobicents.servlet.sip.testsuite.composition; - -import java.util.ListIterator; - -import javax.sip.SipProvider; -import javax.sip.address.SipURI; -import javax.sip.address.URI; -import javax.sip.header.Header; -import javax.sip.header.ReasonHeader; -import javax.sip.header.RecordRouteHeader; - -import org.apache.catalina.deploy.ApplicationParameter; -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class SpeedDial_LocationServiceTwice_JunitTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(SpeedDial_LocationServiceTwice_JunitTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender; - TestSipListener receiver; - TestSipListener receiver2; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - ProtocolObjects receiver2ProtocolObjects; - - public SpeedDial_LocationServiceTwice_JunitTest(String name) { - super(name); - } - - @Override - protected void deployApplication() { - - } - - public void deployBothApplication(boolean isSpeedDialRecordRoute) { - deploySpeedDial("record_route", "" + isSpeedDialRecordRoute); - deployLocationService(); - } - - public void deploySpeedDial(String name, String value) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/speed-dial-servlet/src/main/sipapp"); - context.setName("speed-dial-context"); - context.setPath("speed-dial"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(name); - applicationParameter.setValue(value); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - } - - private void deployLocationService() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/location-service-servlet/src/main/sipapp", - "location-service-context", - "location-service")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/composition/speeddial-locationservice-twice-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects = new ProtocolObjects("sender", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - receiverProtocolObjects = new ProtocolObjects("receiver", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - receiver2ProtocolObjects = new ProtocolObjects("receiver2", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - } - - /* - * Non regression test for https://code.google.com/p/sipservlets/issues/detail?id=273 - */ - public void testSpeedDialLocationServicePRACKCalleeSendBye() throws Exception { - deployBothApplication(true); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, true); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "sender"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "7"; - String toHost = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - String[] headerNames = new String[]{"require"}; - String[] headerValues = new String[]{"100rel"}; - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, headerNames, headerValues, true); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getOkToByeReceived()); - assertTrue(sender.getByeReceived()); - int numberOfPrack = 0; - ListIterator
listHeaderIt = receiver.getPrackRequestReceived().getHeaders("X-Seen"); - while (listHeaderIt.hasNext()) { - listHeaderIt.next(); - numberOfPrack++; - } - assertEquals(2,numberOfPrack); - } - - /* - * Non regression test for https://code.google.com/p/sipservlets/issues/detail?id=274 - */ - public void testSpeedDialLocationServiceRecordRouteReInviteCallerSendBye() throws Exception { - deployBothApplication(true); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "sender"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "7"; - String toHost = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - sender.setSendReinvite(true); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isInviteReceived()); - sender.sendInDialogSipRequest("BYE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - assertTrue(sender.getOkToByeReceived()); - int numberOfRRouteHeaders = 0; - ListIterator
listHeaderIt = receiver.getInviteRequest().getHeaders(RecordRouteHeader.NAME); - while (listHeaderIt.hasNext()) { - listHeaderIt.next(); - numberOfRRouteHeaders++; - } - assertEquals(3,numberOfRRouteHeaders); - } - - /* - * Non regression test for https://code.google.com/p/sipservlets/issues/detail?id=275 - */ - public void testSpeedDialLocationServiceRecordRouteReInviteCalleeSendReInvite() throws Exception { - deployBothApplication(true); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "sender"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "7"; - String toHost = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - receiver.setSendReinvite(true); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isInviteReceived()); - URI requestUri = sender.getInviteRequest().getRequestURI(); - assertEquals("sip:sender@127.0.0.1:5080;transport=udp;lr", requestUri.toString().trim()); - sender.sendInDialogSipRequest("BYE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - assertTrue(sender.getOkToByeReceived()); - int numberOfRRouteHeaders = 0; - ListIterator
listHeaderIt = receiver.getInviteRequest().getHeaders(RecordRouteHeader.NAME); - while (listHeaderIt.hasNext()) { - listHeaderIt.next(); - numberOfRRouteHeaders++; - } - assertEquals(3,numberOfRRouteHeaders); - } - - /* - * Non Regression test for https://code.google.com/p/sipservlets/issues/detail?id=164 - */ - public void testCancelProxying() throws Exception { - deployBothApplication(false); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiver2 = new TestSipListener(5091, 5070, receiver2ProtocolObjects, false); - receiver2.setRecordRoutingProxyTesting(true); - SipProvider receiver2Provider = receiver2.createProvider(); - - receiverProvider.addSipListener(receiver); - receiver2Provider.addSipListener(receiver2); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - receiver2ProtocolObjects.start(); - - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "8"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - receiver2.setWaitForCancel(true); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(receiver2.isCancelReceived()); - assertTrue(sender.isFinalResponseReceived()); - // https://code.google.com/p/sipservlets/issues/detail?id=272 - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2014, Telestax Inc and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * + * This file incorporates work covered by the following copyright contributed under the GNU LGPL : Copyright 2007-2011 Red Hat. + */ +package org.mobicents.servlet.sip.testsuite.composition; + +import gov.nist.javax.sip.header.ims.PPreferredServiceHeader; +import java.util.HashMap; + +import java.util.ListIterator; +import java.util.Map; + +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import javax.sip.address.URI; +import javax.sip.header.Header; + +import javax.sip.header.RecordRouteHeader; + +import org.apache.catalina.deploy.ApplicationParameter; +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.catalina.SipStandardManager; +import org.mobicents.servlet.sip.startup.SipContextConfig; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class SpeedDial_LocationServiceTwice_JunitTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(SpeedDial_LocationServiceTwice_JunitTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + TestSipListener receiver; + TestSipListener receiver2; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + ProtocolObjects receiver2ProtocolObjects; + + public SpeedDial_LocationServiceTwice_JunitTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + protected void deployApplication() { + + } + + public void deployBothApplication(Map params) { + deploySpeedDial(params);//, "" + isSpeedDialRecordRoute); + deployLocationService(params); + } + + private void deploySpeedDial(Map params) { + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/speed-dial-servlet/src/main/sipapp", + "speed-dial", + params, null); + assertTrue(ctx.getAvailable()); + } + + private void deployLocationService(Map params) { + SipStandardContext ctx = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/location-service-servlet/src/main/sipapp", + "location-service", + params, null); + assertTrue(ctx.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/composition/speeddial-locationservice-twice-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects("sender", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects("receiver", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + receiver2ProtocolObjects = new ProtocolObjects("receiver2", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + } + + /* + * Non regression test for https://code.google.com/p/sipservlets/issues/detail?id=273 + */ + public void testSpeedDialLocationServicePRACKCalleeSendBye() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, true); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + params.put("record_route", "true"); + deployBothApplication(params); + + String fromName = "sender"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "7"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + String[] headerNames = new String[]{"require", "P-Preferred-Service"}; + String[] headerValues = new String[]{"100rel", "urn:urn-7:3gpp-service.ims.icsi.mmtel.gsma.ipcall"}; + String sdpContent = "\n" + + "v=0\n" + + "o=- 1 1 IN IP4 127.0.0.1\n" + + "s=helium\n" + + "c=IN IP4 127.0.0.1\n" + + "t=0 0\n" + + "a=sendrecv\n" + + "m=audio 30010 RTP/AVP 8\n" + + "a=rtpmap:8 PCMA/8000"; + + sender.sendSipRequest("INVITE", fromAddress, toAddress, sdpContent, null, false, headerNames, headerValues, true); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getOkToByeReceived()); + assertTrue(sender.getByeReceived()); + assertNotNull(receiver.getInviteRequest().getHeader(PPreferredServiceHeader.NAME)); + System.out.println("received request content " + receiver.getInviteRequest().getContent()); + assertEquals(sdpContent, new String(receiver.getInviteRequest().getRawContent(), "UTF-8")); + + int numberOfPrack = 0; + ListIterator
listHeaderIt = receiver.getPrackRequestReceived().getHeaders("X-Seen"); + while (listHeaderIt.hasNext()) { + listHeaderIt.next(); + numberOfPrack++; + } + assertEquals(2, numberOfPrack); + } + + /* + * Non regression test for https://code.google.com/p/sipservlets/issues/detail?id=274 + */ + public void testSpeedDialLocationServiceRecordRouteReInviteCallerSendBye() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + params.put("record_route", "true"); + deployBothApplication(params); + + String fromName = "sender"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "7"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + sender.setSendReinvite(true); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isInviteReceived()); + sender.sendInDialogSipRequest("BYE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + assertTrue(sender.getOkToByeReceived()); + int numberOfRRouteHeaders = 0; + ListIterator
listHeaderIt = receiver.getInviteRequest().getHeaders(RecordRouteHeader.NAME); + while (listHeaderIt.hasNext()) { + listHeaderIt.next(); + numberOfRRouteHeaders++; + } + assertEquals(3, numberOfRRouteHeaders); + } + + /* + * Non regression test for https://code.google.com/p/sipservlets/issues/detail?id=275 + */ + public void testSpeedDialLocationServiceRecordRouteReInviteCalleeSendReInvite() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + params.put("record_route", "true"); + deployBothApplication(params); + + String fromName = "sender"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "7"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + receiver.setSendReinvite(true); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isInviteReceived()); + URI requestUri = sender.getInviteRequest().getRequestURI(); + assertEquals("sip:sender@127.0.0.1:" + senderPort + ";transport=udp;lr", requestUri.toString().trim()); + sender.sendInDialogSipRequest("BYE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + assertTrue(sender.getOkToByeReceived()); + int numberOfRRouteHeaders = 0; + ListIterator
listHeaderIt = receiver.getInviteRequest().getHeaders(RecordRouteHeader.NAME); + while (listHeaderIt.hasNext()) { + listHeaderIt.next(); + numberOfRRouteHeaders++; + } + assertEquals(3, numberOfRRouteHeaders); + } + + /* + * Non Regression test for https://code.google.com/p/sipservlets/issues/detail?id=164 + */ + public void testCancelProxying() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + int receiver2Port = NetworkPortAssigner.retrieveNextPort(); + receiver2 = new TestSipListener(receiver2Port, containerPort, receiver2ProtocolObjects, false); + receiver2.setRecordRoutingProxyTesting(true); + SipProvider receiver2Provider = receiver2.createProvider(); + + receiverProvider.addSipListener(receiver); + receiver2Provider.addSipListener(receiver2); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + receiver2ProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + params.put("receiver2Port", String.valueOf(receiver2Port)); + params.put("record_route", "false"); + deployBothApplication(params); + + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "8"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + receiver2.setWaitForCancel(true); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(receiver2.isCancelReceived()); + assertTrue(sender.isFinalResponseReceived()); + // https://code.google.com/p/sipservlets/issues/detail?id=272 + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/concurrency/ConcurrentyControlAsyncWorkSessionIsolationTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/concurrency/ConcurrentyControlAsyncWorkSessionIsolationTest.java index c6af020c82..f8ea2efa9d 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/concurrency/ConcurrentyControlAsyncWorkSessionIsolationTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/concurrency/ConcurrentyControlAsyncWorkSessionIsolationTest.java @@ -1,313 +1,352 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.concurrency; - -import java.io.InputStream; -import java.net.URL; -import java.util.Iterator; - -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class ConcurrentyControlAsyncWorkSessionIsolationTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(ConcurrentyControlAsyncWorkSessionIsolationTest.class); - private String CLICK2DIAL_URL; - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; -// private static final int TIMEOUT = 5000; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender; - - ProtocolObjects senderProtocolObjects; - - - public ConcurrentyControlAsyncWorkSessionIsolationTest(String name) { - super(name); - autoDeployOnStartup = false; - } - - public void deployApplication() { - - } - - public void deployApplication(ConcurrencyControlMode concurrencyControlMode) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome - + "/sip-servlets-test-suite/applications/click-to-call-servlet/src/main/sipapp"); - context.setName("click2call"); - context.setPath("/click2call"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - context.setConcurrencyControlMode(concurrencyControlMode); - assertTrue(tomcat.deployContext(context)); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/concurrency/click-to-call-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - CLICK2DIAL_URL = "http://" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":8080/click2call/call"; - - senderProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - } - - public void testElapsedTimeAndSessionOverlapping() throws Exception { - deployApplication(ConcurrencyControlMode.SipSession); - String fromName = "asyncWork"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - fromAddress.setParameter("mode", ConcurrencyControlMode.SipSession.toString()); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setSendBye(false); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(3000); - String sasId = new String(sender.getFinalResponse().getRawContent()); - String CLICK2DIAL_PARAMS = "?asyncWorkMode=" + ConcurrencyControlMode.SipSession + "&asyncWorkSasId="+ sasId; -// long startTime = System.currentTimeMillis(); - sender.sendInDialogSipRequest("OPTIONS", "1", "text", "plain", null, null); - Thread.sleep(100); - sender.sendInDialogSipRequest("OPTIONS", "2", "text", "plain", null, null); - Thread.sleep(100); - logger.info("Trying to reach url : " + CLICK2DIAL_URL - + CLICK2DIAL_PARAMS); - - URL url = new URL(CLICK2DIAL_URL + CLICK2DIAL_PARAMS); - InputStream in = url.openConnection().getInputStream(); - - byte[] buffer = new byte[10000]; - int len = in.read(buffer); - String httpResponse = ""; - for (int q = 0; q < len; q++) - httpResponse += (char) buffer[q]; - logger.info("Received the follwing HTTP response: " + httpResponse); - sender.sendInDialogSipRequest("OPTIONS", "3", "text", "plain", null, null); - Thread.sleep(100); - sender.sendBye(); - Thread.sleep(20000); -// long elapsedTime = sender.getLastInfoResponseTime() - startTime; -// assertTrue(elapsedTime>15000); - assertTrue(!sender.isServerErrorReceived()); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertTrue(sender.getAllMessagesContent().contains("OK")); - } - - public void testElapsedTimeAndSipApplicationSessionOverlapping() throws Exception { - deployApplication(ConcurrencyControlMode.SipApplicationSession); - String fromName = "asyncWork"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - fromAddress.setParameter("mode", ConcurrencyControlMode.SipApplicationSession.toString()); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setSendBye(false); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(3000); - String sasId = new String(sender.getFinalResponse().getRawContent()); - String CLICK2DIAL_PARAMS = "?asyncWorkMode=" + ConcurrencyControlMode.SipApplicationSession + "&asyncWorkSasId="+ sasId; -// long startTime = System.currentTimeMillis(); - sender.sendInDialogSipRequest("OPTIONS", "1", "text", "plain", null, null); - Thread.sleep(100); - sender.sendInDialogSipRequest("OPTIONS", "2", "text", "plain", null, null); - Thread.sleep(100); - logger.info("Trying to reach url : " + CLICK2DIAL_URL - + CLICK2DIAL_PARAMS); - - URL url = new URL(CLICK2DIAL_URL + CLICK2DIAL_PARAMS); - InputStream in = url.openConnection().getInputStream(); - - byte[] buffer = new byte[10000]; - int len = in.read(buffer); - String httpResponse = ""; - for (int q = 0; q < len; q++) - httpResponse += (char) buffer[q]; - logger.info("Received the follwing HTTP response: " + httpResponse); - sender.sendInDialogSipRequest("OPTIONS", "3", "text", "plain", null, null); - Thread.sleep(100); - sender.sendBye(); - Thread.sleep(20000); -// long elapsedTime = sender.getLastInfoResponseTime() - startTime; -// assertTrue(elapsedTime>15000); - assertTrue(!sender.isServerErrorReceived()); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertTrue(sender.getAllMessagesContent().contains("OK")); - } - - public void testElapsedTimeAndSipApplicationSessionDeadlock() throws Exception { - deployApplication(ConcurrencyControlMode.SipApplicationSession); - String fromName = "Thread"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - fromAddress.setParameter("mode", ConcurrencyControlMode.SipApplicationSession.toString()); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - -// sender.setSendBye(false); -// sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); -// Thread.sleep(3000); -// String sasId = new String(sender.getFinalResponse().getRawContent()); - String CLICK2DIAL_PARAMS = "?asyncWorkMode=Thread&asyncWorkSasId=test"; -// long startTime = System.currentTimeMillis(); -// sender.sendInDialogSipRequest("OPTIONS", "1", "text", "plain", null, null); -// Thread.sleep(100); -// sender.sendInDialogSipRequest("OPTIONS", "2", "text", "plain", null, null); -// Thread.sleep(100); - logger.info("Trying to reach url : " + CLICK2DIAL_URL - + CLICK2DIAL_PARAMS); - - URL url = new URL(CLICK2DIAL_URL + CLICK2DIAL_PARAMS); - InputStream in = url.openConnection().getInputStream(); - - byte[] buffer = new byte[10000]; - int len = in.read(buffer); - String httpResponse = ""; - for (int q = 0; q < len; q++) - httpResponse += (char) buffer[q]; - logger.info("Received the follwing HTTP response: " + httpResponse); -// sender.sendInDialogSipRequest("OPTIONS", "3", "text", "plain", null, null); -// Thread.sleep(100); -// sender.sendBye(); - Thread.sleep(10000); -// long elapsedTime = sender.getLastInfoResponseTime() - startTime; -// assertTrue(elapsedTime>15000); -// assertTrue(!sender.isServerErrorReceived()); -// assertTrue(sender.isAckSent()); -// assertTrue(sender.getOkToByeReceived()); - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertTrue(sender.getAllMessagesContent().contains("OK")); - } - - public void testElapsedTimeAndSessionOverlappingWithNoConcurrencyControl() throws Exception { - deployApplication(ConcurrencyControlMode.None); - String fromName = "asyncWork"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - fromAddress.setParameter("mode", ConcurrencyControlMode.None.toString()); - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setSendBye(false); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(3000); - String sasId = new String(sender.getFinalResponse().getRawContent()); - String CLICK2DIAL_PARAMS = "?asyncWorkMode=" + ConcurrencyControlMode.None + "&asyncWorkSasId="+ sasId; -// long startTime = System.currentTimeMillis(); - sender.sendInDialogSipRequest("OPTIONS", "1", "text", "plain", null, null); - Thread.sleep(100); - sender.sendInDialogSipRequest("OPTIONS", "2", "text", "plain", null, null); - Thread.sleep(100); - logger.info("Trying to reach url : " + CLICK2DIAL_URL - + CLICK2DIAL_PARAMS); - - URL url = new URL(CLICK2DIAL_URL + CLICK2DIAL_PARAMS); - InputStream in = url.openConnection().getInputStream(); - - byte[] buffer = new byte[10000]; - int len = in.read(buffer); - String httpResponse = ""; - for (int q = 0; q < len; q++) - httpResponse += (char) buffer[q]; - logger.info("Received the follwing HTTP response: " + httpResponse); - sender.sendInDialogSipRequest("OPTIONS", "3", "text", "plain", null, null); - Thread.sleep(100); - sender.sendBye(); - Thread.sleep(20000); -// long elapsedTime = sender.getLastInfoResponseTime() - startTime; -// assertTrue(elapsedTime>15000); - assertTrue(sender.isServerErrorReceived()); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertTrue(sender.getAllMessagesContent().contains("KO")); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.concurrency; + +import java.io.InputStream; +import java.net.URL; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import javax.sip.SipProvider; +import javax.sip.address.SipURI; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class ConcurrentyControlAsyncWorkSessionIsolationTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ConcurrentyControlAsyncWorkSessionIsolationTest.class); + private String CLICK2DIAL_URL; + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; +// private static final int TIMEOUT = 5000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + + ProtocolObjects senderProtocolObjects; + + public ConcurrentyControlAsyncWorkSessionIsolationTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + public void deployApplication() { + + } + + public void deployApplication(Map params, ConcurrencyControlMode concurrencyControlMode) { + SipStandardContext context = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/click-to-call-servlet/src/main/sipapp", + "click2call", + params, + concurrencyControlMode); + assertTrue(context.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/concurrency/click-to-call-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + CLICK2DIAL_URL = "http://" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + httpContainerPort + "/click2call/call"; + + } + + public void testElapsedTimeAndSessionOverlapping() throws Exception { + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + deployApplication(params, ConcurrencyControlMode.SipSession); + + String fromName = "asyncWork"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + fromAddress.setParameter("mode", ConcurrencyControlMode.SipSession.toString()); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setSendBye(false); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(3000); + String sasId = new String(sender.getFinalResponse().getRawContent()); + String CLICK2DIAL_PARAMS = "?asyncWorkMode=" + ConcurrencyControlMode.SipSession + "&asyncWorkSasId=" + sasId; +// long startTime = System.currentTimeMillis(); + sender.sendInDialogSipRequest("OPTIONS", "1", "text", "plain", null, null); + Thread.sleep(100); + sender.sendInDialogSipRequest("OPTIONS", "2", "text", "plain", null, null); + Thread.sleep(100); + logger.info("Trying to reach url : " + CLICK2DIAL_URL + + CLICK2DIAL_PARAMS); + + URL url = new URL(CLICK2DIAL_URL + CLICK2DIAL_PARAMS); + InputStream in = url.openConnection().getInputStream(); + + byte[] buffer = new byte[10000]; + int len = in.read(buffer); + String httpResponse = ""; + for (int q = 0; q < len; q++) { + httpResponse += (char) buffer[q]; + } + logger.info("Received the follwing HTTP response: " + httpResponse); + sender.sendInDialogSipRequest("OPTIONS", "3", "text", "plain", null, null); + Thread.sleep(100); + sender.sendBye(); + Thread.sleep(20000); +// long elapsedTime = sender.getLastInfoResponseTime() - startTime; +// assertTrue(elapsedTime>15000); + assertTrue(!sender.isServerErrorReceived()); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertTrue(sender.getAllMessagesContent().contains("OK")); + } + + public void testElapsedTimeAndSipApplicationSessionOverlapping() throws Exception { + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + deployApplication(params, ConcurrencyControlMode.SipApplicationSession); + + String fromName = "asyncWork"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + fromAddress.setParameter("mode", ConcurrencyControlMode.SipApplicationSession.toString()); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setSendBye(false); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(3000); + String sasId = new String(sender.getFinalResponse().getRawContent()); + String CLICK2DIAL_PARAMS = "?asyncWorkMode=" + ConcurrencyControlMode.SipApplicationSession + "&asyncWorkSasId=" + sasId; +// long startTime = System.currentTimeMillis(); + sender.sendInDialogSipRequest("OPTIONS", "1", "text", "plain", null, null); + Thread.sleep(100); + sender.sendInDialogSipRequest("OPTIONS", "2", "text", "plain", null, null); + Thread.sleep(100); + logger.info("Trying to reach url : " + CLICK2DIAL_URL + + CLICK2DIAL_PARAMS); + + URL url = new URL(CLICK2DIAL_URL + CLICK2DIAL_PARAMS); + InputStream in = url.openConnection().getInputStream(); + + byte[] buffer = new byte[10000]; + int len = in.read(buffer); + String httpResponse = ""; + for (int q = 0; q < len; q++) { + httpResponse += (char) buffer[q]; + } + logger.info("Received the follwing HTTP response: " + httpResponse); + sender.sendInDialogSipRequest("OPTIONS", "3", "text", "plain", null, null); + Thread.sleep(100); + sender.sendBye(); + Thread.sleep(20000); +// long elapsedTime = sender.getLastInfoResponseTime() - startTime; +// assertTrue(elapsedTime>15000); + assertTrue(!sender.isServerErrorReceived()); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertTrue(sender.getAllMessagesContent().contains("OK")); + } + + public void testElapsedTimeAndSipApplicationSessionDeadlock() throws Exception { + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + deployApplication(params, ConcurrencyControlMode.SipApplicationSession); + + String fromName = "Thread"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + fromAddress.setParameter("mode", ConcurrencyControlMode.SipApplicationSession.toString()); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + +// sender.setSendBye(false); +// sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); +// Thread.sleep(3000); +// String sasId = new String(sender.getFinalResponse().getRawContent()); + String CLICK2DIAL_PARAMS = "?asyncWorkMode=Thread&asyncWorkSasId=test"; +// long startTime = System.currentTimeMillis(); +// sender.sendInDialogSipRequest("OPTIONS", "1", "text", "plain", null, null); +// Thread.sleep(100); +// sender.sendInDialogSipRequest("OPTIONS", "2", "text", "plain", null, null); +// Thread.sleep(100); + logger.info("Trying to reach url : " + CLICK2DIAL_URL + + CLICK2DIAL_PARAMS); + + URL url = new URL(CLICK2DIAL_URL + CLICK2DIAL_PARAMS); + InputStream in = url.openConnection().getInputStream(); + + byte[] buffer = new byte[10000]; + int len = in.read(buffer); + String httpResponse = ""; + for (int q = 0; q < len; q++) { + httpResponse += (char) buffer[q]; + } + logger.info("Received the follwing HTTP response: " + httpResponse); +// sender.sendInDialogSipRequest("OPTIONS", "3", "text", "plain", null, null); +// Thread.sleep(100); +// sender.sendBye(); + Thread.sleep(10000); +// long elapsedTime = sender.getLastInfoResponseTime() - startTime; +// assertTrue(elapsedTime>15000); +// assertTrue(!sender.isServerErrorReceived()); +// assertTrue(sender.isAckSent()); +// assertTrue(sender.getOkToByeReceived()); + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertTrue(sender.getAllMessagesContent().contains("OK")); + } + + public void testElapsedTimeAndSessionOverlappingWithNoConcurrencyControl() throws Exception { + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + deployApplication(params, ConcurrencyControlMode.None); + + String fromName = "asyncWork"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + fromAddress.setParameter("mode", ConcurrencyControlMode.None.toString()); + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setSendBye(false); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(3000); + String sasId = new String(sender.getFinalResponse().getRawContent()); + String CLICK2DIAL_PARAMS = "?asyncWorkMode=" + ConcurrencyControlMode.None + "&asyncWorkSasId=" + sasId; +// long startTime = System.currentTimeMillis(); + sender.sendInDialogSipRequest("OPTIONS", "1", "text", "plain", null, null); + Thread.sleep(100); + sender.sendInDialogSipRequest("OPTIONS", "2", "text", "plain", null, null); + Thread.sleep(100); + logger.info("Trying to reach url : " + CLICK2DIAL_URL + + CLICK2DIAL_PARAMS); + + URL url = new URL(CLICK2DIAL_URL + CLICK2DIAL_PARAMS); + InputStream in = url.openConnection().getInputStream(); + + byte[] buffer = new byte[10000]; + int len = in.read(buffer); + String httpResponse = ""; + for (int q = 0; q < len; q++) { + httpResponse += (char) buffer[q]; + } + logger.info("Received the follwing HTTP response: " + httpResponse); + sender.sendInDialogSipRequest("OPTIONS", "3", "text", "plain", null, null); + Thread.sleep(100); + sender.sendBye(); + Thread.sleep(20000); +// long elapsedTime = sender.getLastInfoResponseTime() - startTime; +// assertTrue(elapsedTime>15000); + assertTrue(sender.isServerErrorReceived()); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertTrue(sender.getAllMessagesContent().contains("KO")); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/concurrency/ConcurrentyControlSipSessionIsolationTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/concurrency/ConcurrentyControlSipSessionIsolationTest.java index e012d7fb9c..d443c77f83 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/concurrency/ConcurrentyControlSipSessionIsolationTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/concurrency/ConcurrentyControlSipSessionIsolationTest.java @@ -1,198 +1,227 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.concurrency; - -import java.text.ParseException; - -import javax.sip.InvalidArgumentException; -import javax.sip.SipException; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class ConcurrentyControlSipSessionIsolationTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(ConcurrentyControlSipSessionIsolationTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; -// private static final int TIMEOUT = 5000; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender; - - ProtocolObjects senderProtocolObjects; - - - public ConcurrentyControlSipSessionIsolationTest(String name) { - super(name); - autoDeployOnStartup = false; - } - - public void deployApplication() { - - } - - public void deployApplication(ConcurrencyControlMode concurrencyControlMode) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome - + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - context.setConcurrencyControlMode(concurrencyControlMode); - assertTrue(tomcat.deployContext(context)); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/simple/simple-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - } - - public void testElapsedTimeAndSessionOverlapping() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - deployApplication(ConcurrencyControlMode.SipSession); - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setSendBye(false); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(2000); -// long startTime = System.currentTimeMillis(); - sender.sendInDialogSipRequest("INFO", "1", "text", "plain", null, null); - Thread.sleep(100); - sender.sendInDialogSipRequest("INFO", "2", "text", "plain", null, null); - Thread.sleep(100); - sender.sendInDialogSipRequest("INFO", "3", "text", "plain", null, null); - Thread.sleep(100); - sender.sendBye(); - Thread.sleep(20000); -// long elapsedTime = sender.getLastInfoResponseTime() - startTime; -// assertTrue(elapsedTime>15000); - assertTrue(!sender.isServerErrorReceived()); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - } - - public void testElapsedTimeAndSipApplicationSessionOverlapping() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - deployApplication(ConcurrencyControlMode.SipApplicationSession); - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setSendBye(false); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(2000); -// long startTime = System.currentTimeMillis(); - sender.sendInDialogSipRequest("INFO", "1", "text", "plain", null, null); - Thread.sleep(100); - sender.sendInDialogSipRequest("INFO", "2", "text", "plain", null, null); - Thread.sleep(100); - sender.sendInDialogSipRequest("INFO", "3", "text", "plain", null, null); - Thread.sleep(100); - sender.sendBye(); - Thread.sleep(20000); -// long elapsedTime = sender.getLastInfoResponseTime() - startTime; -// assertTrue(elapsedTime>15000); - assertTrue(!sender.isServerErrorReceived()); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - } - - public void testElapsedTimeAndSessionOverlappingWithNoConcurrencyControl() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - deployApplication(ConcurrencyControlMode.None); - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setSendBye(false); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(3000); -// long startTime = System.currentTimeMillis(); - sender.sendInDialogSipRequest("INFO", "1", "text", "plain", null, null); - Thread.sleep(100); - sender.sendInDialogSipRequest("INFO", "2", "text", "plain", null, null); - Thread.sleep(100); - sender.sendInDialogSipRequest("INFO", "3", "text", "plain", null, null); - Thread.sleep(100); - sender.sendBye(); - Thread.sleep(20000); -// long elapsedTime = sender.getLastInfoResponseTime() - startTime; -// assertTrue(elapsedTime<7000); - assertTrue(sender.isServerErrorReceived()); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.concurrency; + +import java.text.ParseException; +import java.util.HashMap; +import java.util.Map; + +import javax.sip.InvalidArgumentException; +import javax.sip.SipException; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; +import org.mobicents.servlet.sip.catalina.SipStandardManager; +import org.mobicents.servlet.sip.startup.SipContextConfig; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class ConcurrentyControlSipSessionIsolationTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ConcurrentyControlSipSessionIsolationTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; +// private static final int TIMEOUT = 5000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + + ProtocolObjects senderProtocolObjects; + + public ConcurrentyControlSipSessionIsolationTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + public void deployApplication() { + + } + + public void deployApplication(Map params, ConcurrencyControlMode concurrencyControlMode) { + SipStandardContext context = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp", + "sip-test", + params, + concurrencyControlMode); + assertTrue(context.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/simple/simple-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + } + + public void testElapsedTimeAndSessionOverlapping() throws Exception { + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + deployApplication(params, ConcurrencyControlMode.SipSession); + + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setSendBye(false); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(2000); +// long startTime = System.currentTimeMillis(); + sender.sendInDialogSipRequest("INFO", "1", "text", "plain", null, null); + Thread.sleep(100); + sender.sendInDialogSipRequest("INFO", "2", "text", "plain", null, null); + Thread.sleep(100); + sender.sendInDialogSipRequest("INFO", "3", "text", "plain", null, null); + Thread.sleep(100); + sender.sendBye(); + Thread.sleep(20000); +// long elapsedTime = sender.getLastInfoResponseTime() - startTime; +// assertTrue(elapsedTime>15000); + assertTrue(!sender.isServerErrorReceived()); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + } + + public void testElapsedTimeAndSipApplicationSessionOverlapping() throws Exception { + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + deployApplication(params, ConcurrencyControlMode.SipApplicationSession); + + + + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setSendBye(false); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(2000); +// long startTime = System.currentTimeMillis(); + sender.sendInDialogSipRequest("INFO", "1", "text", "plain", null, null); + Thread.sleep(100); + sender.sendInDialogSipRequest("INFO", "2", "text", "plain", null, null); + Thread.sleep(100); + sender.sendInDialogSipRequest("INFO", "3", "text", "plain", null, null); + Thread.sleep(100); + sender.sendBye(); + Thread.sleep(20000); +// long elapsedTime = sender.getLastInfoResponseTime() - startTime; +// assertTrue(elapsedTime>15000); + assertTrue(!sender.isServerErrorReceived()); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + } + + public void testElapsedTimeAndSessionOverlappingWithNoConcurrencyControl() throws Exception { + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + deployApplication(params, ConcurrencyControlMode.None); + + + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setSendBye(false); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(3000); +// long startTime = System.currentTimeMillis(); + sender.sendInDialogSipRequest("INFO", "1", "text", "plain", null, null); + Thread.sleep(100); + sender.sendInDialogSipRequest("INFO", "2", "text", "plain", null, null); + Thread.sleep(100); + sender.sendInDialogSipRequest("INFO", "3", "text", "plain", null, null); + Thread.sleep(100); + sender.sendBye(); + Thread.sleep(20000); +// long elapsedTime = sender.getLastInfoResponseTime() - startTime; +// assertTrue(elapsedTime<7000); + assertTrue(sender.isServerErrorReceived()); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/concurrency/CongestionControlTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/concurrency/CongestionControlTest.java index bf1ce1e8c4..c23815d095 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/concurrency/CongestionControlTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/concurrency/CongestionControlTest.java @@ -20,7 +20,7 @@ * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ -/* + /* * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of @@ -39,256 +39,268 @@ package org.mobicents.servlet.sip.testsuite.concurrency; import java.text.ParseException; +import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.sip.InvalidArgumentException; import javax.sip.SipException; import javax.sip.SipProvider; import javax.sip.address.SipURI; +import static junit.framework.Assert.assertTrue; import org.apache.catalina.LifecycleException; import org.apache.log4j.Logger; import org.mobicents.javax.servlet.CongestionControlPolicy; +import org.mobicents.javax.servlet.ContainerEventType; +import org.mobicents.servlet.sip.NetworkPortAssigner; import org.mobicents.servlet.sip.SipServletTestCase; import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; -import org.mobicents.servlet.sip.core.session.SipStandardManager; -import org.mobicents.servlet.sip.startup.SipContextConfig; import org.mobicents.servlet.sip.startup.SipStandardContext; import org.mobicents.servlet.sip.testsuite.ProtocolObjects; import org.mobicents.servlet.sip.testsuite.TestSipListener; public class CongestionControlTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(CongestionControlTest.class); - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT_ACK = 5000; - private static final int TIMEOUT = 10000; + private static transient Logger logger = Logger.getLogger(CongestionControlTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT_ACK = 5000; + private static final int TIMEOUT = 10000; // private static final int TIMEOUT = 100000000; - - TestSipListener sender; - - ProtocolObjects senderProtocolObjects; - - - public CongestionControlTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.setConcurrencyControlMode(ConcurrencyControlMode.None); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - assertTrue(tomcat.deployContext(context)); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/simple/simple-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - - } - - public void testCongestedQueueErrorResponse() throws InterruptedException, SipException, ParseException, InvalidArgumentException, LifecycleException { - tomcat.getSipService().getSipApplicationDispatcher().setBypassRequestExecutor(false); - tomcat.getSipService().getSipApplicationDispatcher().setBypassResponseExecutor(false); - tomcat.getSipService().getSipApplicationDispatcher().setCongestionControlCheckingInterval(2000); - tomcat.getSipService().getSipApplicationDispatcher().setQueueSize(1000); - tomcat.getSipService().getSipApplicationDispatcher().setCongestionControlPolicy(CongestionControlPolicy.ErrorResponse); - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setSendBye(false); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT_ACK); - assertTrue(sender.isAckSent()); - tomcat.getSipService().getSipApplicationDispatcher().setQueueSize(-1); - tomcat.getSipService().getSipApplicationDispatcher().setBackToNormalQueueSize(0); - Thread.sleep(TIMEOUT_ACK); - // For this test the queue size is 3, so we feed 40 messages asap and watch for error response. - // Since we dont want to wait 40*5 secs, we kill everything with no clean up, that's fine for this test. - for(int q=0; q < 40; q++) { - sender.sendSipRequest("INVITE", fromAddress, toAddress, Integer.valueOf(q).toString(), null, false); - Thread.sleep(100); - } - Thread.sleep(TIMEOUT); - assertNotNull(sender.getServiceUnavailableResponse()); - assertNotNull(sender.getServiceUnavailableResponse().getHeader("Reason")); - assertNotNull(sender.getServiceUnavailableResponse().getHeader("ReasonMessage")); - List allMessagesContent = sender.getAllMessagesContent(); - assertTrue(allMessagesContent.size() > 0); - assertTrue("congestionControlStarted", allMessagesContent.contains("congestionControlStarted")); - } - - public void testCongestedQueueDropMessage() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - tomcat.getSipService().getSipApplicationDispatcher().setBypassRequestExecutor(false); - tomcat.getSipService().getSipApplicationDispatcher().setBypassResponseExecutor(false); - tomcat.getSipService().getSipApplicationDispatcher().setCongestionControlCheckingInterval(2000); - tomcat.getSipService().getSipApplicationDispatcher().setQueueSize(1); - tomcat.getSipService().getSipApplicationDispatcher().setCongestionControlPolicy(CongestionControlPolicy.DropMessage); - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setSendBye(false); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT_ACK); - assertTrue(sender.isAckSent()); - // For this test the queue size is 3, so we feed 40 messages asap and watch for error response. - // Since we dont want to wait 40*5 secs, we kill everything with no clean up, that's fine for this test. - for(int q=0; q<40; q++) { - sender.sendSipRequest("INVITE", fromAddress, toAddress, Integer.valueOf(q).toString(), null, false); - Thread.sleep(100); - } - Thread.sleep(TIMEOUT); - assertNull(sender.getServiceUnavailableResponse()); - } - - public void testMemoryCongestedErrorResponse() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - tomcat.getSipService().getSipApplicationDispatcher().setCongestionControlCheckingInterval(2000); - tomcat.getSipService().getSipApplicationDispatcher().setMemoryThreshold(95); - tomcat.getSipService().getSipApplicationDispatcher().setCongestionControlPolicy(CongestionControlPolicy.ErrorResponse); - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setSendBye(false); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT_ACK); - assertTrue(sender.isAckSent()); - tomcat.getSipService().getSipApplicationDispatcher().setMemoryThreshold(0); - Thread.sleep(TIMEOUT_ACK); - // For this test the queue size is 3, so we feed 40 messages asap and watch for error response. - // Since we dont want to wait 40*5 secs, we kill everything with no clean up, that's fine for this test. - for(int q=0; q<40; q++) { - sender.sendSipRequest("INVITE", fromAddress, toAddress, Integer.valueOf(q).toString(), null, false); - Thread.sleep(100); - } - Thread.sleep(TIMEOUT); - assertNotNull(sender.getServiceUnavailableResponse()); - assertNotNull(sender.getServiceUnavailableResponse().getHeader("Reason")); - assertNotNull(sender.getServiceUnavailableResponse().getHeader("ReasonMessage")); - List allMessagesContent = sender.getAllMessagesContent(); - assertTrue(allMessagesContent.size() > 0); - assertTrue("congestionControlStarted", allMessagesContent.contains("congestionControlStarted")); - } - - public void testMemoryCongestedDropMessage() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - tomcat.getSipService().getSipApplicationDispatcher().setCongestionControlCheckingInterval(2000); - tomcat.getSipService().getSipApplicationDispatcher().setMemoryThreshold(0); - tomcat.getSipService().getSipApplicationDispatcher().setCongestionControlPolicy(CongestionControlPolicy.DropMessage); - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setSendBye(false); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT_ACK); - assertTrue(sender.isAckSent()); - // For this test the queue size is 3, so we feed 40 messages asap and watch for error response. - // Since we dont want to wait 40*5 secs, we kill everything with no clean up, that's fine for this test. - for(int q=0; q<40; q++) { - sender.sendSipRequest("INVITE", fromAddress, toAddress, Integer.valueOf(q).toString(), null, false); - Thread.sleep(100); - } - Thread.sleep(TIMEOUT); - assertNull(sender.getServiceUnavailableResponse()); - } - - public void testMemoryCongestedErrorResponseReInvite() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - tomcat.getSipService().getSipApplicationDispatcher().setCongestionControlCheckingInterval(2000); - tomcat.getSipService().getSipApplicationDispatcher().setMemoryThreshold(95); - tomcat.getSipService().getSipApplicationDispatcher().setCongestionControlPolicy(CongestionControlPolicy.ErrorResponse); - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setSendBye(false); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT_ACK); - assertTrue(sender.isAckSent()); - tomcat.getSipService().getSipApplicationDispatcher().setMemoryThreshold(0); - Thread.sleep(TIMEOUT_ACK*2); - sender.sendInDialogSipRequest("INVITE", Integer.valueOf(1).toString(), "text", "plain", null, null); - Thread.sleep(100); - Thread.sleep(TIMEOUT); - assertNull(sender.getServiceUnavailableResponse()); - for(int q=0; q<40; q++) { - sender.sendSipRequest("INVITE", fromAddress, toAddress, Integer.valueOf(q).toString(), null, false); - Thread.sleep(100); - } - Thread.sleep(TIMEOUT); - assertNotNull(sender.getServiceUnavailableResponse()); - assertNotNull(sender.getServiceUnavailableResponse().getHeader("Reason")); - assertNotNull(sender.getServiceUnavailableResponse().getHeader("ReasonMessage")); - List allMessagesContent = sender.getAllMessagesContent(); - assertTrue(allMessagesContent.size() > 0); - assertTrue("congestionControlStarted", allMessagesContent.contains("congestionControlStarted")); - tomcat.getSipService().getSipApplicationDispatcher().setMemoryThreshold(100); - Thread.sleep(TIMEOUT); - allMessagesContent = sender.getAllMessagesContent(); - assertTrue(allMessagesContent.size() > 0); - assertTrue("congestionControlStopped", allMessagesContent.contains("congestionControlStopped")); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } + TestSipListener sender; + + ProtocolObjects senderProtocolObjects; + + public CongestionControlTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + + } + + public void deployApplication(Map params ) { + SipStandardContext context = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp", + "sip-test", + params, + null); + assertTrue(context.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/simple/simple-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + deployApplication(params); + + } + + public void testCongestedQueueErrorResponse() throws InterruptedException, SipException, ParseException, InvalidArgumentException, LifecycleException { + tomcat.getSipService().getSipApplicationDispatcher().setBypassRequestExecutor(false); + tomcat.getSipService().getSipApplicationDispatcher().setBypassResponseExecutor(false); + tomcat.getSipService().getSipApplicationDispatcher().setCongestionControlCheckingInterval(2000); + tomcat.getSipService().getSipApplicationDispatcher().setQueueSize(1000); + tomcat.getSipService().getSipApplicationDispatcher().setCongestionControlPolicy(CongestionControlPolicy.ErrorResponse); + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setSendBye(false); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT_ACK); + assertTrue(sender.isAckSent()); + tomcat.getSipService().getSipApplicationDispatcher().setQueueSize(-1); + tomcat.getSipService().getSipApplicationDispatcher().setBackToNormalQueueSize(0); + Thread.sleep(TIMEOUT_ACK); + // For this test the queue size is 3, so we feed 40 messages asap and watch for error response. + // Since we dont want to wait 40*5 secs, we kill everything with no clean up, that's fine for this test. + for (int q = 0; q < 40; q++) { + sender.sendSipRequest("INVITE", fromAddress, toAddress, Integer.valueOf(q).toString(), null, false); + Thread.sleep(100); + } + Thread.sleep(TIMEOUT); + assertNotNull(sender.getServiceUnavailableResponse()); + assertNotNull(sender.getServiceUnavailableResponse().getHeader("Reason")); + assertNotNull(sender.getServiceUnavailableResponse().getHeader("ReasonMessage")); + List allMessagesContent = sender.getAllMessagesContent(); + assertTrue(allMessagesContent.size() > 0); + assertTrue(ContainerEventType.CONGESTION_STARTED.toString(), + allMessagesContent.contains(ContainerEventType.CONGESTION_STARTED.toString())); + } + + public void testCongestedQueueDropMessage() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + tomcat.getSipService().getSipApplicationDispatcher().setBypassRequestExecutor(false); + tomcat.getSipService().getSipApplicationDispatcher().setBypassResponseExecutor(false); + tomcat.getSipService().getSipApplicationDispatcher().setCongestionControlCheckingInterval(2000); + tomcat.getSipService().getSipApplicationDispatcher().setQueueSize(1); + tomcat.getSipService().getSipApplicationDispatcher().setCongestionControlPolicy(CongestionControlPolicy.DropMessage); + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setSendBye(false); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT_ACK); + assertTrue(sender.isAckSent()); + // For this test the queue size is 3, so we feed 40 messages asap and watch for error response. + // Since we dont want to wait 40*5 secs, we kill everything with no clean up, that's fine for this test. + for (int q = 0; q < 40; q++) { + sender.sendSipRequest("INVITE", fromAddress, toAddress, Integer.valueOf(q).toString(), null, false); + Thread.sleep(100); + } + Thread.sleep(TIMEOUT); + assertNull(sender.getServiceUnavailableResponse()); + } + + public void testMemoryCongestedErrorResponse() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + tomcat.getSipService().getSipApplicationDispatcher().setCongestionControlCheckingInterval(2000); + tomcat.getSipService().getSipApplicationDispatcher().setMemoryThreshold(95); + tomcat.getSipService().getSipApplicationDispatcher().setCongestionControlPolicy(CongestionControlPolicy.ErrorResponse); + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setSendBye(false); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT_ACK); + assertTrue(sender.isAckSent()); + tomcat.getSipService().getSipApplicationDispatcher().setMemoryThreshold(0); + Thread.sleep(TIMEOUT_ACK); + // For this test the queue size is 3, so we feed 40 messages asap and watch for error response. + // Since we dont want to wait 40*5 secs, we kill everything with no clean up, that's fine for this test. + for (int q = 0; q < 40; q++) { + sender.sendSipRequest("INVITE", fromAddress, toAddress, Integer.valueOf(q).toString(), null, false); + Thread.sleep(100); + } + Thread.sleep(TIMEOUT); + assertNotNull(sender.getServiceUnavailableResponse()); + assertNotNull(sender.getServiceUnavailableResponse().getHeader("Reason")); + assertNotNull(sender.getServiceUnavailableResponse().getHeader("ReasonMessage")); + List allMessagesContent = sender.getAllMessagesContent(); + assertTrue(allMessagesContent.size() > 0); + assertTrue(ContainerEventType.CONGESTION_STARTED.toString(), + allMessagesContent.contains(ContainerEventType.CONGESTION_STARTED.toString())); + } + + public void testMemoryCongestedDropMessage() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + tomcat.getSipService().getSipApplicationDispatcher().setCongestionControlCheckingInterval(2000); + tomcat.getSipService().getSipApplicationDispatcher().setMemoryThreshold(0); + tomcat.getSipService().getSipApplicationDispatcher().setCongestionControlPolicy(CongestionControlPolicy.DropMessage); + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setSendBye(false); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT_ACK); + assertTrue(sender.isAckSent()); + // For this test the queue size is 3, so we feed 40 messages asap and watch for error response. + // Since we dont want to wait 40*5 secs, we kill everything with no clean up, that's fine for this test. + for (int q = 0; q < 40; q++) { + sender.sendSipRequest("INVITE", fromAddress, toAddress, Integer.valueOf(q).toString(), null, false); + Thread.sleep(100); + } + Thread.sleep(TIMEOUT); + assertNull(sender.getServiceUnavailableResponse()); + } + + public void testMemoryCongestedErrorResponseReInvite() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + tomcat.getSipService().getSipApplicationDispatcher().setCongestionControlCheckingInterval(2000); + tomcat.getSipService().getSipApplicationDispatcher().setMemoryThreshold(95); + tomcat.getSipService().getSipApplicationDispatcher().setCongestionControlPolicy(CongestionControlPolicy.ErrorResponse); + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setSendBye(false); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT_ACK); + assertTrue(sender.isAckSent()); + tomcat.getSipService().getSipApplicationDispatcher().setMemoryThreshold(0); + Thread.sleep(TIMEOUT_ACK * 2); + sender.sendInDialogSipRequest("INVITE", Integer.valueOf(1).toString(), "text", "plain", null, null); + Thread.sleep(100); + Thread.sleep(TIMEOUT); + assertNull(sender.getServiceUnavailableResponse()); + for (int q = 0; q < 40; q++) { + sender.sendSipRequest("INVITE", fromAddress, toAddress, Integer.valueOf(q).toString(), null, false); + Thread.sleep(100); + } + Thread.sleep(TIMEOUT); + assertNotNull(sender.getServiceUnavailableResponse()); + assertNotNull(sender.getServiceUnavailableResponse().getHeader("Reason")); + assertNotNull(sender.getServiceUnavailableResponse().getHeader("ReasonMessage")); + List allMessagesContent = sender.getAllMessagesContent(); + assertTrue(allMessagesContent.size() > 0); + assertTrue(ContainerEventType.CONGESTION_STARTED.toString(), + allMessagesContent.contains(ContainerEventType.CONGESTION_STARTED.toString())); + tomcat.getSipService().getSipApplicationDispatcher().setMemoryThreshold(100); + Thread.sleep(TIMEOUT); + allMessagesContent = sender.getAllMessagesContent(); + assertTrue(allMessagesContent.size() > 0); + assertTrue(ContainerEventType.CONGESTION_STOPPED.toString(), + allMessagesContent.contains(ContainerEventType.CONGESTION_STOPPED.toString())); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } } diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/deployment/DeploymentTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/deployment/DeploymentTest.java index d29806de67..76efb22cfc 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/deployment/DeploymentTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/deployment/DeploymentTest.java @@ -1,229 +1,255 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.deployment; - -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.catalina.deploy.ApplicationParameter; -import org.apache.catalina.realm.MemoryRealm; -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; -/** - * This test ensures that an application with no appname cannot be deployed successfully into Mobicents Sip Servlets - * @author jean.deruelle@gmail.com - * - */ -public class DeploymentTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(DeploymentTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; - - TestSipListener sender; - ProtocolObjects senderProtocolObjects; - - public DeploymentTest(String name) { - super(name); - autoDeployOnStartup = false; - startTomcatOnStartup = false; - } - - public void deployNoAppNameApplication() { - assertFalse(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/no-app-name-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - public void deployNoMainServletApplication() { - assertFalse(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/no-main-servlet-app/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - public void deployShootmeApplication(String webContextName) { - if(webContextName == null) { - webContextName = "sip-test"; - } - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp", - webContextName + "sip-test-context", webContextName)); - } - - public void deployShootmeAuthApplication(String webContextName) { - if(webContextName == null) { - webContextName = "sip-auth-test"; - } - SipStandardContext context = new SipStandardContext(); - context - .setDocBase(projectHome - + "/sip-servlets-test-suite/applications/shootme-sip-servlet-auth/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath(webContextName); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName("testContextApplicationParameter"); - applicationParameter.setValue("OK"); - context.addApplicationParameter(applicationParameter); - MemoryRealm realm = new MemoryRealm(); - realm - .setPathname(projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/security/tomcat-users.xml"); - context.setRealm(realm); - assertTrue(tomcat.deployContext(context)); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/deployment/blank dir/simple-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - } - - public void testDeployApplicationWithNoAppName() throws Exception { - tomcat.startTomcat(); - deployNoAppNameApplication(); - } - - public void testNoMainServletApp() throws Exception { - tomcat.startTomcat(); - deployNoMainServletApplication(); - } - - public void testBlankSpaceInDarPath() throws Exception { - tomcat.startTomcat(); - deployShootmeApplication(null); - senderProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - - senderProtocolObjects.destroy(); - } - - /** - * Issue 1411 http://code.google.com/p/mobicents/issues/detail?id=1411 - * Sip Connectors should be removed after removing all Sip Servlets - * @throws Exception - */ - public void testBYEOnSipServletDestroy() throws Exception { - tomcat.startTomcat(); - deployShootmeApplication(null); - senderProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - - String fromName = "testByeOnDestroy"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - tomcat.stopTomcat(); - Thread.sleep(TIMEOUT); - assertTrue(sender.getByeReceived()); - - senderProtocolObjects.destroy(); - } - - /** - * Issue 1417 http://code.google.com/p/mobicents/issues/detail?id=1417 - * Deploy 2 applications with the same app-name should fail - * @throws Exception - */ - public void testDeploy2AppsWithSameAppName() throws Exception { - tomcat.startTomcat(); - deployShootmeApplication(null); - try { - deployShootmeApplication("second-test-app"); - fail("Should see an illegalStateException saying that an app of that app-name is already deployed"); - } catch (IllegalStateException e) { - logger.info(e.getMessage()); - } - } - - public void testDeployServletContextDestroyed() throws Exception { - tomcat.startTomcat(); - deployShootmeApplication(null); - deployShootmeAuthApplication(null); - tomcat.stopTomcat(); - } - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - } - - @Override - protected void deployApplication() { - - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.deployment; + +import java.util.HashMap; +import java.util.Map; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; + +import org.apache.catalina.deploy.ApplicationParameter; +import org.apache.catalina.realm.MemoryRealm; +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.catalina.SipStandardManager; +import org.mobicents.servlet.sip.core.SipContext; +import org.mobicents.servlet.sip.startup.SipContextConfig; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +/** + * This test ensures that an application with no appname cannot be deployed + * successfully into Mobicents Sip Servlets + * + * @author jean.deruelle@gmail.com + * + */ +public class DeploymentTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(DeploymentTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; + + TestSipListener sender; + ProtocolObjects senderProtocolObjects; + + public DeploymentTest(String name) { + super(name); + autoDeployOnStartup = false; + startTomcatOnStartup = false; + } + + public SipStandardContext deployNoAppNameApplication() { + SipStandardContext ctx = tomcat.deployAppContext( + projectHome + "/sip-servlets-test-suite/applications/no-app-name-servlet/src/main/sipapp", + "sip-test-context", "sip-test"); + assertFalse(ctx.getAvailable()); + return ctx; + } + + public SipStandardContext deployNoMainServletApplication() { + SipStandardContext ctx = tomcat.deployAppContext( + projectHome + "/sip-servlets-test-suite/applications/no-main-servlet-app/src/main/sipapp", + "sip-test-context", "sip-test"); + assertFalse(ctx.getAvailable()); + return ctx; + } + + public SipStandardContext deployShootmeApplication(String webContextName, Map params) { + if (webContextName == null) { + webContextName = "sip-test"; + } + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp", + webContextName, + params, + null); + assertTrue(ctx.getAvailable()); + return ctx; + } + + public SipContext deployShootmeAuthApplication(String webContextName) { + if (webContextName == null) { + webContextName = "sip-auth-test"; + } + SipStandardContext context = new SipStandardContext(); + context + .setDocBase(projectHome + + "/sip-servlets-test-suite/applications/shootme-sip-servlet-auth/src/main/sipapp"); + context.setName("sip-test-context"); + context.setPath(webContextName); + context.addLifecycleListener(new SipContextConfig()); + context.setManager(new SipStandardManager()); + ApplicationParameter applicationParameter = new ApplicationParameter(); + applicationParameter.setName("testContextApplicationParameter"); + applicationParameter.setValue("OK"); + context.addApplicationParameter(applicationParameter); + MemoryRealm realm = new MemoryRealm(); + realm + .setPathname(projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/security/tomcat-users.xml"); + context.setRealm(realm); + assertTrue(tomcat.deployContext(context)); + return context; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/deployment/blank dir/simple-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + } + + public void testDeployApplicationWithNoAppName() throws Exception { + tomcat.startTomcat(); + deployNoAppNameApplication(); + } + + public void testNoMainServletApp() throws Exception { + tomcat.startTomcat(); + deployNoMainServletApplication(); + } + + public void testBlankSpaceInDarPath() throws Exception { + tomcat.startTomcat(); + + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(myPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("testPort", String.valueOf(myPort)); + params.put("servletContainerPort", String.valueOf(containerPort)); + SipContext sipContext = deployShootmeApplication(null, params); + + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + + senderProtocolObjects.destroy(); + } + + /** + * Issue 1411 http://code.google.com/p/mobicents/issues/detail?id=1411 Sip + * Connectors should be removed after removing all Sip Servlets + * + * @throws Exception + */ + public void testBYEOnSipServletDestroy() throws Exception { + tomcat.startTomcat(); + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(myPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("testPort", String.valueOf(myPort)); + params.put("servletContainerPort", String.valueOf(containerPort)); + SipContext sipContext = deployShootmeApplication(null, params); + + String fromName = "testByeOnDestroy"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + tomcat.stopTomcat(); + Thread.sleep(TIMEOUT); + assertTrue(sender.getByeReceived()); + + senderProtocolObjects.destroy(); + } + + /** + * Issue 1417 http://code.google.com/p/mobicents/issues/detail?id=1417 + * Deploy 2 applications with the same app-name should fail + * + * @throws Exception + */ + public void testDeploy2AppsWithSameAppName() throws Exception { + tomcat.startTomcat(); + deployShootmeApplication(null, null); + try { + deployShootmeApplication("second-test-app", null); + fail("Should see an illegalStateException saying that an app of that app-name is already deployed"); + } catch (IllegalStateException e) { + logger.info(e.getMessage()); + } + } + + public void testDeployServletContextDestroyed() throws Exception { + tomcat.startTomcat(); + deployShootmeApplication(null, null); + deployShootmeAuthApplication(null); + tomcat.stopTomcat(); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + } + + @Override + protected void deployApplication() { + + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/deployment/DistributableServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/deployment/DistributableServletTest.java index 1f7110cfa1..1523ec197f 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/deployment/DistributableServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/deployment/DistributableServletTest.java @@ -1,106 +1,129 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.deployment; - -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; -/** - * This test ensures that a sip application whose the sip.xml dd contains the distributable tag - * is able to work in a non distributed environment - * @author jean.deruelle@gmail.com - * - */ -public class DistributableServletTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(DistributableServletTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender; - ProtocolObjects senderProtocolObjects; - - public DistributableServletTest(String name) { - super(name); - } - - @Override - protected void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/distributable-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/deployment/distributable-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - } - - - public void testDistributableApp() throws Exception { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertFalse(sender.isServerErrorReceived()); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - super.tearDown(); - } -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.deployment; + +import java.util.HashMap; +import java.util.Map; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.core.SipContext; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +/** + * This test ensures that a sip application whose the sip.xml dd contains the + * distributable tag is able to work in a non distributed environment + * + * @author jean.deruelle@gmail.com + * + */ +public class DistributableServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(DistributableServletTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + ProtocolObjects senderProtocolObjects; + SipStandardContext sipContext; + + public DistributableServletTest(String name) { + super(name); + autoDeployOnStartup=false; + } + + @Override + protected void deployApplication() { + + } + + public SipStandardContext deployApplication(Map params) { + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/distributable-servlet/src/main/sipapp", + "sip-tes", + params, + null); + assertTrue(ctx.getAvailable()); + return ctx; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/deployment/distributable-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(myPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(myPort)); + deployApplication(params); + } + + public void testDistributableApp() throws Exception { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertFalse(sender.isServerErrorReceived()); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + super.tearDown(); + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/deployment/GracefulStopTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/deployment/GracefulStopTest.java new file mode 100644 index 0000000000..c3393550b6 --- /dev/null +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/deployment/GracefulStopTest.java @@ -0,0 +1,483 @@ +/* + * TeleStax, Open Source Cloud Communications. + * Copyright 2012 and individual contributors by the @authors tag. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.deployment; + +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + +import javax.management.MBeanServer; +import javax.management.MBeanServerFactory; +import javax.management.ObjectName; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; + +import org.apache.catalina.core.StandardContext; +import org.apache.catalina.deploy.ApplicationParameter; +import org.apache.catalina.realm.MemoryRealm; +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.catalina.SipStandardManager; +import org.mobicents.servlet.sip.core.SipContext; +import org.mobicents.servlet.sip.startup.SipContextConfig; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +/** + * Test for http://code.google.com/p/sipservlets/issues/detail?id=195 Support + * for Graceful Shutdown of SIP Applications and Overall Server + * + * @author jean.deruelle@gmail.com + * + */ +public class GracefulStopTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(GracefulStopTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; + + TestSipListener sender; + ProtocolObjects senderProtocolObjects; + + public GracefulStopTest(String name) { + super(name); + autoDeployOnStartup = false; + startTomcatOnStartup = false; + } + + public SipContext deployShootme(String webContextName, Map params) { + if (webContextName == null) { + webContextName = "sip-test"; + } + SipStandardContext context = new SipStandardContext(); + context + .setDocBase(projectHome + + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp"); + context.setName("sip-test-context"); + context.setPath(webContextName); + context.addLifecycleListener(new SipContextConfig()); + context.setManager(new SipStandardManager()); + ApplicationParameter applicationParameter = new ApplicationParameter(); + applicationParameter.setName("testContextApplicationParameter"); + applicationParameter.setValue("OK"); + context.addApplicationParameter(applicationParameter); + if (params != null) { + for (Map.Entry param : params.entrySet()) { + ApplicationParameter applParameter = new ApplicationParameter(); + applParameter.setName(param.getKey()); + applParameter.setValue(param.getValue()); + context.addApplicationParameter(applParameter); + } + } + MemoryRealm realm = new MemoryRealm(); + realm + .setPathname(projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/security/tomcat-users.xml"); + context.setRealm(realm); + assertTrue(tomcat.deployContext(context)); + return context; + } + + public SipContext deployConvergedApp(Map params) { + SipStandardContext context = new SipStandardContext(); + context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/click-to-call-servlet/src/main/sipapp"); + context.setName("click2call-context"); + context.setPath("/click2call"); + if (params != null) { + for (Map.Entry param : params.entrySet()) { + ApplicationParameter applicationParameter = new ApplicationParameter(); + applicationParameter.setName(param.getKey()); + applicationParameter.setValue(param.getValue()); + context.addApplicationParameter(applicationParameter); + } + } + context.addLifecycleListener(new SipContextConfig()); + ((StandardContext) context).setSessionTimeout(1); + context.setSipApplicationSessionTimeout(1); + SipStandardManager manager = new SipStandardManager(); + context.setManager(manager); + assertTrue(tomcat.deployContext(context)); + return context; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/deployment/blank dir/simple-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + } + + /** + * Make sure that the graceful stop guarantees the application is accepting + * subsequent requests but not new requests and that when no sessions are + * present the context is stopped automatically + */ + public void testContextGracefulShutdownNegativeValue() throws Exception { + tomcat.startTomcat(); + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(myPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("testPort", String.valueOf(myPort)); + params.put("servletContainerPort", String.valueOf(containerPort)); + SipContext sipContext = deployShootme(null,params); + + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setTimeToWaitBeforeBye(TIMEOUT * 3 / 2); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(1000); + sipContext.stopGracefully(-1); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + Thread.sleep(TIMEOUT); + // ensure the subsequent requests are responded too + assertTrue(sender.getOkToByeReceived()); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(30000); + // ensure new initial requests are not handled anymore by the app + assertEquals(404, sender.getFinalResponseStatus()); + // make sure the Graceful Stop was effective + assertEquals(0, sipContext.getSipApplicationDispatcher().findInstalledSipApplications().length); + tomcat.stopTomcat(); + senderProtocolObjects.destroy(); + } + + /** + * Make sure that the graceful stop guarantees the application is stopped + * forcefully by using 0 as time to Wait + */ + public void testContextGracefulShutdownZeroValue() throws Exception { + tomcat.startTomcat(); + + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(myPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("testPort", String.valueOf(myPort)); + params.put("servletContainerPort", String.valueOf(containerPort)); + SipContext sipContext = deployShootme(null,params); + + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setTimeToWaitBeforeBye(TIMEOUT * 3 / 2); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(1000); + sipContext.stopGracefully(0); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + Thread.sleep(TIMEOUT); + // ensure the subsequent requests are responded too + assertEquals(500, sender.getFinalResponseStatus()); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(30000); + // ensure new initial requests are not handled anymore by the app + assertEquals(404, sender.getFinalResponseStatus()); + // make sure the Graceful Stop was effective + assertEquals(0, sipContext.getSipApplicationDispatcher().findInstalledSipApplications().length); + tomcat.stopTomcat(); + senderProtocolObjects.destroy(); + } + + /** + * Make sure that the graceful stop guarantees the application is stopped + * forcefully after TIMEOUT and that the result is equivalent to zero value + * in our case + */ + public void testContextGracefulShutdownPositiveValue() throws Exception { + tomcat.startTomcat(); + + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(myPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("testPort", String.valueOf(myPort)); + params.put("servletContainerPort", String.valueOf(containerPort)); + SipContext sipContext = deployShootme(null,params); + + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setTimeToWaitBeforeBye(TIMEOUT * 3 / 2); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(1000); + sipContext.stopGracefully(TIMEOUT); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + Thread.sleep(TIMEOUT); + // ensure the subsequent requests are responded too + assertEquals(500, sender.getFinalResponseStatus()); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(30000); + // ensure new initial requests are not handled anymore by the app + assertEquals(404, sender.getFinalResponseStatus()); + // make sure the Graceful Stop was effective + assertEquals(0, sipContext.getSipApplicationDispatcher().findInstalledSipApplications().length); + tomcat.stopTomcat(); + senderProtocolObjects.destroy(); + } + + /** + * Make sure that the graceful stop guarantees the application is accepting + * subsequent requests but not new requests and that when no sessions are + * present the context is stopped automatically + */ + public void testServiceGracefulShutdownNegativeValue() throws Exception { + tomcat.startTomcat(); + + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(myPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("testPort", String.valueOf(myPort)); + params.put("servletContainerPort", String.valueOf(containerPort)); + SipContext sipContext = deployShootme(null,params); + + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setTimeToWaitBeforeBye(TIMEOUT * 3 / 2); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(1000); + tomcat.getSipService().stopGracefully(-1); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + Thread.sleep(TIMEOUT); + // ensure the subsequent requests are responded too + assertTrue(sender.getOkToByeReceived()); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(30000); + // ensure new initial requests are not handled anymore by the app + assertEquals(404, sender.getFinalResponseStatus()); + // make sure the Graceful Stop was effective + assertEquals(0, sipContext.getSipApplicationDispatcher().findInstalledSipApplications().length); + senderProtocolObjects.destroy(); + } + + /** + * Make sure that the graceful stop guarantees the application is accepting + * subsequent requests but not new requests and that when no sessions are + * present the context is stopped automatically + */ + public void testServiceGracefulShutdownNegativeValueJMX() throws Exception { + tomcat.startTomcat(); + + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(myPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("testPort", String.valueOf(myPort)); + params.put("servletContainerPort", String.valueOf(containerPort)); + SipContext sipContext = deployShootme(null,params); + + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setTimeToWaitBeforeBye(TIMEOUT * 3 / 2); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(1000); + +// tomcat.getSipService().stopGracefully(-1); + MBeanServer mBeanServer = null; + if (MBeanServerFactory.findMBeanServer(null).size() > 0) { + mBeanServer + = (MBeanServer) MBeanServerFactory.findMBeanServer(null).get(0); + } + ObjectName objectName + = tomcat.getSipService().getObjectName(); + mBeanServer.invoke(objectName, "stopGracefully", new Object[]{-1}, new String[]{long.class.getName()}); + + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + Thread.sleep(TIMEOUT); + // ensure the subsequent requests are responded too + assertTrue(sender.getOkToByeReceived()); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(30000); + // ensure new initial requests are not handled anymore by the app + assertEquals(404, sender.getFinalResponseStatus()); + // make sure the Graceful Stop was effective + assertEquals(0, sipContext.getSipApplicationDispatcher().findInstalledSipApplications().length); + senderProtocolObjects.destroy(); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + } + + @Override + protected void deployApplication() { + + } + + /** + * Make sure that the graceful stop guarantees the application is accepting + * subsequent HTTP requests but not new HTTP requests and that when no + * sessions are present the context is stopped automatically + */ + public void testConvergedContextGracefulShutdownNegativeValue() throws Exception { + String CLICK2DIAL_URL = "http://" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + httpContainerPort + "/click2call/call"; + tomcat.startTomcat(); + + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(myPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("testPort", String.valueOf(myPort)); + params.put("servletContainerPort", String.valueOf(containerPort)); + SipContext sipContext = deployConvergedApp(params); + + String CLICK2DIAL_PARAMS = "?from=sip:from@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5056&to=sip:to@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + myPort+"¬ification=false"; + + logger.info("Trying to reach url : " + CLICK2DIAL_URL + + CLICK2DIAL_PARAMS); + + URL url = new URL(CLICK2DIAL_URL + CLICK2DIAL_PARAMS); + HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection(); + InputStream in = httpConnection.getInputStream(); + + byte[] buffer = new byte[10000]; + int len = in.read(buffer); + String httpResponse = ""; + for (int q = 0; q < len; q++) { + httpResponse += (char) buffer[q]; + } + logger.info("Received the follwing HTTP response: " + httpResponse); + + sipContext.stopGracefully(-1); + + Thread.sleep(40000); + logger.info("Trying to access the context after gracefull stop"); + + url = new URL(CLICK2DIAL_URL + CLICK2DIAL_PARAMS); + try { + in = url.openConnection().getInputStream(); + fail("new request should thrown a 404"); + } catch (FileNotFoundException e) { + // expected + } + + Thread.sleep(35000); + + assertEquals(0, ((StandardContext) sipContext).getManager().getActiveSessions()); + assertEquals(0, sipContext.getSipManager().getActiveSipApplicationSessions()); + tomcat.stopTomcat(); + senderProtocolObjects.destroy(); + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/deployment/GracefulStopWithServiceTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/deployment/GracefulStopWithServiceTest.java new file mode 100644 index 0000000000..2727a8de5b --- /dev/null +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/deployment/GracefulStopWithServiceTest.java @@ -0,0 +1,151 @@ +/* + * TeleStax, Open Source Cloud Communications. + * Copyright 2012 and individual contributors by the @authors tag. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.deployment; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.sip.SipProvider; +import static junit.framework.Assert.assertTrue; +import org.apache.catalina.deploy.ApplicationParameter; +import org.apache.catalina.realm.MemoryRealm; +import org.apache.log4j.Logger; +import org.mobicents.javax.servlet.ContainerEventType; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.catalina.SipStandardManager; +import org.mobicents.servlet.sip.core.SipContext; +import org.mobicents.servlet.sip.startup.SipContextConfig; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +/** + * Test for additional service specific criteria. + * + * @author jean.deruelle@gmail.com + * + */ +public class GracefulStopWithServiceTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(GracefulStopWithServiceTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 60000; + private static final long GRACEFUL_INTERVAL = 1000; + + TestSipListener sender; + ProtocolObjects senderProtocolObjects; + + public GracefulStopWithServiceTest(String name) { + super(name); + autoDeployOnStartup = false; + startTomcatOnStartup = false; + } + + public SipStandardContext deployApplication(Map params) { + MemoryRealm realm = new MemoryRealm(); + realm + .setPathname(projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/security/tomcat-users.xml"); + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp", + "sip-tes", + params, + null, + realm); + assertTrue(ctx.getAvailable()); + return ctx; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/deployment/blank dir/simple-sip-servlet-dar.properties"; + } + + private SipContext sipContext; + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + tomcat.startTomcat(); + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int myPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(myPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(myPort)); + params.put("testContextApplicationParameter", "OK"); + sipContext = deployApplication(params); + } + + /** + * Assert container is stopped only when service logic allows it + */ + public void testContextGracefulShutdownPositiveValue() throws Exception { + //wait for the container to be fully started + Thread.sleep(5000); + + tomcat.getSipService().setGracefulInterval(GRACEFUL_INTERVAL); + tomcat.getSipService().stopGracefully(TIMEOUT); + + //wait for MESSAGE to arrive + Thread.sleep(GRACEFUL_INTERVAL); + List allMessagesContent = sender.getAllMessagesContent(); + assertTrue(ContainerEventType.GRACEFUL_SHUTDOWN_STARTED.toString(), + allMessagesContent.contains(ContainerEventType.GRACEFUL_SHUTDOWN_STARTED.toString())); + + //wait a bit more than grace interval + Thread.sleep(GRACEFUL_INTERVAL * 2); + allMessagesContent = sender.getAllMessagesContent(); + assertTrue(ContainerEventType.GRACEFUL_SHUTDOWN_CHECK.toString(), + allMessagesContent.contains(ContainerEventType.GRACEFUL_SHUTDOWN_CHECK.toString())); + + //wait a bit more for the container to finally shutdown + Thread.sleep(GRACEFUL_INTERVAL * 2); + // make sure the Graceful Stop was effective + assertEquals(0, sipContext.getSipApplicationDispatcher().findInstalledSipApplications().length); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + + tomcat.stopTomcat(); + senderProtocolObjects.destroy(); + } + + @Override + protected void deployApplication() { + + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/deployment/LBGracefulStopTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/deployment/LBGracefulStopTest.java new file mode 100644 index 0000000000..10f3de9f04 --- /dev/null +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/deployment/LBGracefulStopTest.java @@ -0,0 +1,364 @@ +/* + * TeleStax, Open Source Cloud Communications. + * Copyright 2012 and individual contributors by the @authors tag. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite.deployment; + +import java.io.File; +import java.net.UnknownHostException; +import java.rmi.RemoteException; +import java.util.Properties; + +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import javax.sip.header.Parameters; +import javax.sip.header.RecordRouteHeader; +import javax.sip.header.ViaHeader; + +import org.apache.catalina.connector.Connector; +import org.apache.catalina.core.StandardContext; +import org.apache.catalina.deploy.ApplicationParameter; +import org.apache.catalina.realm.MemoryRealm; +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.SipEmbedded; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.catalina.SipStandardManager; +import org.mobicents.servlet.sip.core.SipContext; +import org.mobicents.servlet.sip.router.DefaultApplicationRouterProvider; +import org.mobicents.servlet.sip.startup.SipContextConfig; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; +import org.mobicents.tools.sip.balancer.BalancerRunner; +/** + * Test for http://code.google.com/p/sipservlets/issues/detail?id=195 + * Support for Graceful Shutdown of SIP Applications and Overall Server + * @author jean.deruelle@gmail.com + * + */ +public class LBGracefulStopTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(LBGracefulStopTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; + + TestSipListener sender; + ProtocolObjects senderProtocolObjects; + + public LBGracefulStopTest(String name) { + super(name); + System.setProperty("javax.servlet.sip.ar.spi.SipApplicationRouterProvider", DefaultApplicationRouterProvider.class.getName()); + createTomcatOnStartup = false; + initTomcatOnStartup = false; + autoDeployOnStartup = false; + startTomcatOnStartup = false; + } + + public SipContext deployShootme(SipEmbedded sipEmbedded, String webContextName) { + if(webContextName == null) { + webContextName = "sip-test"; + } + SipStandardContext context = new SipStandardContext(); + context + .setDocBase(projectHome + + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp"); + context.setName("sip-test-context"); + context.setPath(webContextName); + context.addLifecycleListener(new SipContextConfig()); + context.setManager(new SipStandardManager()); + ApplicationParameter applicationParameter = new ApplicationParameter(); + applicationParameter.setName("testContextApplicationParameter"); + applicationParameter.setValue("OK"); + context.addApplicationParameter(applicationParameter); + MemoryRealm realm = new MemoryRealm(); + realm + .setPathname(projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/security/tomcat-users.xml"); + context.setRealm(realm); + assertTrue(sipEmbedded.deployContext(context)); + return context; + } + + + public SipContext deployConvergedApp(SipEmbedded sipEmbedded) { + SipStandardContext context = new SipStandardContext(); + context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/click-to-call-servlet/src/main/sipapp"); + context.setName("click2call-context"); + context.setPath("/click2call"); + context.addLifecycleListener(new SipContextConfig()); + ((StandardContext)context).setSessionTimeout(1); + context.setSipApplicationSessionTimeout(1); + SipStandardManager manager = new SipStandardManager(); + context.setManager(manager); + assertTrue(sipEmbedded.deployContext(context)); + return context; + } + + @Override + protected void deployApplication() { + // TODO Auto-generated method stub + + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/deployment/blank dir/simple-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + } + + /** + * Make sure that the graceful stop guarantees the LB is accepting subsequent requests and routing them + * to the same node and routing new requests to the node not shutting down + * Ensure that when all nodes have been grecefully shutted down, the LB is sending back + * no nodes available + */ + public void testLBContainerGracefulShutdown() throws Exception { + BalancerRunner balancerRunner = startLoadBalancer(); + + SipEmbedded node1 = createTomcatNode("node1"); + node1.initTomcat(TRANSPORT, null); + node1.addSipConnector("node1", sipIpAddress, 5070, listeningPointTransport); + node1.startTomcat(); + + SipEmbedded node2 = createTomcatNode("node2"); + node2.initTomcat(TRANSPORT, null); + node2.addSipConnector("node2", sipIpAddress, 5069, listeningPointTransport); + node2.startTomcat(); + + SipContext sipContext = deployShootme(node1, null); + SipContext sipContext2 = deployShootme(node2, null); + + senderProtocolObjects =new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5060", null, null); + + sender = new TestSipListener(5080, 5060, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + + Thread.sleep(TIMEOUT/2); + + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setRecordRoutingProxyTesting(true); + sender.setTimeToWaitBeforeBye(TIMEOUT*3/2); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(1000); + // shutting down node gracefully + node2.getSipService().stopGracefully(-1); + Thread.sleep(TIMEOUT); + assertEquals("5069", ((Parameters)((RecordRouteHeader)sender.getFinalResponse().getHeader(RecordRouteHeader.NAME)).getAddress().getURI()).getParameter("node_port")); + assertTrue(sender.isAckSent()); + Thread.sleep(TIMEOUT); + // ensure the subsequent requests are responded too + assertTrue(sender.getOkToByeReceived()); + sender.setOkToByeReceived(false); + Thread.sleep(30000); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertEquals(200, sender.getFinalResponseStatus()); + // ensure new initial requests are not handled anymore by the same node + assertEquals("5070", ((Parameters)((RecordRouteHeader)sender.getFinalResponse().getHeader(RecordRouteHeader.NAME)).getAddress().getURI()).getParameter("node_port")); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + sender.setOkToByeReceived(false); + sender.setFinalResponse(null); + // make sure the Graceful Stop was effective on node2 + assertEquals(0, sipContext2.getSipApplicationDispatcher().findInstalledSipApplications().length); + assertEquals(1, sipContext.getSipApplicationDispatcher().findInstalledSipApplications().length); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + // ensure new initial requests are routed to the only available node + assertEquals(200, sender.getFinalResponseStatus()); + assertEquals("5070", ((Parameters)((RecordRouteHeader)sender.getFinalResponse().getHeader(RecordRouteHeader.NAME)).getAddress().getURI()).getParameter("node_port")); + // shutting down node1 + node1.getSipService().stopGracefully(-1); + Thread.sleep(TIMEOUT); + // ensure subsequent requests are still handled + sender.setOkToByeReceived(false); + sender.setFinalResponse(null); + Thread.sleep(35000); + // sending last invite with no nodes available + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + // ensure the LB returns 500 no sip nodes available + assertEquals(500, sender.getFinalResponseStatus()); + + assertEquals(0, sipContext2.getSipApplicationDispatcher().findInstalledSipApplications().length); + assertEquals(0, sipContext.getSipApplicationDispatcher().findInstalledSipApplications().length); + + node1.stopTomcat(); + node2.stopTomcat(); + balancerRunner.stop(); + senderProtocolObjects.destroy(); + } + + /** + * Make sure that the graceful stop guarantees the LB is accepting subsequent requests and routing them + * to the same node and routing new requests to the node not shutting down + * Ensure that when the application is restarted the LB starts routing requests back + * to the node whose application was gracefully shutting down + */ + public void testLBContextGracefulShutdownAndReload() throws Exception { + BalancerRunner balancerRunner = startLoadBalancer(); + + SipEmbedded node1 = createTomcatNode("node1"); + node1.initTomcat(TRANSPORT, null); + node1.addSipConnector("node1", sipIpAddress, 5070, listeningPointTransport); + node1.startTomcat(); + + SipEmbedded node2 = createTomcatNode("node2"); + node2.initTomcat(TRANSPORT, null); + node2.addSipConnector("node2", sipIpAddress, 5069, listeningPointTransport); + node2.startTomcat(); + + SipContext sipContext = deployShootme(node1, null); + SipContext sipContext2 = deployShootme(node2, null); + + senderProtocolObjects =new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5060", null, null); + + sender = new TestSipListener(5080, 5060, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + + Thread.sleep(TIMEOUT/2); + + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setRecordRoutingProxyTesting(true); + sender.setTimeToWaitBeforeBye(TIMEOUT*3/2); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(1000); + // shutting down node gracefully + node2.getSipService().stopGracefully(-1); + Thread.sleep(TIMEOUT); + assertEquals("5069", ((Parameters)((RecordRouteHeader)sender.getFinalResponse().getHeader(RecordRouteHeader.NAME)).getAddress().getURI()).getParameter("node_port")); + assertTrue(sender.isAckSent()); + Thread.sleep(TIMEOUT); + // ensure the subsequent requests are responded too + assertTrue(sender.getOkToByeReceived()); + sender.setOkToByeReceived(false); + Thread.sleep(30000); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertEquals(200, sender.getFinalResponseStatus()); + // ensure new initial requests are not handled anymore by the same node + assertEquals("5070", ((Parameters)((RecordRouteHeader)sender.getFinalResponse().getHeader(RecordRouteHeader.NAME)).getAddress().getURI()).getParameter("node_port")); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + sender.setOkToByeReceived(false); + sender.setFinalResponse(null); + // make sure the Graceful Stop was effective on node2 + assertEquals(0, sipContext2.getSipApplicationDispatcher().findInstalledSipApplications().length); + assertEquals(1, sipContext.getSipApplicationDispatcher().findInstalledSipApplications().length); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + // ensure new initial requests are routed to the only available node + assertEquals(200, sender.getFinalResponseStatus()); + assertEquals("5070", ((Parameters)((RecordRouteHeader)sender.getFinalResponse().getHeader(RecordRouteHeader.NAME)).getAddress().getURI()).getParameter("node_port")); + // shutting down node1 + node1.getSipService().stopGracefully(-1); + Thread.sleep(TIMEOUT); + // ensure subsequent requests are still handled + sender.setOkToByeReceived(false); + sender.setFinalResponse(null); + Thread.sleep(35000); + // sending last invite with no nodes available + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + // ensure the LB returns 500 no sip nodes available + assertEquals(500, sender.getFinalResponseStatus()); + + assertEquals(0, sipContext2.getSipApplicationDispatcher().findInstalledSipApplications().length); + assertEquals(0, sipContext.getSipApplicationDispatcher().findInstalledSipApplications().length); + + node1.stopTomcat(); + node2.stopTomcat(); + balancerRunner.stop(); + senderProtocolObjects.destroy(); + } + + private SipEmbedded createTomcatNode(String serverName) { + SipEmbedded sipEmbedded = new SipEmbedded(serverName, serviceFullClassName); + sipEmbedded.setLoggingFilePath( + projectHome + File.separatorChar + "sip-servlets-test-suite" + + File.separatorChar + "testsuite" + + File.separatorChar + "src" + + File.separatorChar + "test" + + File.separatorChar + "resources" + File.separatorChar); + logger.info("Log4j path is : " + sipEmbedded.getLoggingFilePath()); + String darConfigurationFile = getDarConfigurationFile(); + sipEmbedded.setDarConfigurationFilePath(darConfigurationFile); + sipEmbedded.setHA(true); + + return sipEmbedded; + } + + private BalancerRunner startLoadBalancer() throws UnknownHostException, RemoteException { + BalancerRunner balancerRunner = new BalancerRunner(); + /*LoadBalancerConfiguration lbConfig = new LoadBalancerConfiguration(); + lbConfig.getSipConfiguration().getInternalLegConfiguration().setUdpPort(5065); + lbConfig.getSipConfiguration().getExternalLegConfiguration().setUdpPort(5060);*/ + Properties properties = new Properties(); + balancerRunner.start(properties); + return balancerRunner; + } + + @Override + protected Properties getSipStackProperties() { + + return super.getSipStackProperties(); + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/deployment/NoApplicationDeployedTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/deployment/NoApplicationDeployedTest.java index 7346ca95db..2183018529 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/deployment/NoApplicationDeployedTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/deployment/NoApplicationDeployedTest.java @@ -26,6 +26,7 @@ import javax.sip.address.SipURI; import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; import org.mobicents.servlet.sip.SipServletTestCase; import org.mobicents.servlet.sip.testsuite.ProtocolObjects; import org.mobicents.servlet.sip.testsuite.TestSipListener; @@ -80,10 +81,12 @@ protected String getDarConfigurationFile() { } public void testNoAppDeployed404() throws Exception { - tomcat.addSipConnector(serverName, sipIpAddress, 5060, listeningPointTransport); + int myPort = NetworkPortAssigner.retrieveNextPort(); + containerPort = NetworkPortAssigner.retrieveNextPort(); + tomcat.addSipConnector(serverName, sipIpAddress, containerPort, listeningPointTransport); super.tomcat.startTomcat(); - sender = new TestSipListener(5080, 5060, senderProtocolObjects, true); + sender = new TestSipListener(myPort, containerPort, senderProtocolObjects, true); SipProvider senderProvider = sender.createProvider(); senderProvider.addSipListener(sender); @@ -96,7 +99,7 @@ public void testNoAppDeployed404() throws Exception { fromName, fromHost); String toUser = "container"; - String toHost = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; + String toHost = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + containerPort; SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( toUser, toHost); diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/deployment/SameInstanceServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/deployment/SameInstanceServletTest.java index 48dcacd3fc..06547d16c7 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/deployment/SameInstanceServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/deployment/SameInstanceServletTest.java @@ -1,108 +1,130 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.deployment; - -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; -/** - * This test ensures that The behavior of SipServletListener is not based upon Servlet 2.4 Specification. - * and that the same instance is always used for a sip servlet in compliance with Servlet 2.4 Section 2.2 - * @author jean.deruelle@gmail.com - * - */ -public class SameInstanceServletTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(SameInstanceServletTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender; - ProtocolObjects senderProtocolObjects; - - public SameInstanceServletTest(String name) { - super(name); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/deployment/same-instance-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - } - - - public void testSameInstanceServletApp() throws Exception { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertFalse(sender.isServerErrorReceived()); - assertTrue(sender.isAckSent()); - assertTrue(sender.getAllMessagesContent().size() < 1); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - super.tearDown(); - } - - @Override - protected void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/same-instance-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.deployment; + +import java.util.HashMap; +import java.util.Map; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +/** + * This test ensures that The behavior of SipServletListener is not based upon + * Servlet 2.4 Specification. and that the same instance is always used for a + * sip servlet in compliance with Servlet 2.4 Section 2.2 + * + * @author jean.deruelle@gmail.com + * + */ +public class SameInstanceServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(SameInstanceServletTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + ProtocolObjects senderProtocolObjects; + int myPort; + SipStandardContext ctx; + + public SameInstanceServletTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/deployment/same-instance-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + myPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(myPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(myPort)); + deployApplication(params); + } + + public void testSameInstanceServletApp() throws Exception { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertFalse(sender.isServerErrorReceived()); + assertTrue(sender.isAckSent()); + assertTrue(sender.getAllMessagesContent().size() < 1); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + super.tearDown(); + } + + @Override + protected void deployApplication() { + } + + public SipStandardContext deployApplication(Map params) { + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/same-instance-servlet/src/main/sipapp", + "sip-test", + params, + null); + assertTrue(ctx.getAvailable()); + return ctx; + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/join/JoinSipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/join/JoinSipServletTest.java index a9091a003c..a024ccb38f 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/join/JoinSipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/join/JoinSipServletTest.java @@ -1,157 +1,186 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.join; - -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -/** - * Test the behavior of Mobicents Sip Servlets with regard to Join (RFC 3911) Support - * @author jean.deruelle@gmail.com - * - */ -public class JoinSipServletTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(JoinSipServletTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 20000; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender; - TestSipListener receiver; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - - public JoinSipServletTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/join-sip-servlet/src/main/sipapp", - "join-context", - "join-dial")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/join/join-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects = new ProtocolObjects("sender", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - receiverProtocolObjects = new ProtocolObjects("receiver", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - } - - public void testSipServletSendsJoin() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - receiver.setWaitBeforeFinalResponse(2000); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "sender"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "join"; - String toHost = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isJoinRequestReceived()); - assertTrue(receiver.getOkToByeReceived()); - assertTrue(sender.getByeReceived()); - } - - public void testSipServletReceivesJoin() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "sender"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "join-receiver"; - String toHost = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertNotNull(receiver.getLastMessageContent()); - assertFalse(receiver.isServerErrorReceived()); - assertTrue(receiver.getByeReceived()); - assertTrue(sender.getByeReceived()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.join; + +import java.util.HashMap; +import java.util.Map; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +/** + * Test the behavior of Mobicents Sip Servlets with regard to Join (RFC 3911) + * Support + * + * @author jean.deruelle@gmail.com + * + */ +public class JoinSipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(JoinSipServletTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 20000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + TestSipListener receiver; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + + public JoinSipServletTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + public SipStandardContext deployApplication(Map params) { + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/join-sip-servlet/src/main/sipapp", + "join-dial", + params, + null); + assertTrue(ctx.getAvailable()); + return ctx; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/join/join-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects("sender", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects("receiver", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + } + + public void testSipServletSendsJoin() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + receiver.setWaitBeforeFinalResponse(2000); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployApplication(params); + + String fromName = "sender"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "join"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isJoinRequestReceived()); + assertTrue(receiver.getOkToByeReceived()); + assertTrue(sender.getByeReceived()); + } + + public void testSipServletReceivesJoin() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployApplication(params); + + String fromName = "sender"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "join-receiver"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertNotNull(receiver.getLastMessageContent()); + assertFalse(receiver.isServerErrorReceived()); + assertTrue(receiver.getByeReceived()); + assertTrue(sender.getByeReceived()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/listeners/ListenersSipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/listeners/ListenersSipServletTest.java index f479d71292..ca59cd12fa 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/listeners/ListenersSipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/listeners/ListenersSipServletTest.java @@ -1,168 +1,186 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.listeners; - -import java.text.ParseException; -import java.util.Iterator; - -import javax.sip.InvalidArgumentException; -import javax.sip.SipException; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class ListenersSipServletTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(ListenersSipServletTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 2000; - private static final int TIMEOUT_TIMER = 20000; -// private static final int TIMEOUT = 100000000; - - private static final String OK = "OK"; - // the order is important here - private static final String[] LISTENERS_TO_TEST = new String[]{ - "sipServletInitialized", - "sipAppSessionCreated", - //Tested by the tCK -// "sipAppSessionValueBound", "sipAppSessionValueUnbound", - "sipAppSessionAttributeReplaced","sipAppSessionAttributeRemoved", "sipAppSessionAttributeAdded", - "sipSessionCreated", - //Tested by the tCK -// "sipSessionValueBound", "sipSessionValueUnbound", - "sipSessionAttributeReplaced", "sipSessionAttributeRemoved", "sipSessionAttributeAdded" - }; - - private static final String[] LISTENERS_TO_TEST_AFTER = new String[]{ - //tested in TimersSipServletTest -// "sipAppSessionExpired", - //Cannot get this one below because the sipfactory has already been removed when we get the event - //so we cannot send the message - "sipAppSessionDestroyed", - "sipSessionDestroyed" - }; - - private static final String[] LISTENERS_NOT_TESTED = new String[]{ - //difficult to test, leave it for now - "noAckReceived", - //require the container to support Prack, it currently doesn't - "noPrackReceived", - //require the container to session persistence or distribution, it currently doesn't - "sipAppSessionPassivated", "sipAppSessionActivated", "sipSessionPassivated", "sipSessionActivated"}; - - TestSipListener sender; - - ProtocolObjects senderProtocolObjects; - - - public ListenersSipServletTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/listeners-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/listeners/listeners-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() { - try { - super.setUp(); - - senderProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - } catch (Exception ex) { - fail("unexpected exception "); - } - } - - public void testListeners() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - for (int i = 0; i < LISTENERS_TO_TEST.length; i++) { - logger.info("Testing following listener " + LISTENERS_TO_TEST[i]); - sender.sendMessageInDialog(LISTENERS_TO_TEST[i]); - Thread.sleep(TIMEOUT); - String content = sender.getLastMessageContent(); - assertNotNull(content); - if(!OK.equals(content)) { - fail("following listener " + LISTENERS_TO_TEST[i] + " was not fired"); - } - } - Thread.sleep(TIMEOUT); - sender.sendBye(); - Thread.sleep(TIMEOUT); - assertTrue(sender.getOkToByeReceived()); - Thread.sleep(TIMEOUT_TIMER); - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - logger.info("all messages received : "); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - for (int i = 0; i < LISTENERS_TO_TEST_AFTER.length; i++) { - assertTrue(sender.getAllMessagesContent().contains(LISTENERS_TO_TEST_AFTER[i])); - } - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.listeners; + +import java.text.ParseException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import javax.sip.InvalidArgumentException; +import javax.sip.SipException; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class ListenersSipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ListenersSipServletTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 2000; + private static final int TIMEOUT_TIMER = 20000; +// private static final int TIMEOUT = 100000000; + + private static final String OK = "OK"; + // the order is important here + private static final String[] LISTENERS_TO_TEST = new String[]{ + "sipServletInitialized", + "sipAppSessionCreated", + //Tested by the tCK + // "sipAppSessionValueBound", "sipAppSessionValueUnbound", + "sipAppSessionAttributeReplaced", "sipAppSessionAttributeRemoved", "sipAppSessionAttributeAdded", + "sipSessionCreated", + //Tested by the tCK + // "sipSessionValueBound", "sipSessionValueUnbound", + "sipSessionAttributeReplaced", "sipSessionAttributeRemoved", "sipSessionAttributeAdded" + }; + + private static final String[] LISTENERS_TO_TEST_AFTER = new String[]{ + //tested in TimersSipServletTest + // "sipAppSessionExpired", + //Cannot get this one below because the sipfactory has already been removed when we get the event + //so we cannot send the message + "sipAppSessionDestroyed", + "sipSessionDestroyed" + }; + + private static final String[] LISTENERS_NOT_TESTED = new String[]{ + //difficult to test, leave it for now + "noAckReceived", + //require the container to support Prack, it currently doesn't + "noPrackReceived", + //require the container to session persistence or distribution, it currently doesn't + "sipAppSessionPassivated", "sipAppSessionActivated", "sipSessionPassivated", "sipSessionActivated"}; + + TestSipListener sender; + + ProtocolObjects senderProtocolObjects; + + public ListenersSipServletTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + public SipStandardContext deployApplication(Map params) { + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/listeners-sip-servlet/src/main/sipapp", + "sip-test", + params, + null); + assertTrue(ctx.getAvailable()); + return ctx; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/listeners/listeners-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() { + try { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployApplication(params); + } catch (Exception ex) { + fail("unexpected exception "); + } + } + + public void testListeners() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + for (int i = 0; i < LISTENERS_TO_TEST.length; i++) { + logger.info("Testing following listener " + LISTENERS_TO_TEST[i]); + sender.sendMessageInDialog(LISTENERS_TO_TEST[i]); + Thread.sleep(TIMEOUT); + String content = sender.getLastMessageContent(); + assertNotNull(content); + if (!OK.equals(content)) { + fail("following listener " + LISTENERS_TO_TEST[i] + " was not fired"); + } + } + Thread.sleep(TIMEOUT); + sender.sendBye(); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + Thread.sleep(TIMEOUT_TIMER); + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + logger.info("all messages received : "); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + for (int i = 0; i < LISTENERS_TO_TEST_AFTER.length; i++) { + assertTrue(sender.getAllMessagesContent().contains(LISTENERS_TO_TEST_AFTER[i])); + } + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/mapping/ServletMappingSipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/mapping/ServletMappingSipServletTest.java index 7577c51640..5160fcd468 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/mapping/ServletMappingSipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/mapping/ServletMappingSipServletTest.java @@ -1,237 +1,255 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.mapping; - -import java.text.ParseException; -import java.util.Iterator; - -import javax.sip.InvalidArgumentException; -import javax.sip.SipException; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class ServletMappingSipServletTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(ServletMappingSipServletTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender; - - ProtocolObjects senderProtocolObjects; - - private static final String[] MESSAGES = new String[]{ - "servletInitialized", - "inviteReceived" - }; - - public ServletMappingSipServletTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/servlet-mapping-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/mapping/servlet-mapping-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070", null, null); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - } - - public void testServletMappingOK() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "servlet-mapping"; - String toSipAddress = "mobicents.sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - toAddress.setParameter("foo", "fighter"); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); - Thread.sleep(TIMEOUT); - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - for (int i = 0; i < MESSAGES.length; i++) { - assertTrue(sender.getAllMessagesContent().contains(MESSAGES[i])); - } - assertEquals(200, sender.getFinalResponseStatus()); - assertTrue(sender.getOkToByeReceived()); - } - - public void testServletMappingHostKO() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "servlet-mapping"; - String toSipAddress = "mobicents2.sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - toAddress.setParameter("foo", "fighter"); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); - Thread.sleep(TIMEOUT); - assertEquals(404, sender.getFinalResponseStatus()); - assertTrue(sender.isFinalResponseReceived()); - } - - public void testServletMappingUserKO() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "mobicents.sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - toAddress.setParameter("foo", "fighter"); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); - Thread.sleep(TIMEOUT); - assertEquals(404, sender.getFinalResponseStatus()); - assertTrue(sender.isFinalResponseReceived()); - } - - public void testServletMappingParamKO() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "servlet-mapping"; - String toSipAddress = "mobicents.sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); - Thread.sleep(TIMEOUT); - assertEquals(404, sender.getFinalResponseStatus()); - assertTrue(sender.isFinalResponseReceived()); - } - - public void testServletSecondMappingOK() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "servlet-mapping2"; - String toSipAddress = "mobicents.sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); - Thread.sleep(TIMEOUT); - assertEquals(410, sender.getFinalResponseStatus()); - assertTrue(sender.isFinalResponseReceived()); - } - - public void testServletMappingsInTurn() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "servlet-mapping"; - String toSipAddress = "mobicents.sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - toAddress.setParameter("foo", "fighter"); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); - Thread.sleep(TIMEOUT); - assertEquals(200, sender.getFinalResponseStatus()); - assertTrue(sender.isFinalResponseReceived()); - - toUser = "servlet-mapping2"; - toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); - Thread.sleep(TIMEOUT); - assertEquals(410, sender.getFinalResponseStatus()); - assertTrue(sender.isFinalResponseReceived()); - - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - for (int i = 0; i < MESSAGES.length; i++) { - assertTrue(sender.getAllMessagesContent().contains(MESSAGES[i])); - } - } - - public void testServletSecondMappingKO() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "servlet-mapping3"; - String toSipAddress = "mobicents.sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); - Thread.sleep(TIMEOUT); - assertEquals(404, sender.getFinalResponseStatus()); - assertTrue(sender.isFinalResponseReceived()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.mapping; + +import java.text.ParseException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import javax.sip.InvalidArgumentException; +import javax.sip.SipException; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class ServletMappingSipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ServletMappingSipServletTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + + ProtocolObjects senderProtocolObjects; + + private static final String[] MESSAGES = new String[]{ + "servletInitialized", + "inviteReceived" + }; + + public ServletMappingSipServletTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + public SipStandardContext deployApplication(Map params) { + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/servlet-mapping-servlet/src/main/sipapp", + "sip-test", + params, + null); + assertTrue(ctx.getAvailable()); + return ctx; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/mapping/servlet-mapping-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + containerPort, null, null); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployApplication(params); + } + + public void testServletMappingOK() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "servlet-mapping"; + String toSipAddress = "mobicents.sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + toAddress.setParameter("foo", "fighter"); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); + Thread.sleep(TIMEOUT); + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + for (int i = 0; i < MESSAGES.length; i++) { + assertTrue(sender.getAllMessagesContent().contains(MESSAGES[i])); + } + assertEquals(200, sender.getFinalResponseStatus()); + assertTrue(sender.getOkToByeReceived()); + } + + public void testServletMappingHostKO() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "servlet-mapping"; + String toSipAddress = "mobicents2.sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + toAddress.setParameter("foo", "fighter"); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); + Thread.sleep(TIMEOUT); + assertEquals(404, sender.getFinalResponseStatus()); + assertTrue(sender.isFinalResponseReceived()); + } + + public void testServletMappingUserKO() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "mobicents.sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + toAddress.setParameter("foo", "fighter"); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); + Thread.sleep(TIMEOUT); + assertEquals(404, sender.getFinalResponseStatus()); + assertTrue(sender.isFinalResponseReceived()); + } + + public void testServletMappingParamKO() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "servlet-mapping"; + String toSipAddress = "mobicents.sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); + Thread.sleep(TIMEOUT); + assertEquals(404, sender.getFinalResponseStatus()); + assertTrue(sender.isFinalResponseReceived()); + } + + public void testServletSecondMappingOK() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "servlet-mapping2"; + String toSipAddress = "mobicents.sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); + Thread.sleep(TIMEOUT); + assertEquals(410, sender.getFinalResponseStatus()); + assertTrue(sender.isFinalResponseReceived()); + } + + public void testServletMappingsInTurn() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "servlet-mapping"; + String toSipAddress = "mobicents.sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + toAddress.setParameter("foo", "fighter"); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); + Thread.sleep(TIMEOUT); + assertEquals(200, sender.getFinalResponseStatus()); + assertTrue(sender.isFinalResponseReceived()); + + toUser = "servlet-mapping2"; + toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); + Thread.sleep(TIMEOUT); + assertEquals(410, sender.getFinalResponseStatus()); + assertTrue(sender.isFinalResponseReceived()); + + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + for (int i = 0; i < MESSAGES.length; i++) { + assertTrue(sender.getAllMessagesContent().contains(MESSAGES[i])); + } + } + + public void testServletSecondMappingKO() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "servlet-mapping3"; + String toSipAddress = "mobicents.sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); + Thread.sleep(TIMEOUT); + assertEquals(404, sender.getFinalResponseStatus()); + assertTrue(sender.isFinalResponseReceived()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/Cutme.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/Cutme.java index a0c17c6067..3983082762 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/Cutme.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/Cutme.java @@ -58,7 +58,7 @@ public class Cutme implements SipListener { private SipStack sipStack; - private static final int myPort = 5056; + private static int myPort; protected ServerTransaction inviteTid; @@ -75,6 +75,12 @@ public class Cutme implements SipListener { public boolean canceled = false; private long timeToWaitBeforeAnswer = -1; + + public Cutme(Integer port) { + if (port != null) { + this.myPort = port; + } + } class MyTimerTask extends TimerTask { Cutme shootme; @@ -282,9 +288,9 @@ public void init(String transport) { // Your code will limp at 32 but it is best for debugging. properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "32"); properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", - "logs/cutmedebug.txt"); + "target/logs/cutmedebug.txt"); properties.setProperty("gov.nist.javax.sip.SERVER_LOG", - "logs/cutmelog.xml"); + "target/logs/cutmelog.xml"); try { // Create SipStack object diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ParallelProxyTelURLWithRecordRouteTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ParallelProxyTelURLWithRecordRouteTest.java index cc5939d00b..24276c49aa 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ParallelProxyTelURLWithRecordRouteTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ParallelProxyTelURLWithRecordRouteTest.java @@ -1,158 +1,179 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.proxy; - -import java.util.EventObject; -import java.util.Hashtable; - -import javax.sip.DialogTerminatedEvent; -import javax.sip.IOExceptionEvent; -import javax.sip.RequestEvent; -import javax.sip.ResponseEvent; -import javax.sip.SipListener; -import javax.sip.SipProvider; -import javax.sip.TimeoutEvent; -import javax.sip.TransactionTerminatedEvent; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; - -public class ParallelProxyTelURLWithRecordRouteTest extends SipServletTestCase implements SipListener { - - private static transient Logger logger = Logger.getLogger(ParallelProxyTelURLWithRecordRouteTest.class); - - protected Shootist shootist; - - protected Shootme shootme; - - protected Cutme cutme; - - protected Hashtable providerTable = new Hashtable(); - - private static final int TIMEOUT = 15000; - - private static final int receiversCount = 1; - - public ParallelProxyTelURLWithRecordRouteTest(String name) { - super(name); - - this.sipIpAddress="0.0.0.0"; - } - - @Override - public void setUp() throws Exception { - super.setUp(); - this.shootist = new Shootist(false, null); - this.shootme = new Shootme(5057); - this.cutme = new Cutme(); - } - - public void testProxy() { - this.shootme.init("stackName", null); - this.cutme.init(null); - this.shootist.init("useHostName", true, null); - for (int q = 0; q < 20; q++) { - if (shootist.ended == false && cutme.canceled == false) - try { - Thread.sleep(TIMEOUT); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - if (shootist.ended == false) - fail("Conversation not complete!"); - if (cutme.canceled == false) - fail("The party that was supposed to be cancelled didn't cancel."); - } - - @Override - public void tearDown() throws Exception { - shootist.destroy(); - shootme.destroy(); - cutme.destroy(); - super.tearDown(); - } - - @Override - public void deployApplication() { - assertTrue(tomcat - .deployContext( - projectHome - + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/proxy/simple-sip-servlet-dar.properties"; - } - - public void init() { - // setupPhones(); - } - - private SipListener getSipListener(EventObject sipEvent) { - SipProvider source = (SipProvider) sipEvent.getSource(); - SipListener listener = (SipListener) providerTable.get(source); - if (listener == null) - throw new RuntimeException("Unexpected null listener"); - return listener; - } - - public void processRequest(RequestEvent requestEvent) { - getSipListener(requestEvent).processRequest(requestEvent); - - } - - public void processResponse(ResponseEvent responseEvent) { - getSipListener(responseEvent).processResponse(responseEvent); - - } - - public void processTimeout(TimeoutEvent timeoutEvent) { - getSipListener(timeoutEvent).processTimeout(timeoutEvent); - } - - public void processIOException(IOExceptionEvent exceptionEvent) { - fail("unexpected exception"); - - } - - public void processTransactionTerminated( - TransactionTerminatedEvent transactionTerminatedEvent) { - getSipListener(transactionTerminatedEvent) - .processTransactionTerminated(transactionTerminatedEvent); - - } - - public void processDialogTerminated( - DialogTerminatedEvent dialogTerminatedEvent) { - getSipListener(dialogTerminatedEvent).processDialogTerminated( - dialogTerminatedEvent); - - } -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.proxy; + +import java.util.EventObject; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; + +import javax.sip.DialogTerminatedEvent; +import javax.sip.IOExceptionEvent; +import javax.sip.RequestEvent; +import javax.sip.ResponseEvent; +import javax.sip.SipListener; +import javax.sip.SipProvider; +import javax.sip.TimeoutEvent; +import javax.sip.TransactionTerminatedEvent; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; + +public class ParallelProxyTelURLWithRecordRouteTest extends SipServletTestCase implements SipListener { + + private static transient Logger logger = Logger.getLogger(ParallelProxyTelURLWithRecordRouteTest.class); + + protected Shootist shootist; + + protected Shootme shootme; + + protected Cutme cutme; + + protected Hashtable providerTable = new Hashtable(); + + private static final int TIMEOUT = 15000; + + private static final int receiversCount = 1; + + public ParallelProxyTelURLWithRecordRouteTest(String name) { + super(name); + autoDeployOnStartup = false; + this.sipIpAddress = "0.0.0.0"; + } + + @Override + public void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + int shootistPort = NetworkPortAssigner.retrieveNextPort(); + this.shootist = new Shootist(false, shootistPort, String.valueOf(containerPort)); + shootist.setOutboundProxy(false); + int shootmePort = NetworkPortAssigner.retrieveNextPort(); + this.shootme = new Shootme(shootmePort); + int cutmePort = NetworkPortAssigner.retrieveNextPort(); + this.cutme = new Cutme(cutmePort); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(shootistPort)); + params.put("receiverPort", String.valueOf(shootmePort)); + params.put("cutmePort", String.valueOf(cutmePort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + params, null); + } + + public void testProxy() { + this.shootme.init("stackName", null); + this.cutme.init(null); + this.shootist.init("useHostName", true, null); + for (int q = 0; q < 20; q++) { + if (shootist.ended == false && cutme.canceled == false) { + try { + Thread.sleep(TIMEOUT); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + if (shootist.ended == false) { + fail("Conversation not complete!"); + } + if (cutme.canceled == false) { + fail("The party that was supposed to be cancelled didn't cancel."); + } + } + + @Override + public void tearDown() throws Exception { + shootist.destroy(); + shootme.destroy(); + cutme.destroy(); + super.tearDown(); + } + + @Override + public void deployApplication() { + assertTrue(tomcat + .deployContext( + projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + "sip-test-context", "sip-test")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/proxy/simple-sip-servlet-dar.properties"; + } + + public void init() { + // setupPhones(); + } + + private SipListener getSipListener(EventObject sipEvent) { + SipProvider source = (SipProvider) sipEvent.getSource(); + SipListener listener = (SipListener) providerTable.get(source); + if (listener == null) { + throw new RuntimeException("Unexpected null listener"); + } + return listener; + } + + public void processRequest(RequestEvent requestEvent) { + getSipListener(requestEvent).processRequest(requestEvent); + + } + + public void processResponse(ResponseEvent responseEvent) { + getSipListener(responseEvent).processResponse(responseEvent); + + } + + public void processTimeout(TimeoutEvent timeoutEvent) { + getSipListener(timeoutEvent).processTimeout(timeoutEvent); + } + + public void processIOException(IOExceptionEvent exceptionEvent) { + fail("unexpected exception"); + + } + + public void processTransactionTerminated( + TransactionTerminatedEvent transactionTerminatedEvent) { + getSipListener(transactionTerminatedEvent) + .processTransactionTerminated(transactionTerminatedEvent); + + } + + public void processDialogTerminated( + DialogTerminatedEvent dialogTerminatedEvent) { + getSipListener(dialogTerminatedEvent).processDialogTerminated( + dialogTerminatedEvent); + + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ParallelProxyWithRecordRouteTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ParallelProxyWithRecordRouteTest.java index 5353e42827..8553c49116 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ParallelProxyWithRecordRouteTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ParallelProxyWithRecordRouteTest.java @@ -1,318 +1,335 @@ -/* - * TeleStax, Open Source Cloud Communications Copyright 2012. - * and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.proxy; - -import java.util.ListIterator; - -import javax.sip.ListeningPoint; -import javax.sip.header.RecordRouteHeader; - -import org.mobicents.servlet.sip.SipServletTestCase; - -public class ParallelProxyWithRecordRouteTest extends SipServletTestCase { - - private static final String STACK_NAME = "shootme"; - - protected Shootist shootist; - - protected Shootme shootme; - - protected Cutme cutme; - - private static final int TIMEOUT = 15000; - private static final int TIMEOUT_READY_TO_INVALIDATE = 70000; - - public ParallelProxyWithRecordRouteTest(String name) { - super(name); - - this.sipIpAddress="0.0.0.0"; - startTomcatOnStartup = false; - autoDeployOnStartup = false; - } - - @Override - public void setUp() throws Exception { - super.setUp(); - tomcat.addSipConnector(serverName, sipIpAddress, 5070, ListeningPoint.TCP); - tomcat.startTomcat(); - deployApplication(); - this.shootist = new Shootist(false, null); - shootist.setOutboundProxy(false); - this.shootme = new Shootme(5057); - this.cutme = new Cutme(); - } - - public void testProxyCalleeSendsBye() { - this.shootme.init(STACK_NAME, null); - this.shootme.callerSendsBye = false; - this.shootme.setTimeToWaitBeforeAnswer(300); - try { - this.cutme.init(null); - this.cutme.setTimeToWaitBeforeAnswer(300); - this.shootist.init("useHostName",false, null); - for (int q = 0; q < 20; q++) { - if (shootist.ended == false && cutme.canceled == false) - try { - Thread.sleep(TIMEOUT); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - } catch(Exception e) {} - this.shootme.callerSendsBye = true; - if (shootist.ended == false) - fail("Conversation not complete!"); - if (cutme.canceled == false) - fail("The party that was supposed to be cancelled didn't cancel."); - if(shootist.getNumberOfTryingReceived() != 1) { - fail("We got " + shootist.getNumberOfTryingReceived() +" Trying, we should have received one !"); - } - } - - - public void testProxy() { - this.shootme.init(STACK_NAME, null); - this.cutme.init(null); - this.shootist.init("useHostName",false, null); - for (int q = 0; q < 20; q++) { - if (shootist.ended == false && cutme.canceled == false) - try { - Thread.sleep(TIMEOUT); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - if (shootist.isRequestTerminatedReceived()) - fail("487 received from other end!"); - if (!shootist.ended) - fail("Conversation not complete!"); - if (!cutme.canceled) - fail("The party that was supposed to be cancelled didn't cancel."); - } - - public void testProxyReadyToInvalidate() { - this.shootme.init(STACK_NAME, null); - this.cutme.init(null); - this.shootist.init("check_rti",false, null); - for (int q = 0; q < 20; q++) { - if (shootist.ended == false && cutme.canceled == false) - try { - Thread.sleep(TIMEOUT_READY_TO_INVALIDATE); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - if (shootist.ended == false) - fail("Conversation not complete!"); - if (cutme.canceled == false) - fail("The party that was supposed to be cancelled didn't cancel."); - assertNotNull(shootist.getLastMessageContent()); - if(!shootist.getLastMessageContent().equals("sipSessionReadyToInvalidate") && !shootist.getLastMessageContent().equals("sessionReadyToInvalidate")) { - fail(); - } - } - - public void testProxyReadyToInvalidateTCP() { - this.shootme.init(STACK_NAME, "tcp"); - this.cutme.init("tcp"); - this.shootist.init("check_rti",false, "tcp"); - for (int q = 0; q < 20; q++) { - if (shootist.ended == false && cutme.canceled == false) - try { - Thread.sleep(TIMEOUT_READY_TO_INVALIDATE); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - if (shootist.ended == false) - fail("Conversation not complete!"); - if (cutme.canceled == false) - fail("The party that was supposed to be cancelled didn't cancel."); - assertNotNull(shootist.getLastMessageContent()); - if(!shootist.getLastMessageContent().equals("sipSessionReadyToInvalidate") && !shootist.getLastMessageContent().equals("sessionReadyToInvalidate")) { - fail(); - } - } - - // Non regression test for http://code.google.com/p/sipservlets/issues/detail?id=81 - public void testProxyRecordRoutePushRouteTCP() { - this.shootme.init(STACK_NAME, "tcp"); - this.cutme.init("tcp"); - this.shootist.init("unique-location-urn-route-tcp-uri1",false, "tcp"); - for (int q = 0; q < 20; q++) { - if (shootist.ended == false && cutme.canceled == false) - try { - Thread.sleep(TIMEOUT); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - if (shootist.ended == false) - fail("Conversation not complete!"); - //proxied to unique location so no cancel from cutme - if (cutme.canceled == true) - fail("The party that was supposed to be cancelled didn't cancel."); - assertNotNull(shootist.getLastMessageContent()); - ListIterator recordRouteHeaders = shootme.getInviteRequest().getHeaders(RecordRouteHeader.NAME); - assertTrue(recordRouteHeaders.hasNext()); - recordRouteHeaders.next(); - //make sure we only have 1 RR Header - assertFalse(recordRouteHeaders.hasNext()); - assertEquals("sessionReadyToInvalidate", shootist.getLastMessageContent()); - } - - /** - * Non regression test for Issue 747 : Non Record Routing Proxy is adding Record Route on informational response - * http://code.google.com/p/mobicents/issues/detail?id=747 - */ - public void testProxyNonRecordRouting() { - this.shootme.init(STACK_NAME, null); - this.cutme.init(null); - this.shootist.init("nonRecordRouting",false, null); - for (int q = 0; q < 20; q++) { - if (shootist.ended == false && cutme.canceled == false) - try { - Thread.sleep(TIMEOUT); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - if (shootist.ended == false) - fail("Conversation not complete!"); - if (cutme.canceled == false) - fail("The party that was supposed to be cancelled didn't cancel."); - } - - /** - * Non regression test for Issue 851 : NPE on handling URI parameters in address headers - * http://code.google.com/p/mobicents/issues/detail?id=851 - */ - public void testProxyURIParams() { - this.shootme.init(STACK_NAME, null); - this.cutme.init(null); - this.shootist.init("check_uri",false, null); - for (int q = 0; q < 20; q++) { - if (shootist.ended == false && cutme.canceled == false) - try { - Thread.sleep(TIMEOUT); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - if (shootist.ended == false) - fail("Conversation not complete!"); - } - - /** - * Non regression test for Issue 2417 : Two 100 Trying responses sent if Proxy decision is delayed. - * http://code.google.com/p/mobicents/issues/detail?id=2417 - */ - public void testProxy2Trying() { - this.shootme.init(STACK_NAME, null); - this.cutme.init(null); - this.shootist.init("test_2_trying",false, null); - for (int q = 0; q < 20; q++) { - if (shootist.ended == false && cutme.canceled == false) - try { - Thread.sleep(TIMEOUT); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - if (shootist.ended == false) - fail("Conversation not complete!"); - if(shootist.getNumberOfTryingReceived() > 1) { - fail("We got " + shootist.getNumberOfTryingReceived() +" Trying, we should have received only one !"); - } - if(shootist.getNumberOfTryingReceived() != 1) { - fail("We got " + shootist.getNumberOfTryingReceived() +" Trying, we should have received one !"); - } - } - - /** - * Non regression test for Issue 2440 : SipSession.createRequest on proxy SipSession does not throw IllegalStateException - * http://code.google.com/p/mobicents/issues/detail?id=2440 - */ - public void testProxyCreateSubsequent() { - this.shootme.init(STACK_NAME, null); - this.cutme.init(null); - this.shootist.init("test_create_subsequent_request",false, null); - for (int q = 0; q < 20; q++) { - if (shootist.ended == false && cutme.canceled == false) - try { - Thread.sleep(TIMEOUT); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - if (shootist.ended == true) - fail("Conversation complete where it shouldn't be since the createSubsequentRequest should have thrown an IllegalStateException!"); - } - - /** - * Non regression test for Issue 2850 : Use Request-URI custom Mobicents parameters to route request for misbehaving agents - * http://code.google.com/p/mobicents/issues/detail?id=2850 - */ - public void testProxyRequestURIMobicentsParam() { - this.shootme.init(STACK_NAME, null); - this.shootist.init("unique-location",false, null); - this.shootist.moveRouteParamsToRequestURI = true; - this.cutme.init(null); - for (int q = 0; q < 20; q++) { - if (!shootist.ended && !cutme.canceled) - try { - Thread.sleep(TIMEOUT); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - if (!shootist.ended) - fail("Conversation not complete"); - } - - @Override - public void tearDown() throws Exception { - shootist.destroy(); - shootme.destroy(); - if(cutme != null) - cutme.destroy(); - super.tearDown(); - } - - @Override - public void deployApplication() { - assertTrue(tomcat - .deployContext( - projectHome - + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/proxy/simple-sip-servlet-dar.properties"; - } -} +/* + * TeleStax, Open Source Cloud Communications Copyright 2012. + * and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite.proxy; + +import java.util.HashMap; +import java.util.ListIterator; +import java.util.Map; + +import javax.sip.ListeningPoint; +import javax.sip.header.RecordRouteHeader; +import org.mobicents.servlet.sip.NetworkPortAssigner; + +import org.mobicents.servlet.sip.SipServletTestCase; + +public class ParallelProxyWithRecordRouteTest extends SipServletTestCase { + + private static final String STACK_NAME = "shootme"; + + protected Shootist shootist; + + protected Shootme shootme; + + protected Cutme cutme; + + private static final int TIMEOUT = 15000; + private static final int TIMEOUT_READY_TO_INVALIDATE = 70000; + + public ParallelProxyWithRecordRouteTest(String name) { + super(name); + + this.sipIpAddress="0.0.0.0"; + startTomcatOnStartup = false; + autoDeployOnStartup = false; + } + + @Override + public void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + int shootistPort = NetworkPortAssigner.retrieveNextPort(); + this.shootist = new Shootist(false, shootistPort, String.valueOf(containerPort)); + shootist.setOutboundProxy(false); + int shootmePort = NetworkPortAssigner.retrieveNextPort(); + this.shootme = new Shootme(shootmePort); + int cutmePort = NetworkPortAssigner.retrieveNextPort(); + this.cutme = new Cutme(cutmePort); + + tomcat.addSipConnector(serverName, sipIpAddress, containerPort, ListeningPoint.TCP); + tomcat.startTomcat(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(shootistPort)); + params.put( "receiverPort", String.valueOf(shootmePort)); + params.put( "cutmePort", String.valueOf(cutmePort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + params, null); + } + + public void testProxyCalleeSendsBye() { + this.shootme.init(STACK_NAME, null); + this.shootme.callerSendsBye = false; + this.shootme.setTimeToWaitBeforeAnswer(300); + try { + this.cutme.init(null); + this.cutme.setTimeToWaitBeforeAnswer(300); + this.shootist.init("useHostName",false, null); + for (int q = 0; q < 20; q++) { + if (shootist.ended == false && cutme.canceled == false) + try { + Thread.sleep(TIMEOUT); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } catch(Exception e) {} + this.shootme.callerSendsBye = true; + if (shootist.ended == false) + fail("Conversation not complete!"); + if (cutme.canceled == false) + fail("The party that was supposed to be cancelled didn't cancel."); + if(shootist.getNumberOfTryingReceived() != 1) { + fail("We got " + shootist.getNumberOfTryingReceived() +" Trying, we should have received one !"); + } + } + + + public void testProxy() { + this.shootme.init(STACK_NAME, null); + this.cutme.init(null); + this.shootist.init("useHostName",false, null); + for (int q = 0; q < 20; q++) { + if (shootist.ended == false && cutme.canceled == false) + try { + Thread.sleep(TIMEOUT); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + if (shootist.isRequestTerminatedReceived()) + fail("487 received from other end!"); + if (!shootist.ended) + fail("Conversation not complete!"); + if (!cutme.canceled) + fail("The party that was supposed to be cancelled didn't cancel."); + } + + public void testProxyReadyToInvalidate() { + this.shootme.init(STACK_NAME, null); + this.cutme.init(null); + this.shootist.init("check_rti",false, null); + for (int q = 0; q < 20; q++) { + if (shootist.ended == false && cutme.canceled == false) + try { + Thread.sleep(TIMEOUT_READY_TO_INVALIDATE); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + if (shootist.ended == false) + fail("Conversation not complete!"); + if (cutme.canceled == false) + fail("The party that was supposed to be cancelled didn't cancel."); + assertNotNull(shootist.getLastMessageContent()); + if(!shootist.getLastMessageContent().equals("sipSessionReadyToInvalidate") && !shootist.getLastMessageContent().equals("sessionReadyToInvalidate")) { + fail(); + } + } + + public void testProxyReadyToInvalidateTCP() { + this.shootme.init(STACK_NAME, "tcp"); + this.cutme.init("tcp"); + this.shootist.init("check_rti",false, "tcp"); + for (int q = 0; q < 20; q++) { + if (shootist.ended == false && cutme.canceled == false) + try { + Thread.sleep(TIMEOUT_READY_TO_INVALIDATE); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + if (shootist.ended == false) + fail("Conversation not complete!"); + if (cutme.canceled == false) + fail("The party that was supposed to be cancelled didn't cancel."); + assertNotNull(shootist.getLastMessageContent()); + if(!shootist.getLastMessageContent().equals("sipSessionReadyToInvalidate") && !shootist.getLastMessageContent().equals("sessionReadyToInvalidate")) { + fail(); + } + } + + // Non regression test for http://code.google.com/p/sipservlets/issues/detail?id=81 + public void testProxyRecordRoutePushRouteTCP() { + this.shootme.init(STACK_NAME, "tcp"); + this.cutme.init("tcp"); + this.shootist.init("unique-location-urn-route-tcp-uri1",false, "tcp"); + for (int q = 0; q < 20; q++) { + if (shootist.ended == false && cutme.canceled == false) + try { + Thread.sleep(TIMEOUT); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + if (shootist.ended == false) + fail("Conversation not complete!"); + //proxied to unique location so no cancel from cutme + if (cutme.canceled == true) + fail("The party that was supposed to be cancelled didn't cancel."); + assertNotNull(shootist.getLastMessageContent()); + ListIterator recordRouteHeaders = shootme.getInviteRequest().getHeaders(RecordRouteHeader.NAME); + assertTrue(recordRouteHeaders.hasNext()); + recordRouteHeaders.next(); + //make sure we only have 1 RR Header + assertFalse(recordRouteHeaders.hasNext()); + assertEquals("sessionReadyToInvalidate", shootist.getLastMessageContent()); + } + + /** + * Non regression test for Issue 747 : Non Record Routing Proxy is adding Record Route on informational response + * http://code.google.com/p/mobicents/issues/detail?id=747 + */ + public void testProxyNonRecordRouting() { + this.shootme.init(STACK_NAME, null); + this.cutme.init(null); + this.shootist.init("nonRecordRouting",false, null); + for (int q = 0; q < 20; q++) { + if (shootist.ended == false && cutme.canceled == false) + try { + Thread.sleep(TIMEOUT); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + if (shootist.ended == false) + fail("Conversation not complete!"); + if (cutme.canceled == false) + fail("The party that was supposed to be cancelled didn't cancel."); + } + + /** + * Non regression test for Issue 851 : NPE on handling URI parameters in address headers + * http://code.google.com/p/mobicents/issues/detail?id=851 + */ + public void testProxyURIParams() { + this.shootme.init(STACK_NAME, null); + this.cutme.init(null); + this.shootist.init("check_uri",false, null); + for (int q = 0; q < 20; q++) { + if (shootist.ended == false && cutme.canceled == false) + try { + Thread.sleep(TIMEOUT); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + if (shootist.ended == false) + fail("Conversation not complete!"); + } + + /** + * Non regression test for Issue 2417 : Two 100 Trying responses sent if Proxy decision is delayed. + * http://code.google.com/p/mobicents/issues/detail?id=2417 + */ + public void testProxy2Trying() { + this.shootme.init(STACK_NAME, null); + this.cutme.init(null); + this.shootist.init("test_2_trying",false, null); + for (int q = 0; q < 20; q++) { + if (shootist.ended == false && cutme.canceled == false) + try { + Thread.sleep(TIMEOUT); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + if (shootist.ended == false) + fail("Conversation not complete!"); + if(shootist.getNumberOfTryingReceived() > 1) { + fail("We got " + shootist.getNumberOfTryingReceived() +" Trying, we should have received only one !"); + } + if(shootist.getNumberOfTryingReceived() != 1) { + fail("We got " + shootist.getNumberOfTryingReceived() +" Trying, we should have received one !"); + } + } + + /** + * Non regression test for Issue 2440 : SipSession.createRequest on proxy SipSession does not throw IllegalStateException + * http://code.google.com/p/mobicents/issues/detail?id=2440 + */ + public void testProxyCreateSubsequent() { + this.shootme.init(STACK_NAME, null); + this.cutme.init(null); + this.shootist.init("test_create_subsequent_request",false, null); + for (int q = 0; q < 20; q++) { + if (shootist.ended == false && cutme.canceled == false) + try { + Thread.sleep(TIMEOUT); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + if (shootist.ended == true) + fail("Conversation complete where it shouldn't be since the createSubsequentRequest should have thrown an IllegalStateException!"); + } + + /** + * Non regression test for Issue 2850 : Use Request-URI custom Mobicents parameters to route request for misbehaving agents + * http://code.google.com/p/mobicents/issues/detail?id=2850 + */ + public void testProxyRequestURIMobicentsParam() { + this.shootme.init(STACK_NAME, null); + this.shootist.init("unique-location",false, null); + this.shootist.moveRouteParamsToRequestURI = true; + this.cutme.init(null); + for (int q = 0; q < 20; q++) { + if (!shootist.ended && !cutme.canceled) + try { + Thread.sleep(TIMEOUT); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + if (!shootist.ended) + fail("Conversation not complete"); + } + + @Override + public void tearDown() throws Exception { + shootist.destroy(); + shootme.destroy(); + if(cutme != null) + cutme.destroy(); + super.tearDown(); + } + + @Override + public void deployApplication() { + assertTrue(tomcat + .deployContext( + projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + "sip-test-context", "sip-test")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/proxy/simple-sip-servlet-dar.properties"; + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ParallelProxyWithRecordRouteUseHostNameTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ParallelProxyWithRecordRouteUseHostNameTest.java index 6fb26980c2..12a8438f28 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ParallelProxyWithRecordRouteUseHostNameTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ParallelProxyWithRecordRouteUseHostNameTest.java @@ -1,158 +1,136 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.proxy; - -import java.util.EventObject; -import java.util.Hashtable; - -import javax.sip.DialogTerminatedEvent; -import javax.sip.IOExceptionEvent; -import javax.sip.RequestEvent; -import javax.sip.ResponseEvent; -import javax.sip.SipListener; -import javax.sip.SipProvider; -import javax.sip.TimeoutEvent; -import javax.sip.TransactionTerminatedEvent; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; - -public class ParallelProxyWithRecordRouteUseHostNameTest extends SipServletTestCase implements SipListener { - - private static transient Logger logger = Logger.getLogger(ParallelProxyWithRecordRouteUseHostNameTest.class); - - protected Shootist shootist; - - protected Shootme shootme; - - protected Cutme cutme; - - protected Hashtable providerTable = new Hashtable(); - - private static final int timeout = 20000; - - private static final int receiversCount = 1; - - public ParallelProxyWithRecordRouteUseHostNameTest(String name) { - super(name); - - this.sipIpAddress="0.0.0.0"; - } - - @Override - public void setUp() throws Exception { - super.setUp(); - this.shootist = new Shootist(false, null); - this.shootme = new Shootme(5057); - this.cutme = new Cutme(); - } - - public void testProxy() { - this.shootme.init("stackName", null); - this.cutme.init(null); - this.shootist.init(); - for (int q = 0; q < 20; q++) { - if (shootme.ended == false && cutme.canceled == false) - try { - Thread.sleep(10000); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - if (shootme.ended == false) - fail("Conversation not complete!"); - if (cutme.canceled == false) - fail("The party that was supposed to be cancelled didn't cancel."); - } - - @Override - public void tearDown() throws Exception { - shootist.destroy(); - shootme.destroy(); - cutme.destroy(); - super.tearDown(); - } - - @Override - public void deployApplication() { - assertTrue(tomcat - .deployContext( - projectHome - + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/proxy/simple-sip-servlet-dar.properties"; - } - - public void init() { - // setupPhones(); - } - - private SipListener getSipListener(EventObject sipEvent) { - SipProvider source = (SipProvider) sipEvent.getSource(); - SipListener listener = (SipListener) providerTable.get(source); - if (listener == null) - throw new RuntimeException("Unexpected null listener"); - return listener; - } - - public void processRequest(RequestEvent requestEvent) { - getSipListener(requestEvent).processRequest(requestEvent); - - } - - public void processResponse(ResponseEvent responseEvent) { - getSipListener(responseEvent).processResponse(responseEvent); - - } - - public void processTimeout(TimeoutEvent timeoutEvent) { - getSipListener(timeoutEvent).processTimeout(timeoutEvent); - } - - public void processIOException(IOExceptionEvent exceptionEvent) { - fail("unexpected exception"); - - } - - public void processTransactionTerminated( - TransactionTerminatedEvent transactionTerminatedEvent) { - getSipListener(transactionTerminatedEvent) - .processTransactionTerminated(transactionTerminatedEvent); - - } - - public void processDialogTerminated( - DialogTerminatedEvent dialogTerminatedEvent) { - getSipListener(dialogTerminatedEvent).processDialogTerminated( - dialogTerminatedEvent); - - } -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.proxy; + +import java.util.EventObject; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; + +import javax.sip.DialogTerminatedEvent; +import javax.sip.IOExceptionEvent; +import javax.sip.RequestEvent; +import javax.sip.ResponseEvent; +import javax.sip.SipListener; +import javax.sip.SipProvider; +import javax.sip.TimeoutEvent; +import javax.sip.TransactionTerminatedEvent; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; + +public class ParallelProxyWithRecordRouteUseHostNameTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ParallelProxyWithRecordRouteUseHostNameTest.class); + + protected Shootist shootist; + + protected Shootme shootme; + + protected Cutme cutme; + + protected Hashtable providerTable = new Hashtable(); + + private static final int timeout = 20000; + + private static final int receiversCount = 1; + + public ParallelProxyWithRecordRouteUseHostNameTest(String name) { + super(name); + this.sipIpAddress = "0.0.0.0"; + autoDeployOnStartup = false; + } + + @Override + public void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + int shootistPort = NetworkPortAssigner.retrieveNextPort(); + this.shootist = new Shootist(false, shootistPort, String.valueOf(containerPort)); + int shootmePort = NetworkPortAssigner.retrieveNextPort(); + this.shootme = new Shootme(shootmePort); + int cutmePort = NetworkPortAssigner.retrieveNextPort(); + this.cutme = new Cutme(cutmePort); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(shootistPort)); + params.put("receiverPort", String.valueOf(shootmePort)); + params.put("cutmePort", String.valueOf(cutmePort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + params, null); + } + + public void testProxy() { + this.shootme.init("stackName", null); + this.cutme.init(null); + this.shootist.init(); + for (int q = 0; q < 20; q++) { + if (shootme.ended && cutme.canceled) { + //conditions met + break; + } else { + try { + Thread.sleep(10000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + assertTrue("Conversation not complete!", shootme.ended); + assertTrue("The party that was supposed to be cancelled didn't cancel.", cutme.canceled); + } + + @Override + public void tearDown() throws Exception { + shootist.destroy(); + shootme.destroy(); + cutme.destroy(); + super.tearDown(); + } + + @Override + public void deployApplication() { + assertTrue(tomcat + .deployContext( + projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + "sip-test-context", "sip-test")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/proxy/simple-sip-servlet-dar.properties"; + } + + public void init() { + // setupPhones(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/Proxy2AppServersRoutingServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/Proxy2AppServersRoutingServletTest.java index 50d797a504..1412f55ff5 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/Proxy2AppServersRoutingServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/Proxy2AppServersRoutingServletTest.java @@ -1,264 +1,312 @@ -/* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2013, Telestax Inc and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - */ - -package org.mobicents.servlet.sip.testsuite.proxy; - -import java.io.File; -import java.util.ListIterator; -import java.util.Properties; - -import javax.sip.ListeningPoint; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; -import javax.sip.header.ViaHeader; - -import org.apache.log4j.Logger; -import org.cafesip.sipunit.SipStack; -import org.mobicents.servlet.sip.SipEmbedded; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -/** - * - * @author Jean Deruelle - * - */ -public class Proxy2AppServersRoutingServletTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(Proxy2AppServersRoutingServletTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; - - SipEmbedded closestTomcat; - - TestSipListener sender; - TestSipListener receiver; - - ProtocolObjects senderProtocolObjects; - ProtocolObjects recieverProtocolObjects; - - public Proxy2AppServersRoutingServletTest(String name) { - super(name); - autoDeployOnStartup = false; - startTomcatOnStartup = false; - } - - @Override - public void deployApplication() { - assertTrue(tomcat - .deployContext( - projectHome - + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/proxy/proxy-dar.properties"; - } - - protected String getDarConfigurationFileForSecondServer() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/proxy/proxy-dar.properties"; - } - - protected String getDarConfigurationFileUASSecondServer() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/simple/simple-sip-servlet-dar.properties"; - } - - @Override - public void setUp() throws Exception { - super.setUp(); - System.setProperty("javax.servlet.sip.ar.spi.SipApplicationRouterProvider", "org.mobicents.servlet.sip.router.DefaultApplicationRouterProvider"); - senderProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - - - recieverProtocolObjects =new ProtocolObjects( - "reciever", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5057, 5070, recieverProtocolObjects, false); - SipProvider registerRecieverProvider = receiver.createProvider(); - - registerRecieverProvider.addSipListener(receiver); - - recieverProtocolObjects.start(); - } - - public SipStack makeStack(String transport, int port) throws Exception { - Properties properties = new Properties(); - String peerHostPort1 = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5069"; - properties.setProperty("javax.sip.OUTBOUND_PROXY", peerHostPort1 + "/" - + "udp"); - properties.setProperty("javax.sip.STACK_NAME", "UAC_" + transport + "_" - + port); - properties.setProperty("sipunit.BINDADDR", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); - properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", - "logs/callforwarding_debug_5069.txt"); - properties.setProperty("gov.nist.javax.sip.SERVER_LOG", - "logs/callforwarding_server_5069.txt"); - properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "32"); - - return new SipStack(transport, port, properties); - } - - /* - * https://code.google.com/p/sipservlets/issues/detail?id=259 - * This test starts 2 sip servlets container - * one on 5070 that has the proxy app to ROUTE to the other server on 5069 - * one on port 5069 that has the proxy application to route to UAS. - * - * Tests for number of Via Header in ACK to be correct 3 instead of 2 - */ - public void test2Proxies() throws Exception { - //start the most remote server first - tomcat.startTomcat(); - deployApplication(); - //create and start the closest server - //starting tomcat - closestTomcat = new SipEmbedded("SIP-Servlet-Second-Tomcat-Server", serviceFullClassName); - closestTomcat.setLoggingFilePath( - projectHome + File.separatorChar + "sip-servlets-test-suite" + - File.separatorChar + "testsuite" + - File.separatorChar + "src" + - File.separatorChar + "test" + - File.separatorChar + "resources" + File.separatorChar); - logger.info("Log4j path is : " + closestTomcat.getLoggingFilePath()); - closestTomcat.setDarConfigurationFilePath(getDarConfigurationFileForSecondServer()); - closestTomcat.initTomcat(tomcatBasePath, null); - closestTomcat.addSipConnector("SIP-Servlet-Second-Tomcat-Server", sipIpAddress, 5069, ListeningPoint.UDP); - closestTomcat.startTomcat(); - closestTomcat.deployContext( - projectHome - + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test"); - Thread.sleep(TIMEOUT); - - String fromName = "test-unique-location-urn-uri1-push-route-app-server"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - String r = "requestUri"; - String ra = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5057"; - SipURI requestUri = senderProtocolObjects.addressFactory.createSipURI( - r, ra); - sender.setRecordRoutingProxyTesting(true); - receiver.setRecordRoutingProxyTesting(true); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, null, null, requestUri); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(receiver.isAckReceived()); - logger.info("ack received "+ receiver.getAckRequest()); - assertNotNull(receiver.getAckRequest()); - ListIterator viaHeaders = (ListIterator) receiver.getAckRequest().getHeaders(ViaHeader.NAME); - int count = 0; - while(viaHeaders.hasNext()) { - count++; - viaHeaders.next(); - } - assertEquals(3, count); - } - - /* - * https://code.google.com/p/sipservlets/issues/detail?id=237 - * This test starts 2 sip servlets container - * one on 5070 that has the proxy app to ROUTE to the other server on 5069 - * one on port 5069 that has the UAS application to send back an error - * - * Tests for number of Via Header in ACK to be correct 3 instead of 2 - */ - public void testProxyUASError() throws Exception { - //start the most remote server first - tomcat.startTomcat(); - deployApplication(); - //create and start the closest server - //starting tomcat - closestTomcat = new SipEmbedded("SIP-Servlet-Second-Tomcat-Server", serviceFullClassName); - closestTomcat.setLoggingFilePath( - projectHome + File.separatorChar + "sip-servlets-test-suite" + - File.separatorChar + "testsuite" + - File.separatorChar + "src" + - File.separatorChar + "test" + - File.separatorChar + "resources" + File.separatorChar); - logger.info("Log4j path is : " + closestTomcat.getLoggingFilePath()); - closestTomcat.setDarConfigurationFilePath(getDarConfigurationFileUASSecondServer()); - closestTomcat.initTomcat(tomcatBasePath, null); - closestTomcat.addSipConnector("SIP-Servlet-Second-Tomcat-Server", sipIpAddress, 5069, ListeningPoint.UDP); - closestTomcat.startTomcat(); - closestTomcat.deployContext( - projectHome - + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test"); - Thread.sleep(TIMEOUT); - - String fromName = "test-unique-location-urn-uri1-push-route-app-server-error-response"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - String r = "requestUri"; - String ra = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5057"; - SipURI requestUri = senderProtocolObjects.addressFactory.createSipURI( - r, ra); - sender.setRecordRoutingProxyTesting(true); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, null, null, requestUri); - Thread.sleep(TIMEOUT); - assertTrue(sender.isFinalResponseReceived()); - } - - @Override - public void tearDown() throws Exception { - senderProtocolObjects.destroy(); - recieverProtocolObjects.destroy(); - closestTomcat.stopTomcat(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2013, Telestax Inc and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + */ +package org.mobicents.servlet.sip.testsuite.proxy; + +import java.io.File; +import java.util.HashMap; +import java.util.ListIterator; +import java.util.Map; +import java.util.Properties; + +import javax.sip.ListeningPoint; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import javax.sip.header.ViaHeader; +import static junit.framework.Assert.assertTrue; +import org.apache.catalina.Realm; +import org.apache.catalina.deploy.ApplicationParameter; + +import org.apache.log4j.Logger; +import org.cafesip.sipunit.SipStack; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipEmbedded; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; +import org.mobicents.servlet.sip.catalina.SipStandardManager; +import org.mobicents.servlet.sip.startup.SipContextConfig; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +/** + * + * @author Jean Deruelle + * + */ +public class Proxy2AppServersRoutingServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(Proxy2AppServersRoutingServletTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; + + private int closestTomcatPort; + + SipEmbedded closestTomcat; + + TestSipListener sender; + int senderPort; + TestSipListener receiver; + int receiverPort; + + ProtocolObjects senderProtocolObjects; + ProtocolObjects recieverProtocolObjects; + + public Proxy2AppServersRoutingServletTest(String name) { + super(name); + autoDeployOnStartup = false; + startTomcatOnStartup = false; + System.setProperty("javax.servlet.sip.ar.spi.SipApplicationRouterProvider", "org.mobicents.servlet.sip.router.DefaultApplicationRouterProvider"); + } + + @Override + public void deployApplication() { + assertTrue(tomcat + .deployContext( + projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + "sip-test-context", "sip-test")); + } + + protected SipStandardContext deployOnSecondApplication(SipEmbedded second, String docBase, String name, Map params, + ConcurrencyControlMode concurrencyControlMode, Integer sessionTimeout, Realm realm) { + SipStandardContext context = new SipStandardContext(); + context.setDocBase(docBase); + context.setName(name); + context.setPath("/" + name); + context.addLifecycleListener(new SipContextConfig()); + context.setManager(new SipStandardManager()); + if(concurrencyControlMode != null) { + context.setConcurrencyControlMode(concurrencyControlMode); + } + if (sessionTimeout != null) { + context.setSipApplicationSessionTimeout(sessionTimeout); + } + if (realm != null) { + context.setRealm(realm); + } + if (params != null) { + for (Map.Entry param : params.entrySet()) { + ApplicationParameter applicationParameter = new ApplicationParameter(); + applicationParameter.setName(param.getKey()); + applicationParameter.setValue(param.getValue()); + context.addApplicationParameter(applicationParameter); + } + } + ctx = context; + assertTrue(second.deployContext(context)); + return context; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/proxy/proxy-dar.properties"; + } + + protected String getDarConfigurationFileForSecondServer() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/proxy/proxy-dar.properties"; + } + + protected String getDarConfigurationFileUASSecondServer() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/simple/simple-sip-servlet-dar.properties"; + } + + @Override + public void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + } + + public void setupPhones() throws Exception { + + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + recieverProtocolObjects = new ProtocolObjects( + "reciever", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, recieverProtocolObjects, false); + SipProvider registerRecieverProvider = receiver.createProvider(); + registerRecieverProvider.addSipListener(receiver); + recieverProtocolObjects.start(); + + closestTomcatPort = NetworkPortAssigner.retrieveNextPort(); + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + params.put("receiverPort", String.valueOf(receiverPort)); + params.put("downstreamContainerPort", String.valueOf(closestTomcatPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + params, null); + } + + + /* + * https://code.google.com/p/sipservlets/issues/detail?id=259 + * This test starts 2 sip servlets container + * one on 5070 that has the proxy app to ROUTE to the other server on 5069 + * one on port 5069 that has the proxy application to route to UAS. + * + * Tests for number of Via Header in ACK to be correct 3 instead of 2 + */ + public void test2Proxies() throws Exception { + //start the most remote server first + tomcat.startTomcat(); + setupPhones(); + //create and start the closest server + //starting tomcat + closestTomcat = new SipEmbedded("SIP-Servlet-Second-Tomcat-Server", serviceFullClassName); + closestTomcat.setLoggingFilePath( + projectHome + File.separatorChar + "sip-servlets-test-suite" + + File.separatorChar + "testsuite" + + File.separatorChar + "src" + + File.separatorChar + "test" + + File.separatorChar + "resources" + File.separatorChar); + logger.info("Log4j path is : " + closestTomcat.getLoggingFilePath()); + closestTomcat.setDarConfigurationFilePath(getDarConfigurationFileForSecondServer()); + closestTomcat.initTomcat(tomcatBasePath, null); + + closestTomcat.addSipConnector("SIP-Servlet-Second-Tomcat-Server", sipIpAddress, closestTomcatPort, ListeningPoint.UDP); + closestTomcat.startTomcat(); + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + params.put("receiverPort", String.valueOf(receiverPort)); + deployOnSecondApplication(closestTomcat, + projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + "secondProxy", + params, + null,null,null); + Thread.sleep(TIMEOUT); + + String fromName = "test-unique-location-urn-uri1-push-route-app-server"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + String r = "requestUri"; + String ra = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5057"; + SipURI requestUri = senderProtocolObjects.addressFactory.createSipURI( + r, ra); + sender.setRecordRoutingProxyTesting(true); + receiver.setRecordRoutingProxyTesting(true); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, null, null, requestUri); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(receiver.isAckReceived()); + logger.info("ack received " + receiver.getAckRequest()); + assertNotNull(receiver.getAckRequest()); + ListIterator viaHeaders = (ListIterator) receiver.getAckRequest().getHeaders(ViaHeader.NAME); + int count = 0; + while (viaHeaders.hasNext()) { + count++; + viaHeaders.next(); + } + assertEquals(3, count); + } + + /* + * https://code.google.com/p/sipservlets/issues/detail?id=237 + * This test starts 2 sip servlets container + * one on 5070 that has the proxy app to ROUTE to the other server on 5069 + * one on port 5069 that has the UAS application to send back an error + * + * Tests for number of Via Header in ACK to be correct 3 instead of 2 + */ + public void testProxyUASError() throws Exception { + //start the most remote server first + tomcat.startTomcat(); + setupPhones(); + //create and start the closest server + //starting tomcat + closestTomcat = new SipEmbedded("SIP-Servlet-Second-Tomcat-Server", serviceFullClassName); + closestTomcat.setLoggingFilePath( + projectHome + File.separatorChar + "sip-servlets-test-suite" + + File.separatorChar + "testsuite" + + File.separatorChar + "src" + + File.separatorChar + "test" + + File.separatorChar + "resources" + File.separatorChar); + logger.info("Log4j path is : " + closestTomcat.getLoggingFilePath()); + closestTomcat.setDarConfigurationFilePath(getDarConfigurationFileUASSecondServer()); + closestTomcat.initTomcat(tomcatBasePath, null); + closestTomcat.addSipConnector("SIP-Servlet-Second-Tomcat-Server", sipIpAddress, closestTomcatPort, ListeningPoint.UDP); + closestTomcat.startTomcat(); + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + deployOnSecondApplication(closestTomcat, + projectHome + + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp", + "secondUAS", + params, + null,null,null); + Thread.sleep(TIMEOUT); + + String fromName = "test-unique-location-urn-uri1-push-route-app-server-error-response"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + String r = "requestUri"; + String ra = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5057"; + SipURI requestUri = senderProtocolObjects.addressFactory.createSipURI( + r, ra); + sender.setRecordRoutingProxyTesting(true); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, null, null, requestUri); + Thread.sleep(TIMEOUT); + assertTrue(sender.isFinalResponseReceived()); + } + + @Override + public void tearDown() throws Exception { + senderProtocolObjects.destroy(); + recieverProtocolObjects.destroy(); + closestTomcat.stopTomcat(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyAckTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyAckTest.java index 8701c4c3e2..568ad3886b 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyAckTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyAckTest.java @@ -16,12 +16,10 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ - package org.mobicents.servlet.sip.testsuite.proxy; import java.util.ArrayList; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; @@ -30,140 +28,133 @@ import javax.sip.address.SipURI; import javax.sip.message.Response; -import org.apache.catalina.deploy.ApplicationParameter; import org.apache.log4j.Logger; -import org.mobicents.javax.servlet.sip.ResponseType; +import org.mobicents.servlet.sip.NetworkPortAssigner; import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; import org.mobicents.servlet.sip.testsuite.ProtocolObjects; import org.mobicents.servlet.sip.testsuite.TestSipListener; -public class ProxyAckTest extends SipServletTestCase { - private static final String SESSION_EXPIRED = "sessionExpired"; - private static final String SESSION_READY_TO_INVALIDATE = "sessionReadyToInvalidate"; - private static final String SIP_SESSION_READY_TO_INVALIDATE = "sipSessionReadyToInvalidate"; - private static transient Logger logger = Logger.getLogger(ProxyAckTest.class); - private static final boolean AUTODIALOG = true; - TestSipListener sender; - TestSipListener neutral; - TestSipListener receiver; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - ProtocolObjects neutralProto; - - - private static final int TIMEOUT = 20000; - - public ProxyAckTest(String name) { - super(name); - autoDeployOnStartup = false; - } - - @Override - public void setUp() throws Exception { - super.setUp(); - senderProtocolObjects = new ProtocolObjects("proxy-sender", - "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null); - receiverProtocolObjects = new ProtocolObjects("proxy-receiver", - "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null); +public class ProxyAckTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ProxyAckTest.class); + private static final boolean AUTODIALOG = true; + TestSipListener sender; + TestSipListener neutral; + TestSipListener receiver; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + ProtocolObjects neutralProto; + + private static final int TIMEOUT = 20000; + + public ProxyAckTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + } + + public void setupPhones() throws Exception { + senderProtocolObjects = new ProtocolObjects("proxy-sender", + "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects("proxy-receiver", + "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null); // SIP Stack by default doesn't pass the ACK to the Listener for non 2XX responses to INVITE. // So, passing additional properties for SIP stack. - Map additionalProperties = new HashMap(); - additionalProperties.put("gov.nist.javax.sip.PASS_INVITE_NON_2XX_ACK_TO_LISTENER", "true"); - neutralProto = new ProtocolObjects("neutral", - "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null,additionalProperties); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5057, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - //use cutme port 5056 to receive second invite in second branch - neutral = new TestSipListener(5056, 5070, neutralProto, false); - neutral.setRecordRoutingProxyTesting(true); - SipProvider neutralProvider = neutral.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - neutralProvider.addSipListener(neutral); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - neutralProto.start(); - } - - - /** - * test for https://github.com/RestComm/sip-servlets/issues/78 - */ - public void testAckSentToForkedResponses() throws Exception { - deployApplication(); - String fromName = "sequential"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "proxy-receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - List respList=new ArrayList(); - respList.add(180); - receiver.setProvisionalResponsesToSend(respList); - neutral.setProvisionalResponsesToSend(respList); - - receiver.setFinalResponseToSend(Response.OK); - neutral.setFinalResponseToSend(Response.BUSY_HERE); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isAckReceived()); - assertTrue(neutral.isAckReceived()); - } - - - @Override - public void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - neutralProto.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - @Override - public void deployApplication() { - assertTrue(tomcat - .deployContext( - projectHome - + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - public SipStandardContext deployApplication(String name, String value) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(name); - applicationParameter.setValue(value); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - return context; - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/proxy/simple-sip-servlet-dar.properties"; - } + Map additionalProperties = new HashMap(); + additionalProperties.put("gov.nist.javax.sip.PASS_INVITE_NON_2XX_ACK_TO_LISTENER", "true"); + neutralProto = new ProtocolObjects("neutral", + "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null, additionalProperties); + + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + //use cutme port 5056 to receive second invite in second branch + int neutralPort = NetworkPortAssigner.retrieveNextPort(); + neutral = new TestSipListener(neutralPort, containerPort, neutralProto, false); + neutral.setRecordRoutingProxyTesting(true); + SipProvider neutralProvider = neutral.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + neutralProvider.addSipListener(neutral); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + neutralProto.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + params.put("receiverPort", String.valueOf(receiverPort)); + params.put("cutme", String.valueOf(neutralPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + params, null); + } + + /** + * test for https://github.com/RestComm/sip-servlets/issues/78 + */ + public void testAckSentToForkedResponses() throws Exception { + setupPhones(); + String fromName = "sequential"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "proxy-receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + List respList = new ArrayList(); + respList.add(180); + receiver.setProvisionalResponsesToSend(respList); + neutral.setProvisionalResponsesToSend(respList); + + receiver.setFinalResponseToSend(Response.OK); + neutral.setFinalResponseToSend(Response.BUSY_HERE); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isAckReceived()); + assertTrue(neutral.isAckReceived()); + } + + @Override + public void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + neutralProto.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + + @Override + public void deployApplication() { + assertTrue(tomcat + .deployContext( + projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + "sip-test-context", "sip-test")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/proxy/simple-sip-servlet-dar.properties"; + } } diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyBestResponseTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyBestResponseTest.java index d4960faa18..1fef09520f 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyBestResponseTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyBestResponseTest.java @@ -1,182 +1,180 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.proxy; - -import java.util.ArrayList; -import java.util.Iterator; - -import javax.sip.ListeningPoint; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; -import javax.sip.message.Response; - -import org.apache.catalina.deploy.ApplicationParameter; -import org.apache.log4j.Logger; -import org.mobicents.javax.servlet.sip.ResponseType; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class ProxyBestResponseTest extends SipServletTestCase { - private static final String SESSION_EXPIRED = "sessionExpired"; - private static final String SESSION_READY_TO_INVALIDATE = "sessionReadyToInvalidate"; - private static final String SIP_SESSION_READY_TO_INVALIDATE = "sipSessionReadyToInvalidate"; - private static transient Logger logger = Logger.getLogger(ProxyBestResponseTest.class); - private static final boolean AUTODIALOG = true; - TestSipListener sender; - TestSipListener neutral; - TestSipListener receiver; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - ProtocolObjects neutralProto; - - - private static final int TIMEOUT = 20000; - - public ProxyBestResponseTest(String name) { - super(name); - autoDeployOnStartup = false; - } - - @Override - public void setUp() throws Exception { - super.setUp(); - senderProtocolObjects = new ProtocolObjects("proxy-sender", - "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null); - receiverProtocolObjects = new ProtocolObjects("proxy-receiver", - "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null); - neutralProto = new ProtocolObjects("neutral", - "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5057, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - //use cutme port 5056 to receive second invite in second branch - neutral = new TestSipListener(5056, 5070, neutralProto, false); - neutral.setRecordRoutingProxyTesting(true); - SipProvider neutralProvider = neutral.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - neutralProvider.addSipListener(neutral); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - neutralProto.start(); - } - - - /** - * non-regression test for https://telestax.desk.com/agent/case/1805 - */ - public void testProxyBestRes() throws Exception { - deployApplication(); - String fromName = "sequential"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "proxy-receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - receiver.setFinalResponseToSend(Response.SERVER_TIMEOUT); - neutral.setFinalResponseToSend(Response.BUSY_HERE); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertEquals(Response.BUSY_HERE, sender.getFinalResponseStatus()); - } - - /** - * non-regression test for https://telestax.desk.com/agent/case/1805 - */ - public void testProxyBestRes6XXwins() throws Exception { - deployApplication(); - String fromName = "sequential"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "proxy-receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - receiver.setFinalResponseToSend(Response.DECLINE); - neutral.setFinalResponseToSend(Response.BUSY_HERE); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertEquals(Response.DECLINE, sender.getFinalResponseStatus()); - } - - - - @Override - public void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - neutralProto.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - @Override - public void deployApplication() { - assertTrue(tomcat - .deployContext( - projectHome - + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - public SipStandardContext deployApplication(String name, String value) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(name); - applicationParameter.setValue(value); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - return context; - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/proxy/simple-sip-servlet-dar.properties"; - } -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite.proxy; + +import java.util.HashMap; +import java.util.Map; + +import javax.sip.ListeningPoint; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import javax.sip.message.Response; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class ProxyBestResponseTest extends SipServletTestCase { + private static final String SESSION_EXPIRED = "sessionExpired"; + private static final String SESSION_READY_TO_INVALIDATE = "sessionReadyToInvalidate"; + private static final String SIP_SESSION_READY_TO_INVALIDATE = "sipSessionReadyToInvalidate"; + private static transient Logger logger = Logger.getLogger(ProxyBestResponseTest.class); + private static final boolean AUTODIALOG = true; + TestSipListener sender; + TestSipListener neutral; + TestSipListener receiver; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + ProtocolObjects neutralProto; + + + private static final int TIMEOUT = 20000; + + public ProxyBestResponseTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + } + + public void setupPhones() throws Exception { + senderProtocolObjects = new ProtocolObjects("proxy-sender", + "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects("proxy-receiver", + "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null); + neutralProto = new ProtocolObjects("neutral", + "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null); + + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + //use cutme port 5056 to receive second invite in second branch + int neutralPort = NetworkPortAssigner.retrieveNextPort(); + neutral = new TestSipListener(neutralPort, containerPort, neutralProto, false); + neutral.setRecordRoutingProxyTesting(true); + SipProvider neutralProvider = neutral.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + neutralProvider.addSipListener(neutral); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + neutralProto.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(senderPort)); + params.put( "receiverPort", String.valueOf(receiverPort)); + params.put( "cutmePort", String.valueOf(neutralPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + params, null); + } + + + /** + * non-regression test for https://telestax.desk.com/agent/case/1805 + */ + public void testProxyBestRes() throws Exception { + setupPhones(); + String fromName = "sequential"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "proxy-receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + receiver.setFinalResponseToSend(Response.SERVER_TIMEOUT); + neutral.setFinalResponseToSend(Response.BUSY_HERE); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertEquals(Response.BUSY_HERE, sender.getFinalResponseStatus()); + } + + /** + * non-regression test for https://telestax.desk.com/agent/case/1805 + */ + public void testProxyBestRes6XXwins() throws Exception { + setupPhones(); + String fromName = "sequential"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "proxy-receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + receiver.setFinalResponseToSend(Response.DECLINE); + neutral.setFinalResponseToSend(Response.BUSY_HERE); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertEquals(Response.DECLINE, sender.getFinalResponseStatus()); + } + + + + @Override + public void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + neutralProto.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + + @Override + public void deployApplication() { + assertTrue(tomcat + .deployContext( + projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + "sip-test-context", "sip-test")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/proxy/simple-sip-servlet-dar.properties"; + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyBranchTimeoutTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyBranchTimeoutTest.java index 1bf9ba3ac9..20bb4dd12b 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyBranchTimeoutTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyBranchTimeoutTest.java @@ -22,6 +22,8 @@ package org.mobicents.servlet.sip.testsuite.proxy; +import java.util.HashMap; +import java.util.Map; import java.util.Properties; import javax.sip.message.Response; @@ -29,6 +31,7 @@ import org.cafesip.sipunit.SipCall; import org.cafesip.sipunit.SipPhone; import org.cafesip.sipunit.SipStack; +import org.mobicents.servlet.sip.NetworkPortAssigner; import org.mobicents.servlet.sip.SipServletTestCase; public class ProxyBranchTimeoutTest extends SipServletTestCase { @@ -50,11 +53,13 @@ public class ProxyBranchTimeoutTest extends SipServletTestCase { public ProxyBranchTimeoutTest(String name) { super(name); + autoDeployOnStartup = false; } @Override public void setUp() throws Exception { if (firstTime) { + containerPort = NetworkPortAssigner.retrieveNextPort(); super.setUp(); } firstTime = true; @@ -98,16 +103,16 @@ protected String getDarConfigurationFile() { public SipStack makeStack(String transport, int port) throws Exception { Properties properties = new Properties(); - String peerHostPort1 = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070"; + String peerHostPort1 = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + containerPort; properties.setProperty("javax.sip.OUTBOUND_PROXY", peerHostPort1 + "/" + "udp"); properties.setProperty("javax.sip.STACK_NAME", "UAC_" + transport + "_" + port); properties.setProperty("sipunit.BINDADDR", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", - "logs/simplesipservlettest_debug_port" + port + ".txt"); + "target/logs/simplesipservlettest_debug_port" + port + ".txt"); properties.setProperty("gov.nist.javax.sip.SERVER_LOG", - "logs/simplesipservlettest_log_port" + port + ".txt"); + "target/logs/simplesipservlettest_log_port" + port + ".txt"); return new SipStack(transport, port, properties); @@ -117,20 +122,26 @@ public void setupPhones() throws Exception { sipStackReceivers = new SipStack[receiversCount]; sipPhoneReceivers = new SipPhone[receiversCount]; - sipStackSender = makeStack(SipStack.PROTOCOL_UDP, 5058); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sipStackSender = makeStack(SipStack.PROTOCOL_UDP, senderPort); // ListeningPoint lp = sipStackSender.getSipProvider() // .getListeningPoint("udp"); // String stackIPAddress = lp.getIPAddress(); sipPhoneSender = sipStackSender.createSipPhone("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", - SipStack.PROTOCOL_UDP, 5070, "sip:sender@nist.gov"); - - for (int q = 0; q < receiversCount; q++) { - int port = 5058 - 1 - q; - sipStackReceivers[q] = makeStack(SipStack.PROTOCOL_UDP, port); - sipPhoneReceivers[q] = sipStackReceivers[q].createSipPhone( - "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", SipStack.PROTOCOL_UDP, 5070, - "sip:receiver@nist.gov"); - } + SipStack.PROTOCOL_UDP, containerPort, "sip:sender@nist.gov"); + + int port = NetworkPortAssigner.retrieveNextPort(); + sipStackReceivers[0] = makeStack(SipStack.PROTOCOL_UDP, port); + sipPhoneReceivers[0] = sipStackReceivers[0].createSipPhone( + "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", SipStack.PROTOCOL_UDP, containerPort, + "sip:receiver@nist.gov"); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(senderPort)); + params.put( "receiverPort", String.valueOf(port)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", params, null); } public void init() throws Exception { diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyNonRecordRouteTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyNonRecordRouteTest.java index 51f991ef7e..eb3182c721 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyNonRecordRouteTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyNonRecordRouteTest.java @@ -1,154 +1,169 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.proxy; - -import java.util.List; - -import javax.sip.ListeningPoint; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class ProxyNonRecordRouteTest extends SipServletTestCase { - private static transient Logger logger = Logger.getLogger(ProxyNonRecordRouteTest.class); - private static final boolean AUTODIALOG = true; - TestSipListener sender; - TestSipListener receiver; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - - - private static final int TIMEOUT = 20000; - - public ProxyNonRecordRouteTest(String name) { - super(name); - } - - @Override - public void setUp() throws Exception { - super.setUp(); - senderProtocolObjects = new ProtocolObjects("proxy-sender", - "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null); - receiverProtocolObjects = new ProtocolObjects("proxy-receiver", - "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5057, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - } - // Tests Issue 1693 http://code.google.com/p/mobicents/issues/detail?id=1693 - public void testProxyCallerSendBye() throws Exception { - String fromName = "unique-location-nonRecordRouting"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "proxy-receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(receiver.isAckReceived()); - receiver.setAckReceived(false); - sender.setAckSent(false); - sender.sendBye(); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - assertTrue(sender.getOkToByeReceived()); - List allMessagesContent = sender.getAllMessagesContent(); - assertEquals(2,allMessagesContent.size()); - assertTrue("sipSessionReadyToInvalidate", allMessagesContent.contains("sipSessionReadyToInvalidate")); - assertTrue("sessionReadyToInvalidate", allMessagesContent.contains("sessionReadyToInvalidate")); - } - - /* - * Testing setting the SDP Content on Proxy Branches - */ - public void testProxySetSDPContentOnBranches() throws Exception { - String fromName = "unique-location-nonRecordRouting-branches"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "proxy-receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(receiver.isAckReceived()); - receiver.setAckReceived(false); - sender.setAckSent(false); - sender.sendBye(); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - assertTrue(sender.getOkToByeReceived()); - List allMessagesContent = sender.getAllMessagesContent(); - assertEquals(2,allMessagesContent.size()); - assertTrue("sipSessionReadyToInvalidate", allMessagesContent.contains("sipSessionReadyToInvalidate")); - assertTrue("sessionReadyToInvalidate", allMessagesContent.contains("sessionReadyToInvalidate")); - } - - @Override - public void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - @Override - public void deployApplication() { - assertTrue(tomcat - .deployContext( - projectHome - + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/proxy/simple-sip-servlet-dar.properties"; - } -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite.proxy; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.sip.ListeningPoint; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class ProxyNonRecordRouteTest extends SipServletTestCase { + private static transient Logger logger = Logger.getLogger(ProxyNonRecordRouteTest.class); + private static final boolean AUTODIALOG = true; + TestSipListener sender; + TestSipListener receiver; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + + + private static final int TIMEOUT = 20000; + + public ProxyNonRecordRouteTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + senderProtocolObjects = new ProtocolObjects("proxy-sender", + "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects("proxy-receiver", + "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null); + + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(senderPort)); + params.put( "receiverPort", String.valueOf(receiverPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", params, null); + } + // Tests Issue 1693 http://code.google.com/p/mobicents/issues/detail?id=1693 + public void testProxyCallerSendBye() throws Exception { + String fromName = "unique-location-nonRecordRouting"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "proxy-receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(receiver.isAckReceived()); + receiver.setAckReceived(false); + sender.setAckSent(false); + sender.sendBye(); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + assertTrue(sender.getOkToByeReceived()); + List allMessagesContent = sender.getAllMessagesContent(); + assertEquals(2,allMessagesContent.size()); + assertTrue("sipSessionReadyToInvalidate", allMessagesContent.contains("sipSessionReadyToInvalidate")); + assertTrue("sessionReadyToInvalidate", allMessagesContent.contains("sessionReadyToInvalidate")); + } + + /* + * Testing setting the SDP Content on Proxy Branches + */ + public void testProxySetSDPContentOnBranches() throws Exception { + String fromName = "unique-location-nonRecordRouting-branches"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "proxy-receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(receiver.isAckReceived()); + receiver.setAckReceived(false); + sender.setAckSent(false); + sender.sendBye(); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + assertTrue(sender.getOkToByeReceived()); + List allMessagesContent = sender.getAllMessagesContent(); + assertEquals(2,allMessagesContent.size()); + assertTrue("sipSessionReadyToInvalidate", allMessagesContent.contains("sipSessionReadyToInvalidate")); + assertTrue("sessionReadyToInvalidate", allMessagesContent.contains("sessionReadyToInvalidate")); + } + + @Override + public void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + + @Override + public void deployApplication() { + assertTrue(tomcat + .deployContext( + projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + "sip-test-context", "sip-test")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/proxy/simple-sip-servlet-dar.properties"; + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyOverlappingTransactionsTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyOverlappingTransactionsTest.java index 7c5b49373e..adbf73c4fe 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyOverlappingTransactionsTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyOverlappingTransactionsTest.java @@ -24,6 +24,7 @@ import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import javax.sip.ListeningPoint; import javax.sip.SipProvider; @@ -32,6 +33,7 @@ import javax.sip.message.Request; import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; import org.mobicents.servlet.sip.SipServletTestCase; import org.mobicents.servlet.sip.testsuite.ProtocolObjects; import org.mobicents.servlet.sip.testsuite.TestSipListener; @@ -49,10 +51,12 @@ public class ProxyOverlappingTransactionsTest extends SipServletTestCase { public ProxyOverlappingTransactionsTest(String name) { super(name); + autoDeployOnStartup = false; } @Override public void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); super.setUp(); } @@ -142,11 +146,14 @@ public void setupPhones(String transport) throws Exception { "gov.nist", transport, AUTODIALOG, null, null, null); receiverProtocolObjects = new ProtocolObjects("proxy-receiver", "gov.nist", transport, AUTODIALOG, null, null, null); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); + + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); sender.setRecordRoutingProxyTesting(true); SipProvider senderProvider = sender.createProvider(); - receiver = new TestSipListener(5057, 5070, receiverProtocolObjects, false); + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); receiver.setRecordRoutingProxyTesting(true); SipProvider receiverProvider = receiver.createProvider(); @@ -155,6 +162,13 @@ public void setupPhones(String transport) throws Exception { senderProtocolObjects.start(); receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(senderPort)); + params.put( "receiverPort", String.valueOf(receiverPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", params, null); } @Override diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyPrackTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyPrackTest.java index 4868109b6a..921916d935 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyPrackTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyPrackTest.java @@ -19,11 +19,14 @@ package org.mobicents.servlet.sip.testsuite.proxy; +import java.util.HashMap; +import java.util.Map; import javax.sip.ListeningPoint; import javax.sip.SipProvider; import javax.sip.address.SipURI; import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; import org.mobicents.servlet.sip.SipServletTestCase; import org.mobicents.servlet.sip.testsuite.ProtocolObjects; import org.mobicents.servlet.sip.testsuite.TestSipListener; @@ -53,6 +56,7 @@ public ProxyPrackTest(String name) { @Override public void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); super.setUp(); senderProtocolObjects = new ProtocolObjects("proxy-sender", "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null); @@ -60,15 +64,19 @@ public void setUp() throws Exception { "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null); neutralProto = new ProtocolObjects("neutral", "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); + + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); sender.setRecordRoutingProxyTesting(true); SipProvider senderProvider = sender.createProvider(); - receiver = new TestSipListener(5057, 5070, receiverProtocolObjects, false); + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); receiver.setRecordRoutingProxyTesting(true); SipProvider receiverProvider = receiver.createProvider(); - neutral = new TestSipListener(5058, 5070, neutralProto, false); + int neutralPort = NetworkPortAssigner.retrieveNextPort(); + neutral = new TestSipListener(neutralPort, containerPort, neutralProto, false); neutral.setRecordRoutingProxyTesting(true); SipProvider neutralProvider = neutral.createProvider(); @@ -79,10 +87,17 @@ public void setUp() throws Exception { senderProtocolObjects.start(); receiverProtocolObjects.start(); neutralProto.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(senderPort)); + params.put( "receiverPort", String.valueOf(receiverPort)); + params.put( "neutralPort", String.valueOf(neutralPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", params, null); } public void testPrackProxying() throws Exception { - deployApplication(); String fromName = "prack-useHostName"; String fromSipAddress = "sip-servlets.com"; SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( @@ -110,7 +125,6 @@ public void testPrackProxying() throws Exception { * Non Regression test for https://code.google.com/p/sipservlets/issues/detail?id=253 */ public void testCancelPrackProxying() throws Exception { - deployApplication(); String fromName = "prack-useHostName"; String fromSipAddress = "sip-servlets.com"; SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyREGISTERWithSTARContactTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyREGISTERWithSTARContactTest.java index e1ef11146b..b131937f46 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyREGISTERWithSTARContactTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyREGISTERWithSTARContactTest.java @@ -1,121 +1,141 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ -package org.mobicents.servlet.sip.testsuite.proxy; - -import java.util.List; - -import javax.sip.ListeningPoint; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class ProxyREGISTERWithSTARContactTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(ProxyREGISTERWithSTARContactTest.class); - private static final boolean AUTODIALOG = true; - TestSipListener sender; - TestSipListener receiver; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - - private static final int TIMEOUT = 20000; - - public ProxyREGISTERWithSTARContactTest(String name) { - super(name); - } - - @Override - public void setUp() throws Exception { - super.setUp(); - senderProtocolObjects = new ProtocolObjects("proxy-sender", - "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null); - receiverProtocolObjects = new ProtocolObjects("proxy-receiver", - "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5057, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - } - - // Tests Issue 1779 https://telestax.desk.com/web/agent/case/1779 - - public void testStarContactRegister() throws Exception { - String fromName = "unique-location-starContactRegister"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "proxy-receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - //we want to test contact header set to * - //we set expires to 0 just for compliance to actual scenario - String[] headerNames = {"Contact", "Expires"}; - String[] headerValues = {"*", "0"}; - - //it's key to enable setHeader!!, so Contact is properly initialize - sender.sendSipRequest("REGISTER", fromAddress, toAddress, null, null, false, headerNames, headerValues, true); - Thread.sleep(TIMEOUT); - assertEquals(200, sender.getFinalResponseStatus()); - - } - - @Override - public void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - @Override - public void deployApplication() { - assertTrue(tomcat - .deployContext( - projectHome - + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/proxy/simple-sip-servlet-dar.properties"; - } -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.proxy; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.sip.ListeningPoint; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class ProxyREGISTERWithSTARContactTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ProxyREGISTERWithSTARContactTest.class); + private static final boolean AUTODIALOG = true; + TestSipListener sender; + TestSipListener receiver; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + + private static final int TIMEOUT = 20000; + + public ProxyREGISTERWithSTARContactTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + } + public void setupPhones() throws Exception { + senderProtocolObjects = new ProtocolObjects("proxy-sender", + "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects("proxy-receiver", + "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null); + + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(senderPort)); + params.put( "receiverPort", String.valueOf(receiverPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + params, null); + } + + // Tests Issue 1779 https://telestax.desk.com/web/agent/case/1779 + + public void testStarContactRegister() throws Exception { + setupPhones(); + + String fromName = "unique-location-starContactRegister"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "proxy-receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + //we want to test contact header set to * + //we set expires to 0 just for compliance to actual scenario + String[] headerNames = {"Contact", "Expires"}; + String[] headerValues = {"*", "0"}; + + //it's key to enable setHeader!!, so Contact is properly initialize + sender.sendSipRequest("REGISTER", fromAddress, toAddress, null, null, false, headerNames, headerValues, true); + Thread.sleep(TIMEOUT); + assertEquals(200, sender.getFinalResponseStatus()); + + } + + @Override + public void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + + @Override + public void deployApplication() { + assertTrue(tomcat + .deployContext( + projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + "sip-test-context", "sip-test")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/proxy/simple-sip-servlet-dar.properties"; + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyRecordRouteReInviteTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyRecordRouteReInviteTest.java index 5891e34dcb..401c11053c 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyRecordRouteReInviteTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyRecordRouteReInviteTest.java @@ -1,460 +1,476 @@ -/* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2013, Telestax Inc and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - */ - -package org.mobicents.servlet.sip.testsuite.proxy; - -import gov.nist.javax.sip.header.HeaderExt; -import gov.nist.javax.sip.message.MessageExt; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -import javax.sip.ListeningPoint; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; -import javax.sip.header.Header; -import javax.sip.message.Request; -import javax.sip.message.Response; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class ProxyRecordRouteReInviteTest extends SipServletTestCase { - private static transient Logger logger = Logger.getLogger(ProxyRecordRouteReInviteTest.class); - private static final boolean AUTODIALOG = true; - TestSipListener sender; - TestSipListener receiver; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - - - private static final int TIMEOUT = 20000; - - public ProxyRecordRouteReInviteTest(String name) { - super(name); - } - - @Override - public void setUp() throws Exception { - super.setUp(); - } - - public void testProxyCallerSendBye() throws Exception { - setupPhones(ListeningPoint.UDP); - String fromName = "unique-location"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "proxy-receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - // part of non regression test for Issue http://code.google.com/p/mobicents/issues/detail?id=2359 - // allow to check if ACK retrans keep the same different branch id - sender.setTimeToWaitBeforeAck(2000); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(receiver.isAckReceived()); - // non regression test for Issue http://code.google.com/p/mobicents/issues/detail?id=2359 - String inviteBranch = ((MessageExt)receiver.getInviteRequest()).getTopmostViaHeader().getBranch(); - String ackBranch = ((MessageExt)receiver.getAckRequest()).getTopmostViaHeader().getBranch(); - assertFalse(inviteBranch.equals(ackBranch)); - receiver.setAckReceived(false); - sender.setAckSent(false); - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(receiver.isAckReceived()); - receiver.setAckReceived(false); - receiver.setAckSent(false); - sender.setAckSent(false); - sender.setAckReceived(false); - receiver.sendInDialogSipRequest("INVITE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isAckSent()); - assertTrue(sender.isAckReceived()); - sender.sendBye(); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - assertTrue(sender.getOkToByeReceived()); - logger.info("RequestsProcessedByMethod " + tomcat.getSipService().getSipApplicationDispatcher().getRequestsProcessedByMethod()); - logger.info("RequestsSentByMethod " + tomcat.getSipService().getSipApplicationDispatcher().getRequestsSentByMethod()); - logger.info("ResponsesProcessedByStatusCode " + tomcat.getSipService().getSipApplicationDispatcher().getResponsesProcessedByStatusCode()); - logger.info("ResponsesSentByStatusCode " + tomcat.getSipService().getSipApplicationDispatcher().getResponsesSentByStatusCode()); - assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getRequestsProcessedByMethod(Request.INVITE)>1); - assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getRequestsProcessedByMethod(Request.ACK)>1); - assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getRequestsProcessedByMethod(Request.BYE)>0); - assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getResponsesSentByStatusCode("2XX")>1); - assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getRequestsSentByMethod(Request.INVITE)>1); - assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getRequestsSentByMethod(Request.ACK)>1); - assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getRequestsSentByMethod(Request.BYE)>0); - assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getResponsesProcessedByStatusCode("2XX")>1); - } - - /* - * https://code.google.com/p/sipservlets/issues/detail?id=21 - */ - public void testProxyCallerFinalResponseOnSubsequentRequest() throws Exception { - setupPhones(ListeningPoint.UDP); - String fromName = "unique-location-final-response-subsequent"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "proxy-receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(receiver.isAckReceived()); - // non regression test for Issue http://code.google.com/p/mobicents/issues/detail?id=2359 - String inviteBranch = ((MessageExt)receiver.getInviteRequest()).getTopmostViaHeader().getBranch(); - String ackBranch = ((MessageExt)receiver.getAckRequest()).getTopmostViaHeader().getBranch(); - assertFalse(inviteBranch.equals(ackBranch)); - receiver.setAckReceived(false); - sender.setAckSent(false); - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertEquals(491, sender.getFinalResponseStatus()); - assertFalse(receiver.isAckReceived()); - receiver.setAckReceived(false); - receiver.setAckSent(false); - sender.setAckSent(false); - sender.setAckReceived(false); - sender.sendBye(); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - assertTrue(sender.getOkToByeReceived()); - } - - // Test for http://code.google.com/p/sipservlets/issues/detail?id=44 - public void testProxyReinviteAckSeenByApp() throws Exception { - setupPhones(ListeningPoint.UDP); - String fromName = "unique-location-ack-seen-by-app"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "proxy-receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(receiver.isAckReceived()); - // non regression test for Issue http://code.google.com/p/mobicents/issues/detail?id=2359 - String inviteBranch = ((MessageExt)receiver.getInviteRequest()).getTopmostViaHeader().getBranch(); - String ackBranch = ((MessageExt)receiver.getAckRequest()).getTopmostViaHeader().getBranch(); - assertFalse(inviteBranch.equals(ackBranch)); - receiver.setAckReceived(false); - sender.setAckSent(false); - receiver.setFinalResponseToSend(491); - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - sender.sendBye(); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - assertTrue(sender.getOkToByeReceived()); - - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertFalse(sender.getAllMessagesContent().contains("ack-seen-by-app")); - } - - public void testProxyCalleeSendBye() throws Exception { - setupPhones(ListeningPoint.UDP); - String fromName = "unique-location"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "proxy-receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(receiver.isAckReceived()); - receiver.setAckReceived(false); - sender.setAckSent(false); - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(receiver.isAckReceived()); - receiver.setAckReceived(false); - sender.setAckSent(false); - receiver.sendInDialogSipRequest("INVITE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isAckSent()); - assertTrue(sender.isAckReceived()); - receiver.sendBye(); - Thread.sleep(TIMEOUT); - assertTrue(sender.getByeReceived()); - assertTrue(receiver.getOkToByeReceived()); - } - - /* - * Non regression test for Issue 1792 - */ - public void testProxyCancelTCP() throws Exception { - tomcat.addSipConnector(serverName, sipIpAddress, 5070, ListeningPoint.TCP); - setupPhones(ListeningPoint.TCP); - String fromName = "unique-location"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "proxy-receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - List provisionalResponsesToSend = new ArrayList(); - provisionalResponsesToSend.add(Response.TRYING); - provisionalResponsesToSend.add(Response.RINGING); - receiver.setProvisionalResponsesToSend(provisionalResponsesToSend); - - receiver.setWaitForCancel(true); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(1000); - sender.sendCancel(); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isCancelReceived()); - assertTrue(sender.isCancelOkReceived()); - assertTrue(sender.isRequestTerminatedReceived()); - } - - // Issue http://code.google.com/p/mobicents/issues/detail?id=1847 - public void testProxyExtraRouteNoRewrite() throws Exception { - setupPhones(ListeningPoint.UDP); - String fromName = "unique-location"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "proxy-receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Header rh = senderProtocolObjects.headerFactory.createHeader("Route", "sip:extra-route@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5057;lr"); - LinkedList
hh = new LinkedList
(); - hh.add(rh); - Thread.sleep(TIMEOUT/4); - sender.sendInDialogSipRequest("INVITE", null, null, null, hh, "udp"); - Thread.sleep(TIMEOUT/2); - - assertTrue(receiver.getInviteRequest().getRequestURI().toString().contains("extra-route")); - } - - // Check branchId of the ACK in case the reINVITE has an INFO in between to make sure that - // the ACK to 200 OK reINVITE is different than the INFO branchId - public void testProxyReinviteINFOCheckACKBranchId() throws Exception { - setupPhones(ListeningPoint.UDP); - String fromName = "unique-location"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "proxy-receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - // part of non regression test for Issue http://code.google.com/p/mobicents/issues/detail?id=2359 - // allow to check if ACK retrans keep the same different branch id - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(receiver.isAckReceived()); - receiver.setAckReceived(false); - sender.setAckSent(false); - sender.sendInDialogSipRequest("INFO", null, null, null, null, null); - Thread.sleep(500); - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(receiver.isAckReceived()); - receiver.setAckReceived(false); - receiver.setAckSent(false); - sender.setAckSent(false); - sender.setAckReceived(false); - //non regression test for Issue http://code.google.com/p/mobicents/issues/detail?id=2359 - String inviteBranch = ((MessageExt)receiver.getInviteRequest()).getTopmostViaHeader().getBranch(); - String infoBranch = ((MessageExt)receiver.getInfoRequest()).getTopmostViaHeader().getBranch(); - String ackBranch = ((MessageExt)receiver.getAckRequest()).getTopmostViaHeader().getBranch(); - assertFalse(inviteBranch.equals(ackBranch)); - assertFalse(infoBranch.equals(ackBranch)); - sender.sendBye(); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - assertTrue(sender.getOkToByeReceived()); - } - - // https://code.google.com/p/sipservlets/issues/detail?id=238 - public void testProxyINFOLeak() throws Exception { - setupPhones(ListeningPoint.UDP); - String fromName = "unique-location"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "proxy-receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - // part of non regression test for Issue http://code.google.com/p/mobicents/issues/detail?id=2359 - // allow to check if ACK retrans keep the same different branch id - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(receiver.isAckReceived()); - receiver.setAckReceived(false); - sender.setAckSent(false); - sender.sendInDialogSipRequest("INFO", null, null, null, null, null); - Thread.sleep(500); - sender.sendInDialogSipRequest("INFO", null, null, null, null, null); - Thread.sleep(500); - sender.sendInDialogSipRequest("INFO", null, null, null, null, null); - Thread.sleep(500); - sender.sendInDialogSipRequest("INFO", null, null, null, null, null); - Thread.sleep(500); - sender.sendInDialogSipRequest("INFO", null, null, null, null, null); - Thread.sleep(TIMEOUT*2); - sender.sendBye(); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - assertTrue(sender.getOkToByeReceived()); - assertNotNull(sender.getFinalResponse().getHeader("X-Proxy-Transactions")); - assertEquals("1",((HeaderExt)sender.getFinalResponse().getHeader("X-Proxy-Transactions")).getValue()); - } - - /* - * Non regression test for https://code.google.com/p/sipservlets/issues/detail?id=202 - */ - public void testProxyModifySDP() throws Exception { - setupPhones(ListeningPoint.UDP); - String fromName = "modify-SDP"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "proxy-receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - // part of non regression test for Issue http://code.google.com/p/mobicents/issues/detail?id=2359 - // allow to check if ACK retrans keep the same different branch id - sender.setTimeToWaitBeforeAck(2000); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(receiver.isAckReceived()); - assertEquals("SDP modified successfully", new String(sender.getFinalResponse().getRawContent(), "UTF-8")); - // non regression test for Issue http://code.google.com/p/mobicents/issues/detail?id=2359 - String inviteBranch = ((MessageExt)receiver.getInviteRequest()).getTopmostViaHeader().getBranch(); - String ackBranch = ((MessageExt)receiver.getAckRequest()).getTopmostViaHeader().getBranch(); - assertFalse(inviteBranch.equals(ackBranch)); - receiver.setAckReceived(false); - sender.setAckSent(false); - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(receiver.isAckReceived()); - receiver.setAckReceived(false); - receiver.setAckSent(false); - sender.setAckSent(false); - sender.setAckReceived(false); - assertEquals("SDP modified successfully", new String(sender.getFinalResponse().getRawContent(), "UTF-8")); - receiver.sendInDialogSipRequest("INVITE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isAckSent()); - assertTrue(sender.isAckReceived()); - assertEquals("SDP modified successfully", new String(receiver.getFinalResponse().getRawContent(), "UTF-8")); - sender.sendBye(); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - assertTrue(sender.getOkToByeReceived()); - } - - public void setupPhones(String transport) throws Exception { - senderProtocolObjects = new ProtocolObjects("proxy-sender", - "gov.nist", transport, AUTODIALOG, null, null, null); - receiverProtocolObjects = new ProtocolObjects("proxy-receiver", - "gov.nist", transport, AUTODIALOG, null, null, null); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5057, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - } - - @Override - public void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - @Override - public void deployApplication() { - assertTrue(tomcat - .deployContext( - projectHome - + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/proxy/simple-sip-servlet-dar.properties"; - } -} +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2013, Telestax Inc and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + */ + +package org.mobicents.servlet.sip.testsuite.proxy; + +import gov.nist.javax.sip.header.HeaderExt; +import gov.nist.javax.sip.message.MessageExt; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import javax.sip.ListeningPoint; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import javax.sip.header.Header; +import javax.sip.message.Request; +import javax.sip.message.Response; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class ProxyRecordRouteReInviteTest extends SipServletTestCase { + private static transient Logger logger = Logger.getLogger(ProxyRecordRouteReInviteTest.class); + private static final boolean AUTODIALOG = true; + TestSipListener sender; + TestSipListener receiver; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + + + private static final int TIMEOUT = 20000; + + public ProxyRecordRouteReInviteTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + } + + public void testProxyCallerSendBye() throws Exception { + setupPhones(ListeningPoint.UDP); + String fromName = "unique-location"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "proxy-receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + // part of non regression test for Issue http://code.google.com/p/mobicents/issues/detail?id=2359 + // allow to check if ACK retrans keep the same different branch id + sender.setTimeToWaitBeforeAck(2000); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(receiver.isAckReceived()); + // non regression test for Issue http://code.google.com/p/mobicents/issues/detail?id=2359 + String inviteBranch = ((MessageExt)receiver.getInviteRequest()).getTopmostViaHeader().getBranch(); + String ackBranch = ((MessageExt)receiver.getAckRequest()).getTopmostViaHeader().getBranch(); + assertFalse(inviteBranch.equals(ackBranch)); + receiver.setAckReceived(false); + sender.setAckSent(false); + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(receiver.isAckReceived()); + receiver.setAckReceived(false); + receiver.setAckSent(false); + sender.setAckSent(false); + sender.setAckReceived(false); + receiver.sendInDialogSipRequest("INVITE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isAckSent()); + assertTrue(sender.isAckReceived()); + sender.sendBye(); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + assertTrue(sender.getOkToByeReceived()); + logger.info("RequestsProcessedByMethod " + tomcat.getSipService().getSipApplicationDispatcher().getRequestsProcessedByMethod()); + logger.info("RequestsSentByMethod " + tomcat.getSipService().getSipApplicationDispatcher().getRequestsSentByMethod()); + logger.info("ResponsesProcessedByStatusCode " + tomcat.getSipService().getSipApplicationDispatcher().getResponsesProcessedByStatusCode()); + logger.info("ResponsesSentByStatusCode " + tomcat.getSipService().getSipApplicationDispatcher().getResponsesSentByStatusCode()); + assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getRequestsProcessedByMethod(Request.INVITE)>1); + assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getRequestsProcessedByMethod(Request.ACK)>1); + assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getRequestsProcessedByMethod(Request.BYE)>0); + assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getResponsesSentByStatusCode("2XX")>1); + assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getRequestsSentByMethod(Request.INVITE)>1); + assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getRequestsSentByMethod(Request.ACK)>1); + assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getRequestsSentByMethod(Request.BYE)>0); + assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getResponsesProcessedByStatusCode("2XX")>1); + } + + /* + * https://code.google.com/p/sipservlets/issues/detail?id=21 + */ + public void testProxyCallerFinalResponseOnSubsequentRequest() throws Exception { + setupPhones(ListeningPoint.UDP); + String fromName = "unique-location-final-response-subsequent"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "proxy-receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(receiver.isAckReceived()); + // non regression test for Issue http://code.google.com/p/mobicents/issues/detail?id=2359 + String inviteBranch = ((MessageExt)receiver.getInviteRequest()).getTopmostViaHeader().getBranch(); + String ackBranch = ((MessageExt)receiver.getAckRequest()).getTopmostViaHeader().getBranch(); + assertFalse(inviteBranch.equals(ackBranch)); + receiver.setAckReceived(false); + sender.setAckSent(false); + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertEquals(491, sender.getFinalResponseStatus()); + assertFalse(receiver.isAckReceived()); + receiver.setAckReceived(false); + receiver.setAckSent(false); + sender.setAckSent(false); + sender.setAckReceived(false); + sender.sendBye(); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + assertTrue(sender.getOkToByeReceived()); + } + + // Test for http://code.google.com/p/sipservlets/issues/detail?id=44 + public void testProxyReinviteAckSeenByApp() throws Exception { + setupPhones(ListeningPoint.UDP); + String fromName = "unique-location-ack-seen-by-app"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "proxy-receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(receiver.isAckReceived()); + // non regression test for Issue http://code.google.com/p/mobicents/issues/detail?id=2359 + String inviteBranch = ((MessageExt)receiver.getInviteRequest()).getTopmostViaHeader().getBranch(); + String ackBranch = ((MessageExt)receiver.getAckRequest()).getTopmostViaHeader().getBranch(); + assertFalse(inviteBranch.equals(ackBranch)); + receiver.setAckReceived(false); + sender.setAckSent(false); + receiver.setFinalResponseToSend(491); + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + sender.sendBye(); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + assertTrue(sender.getOkToByeReceived()); + + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertFalse(sender.getAllMessagesContent().contains("ack-seen-by-app")); + } + + public void testProxyCalleeSendBye() throws Exception { + setupPhones(ListeningPoint.UDP); + String fromName = "unique-location"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "proxy-receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(receiver.isAckReceived()); + receiver.setAckReceived(false); + sender.setAckSent(false); + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(receiver.isAckReceived()); + receiver.setAckReceived(false); + sender.setAckSent(false); + receiver.sendInDialogSipRequest("INVITE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isAckSent()); + assertTrue(sender.isAckReceived()); + receiver.sendBye(); + Thread.sleep(TIMEOUT); + assertTrue(sender.getByeReceived()); + assertTrue(receiver.getOkToByeReceived()); + } + + /* + * Non regression test for Issue 1792 + */ + public void testProxyCancelTCP() throws Exception { + tomcat.addSipConnector(serverName, sipIpAddress, containerPort, ListeningPoint.TCP); + setupPhones(ListeningPoint.TCP); + String fromName = "unique-location"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "proxy-receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + List provisionalResponsesToSend = new ArrayList(); + provisionalResponsesToSend.add(Response.TRYING); + provisionalResponsesToSend.add(Response.RINGING); + receiver.setProvisionalResponsesToSend(provisionalResponsesToSend); + + receiver.setWaitForCancel(true); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(1000); + sender.sendCancel(); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isCancelReceived()); + assertTrue(sender.isCancelOkReceived()); + assertTrue(sender.isRequestTerminatedReceived()); + } + + // Issue http://code.google.com/p/mobicents/issues/detail?id=1847 + public void testProxyExtraRouteNoRewrite() throws Exception { + setupPhones(ListeningPoint.UDP); + String fromName = "unique-location"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "proxy-receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Header rh = senderProtocolObjects.headerFactory.createHeader("Route", "sip:extra-route@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + ctx.getServletContext().getInitParameter("receiverPort") + ";lr"); + LinkedList
hh = new LinkedList
(); + hh.add(rh); + Thread.sleep(TIMEOUT/4); + sender.sendInDialogSipRequest("INVITE", null, null, null, hh, "udp"); + Thread.sleep(TIMEOUT/2); + + assertTrue(receiver.getInviteRequest().getRequestURI().toString().contains("extra-route")); + } + + // Check branchId of the ACK in case the reINVITE has an INFO in between to make sure that + // the ACK to 200 OK reINVITE is different than the INFO branchId + public void testProxyReinviteINFOCheckACKBranchId() throws Exception { + setupPhones(ListeningPoint.UDP); + String fromName = "unique-location"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "proxy-receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + // part of non regression test for Issue http://code.google.com/p/mobicents/issues/detail?id=2359 + // allow to check if ACK retrans keep the same different branch id + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(receiver.isAckReceived()); + receiver.setAckReceived(false); + sender.setAckSent(false); + sender.sendInDialogSipRequest("INFO", null, null, null, null, null); + Thread.sleep(500); + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(receiver.isAckReceived()); + receiver.setAckReceived(false); + receiver.setAckSent(false); + sender.setAckSent(false); + sender.setAckReceived(false); + //non regression test for Issue http://code.google.com/p/mobicents/issues/detail?id=2359 + String inviteBranch = ((MessageExt)receiver.getInviteRequest()).getTopmostViaHeader().getBranch(); + String infoBranch = ((MessageExt)receiver.getInfoRequest()).getTopmostViaHeader().getBranch(); + String ackBranch = ((MessageExt)receiver.getAckRequest()).getTopmostViaHeader().getBranch(); + assertFalse(inviteBranch.equals(ackBranch)); + assertFalse(infoBranch.equals(ackBranch)); + sender.sendBye(); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + assertTrue(sender.getOkToByeReceived()); + } + + // https://code.google.com/p/sipservlets/issues/detail?id=238 + public void testProxyINFOLeak() throws Exception { + setupPhones(ListeningPoint.UDP); + String fromName = "unique-location"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "proxy-receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + // part of non regression test for Issue http://code.google.com/p/mobicents/issues/detail?id=2359 + // allow to check if ACK retrans keep the same different branch id + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(receiver.isAckReceived()); + receiver.setAckReceived(false); + sender.setAckSent(false); + sender.sendInDialogSipRequest("INFO", null, null, null, null, null); + Thread.sleep(500); + sender.sendInDialogSipRequest("INFO", null, null, null, null, null); + Thread.sleep(500); + sender.sendInDialogSipRequest("INFO", null, null, null, null, null); + Thread.sleep(500); + sender.sendInDialogSipRequest("INFO", null, null, null, null, null); + Thread.sleep(500); + sender.sendInDialogSipRequest("INFO", null, null, null, null, null); + Thread.sleep(TIMEOUT*2); + sender.sendBye(); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + assertTrue(sender.getOkToByeReceived()); + assertNotNull(sender.getFinalResponse().getHeader("X-Proxy-Transactions")); + assertEquals("1",((HeaderExt)sender.getFinalResponse().getHeader("X-Proxy-Transactions")).getValue()); + } + + /* + * Non regression test for https://code.google.com/p/sipservlets/issues/detail?id=202 + */ + public void testProxyModifySDP() throws Exception { + setupPhones(ListeningPoint.UDP); + String fromName = "modify-SDP"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "proxy-receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + // part of non regression test for Issue http://code.google.com/p/mobicents/issues/detail?id=2359 + // allow to check if ACK retrans keep the same different branch id + sender.setTimeToWaitBeforeAck(2000); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(receiver.isAckReceived()); + assertEquals("SDP modified successfully", new String(sender.getFinalResponse().getRawContent(), "UTF-8")); + // non regression test for Issue http://code.google.com/p/mobicents/issues/detail?id=2359 + String inviteBranch = ((MessageExt)receiver.getInviteRequest()).getTopmostViaHeader().getBranch(); + String ackBranch = ((MessageExt)receiver.getAckRequest()).getTopmostViaHeader().getBranch(); + assertFalse(inviteBranch.equals(ackBranch)); + receiver.setAckReceived(false); + sender.setAckSent(false); + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(receiver.isAckReceived()); + receiver.setAckReceived(false); + receiver.setAckSent(false); + sender.setAckSent(false); + sender.setAckReceived(false); + assertEquals("SDP modified successfully", new String(sender.getFinalResponse().getRawContent(), "UTF-8")); + receiver.sendInDialogSipRequest("INVITE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isAckSent()); + assertTrue(sender.isAckReceived()); + assertEquals("SDP modified successfully", new String(receiver.getFinalResponse().getRawContent(), "UTF-8")); + sender.sendBye(); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + assertTrue(sender.getOkToByeReceived()); + } + + public void setupPhones(String transport) throws Exception { + senderProtocolObjects = new ProtocolObjects("proxy-sender", + "gov.nist", transport, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects("proxy-receiver", + "gov.nist", transport, AUTODIALOG, null, null, null); + + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(senderPort)); + params.put( "receiverPort", String.valueOf(receiverPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + params, null); + } + + @Override + public void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + + @Override + public void deployApplication() { + assertTrue(tomcat + .deployContext( + projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + "sip-test-context", "sip-test")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/proxy/simple-sip-servlet-dar.properties"; + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyRecordRouteUpdateTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyRecordRouteUpdateTest.java index 0a128fb8ed..2f0f48481d 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyRecordRouteUpdateTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyRecordRouteUpdateTest.java @@ -25,8 +25,10 @@ import gov.nist.javax.sip.message.MessageExt; import java.util.ArrayList; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import javax.sip.ListeningPoint; import javax.sip.SipProvider; @@ -34,6 +36,7 @@ import javax.sip.message.Response; import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; import org.mobicents.servlet.sip.SipServletTestCase; import org.mobicents.servlet.sip.testsuite.ProtocolObjects; import org.mobicents.servlet.sip.testsuite.TestSipListener; @@ -50,10 +53,12 @@ public class ProxyRecordRouteUpdateTest extends SipServletTestCase { public ProxyRecordRouteUpdateTest(String name) { super(name); + autoDeployOnStartup = false; } @Override public void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); super.setUp(); } @@ -263,11 +268,14 @@ public void setupPhones(String transport) throws Exception { "gov.nist", transport, AUTODIALOG, null, null, null); receiverProtocolObjects = new ProtocolObjects("proxy-receiver", "gov.nist", transport, AUTODIALOG, null, "3", "true"); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); + + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); sender.setRecordRoutingProxyTesting(true); SipProvider senderProvider = sender.createProvider(); - receiver = new TestSipListener(5057, 5070, receiverProtocolObjects, false); + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); receiver.setRecordRoutingProxyTesting(true); SipProvider receiverProvider = receiver.createProvider(); @@ -276,6 +284,14 @@ public void setupPhones(String transport) throws Exception { senderProtocolObjects.start(); receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(senderPort)); + params.put( "receiverPort", String.valueOf(receiverPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + params, null); } @Override diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyRecordRoutingTcpTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyRecordRoutingTcpTest.java index dd853b81ae..b1dfd2577a 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyRecordRoutingTcpTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyRecordRoutingTcpTest.java @@ -19,7 +19,9 @@ package org.mobicents.servlet.sip.testsuite.proxy; +import java.util.HashMap; import java.util.ListIterator; +import java.util.Map; import javax.sip.ListeningPoint; import javax.sip.SipProvider; @@ -28,6 +30,7 @@ import javax.sip.header.RecordRouteHeader; import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; import org.mobicents.servlet.sip.SipServletTestCase; import org.mobicents.servlet.sip.testsuite.ProtocolObjects; import org.mobicents.servlet.sip.testsuite.TestSipListener; @@ -58,22 +61,29 @@ public ProxyRecordRoutingTcpTest(String name) { @Override public void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); super.setUp(); + } + public void setupPhones() throws Exception { senderProtocolObjects = new ProtocolObjects("proxy-sender", "gov.nist", ListeningPoint.TCP, AUTODIALOG, null, null, null); receiverProtocolObjects = new ProtocolObjects("proxy-receiver", "gov.nist", ListeningPoint.TCP, AUTODIALOG, null, null, null); neutralProto = new ProtocolObjects("neutral", "gov.nist", ListeningPoint.TCP, AUTODIALOG, null, null, null); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); + + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); sender.setRecordRoutingProxyTesting(true); SipProvider senderProvider = sender.createProvider(); - receiver = new TestSipListener(5057, 5070, receiverProtocolObjects, false); + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); receiver.setRecordRoutingProxyTesting(true); SipProvider receiverProvider = receiver.createProvider(); - neutral = new TestSipListener(5058, 5070, neutralProto, false); + int neutralPort = NetworkPortAssigner.retrieveNextPort(); + neutral = new TestSipListener(neutralPort, containerPort, neutralProto, false); neutral.setRecordRoutingProxyTesting(true); SipProvider neutralProvider = neutral.createProvider(); @@ -84,13 +94,22 @@ public void setUp() throws Exception { senderProtocolObjects.start(); receiverProtocolObjects.start(); neutralProto.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(senderPort)); + params.put( "receiverPort", String.valueOf(receiverPort)); + params.put( "neutralPort", String.valueOf(neutralPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + params, null); } /* * https://code.google.com/p/sipservlets/issues/detail?id=20 */ public void testTCPRecordRouteProxying() throws Exception { - deployApplication(); + setupPhones(); String fromName = "tcp-record-route-tcp-unique-location"; String fromSipAddress = "sip-servlets.com"; SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyRecordRoutingTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyRecordRoutingTest.java index 8ee03160da..23756552ff 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyRecordRoutingTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyRecordRoutingTest.java @@ -22,8 +22,10 @@ package org.mobicents.servlet.sip.testsuite.proxy; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.ListIterator; +import java.util.Map; import java.util.Random; import javax.sip.ListeningPoint; @@ -37,6 +39,7 @@ import org.apache.catalina.connector.Connector; import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; import org.mobicents.servlet.sip.SipServletTestCase; import org.mobicents.servlet.sip.catalina.SipProtocolHandler; import org.mobicents.servlet.sip.testsuite.ProtocolObjects; @@ -69,7 +72,10 @@ public ProxyRecordRoutingTest(String name) { @Override public void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); super.setUp(); + } + public void setupPhones() throws Exception { senderProtocolObjects = new ProtocolObjects("proxy-sender", "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null); receiverProtocolObjects = new ProtocolObjects("proxy-receiver", @@ -78,19 +84,24 @@ public void setUp() throws Exception { "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null); secondProto = new ProtocolObjects("proxy-second-receiver", "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); + + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); sender.setRecordRoutingProxyTesting(true); SipProvider senderProvider = sender.createProvider(); - receiver = new TestSipListener(5057, 5070, receiverProtocolObjects, false); + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); receiver.setRecordRoutingProxyTesting(true); SipProvider receiverProvider = receiver.createProvider(); - neutral = new TestSipListener(5058, 5070, neutralProto, false); + int neutralPort = NetworkPortAssigner.retrieveNextPort(); + neutral = new TestSipListener(neutralPort, containerPort, neutralProto, false); neutral.setRecordRoutingProxyTesting(true); SipProvider neutralProvider = neutral.createProvider(); - secondReceiver = new TestSipListener(5056, 5070, secondProto, false); + int secondReceiverPort = NetworkPortAssigner.retrieveNextPort(); + secondReceiver = new TestSipListener(secondReceiverPort, containerPort, secondProto, false); secondReceiver.setRecordRoutingProxyTesting(true); SipProvider secondProvider = secondReceiver.createProvider(); @@ -103,13 +114,23 @@ public void setUp() throws Exception { receiverProtocolObjects.start(); neutralProto.start(); secondProto.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(senderPort)); + params.put( "receiverPort", String.valueOf(receiverPort)); + params.put( "neutralPort", String.valueOf(neutralPort)); + params.put( "cutmePort", String.valueOf(secondReceiverPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + params, null); } /* * Non Regression test for https://code.google.com/p/sipservlets/issues/detail?id=164 */ public void testCancelProxying() throws Exception { - deployApplication(); + setupPhones(); String fromName = "cancel-unique-location"; String fromSipAddress = "sip-servlets.com"; SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( @@ -158,7 +179,7 @@ public void testCancelProxying() throws Exception { * Non Regression test for https://code.google.com/p/sipservlets/issues/detail?id=283 */ public void testCancelProxying2Locations() throws Exception { - deployApplication(); + setupPhones(); String fromName = "cancel-both-location"; String fromSipAddress = "sip-servlets.com"; SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( @@ -213,7 +234,7 @@ public void testCancelProxying2Locations() throws Exception { * Non Regression test for https://code.google.com/p/sipservlets/issues/detail?id=164 */ public void testCancelProxyingNon1XX() throws Exception { - deployApplication(); + setupPhones(); String fromName = "cancel-unique-location"; String fromSipAddress = "sip-servlets.com"; SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( @@ -239,7 +260,7 @@ public void testCancelProxyingNon1XX() throws Exception { * https://code.google.com/p/sipservlets/issues/detail?id=2 */ public void testRedirectProxying() throws Exception { - deployApplication(); + setupPhones(); String fromName = "redirect-unique-location"; String fromSipAddress = "sip-servlets.com"; SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( @@ -266,7 +287,7 @@ public void testRedirectProxying() throws Exception { * https://github.com/Mobicents/sip-servlets/issues/63 */ public void testRecordRouteFQDNUriProxying() throws Exception { - deployApplication(); + setupPhones(); String fromName = "record-route-uri"; String fromSipAddress = "sip-servlets.com"; SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( @@ -289,13 +310,13 @@ public void testRecordRouteFQDNUriProxying() throws Exception { * */ public void testPoppedRouteFQDN() throws Exception { - deployApplication(); + setupPhones(); tomcat.removeConnector(sipConnector); Connector udpSipConnector = new Connector( SipProtocolHandler.class.getName()); SipProtocolHandler udpProtocolHandler = (SipProtocolHandler) udpSipConnector .getProtocolHandler(); - udpProtocolHandler.setPort(5070); + udpProtocolHandler.setPort(containerPort); udpProtocolHandler.setIpAddress(sipIpAddress); udpProtocolHandler.setSignalingTransport(listeningPointTransport); udpProtocolHandler.setHostNames("test.mobicents.org"); @@ -311,7 +332,7 @@ public void testPoppedRouteFQDN() throws Exception { SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( toUser, toSipAddress); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[]{RouteHeader.NAME}, new String[]{""}, true); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[]{RouteHeader.NAME}, new String[]{""}, true); Thread.sleep(TIMEOUT); assertEquals(200,sender.getFinalResponseStatus()); assertTrue(sender.isAckSent()); @@ -322,7 +343,7 @@ public void testPoppedRouteFQDN() throws Exception { * Non Regression test for https://code.google.com/p/sipservlets/issues/detail?id=2 */ public void testCancelRedirectProxying() throws Exception { - deployApplication(); + setupPhones(); String fromName = "cancel-unique-location"; String fromSipAddress = "sip-servlets.com"; SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( @@ -347,7 +368,7 @@ public void testCancelRedirectProxying() throws Exception { * Non Regression test for https://code.google.com/p/sipservlets/issues/detail?id=266 */ public void testCancel480Proxying() throws Exception { - deployApplication(); + setupPhones(); String fromName = "cancel-480-sequential-2-locations"; String fromSipAddress = "sip-servlets.com"; SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( @@ -376,7 +397,7 @@ public void testCancel480Proxying() throws Exception { * Non Regression test for https://code.google.com/p/sipservlets/issues/detail?id=154 */ public void testCancel480ChangeToUserProxying() throws Exception { - deployApplication(); + setupPhones(); String fromName = "cancel-480-sequential-2-locations-change-to-user"; String fromSipAddress = "sip-servlets.com"; SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( @@ -406,7 +427,7 @@ public void testCancel480ChangeToUserProxying() throws Exception { * https://code.google.com/p/sipservlets/issues/detail?id=22 */ public void testUnderscoreToTagFinalResponseProxying() throws Exception { - deployApplication(); + setupPhones(); String fromName = "underscore-to-tag-unique-location"; String fromSipAddress = "sip-servlets.com"; SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxySubsequentPublishRequestTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxySubsequentPublishRequestTest.java index 8cb1a621ef..c3fc2593b9 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxySubsequentPublishRequestTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxySubsequentPublishRequestTest.java @@ -40,7 +40,9 @@ */ import java.util.EventObject; +import java.util.HashMap; import java.util.Hashtable; +import java.util.Map; import javax.sip.DialogTerminatedEvent; import javax.sip.IOExceptionEvent; @@ -54,6 +56,7 @@ import javax.sip.message.Request; import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; import org.mobicents.servlet.sip.SipServletTestCase; /* @@ -78,17 +81,32 @@ public class ProxySubsequentPublishRequestTest extends SipServletTestCase implem public ProxySubsequentPublishRequestTest(String name) { super(name); - this.sipIpAddress="0.0.0.0"; + autoDeployOnStartup = false; + } @Override public void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); super.setUp(); - this.shootist = new Shootist(false, null); - this.shootme = new Shootme(5057); - this.cutme = new Cutme(); + + int shootistPort = NetworkPortAssigner.retrieveNextPort(); + this.shootist = new Shootist(false, shootistPort, String.valueOf(containerPort)); + int shootmePort = NetworkPortAssigner.retrieveNextPort(); + this.shootme = new Shootme(shootmePort); + int cutmePort = NetworkPortAssigner.retrieveNextPort(); + this.cutme = new Cutme(cutmePort); this.shootist.requestMethod = Request.PUBLISH; + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(shootistPort)); + params.put( "receiverPort", String.valueOf(shootmePort)); + params.put( "cutmePort", String.valueOf(cutmePort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + params, null); } public void testProxyPublish() { diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyTerminationTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyTerminationTest.java index 103960b0e5..69822459a0 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyTerminationTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyTerminationTest.java @@ -1,124 +1,140 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.proxy; - -import java.util.List; - -import javax.sip.ListeningPoint; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class ProxyTerminationTest extends SipServletTestCase { - private static transient Logger logger = Logger.getLogger(ProxyTerminationTest.class); - private static final boolean AUTODIALOG = true; - TestSipListener sender; - TestSipListener receiver; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - - - private static final int TIMEOUT = 30000; - - public ProxyTerminationTest(String name) { - super(name); - } - - @Override - public void setUp() throws Exception { - super.setUp(); - } - - public void testProxyTermination() throws Exception { - setupPhones(ListeningPoint.UDP); - String fromName = "test_termination_unique_location"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "proxy-receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(receiver.isAckReceived()); - assertTrue(receiver.getByeReceived()); - assertTrue(sender.getByeReceived()); - List allMessagesContent = sender.getAllMessagesContent(); - assertEquals(2,allMessagesContent.size()); - assertTrue("sipSessionReadyToInvalidate", allMessagesContent.contains("sipSessionReadyToInvalidate")); - assertTrue("sessionReadyToInvalidate", allMessagesContent.contains("sessionReadyToInvalidate")); - } - - public void setupPhones(String transport) throws Exception { - senderProtocolObjects = new ProtocolObjects("proxy-sender", - "gov.nist", transport, AUTODIALOG, null, null, null); - receiverProtocolObjects = new ProtocolObjects("proxy-receiver", - "gov.nist", transport, AUTODIALOG, null, null, null); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5057, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - } - - @Override - public void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - @Override - public void deployApplication() { - assertTrue(tomcat - .deployContext( - projectHome - + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/proxy/simple-sip-servlet-dar.properties"; - } -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite.proxy; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.sip.ListeningPoint; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class ProxyTerminationTest extends SipServletTestCase { + private static transient Logger logger = Logger.getLogger(ProxyTerminationTest.class); + private static final boolean AUTODIALOG = true; + TestSipListener sender; + TestSipListener receiver; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + + + private static final int TIMEOUT = 30000; + + public ProxyTerminationTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + } + + public void testProxyTermination() throws Exception { + setupPhones(ListeningPoint.UDP); + String fromName = "test_termination_unique_location"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "proxy-receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(receiver.isAckReceived()); + assertTrue(receiver.getByeReceived()); + assertTrue(sender.getByeReceived()); + List allMessagesContent = sender.getAllMessagesContent(); + assertEquals(2,allMessagesContent.size()); + assertTrue("sipSessionReadyToInvalidate", allMessagesContent.contains("sipSessionReadyToInvalidate")); + assertTrue("sessionReadyToInvalidate", allMessagesContent.contains("sessionReadyToInvalidate")); + } + + public void setupPhones(String transport) throws Exception { + senderProtocolObjects = new ProtocolObjects("proxy-sender", + "gov.nist", transport, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects("proxy-receiver", + "gov.nist", transport, AUTODIALOG, null, null, null); + + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(senderPort)); + params.put( "receiverPort", String.valueOf(receiverPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + params, null); + } + + @Override + public void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + + @Override + public void deployApplication() { + assertTrue(tomcat + .deployContext( + projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + "sip-test-context", "sip-test")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/proxy/simple-sip-servlet-dar.properties"; + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyTimeoutTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyTimeoutTest.java index f022bed851..8d2dfad00a 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyTimeoutTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyTimeoutTest.java @@ -1,263 +1,263 @@ -/* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2014, Telestax Inc and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - */ - -package org.mobicents.servlet.sip.testsuite.proxy; - -import java.util.ArrayList; -import java.util.Iterator; - -import javax.sip.ListeningPoint; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.catalina.deploy.ApplicationParameter; -import org.apache.log4j.Logger; -import org.mobicents.javax.servlet.sip.ResponseType; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class ProxyTimeoutTest extends SipServletTestCase { - private static final String SESSION_EXPIRED = "sessionExpired"; - private static final String SESSION_READY_TO_INVALIDATE = "sessionReadyToInvalidate"; - private static final String SIP_SESSION_READY_TO_INVALIDATE = "sipSessionReadyToInvalidate"; - private static transient Logger logger = Logger.getLogger(ProxyTimeoutTest.class); - private static final boolean AUTODIALOG = true; - TestSipListener sender; - TestSipListener neutral; - TestSipListener receiver; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - ProtocolObjects neutralProto; - - - private static final int TIMEOUT = 20000; - - public ProxyTimeoutTest(String name) { - super(name); - autoDeployOnStartup = false; - } - - @Override - public void setUp() throws Exception { - super.setUp(); - senderProtocolObjects = new ProtocolObjects("proxy-sender", - "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null); - receiverProtocolObjects = new ProtocolObjects("proxy-receiver", - "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null); - neutralProto = new ProtocolObjects("neutral", - "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5057, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - neutral = new TestSipListener(5058, 5070, neutralProto, false); - neutral.setRecordRoutingProxyTesting(true); - SipProvider neutralProvider = neutral.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - neutralProvider.addSipListener(neutral); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - neutralProto.start(); - } - - /** - * It will proxy to 2 locations, one will send a trying that will stop the 1xx timer but the final response timer should fire - * and the other is not alive so will no send any response so the 1xx timer should fire - * @throws Exception - */ - public void testProxy1xxResponseTimeout() throws Exception { - deployApplication(); - String fromName = "sequential-1xxResponseTimeout"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "proxy-receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - receiver.setProvisionalResponsesToSend(new ArrayList()); - receiver.setWaitForCancel(true); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT*3); - assertEquals(0,receiver.getFinalResponseStatus()); - assertTrue(!sender.isAckSent()); - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertTrue(sender.getAllMessagesContent().size() >= 4); - assertTrue(sender.getAllMessagesContent().contains(ResponseType.INFORMATIONAL.toString())); - assertTrue(sender.getAllMessagesContent().contains(ResponseType.FINAL.toString())); - assertTrue(sender.getAllMessagesContent().contains(SESSION_READY_TO_INVALIDATE)); - assertTrue(sender.getAllMessagesContent().contains(SIP_SESSION_READY_TO_INVALIDATE)); - } - - /** - * It will proxy to 1 locations that will send a final response that will stop the 1xx and final response timer - * @throws Exception - */ - public void testProxyNoTimeout() throws Exception { - deployApplication(); - String fromName = "sequential-reverse-NoResponseTimeout"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "proxy-receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - receiver.setProvisionalResponsesToSend(new ArrayList()); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertEquals(0, sender.getAllMessagesContent().size()); - } - - /** - * Test Issue 1678 : SipApplicationSession.setExpires() doesn't work sometimes - * Test Issue 1676 : SipApplicationSession.getExpirationTime() is incorrect - */ - public void testProxySipApplicationSessionTimeout() throws Exception { - deployApplication("sipApplicationSessionTimeout", "1"); - String fromName = "sipApplicationSessionTimeout"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "proxy-receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - receiver.setProvisionalResponsesToSend(new ArrayList()); - sender.setSendBye(true); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(70000); - assertTrue(sender.isAckSent()); - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertTrue(sender.getAllMessagesContent().size() >= 3); - assertTrue(sender.getAllMessagesContent().contains(SESSION_EXPIRED)); - assertTrue(sender.getAllMessagesContent().contains(SESSION_READY_TO_INVALIDATE)); - assertTrue(sender.getAllMessagesContent().contains(SIP_SESSION_READY_TO_INVALIDATE)); - - } - - public void testNonExistLegTimeout() throws Exception { - deployApplication(); - String fromName = "sequential-nonexist"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "proxy-receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - receiver.setProvisionalResponsesToSend(new ArrayList()); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(50000); - assertTrue(sender.getMessageRequest() != null); - } - - /* - * Non regression test for https://code.google.com/p/sipservlets/issues/detail?id=263 - */ - public void testNonExistLeg1xxTimeout() throws Exception { - deployApplication(); - String fromName = "sequential-nonexist-1xx"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "proxy-receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - receiver.setProvisionalResponsesToSend(new ArrayList()); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(50000); - assertTrue(sender.getMessageRequest() != null); - assertTrue(sender.getAllMessagesContent().contains("doBranchTimeoutReceived")); - assertTrue(sender.getAllMessagesContent().contains(SESSION_READY_TO_INVALIDATE)); - assertTrue(sender.getAllMessagesContent().contains(SIP_SESSION_READY_TO_INVALIDATE)); - } - - @Override - public void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - neutralProto.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - @Override - public void deployApplication() { - assertTrue(tomcat - .deployContext( - projectHome - + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - public SipStandardContext deployApplication(String name, String value) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(name); - applicationParameter.setValue(value); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - return context; - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/proxy/simple-sip-servlet-dar.properties"; - } -} +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2014, Telestax Inc and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + */ + +package org.mobicents.servlet.sip.testsuite.proxy; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import javax.sip.ListeningPoint; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; + +import org.apache.log4j.Logger; +import org.mobicents.javax.servlet.sip.ResponseType; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class ProxyTimeoutTest extends SipServletTestCase { + private static final String SESSION_EXPIRED = "sessionExpired"; + private static final String SESSION_READY_TO_INVALIDATE = "sessionReadyToInvalidate"; + private static final String SIP_SESSION_READY_TO_INVALIDATE = "sipSessionReadyToInvalidate"; + private static transient Logger logger = Logger.getLogger(ProxyTimeoutTest.class); + private static final boolean AUTODIALOG = true; + TestSipListener sender; + TestSipListener neutral; + TestSipListener receiver; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + ProtocolObjects neutralProto; + + + private static final int TIMEOUT = 20000; + + public ProxyTimeoutTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void setUp() throws Exception { + } + + public void setupPhones(Map params) throws Exception{ + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + senderProtocolObjects = new ProtocolObjects("proxy-sender", + "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects("proxy-receiver", + "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null); + neutralProto = new ProtocolObjects("neutral", + "gov.nist", ListeningPoint.UDP, AUTODIALOG, null, null, null); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + int neutralPort = NetworkPortAssigner.retrieveNextPort(); + neutral = new TestSipListener(neutralPort, containerPort, neutralProto, false); + neutral.setRecordRoutingProxyTesting(true); + SipProvider neutralProvider = neutral.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + neutralProvider.addSipListener(neutral); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + neutralProto.start(); + + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(senderPort)); + params.put( "receiverPort", String.valueOf(receiverPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + params, null); + } + + /** + * It will proxy to 2 locations, one will send a trying that will stop the 1xx timer but the final response timer should fire + * and the other is not alive so will no send any response so the 1xx timer should fire + * @throws Exception + */ + public void testProxy1xxResponseTimeout() throws Exception { + setupPhones(new HashMap()); + String fromName = "sequential-1xxResponseTimeout"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "proxy-receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + receiver.setProvisionalResponsesToSend(new ArrayList()); + receiver.setWaitForCancel(true); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT*3); + assertEquals(0,receiver.getFinalResponseStatus()); + assertTrue(!sender.isAckSent()); + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertTrue(sender.getAllMessagesContent().size() >= 4); + assertTrue(sender.getAllMessagesContent().contains(ResponseType.INFORMATIONAL.toString())); + assertTrue(sender.getAllMessagesContent().contains(ResponseType.FINAL.toString())); + assertTrue(sender.getAllMessagesContent().contains(SESSION_READY_TO_INVALIDATE)); + assertTrue(sender.getAllMessagesContent().contains(SIP_SESSION_READY_TO_INVALIDATE)); + } + + /** + * It will proxy to 1 locations that will send a final response that will stop the 1xx and final response timer + * @throws Exception + */ + public void testProxyNoTimeout() throws Exception { + setupPhones(new HashMap()); + String fromName = "sequential-reverse-NoResponseTimeout"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "proxy-receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + receiver.setProvisionalResponsesToSend(new ArrayList()); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertEquals(0, sender.getAllMessagesContent().size()); + } + + /** + * Test Issue 1678 : SipApplicationSession.setExpires() doesn't work sometimes + * Test Issue 1676 : SipApplicationSession.getExpirationTime() is incorrect + */ + public void testProxySipApplicationSessionTimeout() throws Exception { + Map map = new HashMap(); + map.put("sipApplicationSessionTimeout", "1"); + setupPhones(map); + String fromName = "sipApplicationSessionTimeout"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "proxy-receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + receiver.setProvisionalResponsesToSend(new ArrayList()); + sender.setSendBye(true); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(70000); + assertTrue(sender.isAckSent()); + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertTrue(sender.getAllMessagesContent().size() >= 3); + assertTrue(sender.getAllMessagesContent().contains(SESSION_EXPIRED)); + assertTrue(sender.getAllMessagesContent().contains(SESSION_READY_TO_INVALIDATE)); + assertTrue(sender.getAllMessagesContent().contains(SIP_SESSION_READY_TO_INVALIDATE)); + + } + + public void testNonExistLegTimeout() throws Exception { + setupPhones(new HashMap());; + String fromName = "sequential-nonexist"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "proxy-receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + receiver.setProvisionalResponsesToSend(new ArrayList()); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(50000); + assertTrue(sender.getMessageRequest() != null); + } + + /* + * Non regression test for https://code.google.com/p/sipservlets/issues/detail?id=263 + */ + public void testNonExistLeg1xxTimeout() throws Exception { + setupPhones(new HashMap()); + String fromName = "sequential-nonexist-1xx"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "proxy-receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + receiver.setProvisionalResponsesToSend(new ArrayList()); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(50000); + assertTrue(sender.getMessageRequest() != null); + assertTrue(sender.getAllMessagesContent().contains("doBranchTimeoutReceived")); + assertTrue(sender.getAllMessagesContent().contains(SESSION_READY_TO_INVALIDATE)); + assertTrue(sender.getAllMessagesContent().contains(SIP_SESSION_READY_TO_INVALIDATE)); + } + + @Override + public void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + neutralProto.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + + @Override + public void deployApplication() { + assertTrue(tomcat + .deployContext( + projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + "sip-test-context", "sip-test")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/proxy/simple-sip-servlet-dar.properties"; + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyURNTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyURNTest.java index de4e9f7286..e2f712e0fa 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyURNTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyURNTest.java @@ -23,7 +23,9 @@ package org.mobicents.servlet.sip.testsuite.proxy; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.sip.ListeningPoint; import javax.sip.SipProvider; @@ -33,6 +35,7 @@ import org.apache.log4j.Logger; import org.mobicents.javax.servlet.sip.ResponseType; +import org.mobicents.servlet.sip.NetworkPortAssigner; import org.mobicents.servlet.sip.SipServletTestCase; import org.mobicents.servlet.sip.testsuite.ProtocolObjects; import org.mobicents.servlet.sip.testsuite.TestSipListener; @@ -52,10 +55,12 @@ public class ProxyURNTest extends SipServletTestCase { public ProxyURNTest(String name) { super(name); + autoDeployOnStartup = false; } @Override public void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); super.setUp(); } @@ -125,11 +130,13 @@ public void setupPhones(String transport) throws Exception { "gov.nist", transport, AUTODIALOG, null, null, null); receiverProtocolObjects = new ProtocolObjects("proxy-receiver", "gov.nist", transport, AUTODIALOG, null, null, null); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); sender.setRecordRoutingProxyTesting(true); SipProvider senderProvider = sender.createProvider(); - receiver = new TestSipListener(5057, 5070, receiverProtocolObjects, false); + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); receiver.setRecordRoutingProxyTesting(true); SipProvider receiverProvider = receiver.createProvider(); @@ -138,6 +145,14 @@ public void setupPhones(String transport) throws Exception { senderProtocolObjects.start(); receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(senderPort)); + params.put( "receiverPort", String.valueOf(receiverPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + params, null); } @Override diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyUdpTcpTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyUdpTcpTest.java index 0837d6cc21..4ae0736305 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyUdpTcpTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/ProxyUdpTcpTest.java @@ -22,6 +22,8 @@ package org.mobicents.servlet.sip.testsuite.proxy; +import java.util.HashMap; +import java.util.Map; import javax.sip.ListeningPoint; import javax.sip.SipProvider; import javax.sip.address.SipURI; @@ -31,7 +33,9 @@ import javax.sip.header.Header; import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; import org.mobicents.servlet.sip.testsuite.ProtocolObjects; import org.mobicents.servlet.sip.testsuite.TestSipListener; @@ -81,14 +85,12 @@ protected String getDarConfigurationFile() { } @Override - protected void setUp() throws Exception { + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); super.setUp(); - tomcat.addSipConnector(serverName, sipIpAddress, 5070, ListeningPoint.TCP); + tomcat.addSipConnector(serverName, sipIpAddress, containerPort, ListeningPoint.TCP); tomcat.startTomcat(); - deployApplication(); - - } public void testCallForwardingCallerSendBye() throws Exception { @@ -97,11 +99,13 @@ public void testCallForwardingCallerSendBye() throws Exception { "gov.nist", TRANSPORT_UDP, AUTODIALOG, null, listeningPointTransport, listeningPointTransport); receiverProtocolObjects = new ProtocolObjects("forward-tcp-receiver", "gov.nist", TRANSPORT_TCP, AUTODIALOG, null, listeningPointTransport, listeningPointTransport); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); sender.setRecordRoutingProxyTesting(true); SipProvider senderProvider = sender.createProvider(); - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); SipProvider receiverProvider = receiver.createProvider(); receiverProvider.addSipListener(receiver); @@ -109,6 +113,13 @@ public void testCallForwardingCallerSendBye() throws Exception { senderProtocolObjects.start(); receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(senderPort)); + params.put( "receiverPort", String.valueOf(receiverPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", params, null); String fromName = "proxy-tcp"; String fromSipAddress = "sip-servlets.com"; @@ -138,11 +149,13 @@ public void testCallForwardingCalleeSendByeTCPSender() throws Exception { "gov.nist", TRANSPORT_TCP, AUTODIALOG, null, listeningPointTransport, listeningPointTransport); receiverProtocolObjects = new ProtocolObjects("forward-tcp-receiver", "gov.nist", TRANSPORT_UDP, AUTODIALOG, null, listeningPointTransport, listeningPointTransport); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); sender.setRecordRoutingProxyTesting(true); SipProvider senderProvider = sender.createProvider(); - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); // receiver.setTransport(false); SipProvider receiverProvider = receiver.createProvider(); @@ -151,6 +164,13 @@ public void testCallForwardingCalleeSendByeTCPSender() throws Exception { senderProtocolObjects.start(); receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(senderPort)); + params.put( "receiverPort", String.valueOf(receiverPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", params, null); String fromName = "proxy-udp"; String fromSipAddress = "sip-servlets.com"; @@ -177,11 +197,13 @@ public void testCallForwardingCalleeSendByeTCPSenderExtraRoutes() throws Excepti "gov.nist", TRANSPORT_TCP, AUTODIALOG, null, listeningPointTransport, listeningPointTransport); receiverProtocolObjects = new ProtocolObjects("forward-tcp-receiver", "gov.nist", TRANSPORT_UDP, AUTODIALOG, null, listeningPointTransport, listeningPointTransport); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); sender.setRecordRoutingProxyTesting(true); SipProvider senderProvider = sender.createProvider(); - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); // receiver.setTransport(false); SipProvider receiverProvider = receiver.createProvider(); @@ -190,6 +212,13 @@ public void testCallForwardingCalleeSendByeTCPSenderExtraRoutes() throws Excepti senderProtocolObjects.start(); receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(senderPort)); + params.put( "receiverPort", String.valueOf(receiverPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", params, null); String fromName = "proxy-udp"; String fromSipAddress = "sip-servlets.com"; @@ -202,7 +231,7 @@ public void testCallForwardingCalleeSendByeTCPSenderExtraRoutes() throws Excepti toUser, toSipAddress); SipURI route = senderProtocolObjects.addressFactory.createSipURI( - toUser, "127.0.0.1:5070"); + toUser, "127.0.0.1:" + containerPort); sender.extraRoute = true; sender.sendSipRequest("INVITE", fromAddress, toAddress, null, route, false); @@ -226,11 +255,13 @@ public void testUnspecifiedCallForwardingCalleeSendByeTCPSender() throws Excepti "gov.nist", TRANSPORT_TCP, AUTODIALOG, null, listeningPointTransport, listeningPointTransport); receiverProtocolObjects = new ProtocolObjects("forward-tcp-receiver", "gov.nist", TRANSPORT_UDP, AUTODIALOG, null, listeningPointTransport, listeningPointTransport); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); sender.setRecordRoutingProxyTesting(true); SipProvider senderProvider = sender.createProvider(); - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); // receiver.setTransport(false); SipProvider receiverProvider = receiver.createProvider(); @@ -239,6 +270,13 @@ public void testUnspecifiedCallForwardingCalleeSendByeTCPSender() throws Excepti senderProtocolObjects.start(); receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(senderPort)); + params.put( "receiverPort", String.valueOf(receiverPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", params, null); String fromName = "proxy-unspecified"; String fromSipAddress = "sip-servlets.com"; @@ -266,11 +304,13 @@ public void testCallForwardingCallerSendByeOrphan() throws Exception { "gov.nist", TRANSPORT_UDP, AUTODIALOG, null, listeningPointTransport, listeningPointTransport); receiverProtocolObjects = new ProtocolObjects("forward-udp-receiver", "gov.nist", TRANSPORT_UDP, AUTODIALOG, null, listeningPointTransport, listeningPointTransport); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); sender.setRecordRoutingProxyTesting(true); SipProvider senderProvider = sender.createProvider(); - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); SipProvider receiverProvider = receiver.createProvider(); receiverProvider.addSipListener(receiver); @@ -278,6 +318,13 @@ public void testCallForwardingCallerSendByeOrphan() throws Exception { senderProtocolObjects.start(); receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(senderPort)); + params.put( "receiverPort", String.valueOf(receiverPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", params, null); String fromName = "proxy-orphan"; String fromSipAddress = "sip-servlets.com"; @@ -307,11 +354,14 @@ public void testCallForwardingCallerSendByeOrphan2() throws Exception { "gov.nist", TRANSPORT_UDP, AUTODIALOG, null, listeningPointTransport, listeningPointTransport); receiverProtocolObjects = new ProtocolObjects("forward-udp-receiver", "gov.nist", TRANSPORT_UDP, AUTODIALOG, null, listeningPointTransport, listeningPointTransport); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); sender.setRecordRoutingProxyTesting(true); SipProvider senderProvider = sender.createProvider(); - sender.setSendBye(false); - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); + sender.setSendBye(false); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); SipProvider receiverProvider = receiver.createProvider(); receiverProvider.addSipListener(receiver); @@ -319,6 +369,13 @@ public void testCallForwardingCallerSendByeOrphan2() throws Exception { senderProtocolObjects.start(); receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(senderPort)); + params.put( "receiverPort", String.valueOf(receiverPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", params, null); String fromName = "proxy-orphan"; String fromSipAddress = "sip-servlets.com"; @@ -362,11 +419,13 @@ public void testTCPCallForwardingCalleeSendByeTCPSender() throws Exception { "gov.nist", TRANSPORT_TCP, AUTODIALOG, null, listeningPointTransport, listeningPointTransport); receiverProtocolObjects = new ProtocolObjects("forward-tcp-receiver", "gov.nist", TRANSPORT_TCP, AUTODIALOG, null, listeningPointTransport, listeningPointTransport); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); sender.setRecordRoutingProxyTesting(true); SipProvider senderProvider = sender.createProvider(); - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); // receiver.setTransport(false); SipProvider receiverProvider = receiver.createProvider(); @@ -375,6 +434,13 @@ public void testTCPCallForwardingCalleeSendByeTCPSender() throws Exception { senderProtocolObjects.start(); receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(senderPort)); + params.put( "receiverPort", String.valueOf(receiverPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", params, null); String fromName = "proxy-tcp"; String fromSipAddress = "sip-servlets.com"; @@ -402,10 +468,13 @@ public void testCallForwardingCalleeSendBye() throws Exception { "gov.nist", TRANSPORT_UDP, AUTODIALOG, null, listeningPointTransport, listeningPointTransport); receiverProtocolObjects = new ProtocolObjects("forward-tcp-receiver", "gov.nist", TRANSPORT_TCP, AUTODIALOG, null, listeningPointTransport, listeningPointTransport); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); sender.setRecordRoutingProxyTesting(true); - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); SipProvider receiverProvider = receiver.createProvider(); receiverProvider.addSipListener(receiver); @@ -413,6 +482,13 @@ public void testCallForwardingCalleeSendBye() throws Exception { senderProtocolObjects.start(); receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(senderPort)); + params.put( "receiverPort", String.valueOf(receiverPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", params, null); String fromName = "proxy-tcp"; String fromSipAddress = "sip-servlets.com"; diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/SequentialProxyTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/SequentialProxyTest.java index 0085ee0ee4..b602977806 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/SequentialProxyTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/SequentialProxyTest.java @@ -22,6 +22,9 @@ package org.mobicents.servlet.sip.testsuite.proxy; +import java.util.HashMap; +import java.util.Map; +import org.mobicents.servlet.sip.NetworkPortAssigner; import org.mobicents.servlet.sip.SipServletTestCase; import org.mobicents.servlet.sip.catalina.SipStandardService; @@ -39,15 +42,29 @@ public SequentialProxyTest(String name) { super(name); this.sipIpAddress="0.0.0.0"; + autoDeployOnStartup = false; } @Override public void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); super.setUp(); - this.shootist = new Shootist(false, null); + int shootistPort = NetworkPortAssigner.retrieveNextPort(); + this.shootist = new Shootist(false, shootistPort, String.valueOf(containerPort)); shootist.setOutboundProxy(false); - this.shootme = new Shootme(5057); - this.cutme = new Cutme(); + int shootmePort = NetworkPortAssigner.retrieveNextPort(); + this.shootme = new Shootme(shootmePort); + int cutmePort = NetworkPortAssigner.retrieveNextPort(); + this.cutme = new Cutme(cutmePort); + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(shootistPort)); + params.put( "receiverPort", String.valueOf(shootmePort)); + params.put( "cutmePort", String.valueOf(cutmePort)); + sipService = tomcat.getSipService(); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + params, null); } public void testTreePhonesSecondAnswer() { @@ -161,7 +178,7 @@ public void testFirstTargetResponds() { // Test for http://code.google.com/p/mobicents/issues/detail?id=2740 public void testOutboundProxySetting() { - sipService.setOutboundProxy("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5057"); + sipService.setOutboundProxy("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + shootme.getMyPort()); this.shootme.init("stackName", null); this.cutme.init(null); this.shootist.init("sequential-reverse", false, null); @@ -253,14 +270,14 @@ public void tearDown() throws Exception { } SipStandardService sipService; + @Override public void deployApplication() { sipService = tomcat.getSipService(); - assertTrue(tomcat - .deployContext( - projectHome - + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); + ctx = tomcat.deployAppContext( + projectHome + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + "sip-test-context", "sip-test"); + assertTrue(ctx.getAvailable()); } @Override diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/Shootist.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/Shootist.java index d957ffd860..b8f42d7f16 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/Shootist.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/Shootist.java @@ -1,830 +1,833 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.proxy; -import gov.nist.javax.sip.ClientTransactionExt; -import gov.nist.javax.sip.ResponseEventExt; -import gov.nist.javax.sip.SipStackImpl; - -import java.text.ParseException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Properties; -import java.util.Random; -import java.util.Timer; -import java.util.TimerTask; - -import javax.sip.ClientTransaction; -import javax.sip.Dialog; -import javax.sip.DialogState; -import javax.sip.DialogTerminatedEvent; -import javax.sip.IOExceptionEvent; -import javax.sip.InvalidArgumentException; -import javax.sip.ListeningPoint; -import javax.sip.ObjectInUseException; -import javax.sip.PeerUnavailableException; -import javax.sip.RequestEvent; -import javax.sip.ResponseEvent; -import javax.sip.ServerTransaction; -import javax.sip.SipException; -import javax.sip.SipFactory; -import javax.sip.SipListener; -import javax.sip.SipProvider; -import javax.sip.SipStack; -import javax.sip.TransactionTerminatedEvent; -import javax.sip.address.Address; -import javax.sip.address.AddressFactory; -import javax.sip.address.SipURI; -import javax.sip.address.URI; -import javax.sip.header.CSeqHeader; -import javax.sip.header.CallIdHeader; -import javax.sip.header.ContactHeader; -import javax.sip.header.ContentTypeHeader; -import javax.sip.header.FromHeader; -import javax.sip.header.Header; -import javax.sip.header.HeaderFactory; -import javax.sip.header.MaxForwardsHeader; -import javax.sip.header.RecordRouteHeader; -import javax.sip.header.RequireHeader; -import javax.sip.header.RouteHeader; -import javax.sip.header.ToHeader; -import javax.sip.header.ViaHeader; -import javax.sip.message.MessageFactory; -import javax.sip.message.Request; -import javax.sip.message.Response; - -import org.apache.log4j.Logger; - - -public class Shootist implements SipListener { - private static transient Logger logger = Logger.getLogger(Shootist.class); - - private static SipProvider sipProvider; - - private static AddressFactory addressFactory; - - private static MessageFactory messageFactory; - - private static HeaderFactory headerFactory; - - private SipStack sipStack; - - private ContactHeader contactHeader; - - private ListeningPoint listeningPoint; - - private ClientTransaction inviteTid; - - private Dialog dialog; - - private boolean byeTaskRunning; - - public boolean ended = false; - - public boolean usePrack = false; - - public boolean prackOkReceived = false; - - public boolean okToInviteRecevied = false; - - public int pauseBeforeBye = 10000; - public int pauseBeforeAck = 0; - - int count = 0; - - private boolean forkingProxy = false; - - private boolean outboundProxy = true; - - public String requestMethod; - - public Request request; - - public Response lastResponse; - - private static final String TEXT_CONTENT_TYPE = "text"; - - private String lastMessageContent; - - private List allMessagesContent = new ArrayList(); - - private int numberOfTryingReceived = 0; - - private boolean sendCancelOn180; - - private String remotePort = "5070"; - - private String fromHost; - - // Save the created ACK request, to respond to retransmitted 2xx - private Request ackRequest; - - private boolean forkedResponseReceived; - - private boolean isRequestTerminatedReceived; - - public boolean moveRouteParamsToRequestURI; - - - class ByeTask extends TimerTask { - Dialog dialog; - public ByeTask(Dialog dialog) { - this.dialog = dialog; - } - public void run () { - try { - Request byeRequest = this.dialog.createRequest(Request.BYE); - if(moveRouteParamsToRequestURI) { - RouteHeader routeHeader = (RouteHeader) byeRequest.getHeader(RouteHeader.NAME); - SipURI sipURI = (SipURI) routeHeader.getAddress().getURI(); - Iterator parameterNames = sipURI.getParameterNames(); - while (parameterNames.hasNext()) { - String parameterName = parameterNames.next(); - if(!parameterName.equals("transport") && !parameterName.equals("lr")) { - ((SipURI)byeRequest.getRequestURI()).setParameter(parameterName, sipURI.getParameter(parameterName)); - sipURI.removeParameter(parameterName); - parameterNames = sipURI.getParameterNames(); - } - } - ((SipURI)byeRequest.getRequestURI()).setPort(Integer.parseInt(remotePort)); - } - System.out.println("Sending BYE " + byeRequest); - ClientTransaction ct = sipProvider.getNewClientTransaction(byeRequest); - dialog.sendRequest(ct); - } catch (Exception ex) { - ex.printStackTrace(); - } - - } - - } - - private static final String usageString = "java " - + "examples.shootist.Shootist \n" - + ">>>> is your class path set to the root?"; - - - public Shootist(boolean forkingProxy, String remotePort) { - this.forkingProxy = forkingProxy; - if(remotePort != null) { - this.remotePort = remotePort; - } - } - - - private static void usage() { - System.out.println(usageString); - } - - - public void processRequest(RequestEvent requestReceivedEvent) { - Request request = requestReceivedEvent.getRequest(); - ServerTransaction serverTransactionId = requestReceivedEvent - .getServerTransaction(); - - System.out.println("\n\nRequest " + request.getMethod() - + " received at " + sipStack.getStackName() - + " with server transaction id " + serverTransactionId); - - // We are the UAC so the only request we get is the BYE. - if (request.getMethod().equals(Request.BYE)) { - processBye(request, serverTransactionId); - } else if (request.getMethod().equals(Request.MESSAGE)) { - processMessage(request, serverTransactionId); - } - else { - try { - serverTransactionId.sendResponse( messageFactory.createResponse(202,request) ); - } catch (SipException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (InvalidArgumentException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (ParseException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - } - - private void processMessage(Request request, - ServerTransaction serverTransactionId) { - ServerTransaction serverTransaction = null; - - try { - serverTransaction = - (serverTransactionId == null? - sipProvider.getNewServerTransaction(request): - serverTransactionId); - } catch (javax.sip.TransactionAlreadyExistsException ex) { - ex.printStackTrace(); - return; - } catch (javax.sip.TransactionUnavailableException ex1) { - ex1.printStackTrace(); - return; - } - - ContentTypeHeader contentTypeHeader = (ContentTypeHeader) - request.getHeader(ContentTypeHeader.NAME); - if(contentTypeHeader != null) { - this.lastMessageContent = new String(request.getRawContent()); - allMessagesContent.add(new String(lastMessageContent)); - } - try { - Response okResponse = messageFactory.createResponse( - Response.OK, request); - ToHeader toHeader = (ToHeader) okResponse.getHeader(ToHeader.NAME); - if (toHeader.getTag() == null) { - toHeader.setTag(Integer.toString(new Random().nextInt(10000000))); - } -// okResponse.addHeader(contactHeader); - serverTransaction.sendResponse(okResponse); - } catch (Exception ex) { - ex.printStackTrace(); - logger.error("error sending OK response to message", ex); - } - } - - public void processBye(Request request, - ServerTransaction serverTransactionId) { - try { - System.out.println("shootist: got a bye ."); - ended = true; - if (serverTransactionId == null) { - System.out.println("shootist: null TID."); - return; - } - Dialog dialog = serverTransactionId.getDialog(); - System.out.println("Dialog State = " + dialog.getState()); - Response response = messageFactory.createResponse(200, request); - serverTransactionId.sendResponse(response); - System.out.println("shootist: Sending OK."); - System.out.println("Dialog State = " + dialog.getState()); - - } catch (Exception ex) { - ex.printStackTrace(); - } - } - - public void processResponse(ResponseEvent responseReceivedEvent) { - ResponseEventExt responseEventExt = (ResponseEventExt) responseReceivedEvent; - Response response = (Response) responseReceivedEvent.getResponse(); - ((SipStackImpl)sipStack).getStackLogger().logInfo("Got a response " + response); - if(responseEventExt.isForkedResponse()) { - forkedResponseReceived = true; - } - ClientTransaction clientTransaction = responseEventExt.getClientTransaction(); - final Dialog dialog = responseEventExt.getDialog(); - final boolean isForkedResponse = responseEventExt.isForkedResponse(); - final boolean isRetransmission = responseEventExt.isRetransmission(); - final ClientTransactionExt originalTransaction = responseEventExt.getOriginalTransaction(); - ((SipStackImpl)sipStack).getStackLogger().logInfo("is Forked Response " + isForkedResponse); - ((SipStackImpl)sipStack).getStackLogger().logInfo("is Retransmission " + isRetransmission); - ((SipStackImpl)sipStack).getStackLogger().logInfo("Client Transaction " + clientTransaction); - ((SipStackImpl)sipStack).getStackLogger().logInfo("Original Transaction " + originalTransaction); - ((SipStackImpl)sipStack).getStackLogger().logInfo("Dialog " + dialog); - this.lastResponse = response; - ClientTransaction tid = responseReceivedEvent.getClientTransaction(); - CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME); - - if(response.getStatusCode() == 100) { - numberOfTryingReceived++; - } - if (response.getStatusCode() == Response.REQUEST_TERMINATED) { - isRequestTerminatedReceived = true; - return; - } - - SipURI fromUri = (SipURI)((FromHeader)response.getHeader(FromHeader.NAME)).getAddress().getURI(); - RecordRouteHeader recordRouteHeader = (RecordRouteHeader)response.getHeader(RecordRouteHeader.NAME); - if(response.getStatusCode() > 100 && fromUri.getUser().equals("nonRecordRouting") && recordRouteHeader != null) { - logger.error("the proxy is non record routing and we received a record route header in the response !"); - return; - } - - if (tid == null) { - - // RFC3261: MUST respond to every 2xx - if (ackRequest!=null && dialog!=null) { - System.out.println("re-sending ACK"); - try { - dialog.sendAck(ackRequest); - } catch (SipException se) { - se.printStackTrace(); - } - } - return; - } - - // If the caller is supposed to send the bye -// if ( !byeTaskRunning && dialog != null) { -// if(!response.getHeader("From").toString().contains("sequential")) { -// byeTaskRunning = true; -// new Timer().schedule(new ByeTask(dialog), 4000) ; -// } -// } - System.out.println("transaction state is " + tid.getState()); - //System.out.println("Dialog = " + tid.getDialog()); - //System.out.println("Dialog State is " + tid.getDialog().getState()); - - try { - if (response.getStatusCode() == Response.OK) { - if (cseq.getMethod().equals(Request.INVITE)) { - okToInviteRecevied = true; - Thread.sleep(pauseBeforeAck); - ackRequest = dialog.createAck(cseq.getSeqNumber()); - if(forkingProxy) { - logger.info("dialog = " + dialog); - // Proxy will fork. I will accept the second dialog - // but not the first. - logger.info("count = " + count); -// if (count == 0) { - //assertTrue(dialog != this.dialog); - logger.info("Sending ACK"); - dialog.sendAck(ackRequest); - - if(!byeTaskRunning) { - try { - System.out.println("Waiting for " + pauseBeforeBye + " before sending BYE"); - Thread.sleep(pauseBeforeBye); - Request byeRequest = dialog.createRequest(Request.BYE); - ClientTransaction ct = sipProvider.getNewClientTransaction(byeRequest); - dialog.sendRequest(ct); - } catch (Exception ex) { - ex.printStackTrace(); - } - } -// } else { -// // Kill the first dialog by sending a bye. -// //assertTrue (dialog == this.dialog); -// count++; -// logger.info("count = " + count); -// dialog.sendAck(ackRequest); -// SipProvider sipProvider = (SipProvider) responseReceivedEvent.getSource(); -// Request byeRequest = dialog.createRequest(Request.BYE); -// ClientTransaction ct = sipProvider.getNewClientTransaction(byeRequest); -// dialog.sendRequest(ct); -// } - } else { - System.out.println("Dialog after 200 OK " + dialog); - System.out.println("Dialog State after 200 OK " + dialog.getState()); - System.out.println("Sending ACK"); - dialog.sendAck(ackRequest); - - if(!byeTaskRunning) { - try { - System.out.println("Waiting for " + pauseBeforeBye + " before sending BYE"); - Thread.sleep(pauseBeforeBye); - Request byeRequest = dialog.createRequest(Request.BYE); - ClientTransaction ct = sipProvider.getNewClientTransaction(byeRequest); - dialog.sendRequest(ct); - } catch (Exception ex) { - ex.printStackTrace(); - } - } - } - - } else if (cseq.getMethod().equals(Request.CANCEL)) { - if (dialog.getState() == DialogState.CONFIRMED) { - // oops cancel went in too late. Need to hang up the - // dialog. - System.out - .println("Sending BYE -- cancel went in too late !!"); - Request byeRequest = dialog.createRequest(Request.BYE); - ClientTransaction ct = sipProvider - .getNewClientTransaction(byeRequest); - dialog.sendRequest(ct); - } - - } else if(cseq.getMethod().equals(Request.BYE)) { - ended = true; - } else if(cseq.getMethod().equals(Request.PRACK)) { - prackOkReceived = true; - } - } else if(response.getStatusCode() == 180 && !((ResponseEventExt)responseReceivedEvent).isRetransmission()) { - if(usePrack) { - Request prackRequest = dialog.createPrack(response); - ClientTransaction ct = sipProvider.getNewClientTransaction(prackRequest); - dialog.sendRequest(ct); - } - if(sendCancelOn180) { - System.out.println("received 180 sending cancel"); - sendCancel(); - } - } - } catch (Exception ex) { - ex.printStackTrace(); - } - - } - - public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) { - - System.out.println("Transaction Time out"); - } - - public void sendCancel() { - try { - Request cancelRequest = inviteTid.createCancel(); - System.out.println("Sending cancel " + cancelRequest); - ClientTransaction cancelTid = sipProvider - .getNewClientTransaction(cancelRequest); - cancelTid.sendRequest(); - } catch (Exception ex) { - ex.printStackTrace(); - } - } - - public void init() { - init("BigGuy", false, null); - } - - public void init(String fromName, boolean useTelURL, String transport) { - if(transport == null) { - transport = ListeningPoint.UDP; - } - SipFactory sipFactory = null; - sipStack = null; - sipFactory = SipFactory.getInstance(); - sipFactory.setPathName("gov.nist"); - Properties properties = new Properties(); - String peerHostPort = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + remotePort; - if(outboundProxy) { - properties.setProperty("javax.sip.OUTBOUND_PROXY", peerHostPort + "/" - + transport); - } - // If you want to use UDP then uncomment this. - properties.setProperty("javax.sip.STACK_NAME", "shootist"); - - properties.setProperty("gov.nist.javax.sip.MAX_FORK_TIME_SECONDS", "10"); - properties.setProperty("gov.nist.javax.sip.THREAD_POOL_SIZE", "4"); - properties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", "true"); - - // The following properties are specific to nist-sip - // and are not necessarily part of any other jain-sip - // implementation. - // You can set a max message size for tcp transport to - // guard against denial of service attack. - properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", - "logs/shootistdebug.txt"); - properties.setProperty("gov.nist.javax.sip.SERVER_LOG", - "logs/shootistlog.xml"); - - // Drop the client connection after we are done with the transaction. - //properties.setProperty("gov.nist.javax.sip.CACHE_CLIENT_CONNECTIONS", - // "false"); - // Set to 0 (or NONE) in your production code for max speed. - // You need 16 (or TRACE) for logging traces. 32 (or DEBUG) for debug + traces. - // Your code will limp at 32 but it is best for debugging. - properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "DEBUG"); - - try { - // Create SipStack object - sipStack = sipFactory.createSipStack(properties); - System.out.println("createSipStack " + sipStack); - } catch (PeerUnavailableException e) { - // could not find - // gov.nist.jain.protocol.ip.sip.SipStackImpl - // in the classpath - e.printStackTrace(); - System.err.println(e.getMessage()); - } - - try { - headerFactory = sipFactory.createHeaderFactory(); - addressFactory = sipFactory.createAddressFactory(); - messageFactory = sipFactory.createMessageFactory(); - listeningPoint = sipStack.createListeningPoint("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", 5058, transport); - sipProvider = sipStack.createSipProvider(listeningPoint); - Shootist listener = this; - sipProvider.addSipListener(listener); - - String fromSipAddress = "here.com"; - if(fromHost != null) { - fromSipAddress = fromHost; - } - String fromDisplayName = "The Master Blaster"; - - String toSipAddress = "there.com"; - String toUser = "LittleGuy"; - String toDisplayName = "The Little Blister"; - - // create >From Header - SipURI fromAddress = addressFactory.createSipURI(fromName, - fromSipAddress); - - Address fromNameAddress = addressFactory.createAddress(fromAddress); - fromNameAddress.setDisplayName(fromDisplayName); - FromHeader fromHeader = headerFactory.createFromHeader( - fromNameAddress, "12345"); - - // create To Header - URI toAddress = null; - if(useTelURL) { - toAddress = addressFactory.createTelURL("+358-555-1234567"); - } else { - toAddress = addressFactory - .createSipURI(toUser, toSipAddress); - } - Address toNameAddress = addressFactory.createAddress(toAddress); - toNameAddress.setDisplayName(toDisplayName); - ToHeader toHeader = headerFactory.createToHeader(toNameAddress, - null); - - // create Request URI - SipURI requestURI = addressFactory.createSipURI(toUser, - peerHostPort); - - // Create ViaHeaders - - ArrayList viaHeaders = new ArrayList(); - String ipAddress = listeningPoint.getIPAddress(); - ViaHeader viaHeader = headerFactory.createViaHeader(ipAddress, - sipProvider.getListeningPoint(transport).getPort(), - transport, null); - - // add via headers - viaHeaders.add(viaHeader); - - // Create ContentTypeHeader - ContentTypeHeader contentTypeHeader = headerFactory - .createContentTypeHeader("application", "sdp"); - - // Create a new CallId header - CallIdHeader callIdHeader = sipProvider.getNewCallId(); - - // Create a new MaxForwardsHeader - MaxForwardsHeader maxForwards = headerFactory - .createMaxForwardsHeader(70); - - // Create the request. - if(requestMethod == null) requestMethod = Request.INVITE; - - // Create a new Cseq header - CSeqHeader cSeqHeader = headerFactory.createCSeqHeader(1L, - requestMethod); - - Request request = messageFactory.createRequest(requestURI, - requestMethod, callIdHeader, cSeqHeader, fromHeader, - toHeader, viaHeaders, maxForwards); - - if(requestMethod.equals(Request.PUBLISH)) { - request.setHeader(headerFactory.createEventHeader("presence")); - - } - // Create contact headers - String host = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; - - SipURI contactUrl = addressFactory.createSipURI(fromName, host); - contactUrl.setPort(listeningPoint.getPort()); - contactUrl.setLrParam(); - - // Create the contact name address. - SipURI contactURI = addressFactory.createSipURI(fromName, host); - contactURI.setPort(sipProvider.getListeningPoint(transport) - .getPort()); - - Address contactAddress = addressFactory.createAddress(contactURI); - - // Add the contact address. - contactAddress.setDisplayName(fromName); - - contactHeader = headerFactory.createContactHeader(contactAddress); - request.addHeader(contactHeader); - - // You can add extension headers of your own making - // to the outgoing SIP request. - // Add the extension header. - Header extensionHeader = headerFactory.createHeader("My-Header", - "my header value"); - request.addHeader(extensionHeader); - - String sdpData = "v=0\r\n" - + "o=4855 13760799956958020 13760799956958020" - + " IN IP4 129.6.55.78\r\n" + "s=mysession session\r\n" - + "p=+46 8 52018010\r\n" + "c=IN IP4 129.6.55.78\r\n" - + "t=0 0\r\n" + "m=audio 6022 RTP/AVP 0 4 18\r\n" - + "a=rtpmap:0 PCMU/8000\r\n" + "a=rtpmap:4 G723/8000\r\n" - + "a=rtpmap:18 G729A/8000\r\n" + "a=ptime:20\r\n"; - byte[] contents = sdpData.getBytes(); - - request.setContent(contents, contentTypeHeader); - // You can add as many extension headers as you - // want. - - extensionHeader = headerFactory.createHeader("My-Other-Header", - "my new header value "); - request.addHeader(extensionHeader); - - Header callInfoHeader = headerFactory.createHeader("Call-Info", - ""); - request.addHeader(callInfoHeader); - - if(usePrack) { - RequireHeader requireHeader = headerFactory - .createRequireHeader("100rel"); - request.addHeader(requireHeader); - } - Request subSeq = (Request) request.clone(); - this.request = request; - - // Create the client transaction. - inviteTid = sipProvider.getNewClientTransaction(request); - - // send the request out. - inviteTid.sendRequest(); - - dialog = inviteTid.getDialog(); - - if(!outboundProxy) { - Address address = addressFactory.createAddress("sip:" + peerHostPort); - RouteHeader routeHeader = headerFactory.createRouteHeader(address); - request.addHeader(routeHeader); - } - - - // Send a subsequent request after 2 secs - if(requestMethod.equals(Request.PUBLISH) || - requestMethod.equals(Request.SUBSCRIBE)) { - Thread.sleep(2000); - - CSeqHeader subSeqcSeqHeader = headerFactory.createCSeqHeader(2L, - requestMethod); - subSeq.setHeader(subSeqcSeqHeader); - subSeq.setHeader(lastResponse.getHeader(FromHeader.NAME)); - ClientTransaction subseqCt = sipProvider.getNewClientTransaction(subSeq); - subseqCt.sendRequest(); - } - - - - } catch (Exception ex) { - System.out.println(ex.getMessage()); - ex.printStackTrace(); - usage(); - } - } - - public void processIOException(IOExceptionEvent exceptionEvent) { - System.out.println("IOException happened for " - + exceptionEvent.getHost() + " port = " - + exceptionEvent.getPort()); - - } - - public void processTransactionTerminated( - TransactionTerminatedEvent transactionTerminatedEvent) { - System.out.println("Transaction terminated event recieved"); - } - - public void processDialogTerminated( - DialogTerminatedEvent dialogTerminatedEvent) { - System.out.println("dialogTerminatedEvent"); - - } - - public void destroy() { - logger.info("Destroying following sip stack " + sipStack.getStackName()); - HashSet hashSet = new HashSet(); - - for (SipProvider sipProvider : hashSet) { - hashSet.add(sipProvider); - } - - for (SipProvider sipProvider : hashSet) { - for (int j = 0; j < 5; j++) { - try { - sipStack.deleteSipProvider(sipProvider); - } catch (ObjectInUseException ex) { - try { - Thread.sleep(1000); - } catch (Exception e) { - } - - } - } - } - - sipStack.stop(); - } - - - /** - * @param outboundProxy the outboundProxy to set - */ - public void setOutboundProxy(boolean outboundProxy) { - this.outboundProxy = outboundProxy; - } - - - /** - * @return the outboundProxy - */ - public boolean isOutboundProxy() { - return outboundProxy; - } - - /** - * @return the lastMessageContent - */ - public String getLastMessageContent() { - return lastMessageContent; - } - - /** - * @return the allMessagesContent - */ - public List getAllMessagesContent() { - return allMessagesContent; - } - - /** - * @return the numberOfTryingReceived - */ - public int getNumberOfTryingReceived() { - return numberOfTryingReceived; - } - - - /** - * @param sendCancelOn180 the sendCancelOn180 to set - */ - public void setSendCancelOn180(boolean sendCancelOn180) { - this.sendCancelOn180 = sendCancelOn180; - } - - - /** - * @return the sendCancelOn180 - */ - public boolean isSendCancelOn180() { - return sendCancelOn180; - } - - - /** - * @param fromHost the fromHost to set - */ - public void setFromHost(String fromHost) { - this.fromHost = fromHost; - } - - - /** - * @return the fromHost - */ - public String getFromHost() { - return fromHost; - } - - - /** - * @param forkedResponseReceived the forkedResponseReceived to set - */ - public void setForkedResponseReceived(boolean forkedResponseReceived) { - this.forkedResponseReceived = forkedResponseReceived; - } - - - /** - * @return the forkedResponseReceived - */ - public boolean isForkedResponseReceived() { - return forkedResponseReceived; - } - - - /** - * @return the isRequestTerminatedReceived - */ - public boolean isRequestTerminatedReceived() { - return isRequestTerminatedReceived; - } - - public void stop() { - this.sipStack.stop(); - } -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite.proxy; +import gov.nist.javax.sip.ClientTransactionExt; +import gov.nist.javax.sip.ResponseEventExt; +import gov.nist.javax.sip.SipStackImpl; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; +import java.util.Random; +import java.util.Timer; +import java.util.TimerTask; + +import javax.sip.ClientTransaction; +import javax.sip.Dialog; +import javax.sip.DialogState; +import javax.sip.DialogTerminatedEvent; +import javax.sip.IOExceptionEvent; +import javax.sip.InvalidArgumentException; +import javax.sip.ListeningPoint; +import javax.sip.ObjectInUseException; +import javax.sip.PeerUnavailableException; +import javax.sip.RequestEvent; +import javax.sip.ResponseEvent; +import javax.sip.ServerTransaction; +import javax.sip.SipException; +import javax.sip.SipFactory; +import javax.sip.SipListener; +import javax.sip.SipProvider; +import javax.sip.SipStack; +import javax.sip.TransactionTerminatedEvent; +import javax.sip.address.Address; +import javax.sip.address.AddressFactory; +import javax.sip.address.SipURI; +import javax.sip.address.URI; +import javax.sip.header.CSeqHeader; +import javax.sip.header.CallIdHeader; +import javax.sip.header.ContactHeader; +import javax.sip.header.ContentTypeHeader; +import javax.sip.header.FromHeader; +import javax.sip.header.Header; +import javax.sip.header.HeaderFactory; +import javax.sip.header.MaxForwardsHeader; +import javax.sip.header.RecordRouteHeader; +import javax.sip.header.RequireHeader; +import javax.sip.header.RouteHeader; +import javax.sip.header.ToHeader; +import javax.sip.header.ViaHeader; +import javax.sip.message.MessageFactory; +import javax.sip.message.Request; +import javax.sip.message.Response; + +import org.apache.log4j.Logger; + + +public class Shootist implements SipListener { + private static transient Logger logger = Logger.getLogger(Shootist.class); + + private static SipProvider sipProvider; + + private static AddressFactory addressFactory; + + private static MessageFactory messageFactory; + + private static HeaderFactory headerFactory; + + private SipStack sipStack; + + private ContactHeader contactHeader; + + private ListeningPoint listeningPoint; + + private ClientTransaction inviteTid; + + private Dialog dialog; + + private boolean byeTaskRunning; + + public boolean ended = false; + + public boolean usePrack = false; + + public boolean prackOkReceived = false; + + public boolean okToInviteRecevied = false; + + public int pauseBeforeBye = 10000; + public int pauseBeforeAck = 0; + + int count = 0; + + private boolean forkingProxy = false; + + private boolean outboundProxy = true; + + public String requestMethod; + + public Request request; + + public Response lastResponse; + + private static final String TEXT_CONTENT_TYPE = "text"; + + private String lastMessageContent; + + private List allMessagesContent = new ArrayList(); + + private int numberOfTryingReceived = 0; + + private boolean sendCancelOn180; + + private String remotePort; + + private String fromHost; + + // Save the created ACK request, to respond to retransmitted 2xx + private Request ackRequest; + + private boolean forkedResponseReceived; + + private boolean isRequestTerminatedReceived; + + public boolean moveRouteParamsToRequestURI; + + int myPort = 5058; + + + class ByeTask extends TimerTask { + Dialog dialog; + public ByeTask(Dialog dialog) { + this.dialog = dialog; + } + public void run () { + try { + Request byeRequest = this.dialog.createRequest(Request.BYE); + if(moveRouteParamsToRequestURI) { + RouteHeader routeHeader = (RouteHeader) byeRequest.getHeader(RouteHeader.NAME); + SipURI sipURI = (SipURI) routeHeader.getAddress().getURI(); + Iterator parameterNames = sipURI.getParameterNames(); + while (parameterNames.hasNext()) { + String parameterName = parameterNames.next(); + if(!parameterName.equals("transport") && !parameterName.equals("lr")) { + ((SipURI)byeRequest.getRequestURI()).setParameter(parameterName, sipURI.getParameter(parameterName)); + sipURI.removeParameter(parameterName); + parameterNames = sipURI.getParameterNames(); + } + } + ((SipURI)byeRequest.getRequestURI()).setPort(Integer.parseInt(remotePort)); + } + System.out.println("Sending BYE " + byeRequest); + ClientTransaction ct = sipProvider.getNewClientTransaction(byeRequest); + dialog.sendRequest(ct); + } catch (Exception ex) { + ex.printStackTrace(); + } + + } + + } + + private static final String usageString = "java " + + "examples.shootist.Shootist \n" + + ">>>> is your class path set to the root?"; + + + public Shootist(boolean forkingProxy, int myPort, String remotePort) { + this.forkingProxy = forkingProxy; + if(remotePort != null) { + this.remotePort = remotePort; + } + this.myPort = myPort; + } + + + private static void usage() { + System.out.println(usageString); + } + + + public void processRequest(RequestEvent requestReceivedEvent) { + Request request = requestReceivedEvent.getRequest(); + ServerTransaction serverTransactionId = requestReceivedEvent + .getServerTransaction(); + + System.out.println("\n\nRequest " + request.getMethod() + + " received at " + sipStack.getStackName() + + " with server transaction id " + serverTransactionId); + + // We are the UAC so the only request we get is the BYE. + if (request.getMethod().equals(Request.BYE)) { + processBye(request, serverTransactionId); + } else if (request.getMethod().equals(Request.MESSAGE)) { + processMessage(request, serverTransactionId); + } + else { + try { + serverTransactionId.sendResponse( messageFactory.createResponse(202,request) ); + } catch (SipException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InvalidArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + } + + private void processMessage(Request request, + ServerTransaction serverTransactionId) { + ServerTransaction serverTransaction = null; + + try { + serverTransaction = + (serverTransactionId == null? + sipProvider.getNewServerTransaction(request): + serverTransactionId); + } catch (javax.sip.TransactionAlreadyExistsException ex) { + ex.printStackTrace(); + return; + } catch (javax.sip.TransactionUnavailableException ex1) { + ex1.printStackTrace(); + return; + } + + ContentTypeHeader contentTypeHeader = (ContentTypeHeader) + request.getHeader(ContentTypeHeader.NAME); + if(contentTypeHeader != null) { + this.lastMessageContent = new String(request.getRawContent()); + allMessagesContent.add(new String(lastMessageContent)); + } + try { + Response okResponse = messageFactory.createResponse( + Response.OK, request); + ToHeader toHeader = (ToHeader) okResponse.getHeader(ToHeader.NAME); + if (toHeader.getTag() == null) { + toHeader.setTag(Integer.toString(new Random().nextInt(10000000))); + } +// okResponse.addHeader(contactHeader); + serverTransaction.sendResponse(okResponse); + } catch (Exception ex) { + ex.printStackTrace(); + logger.error("error sending OK response to message", ex); + } + } + + public void processBye(Request request, + ServerTransaction serverTransactionId) { + try { + System.out.println("shootist: got a bye ."); + ended = true; + if (serverTransactionId == null) { + System.out.println("shootist: null TID."); + return; + } + Dialog dialog = serverTransactionId.getDialog(); + System.out.println("Dialog State = " + dialog.getState()); + Response response = messageFactory.createResponse(200, request); + serverTransactionId.sendResponse(response); + System.out.println("shootist: Sending OK."); + System.out.println("Dialog State = " + dialog.getState()); + + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + public void processResponse(ResponseEvent responseReceivedEvent) { + ResponseEventExt responseEventExt = (ResponseEventExt) responseReceivedEvent; + Response response = (Response) responseReceivedEvent.getResponse(); + ((SipStackImpl)sipStack).getStackLogger().logInfo("Got a response " + response); + if(responseEventExt.isForkedResponse()) { + forkedResponseReceived = true; + } + ClientTransaction clientTransaction = responseEventExt.getClientTransaction(); + final Dialog dialog = responseEventExt.getDialog(); + final boolean isForkedResponse = responseEventExt.isForkedResponse(); + final boolean isRetransmission = responseEventExt.isRetransmission(); + final ClientTransactionExt originalTransaction = responseEventExt.getOriginalTransaction(); + ((SipStackImpl)sipStack).getStackLogger().logInfo("is Forked Response " + isForkedResponse); + ((SipStackImpl)sipStack).getStackLogger().logInfo("is Retransmission " + isRetransmission); + ((SipStackImpl)sipStack).getStackLogger().logInfo("Client Transaction " + clientTransaction); + ((SipStackImpl)sipStack).getStackLogger().logInfo("Original Transaction " + originalTransaction); + ((SipStackImpl)sipStack).getStackLogger().logInfo("Dialog " + dialog); + this.lastResponse = response; + ClientTransaction tid = responseReceivedEvent.getClientTransaction(); + CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME); + + if(response.getStatusCode() == 100) { + numberOfTryingReceived++; + } + if (response.getStatusCode() == Response.REQUEST_TERMINATED) { + isRequestTerminatedReceived = true; + return; + } + + SipURI fromUri = (SipURI)((FromHeader)response.getHeader(FromHeader.NAME)).getAddress().getURI(); + RecordRouteHeader recordRouteHeader = (RecordRouteHeader)response.getHeader(RecordRouteHeader.NAME); + if(response.getStatusCode() > 100 && fromUri.getUser().equals("nonRecordRouting") && recordRouteHeader != null) { + logger.error("the proxy is non record routing and we received a record route header in the response !"); + return; + } + + if (tid == null) { + + // RFC3261: MUST respond to every 2xx + if (ackRequest!=null && dialog!=null) { + System.out.println("re-sending ACK"); + try { + dialog.sendAck(ackRequest); + } catch (SipException se) { + se.printStackTrace(); + } + } + return; + } + + // If the caller is supposed to send the bye +// if ( !byeTaskRunning && dialog != null) { +// if(!response.getHeader("From").toString().contains("sequential")) { +// byeTaskRunning = true; +// new Timer().schedule(new ByeTask(dialog), 4000) ; +// } +// } + System.out.println("transaction state is " + tid.getState()); + //System.out.println("Dialog = " + tid.getDialog()); + //System.out.println("Dialog State is " + tid.getDialog().getState()); + + try { + if (response.getStatusCode() == Response.OK) { + if (cseq.getMethod().equals(Request.INVITE)) { + okToInviteRecevied = true; + Thread.sleep(pauseBeforeAck); + ackRequest = dialog.createAck(cseq.getSeqNumber()); + if(forkingProxy) { + logger.info("dialog = " + dialog); + // Proxy will fork. I will accept the second dialog + // but not the first. + logger.info("count = " + count); +// if (count == 0) { + //assertTrue(dialog != this.dialog); + logger.info("Sending ACK"); + dialog.sendAck(ackRequest); + + if(!byeTaskRunning) { + try { + System.out.println("Waiting for " + pauseBeforeBye + " before sending BYE"); + Thread.sleep(pauseBeforeBye); + Request byeRequest = dialog.createRequest(Request.BYE); + ClientTransaction ct = sipProvider.getNewClientTransaction(byeRequest); + dialog.sendRequest(ct); + } catch (Exception ex) { + ex.printStackTrace(); + } + } +// } else { +// // Kill the first dialog by sending a bye. +// //assertTrue (dialog == this.dialog); +// count++; +// logger.info("count = " + count); +// dialog.sendAck(ackRequest); +// SipProvider sipProvider = (SipProvider) responseReceivedEvent.getSource(); +// Request byeRequest = dialog.createRequest(Request.BYE); +// ClientTransaction ct = sipProvider.getNewClientTransaction(byeRequest); +// dialog.sendRequest(ct); +// } + } else { + System.out.println("Dialog after 200 OK " + dialog); + System.out.println("Dialog State after 200 OK " + dialog.getState()); + System.out.println("Sending ACK"); + dialog.sendAck(ackRequest); + + if(!byeTaskRunning) { + try { + System.out.println("Waiting for " + pauseBeforeBye + " before sending BYE"); + Thread.sleep(pauseBeforeBye); + Request byeRequest = dialog.createRequest(Request.BYE); + ClientTransaction ct = sipProvider.getNewClientTransaction(byeRequest); + dialog.sendRequest(ct); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } + + } else if (cseq.getMethod().equals(Request.CANCEL)) { + if (dialog.getState() == DialogState.CONFIRMED) { + // oops cancel went in too late. Need to hang up the + // dialog. + System.out + .println("Sending BYE -- cancel went in too late !!"); + Request byeRequest = dialog.createRequest(Request.BYE); + ClientTransaction ct = sipProvider + .getNewClientTransaction(byeRequest); + dialog.sendRequest(ct); + } + + } else if(cseq.getMethod().equals(Request.BYE)) { + ended = true; + } else if(cseq.getMethod().equals(Request.PRACK)) { + prackOkReceived = true; + } + } else if(response.getStatusCode() == 180 && !((ResponseEventExt)responseReceivedEvent).isRetransmission()) { + if(usePrack) { + Request prackRequest = dialog.createPrack(response); + ClientTransaction ct = sipProvider.getNewClientTransaction(prackRequest); + dialog.sendRequest(ct); + } + if(sendCancelOn180) { + System.out.println("received 180 sending cancel"); + sendCancel(); + } + } + } catch (Exception ex) { + ex.printStackTrace(); + } + + } + + public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) { + + System.out.println("Transaction Time out"); + } + + public void sendCancel() { + try { + Request cancelRequest = inviteTid.createCancel(); + System.out.println("Sending cancel " + cancelRequest); + ClientTransaction cancelTid = sipProvider + .getNewClientTransaction(cancelRequest); + cancelTid.sendRequest(); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + public void init() { + init("BigGuy", false, null); + } + + public void init(String fromName, boolean useTelURL, String transport) { + if(transport == null) { + transport = ListeningPoint.UDP; + } + SipFactory sipFactory = null; + sipStack = null; + sipFactory = SipFactory.getInstance(); + sipFactory.setPathName("gov.nist"); + Properties properties = new Properties(); + String peerHostPort = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + remotePort; + if(outboundProxy) { + properties.setProperty("javax.sip.OUTBOUND_PROXY", peerHostPort + "/" + + transport); + } + // If you want to use UDP then uncomment this. + properties.setProperty("javax.sip.STACK_NAME", "shootist"); + + properties.setProperty("gov.nist.javax.sip.MAX_FORK_TIME_SECONDS", "10"); + properties.setProperty("gov.nist.javax.sip.THREAD_POOL_SIZE", "4"); + properties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", "true"); + + // The following properties are specific to nist-sip + // and are not necessarily part of any other jain-sip + // implementation. + // You can set a max message size for tcp transport to + // guard against denial of service attack. + properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", + "target/logs/shootistdebug.txt"); + properties.setProperty("gov.nist.javax.sip.SERVER_LOG", + "target/logs/shootistlog.xml"); + + // Drop the client connection after we are done with the transaction. + //properties.setProperty("gov.nist.javax.sip.CACHE_CLIENT_CONNECTIONS", + // "false"); + // Set to 0 (or NONE) in your production code for max speed. + // You need 16 (or TRACE) for logging traces. 32 (or DEBUG) for debug + traces. + // Your code will limp at 32 but it is best for debugging. + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "DEBUG"); + + try { + // Create SipStack object + sipStack = sipFactory.createSipStack(properties); + System.out.println("createSipStack " + sipStack); + } catch (PeerUnavailableException e) { + // could not find + // gov.nist.jain.protocol.ip.sip.SipStackImpl + // in the classpath + e.printStackTrace(); + System.err.println(e.getMessage()); + } + + try { + headerFactory = sipFactory.createHeaderFactory(); + addressFactory = sipFactory.createAddressFactory(); + messageFactory = sipFactory.createMessageFactory(); + listeningPoint = sipStack.createListeningPoint("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", myPort, transport); + sipProvider = sipStack.createSipProvider(listeningPoint); + Shootist listener = this; + sipProvider.addSipListener(listener); + + String fromSipAddress = "here.com"; + if(fromHost != null) { + fromSipAddress = fromHost; + } + String fromDisplayName = "The Master Blaster"; + + String toSipAddress = "there.com"; + String toUser = "LittleGuy"; + String toDisplayName = "The Little Blister"; + + // create >From Header + SipURI fromAddress = addressFactory.createSipURI(fromName, + fromSipAddress); + + Address fromNameAddress = addressFactory.createAddress(fromAddress); + fromNameAddress.setDisplayName(fromDisplayName); + FromHeader fromHeader = headerFactory.createFromHeader( + fromNameAddress, "12345"); + + // create To Header + URI toAddress = null; + if(useTelURL) { + toAddress = addressFactory.createTelURL("+358-555-1234567"); + } else { + toAddress = addressFactory + .createSipURI(toUser, toSipAddress); + } + Address toNameAddress = addressFactory.createAddress(toAddress); + toNameAddress.setDisplayName(toDisplayName); + ToHeader toHeader = headerFactory.createToHeader(toNameAddress, + null); + + // create Request URI + SipURI requestURI = addressFactory.createSipURI(toUser, + peerHostPort); + + // Create ViaHeaders + + ArrayList viaHeaders = new ArrayList(); + String ipAddress = listeningPoint.getIPAddress(); + ViaHeader viaHeader = headerFactory.createViaHeader(ipAddress, + sipProvider.getListeningPoint(transport).getPort(), + transport, null); + + // add via headers + viaHeaders.add(viaHeader); + + // Create ContentTypeHeader + ContentTypeHeader contentTypeHeader = headerFactory + .createContentTypeHeader("application", "sdp"); + + // Create a new CallId header + CallIdHeader callIdHeader = sipProvider.getNewCallId(); + + // Create a new MaxForwardsHeader + MaxForwardsHeader maxForwards = headerFactory + .createMaxForwardsHeader(70); + + // Create the request. + if(requestMethod == null) requestMethod = Request.INVITE; + + // Create a new Cseq header + CSeqHeader cSeqHeader = headerFactory.createCSeqHeader(1L, + requestMethod); + + Request request = messageFactory.createRequest(requestURI, + requestMethod, callIdHeader, cSeqHeader, fromHeader, + toHeader, viaHeaders, maxForwards); + + if(requestMethod.equals(Request.PUBLISH)) { + request.setHeader(headerFactory.createEventHeader("presence")); + + } + // Create contact headers + String host = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; + + SipURI contactUrl = addressFactory.createSipURI(fromName, host); + contactUrl.setPort(listeningPoint.getPort()); + contactUrl.setLrParam(); + + // Create the contact name address. + SipURI contactURI = addressFactory.createSipURI(fromName, host); + contactURI.setPort(sipProvider.getListeningPoint(transport) + .getPort()); + + Address contactAddress = addressFactory.createAddress(contactURI); + + // Add the contact address. + contactAddress.setDisplayName(fromName); + + contactHeader = headerFactory.createContactHeader(contactAddress); + request.addHeader(contactHeader); + + // You can add extension headers of your own making + // to the outgoing SIP request. + // Add the extension header. + Header extensionHeader = headerFactory.createHeader("My-Header", + "my header value"); + request.addHeader(extensionHeader); + + String sdpData = "v=0\r\n" + + "o=4855 13760799956958020 13760799956958020" + + " IN IP4 129.6.55.78\r\n" + "s=mysession session\r\n" + + "p=+46 8 52018010\r\n" + "c=IN IP4 129.6.55.78\r\n" + + "t=0 0\r\n" + "m=audio 6022 RTP/AVP 0 4 18\r\n" + + "a=rtpmap:0 PCMU/8000\r\n" + "a=rtpmap:4 G723/8000\r\n" + + "a=rtpmap:18 G729A/8000\r\n" + "a=ptime:20\r\n"; + byte[] contents = sdpData.getBytes(); + + request.setContent(contents, contentTypeHeader); + // You can add as many extension headers as you + // want. + + extensionHeader = headerFactory.createHeader("My-Other-Header", + "my new header value "); + request.addHeader(extensionHeader); + + Header callInfoHeader = headerFactory.createHeader("Call-Info", + ""); + request.addHeader(callInfoHeader); + + if(usePrack) { + RequireHeader requireHeader = headerFactory + .createRequireHeader("100rel"); + request.addHeader(requireHeader); + } + Request subSeq = (Request) request.clone(); + this.request = request; + + // Create the client transaction. + inviteTid = sipProvider.getNewClientTransaction(request); + + // send the request out. + inviteTid.sendRequest(); + + dialog = inviteTid.getDialog(); + + if(!outboundProxy) { + Address address = addressFactory.createAddress("sip:" + peerHostPort); + RouteHeader routeHeader = headerFactory.createRouteHeader(address); + request.addHeader(routeHeader); + } + + + // Send a subsequent request after 2 secs + if(requestMethod.equals(Request.PUBLISH) || + requestMethod.equals(Request.SUBSCRIBE)) { + Thread.sleep(2000); + + CSeqHeader subSeqcSeqHeader = headerFactory.createCSeqHeader(2L, + requestMethod); + subSeq.setHeader(subSeqcSeqHeader); + subSeq.setHeader(lastResponse.getHeader(FromHeader.NAME)); + ClientTransaction subseqCt = sipProvider.getNewClientTransaction(subSeq); + subseqCt.sendRequest(); + } + + + + } catch (Exception ex) { + System.out.println(ex.getMessage()); + ex.printStackTrace(); + usage(); + } + } + + public void processIOException(IOExceptionEvent exceptionEvent) { + System.out.println("IOException happened for " + + exceptionEvent.getHost() + " port = " + + exceptionEvent.getPort()); + + } + + public void processTransactionTerminated( + TransactionTerminatedEvent transactionTerminatedEvent) { + System.out.println("Transaction terminated event recieved"); + } + + public void processDialogTerminated( + DialogTerminatedEvent dialogTerminatedEvent) { + System.out.println("dialogTerminatedEvent"); + + } + + public void destroy() { + logger.info("Destroying following sip stack " + sipStack.getStackName()); + HashSet hashSet = new HashSet(); + + for (SipProvider sipProvider : hashSet) { + hashSet.add(sipProvider); + } + + for (SipProvider sipProvider : hashSet) { + for (int j = 0; j < 5; j++) { + try { + sipStack.deleteSipProvider(sipProvider); + } catch (ObjectInUseException ex) { + try { + Thread.sleep(1000); + } catch (Exception e) { + } + + } + } + } + + sipStack.stop(); + } + + + /** + * @param outboundProxy the outboundProxy to set + */ + public void setOutboundProxy(boolean outboundProxy) { + this.outboundProxy = outboundProxy; + } + + + /** + * @return the outboundProxy + */ + public boolean isOutboundProxy() { + return outboundProxy; + } + + /** + * @return the lastMessageContent + */ + public String getLastMessageContent() { + return lastMessageContent; + } + + /** + * @return the allMessagesContent + */ + public List getAllMessagesContent() { + return allMessagesContent; + } + + /** + * @return the numberOfTryingReceived + */ + public int getNumberOfTryingReceived() { + return numberOfTryingReceived; + } + + + /** + * @param sendCancelOn180 the sendCancelOn180 to set + */ + public void setSendCancelOn180(boolean sendCancelOn180) { + this.sendCancelOn180 = sendCancelOn180; + } + + + /** + * @return the sendCancelOn180 + */ + public boolean isSendCancelOn180() { + return sendCancelOn180; + } + + + /** + * @param fromHost the fromHost to set + */ + public void setFromHost(String fromHost) { + this.fromHost = fromHost; + } + + + /** + * @return the fromHost + */ + public String getFromHost() { + return fromHost; + } + + + /** + * @param forkedResponseReceived the forkedResponseReceived to set + */ + public void setForkedResponseReceived(boolean forkedResponseReceived) { + this.forkedResponseReceived = forkedResponseReceived; + } + + + /** + * @return the forkedResponseReceived + */ + public boolean isForkedResponseReceived() { + return forkedResponseReceived; + } + + + /** + * @return the isRequestTerminatedReceived + */ + public boolean isRequestTerminatedReceived() { + return isRequestTerminatedReceived; + } + + public void stop() { + this.sipStack.stop(); + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/Shootme.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/Shootme.java index 3afe4ed8cd..46c20e1b65 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/Shootme.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/Shootme.java @@ -1,553 +1,559 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.proxy; - -import java.text.ParseException; -import java.util.HashSet; -import java.util.Properties; -import java.util.Timer; -import java.util.TimerTask; - -import javax.sip.ClientTransaction; -import javax.sip.Dialog; -import javax.sip.DialogState; -import javax.sip.DialogTerminatedEvent; -import javax.sip.IOExceptionEvent; -import javax.sip.InvalidArgumentException; -import javax.sip.ListeningPoint; -import javax.sip.ObjectInUseException; -import javax.sip.PeerUnavailableException; -import javax.sip.RequestEvent; -import javax.sip.ResponseEvent; -import javax.sip.ServerTransaction; -import javax.sip.SipException; -import javax.sip.SipFactory; -import javax.sip.SipListener; -import javax.sip.SipProvider; -import javax.sip.SipStack; -import javax.sip.Transaction; -import javax.sip.TransactionState; -import javax.sip.TransactionTerminatedEvent; -import javax.sip.address.Address; -import javax.sip.address.AddressFactory; -import javax.sip.header.ContactHeader; -import javax.sip.header.HeaderFactory; -import javax.sip.header.ToHeader; -import javax.sip.message.MessageFactory; -import javax.sip.message.Request; -import javax.sip.message.Response; - -import org.apache.log4j.Logger; - -public class Shootme implements SipListener { - private static transient Logger logger = Logger.getLogger(Shootme.class); - private static AddressFactory addressFactory; - - private static MessageFactory messageFactory; - - private static HeaderFactory headerFactory; - - private static SipProvider sipProvider; - - private SipStack sipStack; - - private static final String myAddress = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; - - private int myPort = 5057; - private String toTag; - - protected ServerTransaction inviteTid; - - private Response okResponse; - - private Response ringingResponse; - - private Request inviteRequest; - - private Dialog dialog; - - public boolean ended = false; - - public boolean cancelled = false; - - public boolean usePrack = false; - - public int inviteResponseCode = 0; - - public static boolean callerSendsBye = true; - - private long timeToWaitBeforeAnswer = -1; - - String transport = "UDP"; - - class MyTimerTask extends TimerTask { - Shootme shootme; - - public MyTimerTask(Shootme shootme) { - this.shootme = shootme; - - } - - public void run() { - shootme.sendInviteOK(); - } - - } - - protected static final String usageString = "java " - + "examples.shootist.Shootist \n" - + ">>>> is your class path set to the root?"; - - public Shootme(int port) { - myPort = port; - } - - private static void usage() { - System.out.println(usageString); - System.exit(0); - - } - - public void processPublishSubscribe (RequestEvent requestEvent, - ServerTransaction serverTransaction) { - try { - this.okResponse = messageFactory.createResponse(Response.OK, - requestEvent.getRequest()); - this.okResponse.setHeader(headerFactory.createExpiresHeader(1000)); - if(serverTransaction == null) { - serverTransaction = sipProvider.getNewServerTransaction(requestEvent.getRequest()); - } - serverTransaction.sendResponse(this.okResponse); - - } catch (ParseException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (SipException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (InvalidArgumentException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - public void processRequest(RequestEvent requestEvent) { - Request request = requestEvent.getRequest(); - ServerTransaction serverTransactionId = requestEvent - .getServerTransaction(); - - System.out.println("\n\nRequest " + request.getMethod() - + " received at " + sipStack.getStackName() - + " with server transaction id " + serverTransactionId); - - if (request.getMethod().equals(Request.INVITE)) { - processInvite(requestEvent, serverTransactionId); - } else if (request.getMethod().equals(Request.ACK)) { - processAck(requestEvent, serverTransactionId); - } else if (request.getMethod().equals(Request.BYE)) { - processBye(requestEvent, serverTransactionId); - } else if (request.getMethod().equals(Request.CANCEL)) { - processCancel(requestEvent, serverTransactionId); - } else if (request.getMethod().equals(Request.PRACK)) { - processPrack(requestEvent, serverTransactionId); - } else if (request.getMethod().equals(Request.PUBLISH)){ - processPublishSubscribe(requestEvent, serverTransactionId); - } else if (request.getMethod().equals(Request.SUBSCRIBE)){ - processPublishSubscribe(requestEvent, serverTransactionId); - } else { - try { - serverTransactionId.sendResponse( messageFactory.createResponse( 202, request ) ); - - // send one back - SipProvider prov = (SipProvider) requestEvent.getSource(); - Request refer = requestEvent.getDialog().createRequest("REFER"); - requestEvent.getDialog().sendRequest( prov.getNewClientTransaction(refer) ); - - } catch (SipException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (InvalidArgumentException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (ParseException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - } - - public void processResponse(ResponseEvent responseEvent) { - } - - public int retrans = -1; - public boolean scrambleResponses = false; - public int waitFinalResponse =1000; - /** - * Process the ACK request. Send the bye and complete the call flow. - */ - public void processAck(RequestEvent requestEvent, - ServerTransaction serverTransaction) { - try { - if(retrans >= 0 && retrans <4) { - new Timer().scheduleAtFixedRate(new TimerTask(){ - public void run() { - if(retrans >= 0 && retrans <4) { - retrans ++; - try { - sipProvider.sendResponse(okResponse); - if(scrambleResponses) { - sipProvider.sendResponse(ringingResponse); - } - } catch (Exception e) { - e.printStackTrace(); - System.exit(0); - } - } - } - }, 0, 1000); - - } else { - System.out.println("shootme: got an ACK! "); - System.out.println("Dialog State = " + dialog.getState()); - SipProvider provider = (SipProvider) requestEvent.getSource(); - if (!callerSendsBye) { - Request byeRequest = dialog.createRequest(Request.BYE); - ClientTransaction ct = provider - .getNewClientTransaction(byeRequest); - dialog.sendRequest(ct); - } - } - } catch (Exception ex) { - ex.printStackTrace(); - } - - } - - /** - * Process the invite request. - */ - public void processInvite(RequestEvent requestEvent, - ServerTransaction serverTransaction) { - SipProvider sipProvider = (SipProvider) requestEvent.getSource(); - Request request = requestEvent.getRequest(); - try { - System.out.println("shootme: got an Invite sending Trying"); - // System.out.println("shootme: " + request); - Response response = null; - - if(serverTransaction == null) { - serverTransaction = sipProvider.getNewServerTransaction(request); - } - if(!usePrack) response = messageFactory.createResponse(Response.RINGING, - request); - else response = serverTransaction.getDialog().createReliableProvisionalResponse(180); - - ringingResponse = response; - String toTag = Integer.toString((int) (Math.random()*10000000)); - ToHeader toHeader = (ToHeader) response.getHeader(ToHeader.NAME); - toHeader.setTag(toTag); // Application is supposed to set. - this.toTag = toTag; - - dialog = serverTransaction.getDialog(); - - if(timeToWaitBeforeAnswer > 0) { - Thread.sleep(timeToWaitBeforeAnswer); - } - - if(!usePrack) - serverTransaction.sendResponse(response); - else - dialog.sendReliableProvisionalResponse(response); - - this.okResponse = messageFactory.createResponse(Response.OK, - request); - Address address = addressFactory.createAddress("Shootme "); - ContactHeader contactHeader = headerFactory - .createContactHeader(address); - response.addHeader(contactHeader); - toHeader = (ToHeader) okResponse.getHeader(ToHeader.NAME); - toHeader.setTag(toTag); // Application is supposed to set. - okResponse.addHeader(contactHeader); - this.inviteTid = serverTransaction; - // Defer sending the OK to simulate the phone ringing. - // Answered in 1 second ( this guy is fast at taking calls) - this.inviteRequest = request; - - if(!usePrack) { - if(inviteResponseCode == 0) { - new Timer().schedule(new MyTimerTask(this), waitFinalResponse); - } else { - Response customResp = messageFactory.createResponse(inviteResponseCode, - request); - serverTransaction.sendResponse(customResp); - } - } - } catch (Exception ex) { - ex.printStackTrace(); - System.exit(0); - } - } - - private void sendInviteOK() { - try { - if (inviteTid.getState() != TransactionState.COMPLETED) { - System.out.println("shootme: Dialog state before 200: " - + inviteTid.getDialog().getState()); - inviteTid.sendResponse(okResponse); - System.out.println("shootme: Dialog state after 200: " - + inviteTid.getDialog().getState()); - } - } catch (SipException ex) { - ex.printStackTrace(); - } catch (InvalidArgumentException ex) { - ex.printStackTrace(); - } - } - - /** - * Process the bye request. - */ - public void processBye(RequestEvent requestEvent, - ServerTransaction serverTransactionId) { - ended = true; - Request request = requestEvent.getRequest(); - Dialog dialog = requestEvent.getDialog(); - System.out.println("local party = " + dialog.getLocalParty()); - try { - System.out.println("shootme: got a bye sending OK."); - Response response = messageFactory.createResponse(200, request); - serverTransactionId.sendResponse(response); - System.out.println("Dialog State is " - + serverTransactionId.getDialog().getState()); - - } catch (Exception ex) { - ex.printStackTrace(); - System.exit(0); - - } - } - - public void processCancel(RequestEvent requestEvent, - ServerTransaction serverTransactionId) { - Request request = requestEvent.getRequest(); - try { - System.out.println("shootme: got a cancel."); - cancelled = true; - if (serverTransactionId == null) { - System.out.println("shootme: null tid."); - return; - } - Response response = messageFactory.createResponse(487, request); - serverTransactionId.sendResponse(response); - if (dialog.getState() != DialogState.CONFIRMED) { - response = messageFactory.createResponse( - Response.REQUEST_TERMINATED, inviteRequest); - inviteTid.sendResponse(response); - } - - } catch (Exception ex) { - ex.printStackTrace(); - System.exit(0); - - } - } - - public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) { - Transaction transaction; - if (timeoutEvent.isServerTransaction()) { - transaction = timeoutEvent.getServerTransaction(); - } else { - transaction = timeoutEvent.getClientTransaction(); - } - System.out.println("state = " + transaction.getState()); - System.out.println("dialog = " + transaction.getDialog()); - System.out.println("dialogState = " - + transaction.getDialog().getState()); - System.out.println("Transaction Time out"); - } - - public void init(String stackName, String transport) { - if(transport == null) { - transport = ListeningPoint.UDP; - } - this.transport = transport; - SipFactory sipFactory = null; - sipStack = null; - sipFactory = SipFactory.getInstance(); - sipFactory.setPathName("gov.nist"); - Properties properties = new Properties(); - properties.setProperty("javax.sip.STACK_NAME", stackName); - // You need 16 for logging traces. 32 for debug + traces. - // Your code will limp at 32 but it is best for debugging. - properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "32"); - properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", - "logs/debug"+stackName+".txt"); - properties.setProperty("gov.nist.javax.sip.SERVER_LOG", - "logs/" + stackName + ".xml"); - - try { - // Create SipStack object - sipStack = sipFactory.createSipStack(properties); - System.out.println("sipStack = " + sipStack); - } catch (PeerUnavailableException e) { - // could not find - // gov.nist.jain.protocol.ip.sip.SipStackImpl - // in the classpath - e.printStackTrace(); - System.err.println(e.getMessage()); - if (e.getCause() != null) - e.getCause().printStackTrace(); - System.exit(0); - } - - try { - headerFactory = sipFactory.createHeaderFactory(); - addressFactory = sipFactory.createAddressFactory(); - messageFactory = sipFactory.createMessageFactory(); - ListeningPoint lp = sipStack.createListeningPoint("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", - myPort, transport); - - Shootme listener = this; - - sipProvider = sipStack.createSipProvider(lp); - System.out.println("udp provider " + sipProvider); - sipProvider.addSipListener(listener); - - } catch (Exception ex) { - System.out.println(ex.getMessage()); - ex.printStackTrace(); - usage(); - } - - } - - public void processIOException(IOExceptionEvent exceptionEvent) { - System.out.println("IOException"); - - } - - public void processTransactionTerminated( - TransactionTerminatedEvent transactionTerminatedEvent) { - if (transactionTerminatedEvent.isServerTransaction()) - System.out.println("Transaction terminated event recieved" - + transactionTerminatedEvent.getServerTransaction()); - else - System.out.println("Transaction terminated " - + transactionTerminatedEvent.getClientTransaction()); - - } - - public void processDialogTerminated( - DialogTerminatedEvent dialogTerminatedEvent) { - System.out.println("Dialog terminated event recieved"); - Dialog d = dialogTerminatedEvent.getDialog(); - System.out.println("Local Party = " + d.getLocalParty()); - - } - - public void destroy() { - logger.info("Destroying following sip stack " + sipStack.getStackName()); - HashSet hashSet = new HashSet(); - - for (SipProvider sipProvider : hashSet) { - hashSet.add(sipProvider); - } - try { - for (SipProvider sipProvider : hashSet) { - for (int j = 0; j < 5; j++) { - try { - sipStack.deleteSipProvider(sipProvider); - } catch (ObjectInUseException ex) { - try { - Thread.sleep(1000); - } catch (Exception e) { - } - - } - } - } - - sipStack.stop(); - } catch (Throwable e) { - e.printStackTrace(); - } - } - - private void processPrack(RequestEvent requestEvent, - ServerTransaction serverTransactionId) { - try { - System.out.println("shootme: got an PRACK! "); - System.out.println("Dialog State = " + dialog.getState()); - - /** - * JvB: First, send 200 OK for PRACK - */ - Request prack = requestEvent.getRequest(); - Response prackOk = messageFactory.createResponse( 200, prack ); - serverTransactionId.sendResponse( prackOk ); - - /** - * Send a 200 OK response to complete the 3 way handshake for the - * INIVTE. - */ - Response response = messageFactory.createResponse(200, - inviteRequest); - ToHeader to = (ToHeader) response.getHeader(ToHeader.NAME); - to.setTag(this.toTag); - Address address = addressFactory.createAddress("sip:" - + myAddress + ":" + myPort + ";transport=" + transport); - ContactHeader contactHeader = headerFactory - .createContactHeader(address); - response.addHeader(contactHeader); - inviteTid.sendResponse(response); - } catch (Exception ex) { - ex.printStackTrace(); - - } - - } - - public void setTimeToWaitBeforeAnswer(long timeToWaitBeforeAnswer) { - this.timeToWaitBeforeAnswer = timeToWaitBeforeAnswer; - } - - public long getTimeToWaitBeforeAnswer() { - return timeToWaitBeforeAnswer; - } - - /** - * @return the inviteRequest - */ - public Request getInviteRequest() { - return inviteRequest; - } - - /** - * @param inviteRequest the inviteRequest to set - */ - public void setInviteRequest(Request inviteRequest) { - this.inviteRequest = inviteRequest; - } -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite.proxy; + +import java.text.ParseException; +import java.util.HashSet; +import java.util.Properties; +import java.util.Timer; +import java.util.TimerTask; + +import javax.sip.ClientTransaction; +import javax.sip.Dialog; +import javax.sip.DialogState; +import javax.sip.DialogTerminatedEvent; +import javax.sip.IOExceptionEvent; +import javax.sip.InvalidArgumentException; +import javax.sip.ListeningPoint; +import javax.sip.ObjectInUseException; +import javax.sip.PeerUnavailableException; +import javax.sip.RequestEvent; +import javax.sip.ResponseEvent; +import javax.sip.ServerTransaction; +import javax.sip.SipException; +import javax.sip.SipFactory; +import javax.sip.SipListener; +import javax.sip.SipProvider; +import javax.sip.SipStack; +import javax.sip.Transaction; +import javax.sip.TransactionState; +import javax.sip.TransactionTerminatedEvent; +import javax.sip.address.Address; +import javax.sip.address.AddressFactory; +import javax.sip.header.ContactHeader; +import javax.sip.header.HeaderFactory; +import javax.sip.header.ToHeader; +import javax.sip.message.MessageFactory; +import javax.sip.message.Request; +import javax.sip.message.Response; + +import org.apache.log4j.Logger; + +public class Shootme implements SipListener { + private static transient Logger logger = Logger.getLogger(Shootme.class); + private static AddressFactory addressFactory; + + private static MessageFactory messageFactory; + + private static HeaderFactory headerFactory; + + private static SipProvider sipProvider; + + private SipStack sipStack; + + private static final String myAddress = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; + + private int myPort = 5057; + private String toTag; + + protected ServerTransaction inviteTid; + + private Response okResponse; + + private Response ringingResponse; + + private Request inviteRequest; + + private Dialog dialog; + + public boolean ended = false; + + public boolean cancelled = false; + + public boolean usePrack = false; + + public int inviteResponseCode = 0; + + public static boolean callerSendsBye = true; + + private long timeToWaitBeforeAnswer = -1; + + String transport = "UDP"; + + class MyTimerTask extends TimerTask { + Shootme shootme; + + public MyTimerTask(Shootme shootme) { + this.shootme = shootme; + + } + + public void run() { + shootme.sendInviteOK(); + } + + } + + protected static final String usageString = "java " + + "examples.shootist.Shootist \n" + + ">>>> is your class path set to the root?"; + + public Shootme(int port) { + myPort = port; + } + + private static void usage() { + System.out.println(usageString); + System.exit(0); + + } + + public void processPublishSubscribe (RequestEvent requestEvent, + ServerTransaction serverTransaction) { + try { + this.okResponse = messageFactory.createResponse(Response.OK, + requestEvent.getRequest()); + this.okResponse.setHeader(headerFactory.createExpiresHeader(1000)); + if(serverTransaction == null) { + serverTransaction = sipProvider.getNewServerTransaction(requestEvent.getRequest()); + } + serverTransaction.sendResponse(this.okResponse); + + } catch (ParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (SipException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InvalidArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + public void processRequest(RequestEvent requestEvent) { + Request request = requestEvent.getRequest(); + ServerTransaction serverTransactionId = requestEvent + .getServerTransaction(); + + System.out.println("\n\nRequest " + request.getMethod() + + " received at " + sipStack.getStackName() + + " with server transaction id " + serverTransactionId); + + if (request.getMethod().equals(Request.INVITE)) { + processInvite(requestEvent, serverTransactionId); + } else if (request.getMethod().equals(Request.ACK)) { + processAck(requestEvent, serverTransactionId); + } else if (request.getMethod().equals(Request.BYE)) { + processBye(requestEvent, serverTransactionId); + } else if (request.getMethod().equals(Request.CANCEL)) { + processCancel(requestEvent, serverTransactionId); + } else if (request.getMethod().equals(Request.PRACK)) { + processPrack(requestEvent, serverTransactionId); + } else if (request.getMethod().equals(Request.PUBLISH)){ + processPublishSubscribe(requestEvent, serverTransactionId); + } else if (request.getMethod().equals(Request.SUBSCRIBE)){ + processPublishSubscribe(requestEvent, serverTransactionId); + } else { + try { + serverTransactionId.sendResponse( messageFactory.createResponse( 202, request ) ); + + // send one back + SipProvider prov = (SipProvider) requestEvent.getSource(); + Request refer = requestEvent.getDialog().createRequest("REFER"); + requestEvent.getDialog().sendRequest( prov.getNewClientTransaction(refer) ); + + } catch (SipException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InvalidArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + } + + public void processResponse(ResponseEvent responseEvent) { + } + + public int retrans = -1; + public boolean scrambleResponses = false; + public int waitFinalResponse =1000; + /** + * Process the ACK request. Send the bye and complete the call flow. + */ + public void processAck(RequestEvent requestEvent, + ServerTransaction serverTransaction) { + try { + if(retrans >= 0 && retrans <4) { + new Timer().scheduleAtFixedRate(new TimerTask(){ + public void run() { + if(retrans >= 0 && retrans <4) { + retrans ++; + try { + sipProvider.sendResponse(okResponse); + if(scrambleResponses) { + sipProvider.sendResponse(ringingResponse); + } + } catch (Exception e) { + e.printStackTrace(); + System.exit(0); + } + } + } + }, 0, 1000); + + } else { + System.out.println("shootme: got an ACK! "); + System.out.println("Dialog State = " + dialog.getState()); + SipProvider provider = (SipProvider) requestEvent.getSource(); + if (!callerSendsBye) { + Request byeRequest = dialog.createRequest(Request.BYE); + ClientTransaction ct = provider + .getNewClientTransaction(byeRequest); + dialog.sendRequest(ct); + } + } + } catch (Exception ex) { + ex.printStackTrace(); + } + + } + + /** + * Process the invite request. + */ + public void processInvite(RequestEvent requestEvent, + ServerTransaction serverTransaction) { + SipProvider sipProvider = (SipProvider) requestEvent.getSource(); + Request request = requestEvent.getRequest(); + try { + System.out.println("shootme: got an Invite sending Trying"); + // System.out.println("shootme: " + request); + Response response = null; + + if(serverTransaction == null) { + serverTransaction = sipProvider.getNewServerTransaction(request); + } + if(!usePrack) response = messageFactory.createResponse(Response.RINGING, + request); + else response = serverTransaction.getDialog().createReliableProvisionalResponse(180); + + ringingResponse = response; + String toTag = Integer.toString((int) (Math.random()*10000000)); + ToHeader toHeader = (ToHeader) response.getHeader(ToHeader.NAME); + toHeader.setTag(toTag); // Application is supposed to set. + this.toTag = toTag; + + dialog = serverTransaction.getDialog(); + + if(timeToWaitBeforeAnswer > 0) { + Thread.sleep(timeToWaitBeforeAnswer); + } + + if(!usePrack) + serverTransaction.sendResponse(response); + else + dialog.sendReliableProvisionalResponse(response); + + this.okResponse = messageFactory.createResponse(Response.OK, + request); + Address address = addressFactory.createAddress("Shootme "); + ContactHeader contactHeader = headerFactory + .createContactHeader(address); + response.addHeader(contactHeader); + toHeader = (ToHeader) okResponse.getHeader(ToHeader.NAME); + toHeader.setTag(toTag); // Application is supposed to set. + okResponse.addHeader(contactHeader); + this.inviteTid = serverTransaction; + // Defer sending the OK to simulate the phone ringing. + // Answered in 1 second ( this guy is fast at taking calls) + this.inviteRequest = request; + + if(!usePrack) { + if(inviteResponseCode == 0) { + new Timer().schedule(new MyTimerTask(this), waitFinalResponse); + } else { + Response customResp = messageFactory.createResponse(inviteResponseCode, + request); + serverTransaction.sendResponse(customResp); + } + } + } catch (Exception ex) { + ex.printStackTrace(); + System.exit(0); + } + } + + private void sendInviteOK() { + try { + if (inviteTid.getState() != TransactionState.COMPLETED) { + System.out.println("shootme: Dialog state before 200: " + + inviteTid.getDialog().getState()); + inviteTid.sendResponse(okResponse); + System.out.println("shootme: Dialog state after 200: " + + inviteTid.getDialog().getState()); + } + } catch (SipException ex) { + ex.printStackTrace(); + } catch (InvalidArgumentException ex) { + ex.printStackTrace(); + } + } + + /** + * Process the bye request. + */ + public void processBye(RequestEvent requestEvent, + ServerTransaction serverTransactionId) { + ended = true; + Request request = requestEvent.getRequest(); + Dialog dialog = requestEvent.getDialog(); + System.out.println("local party = " + dialog.getLocalParty()); + try { + System.out.println("shootme: got a bye sending OK."); + Response response = messageFactory.createResponse(200, request); + serverTransactionId.sendResponse(response); + System.out.println("Dialog State is " + + serverTransactionId.getDialog().getState()); + + } catch (Exception ex) { + ex.printStackTrace(); + System.exit(0); + + } + } + + public void processCancel(RequestEvent requestEvent, + ServerTransaction serverTransactionId) { + Request request = requestEvent.getRequest(); + try { + System.out.println("shootme: got a cancel."); + cancelled = true; + if (serverTransactionId == null) { + System.out.println("shootme: null tid."); + return; + } + Response response = messageFactory.createResponse(487, request); + serverTransactionId.sendResponse(response); + if (dialog.getState() != DialogState.CONFIRMED) { + response = messageFactory.createResponse( + Response.REQUEST_TERMINATED, inviteRequest); + inviteTid.sendResponse(response); + } + + } catch (Exception ex) { + ex.printStackTrace(); + System.exit(0); + + } + } + + public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) { + Transaction transaction; + if (timeoutEvent.isServerTransaction()) { + transaction = timeoutEvent.getServerTransaction(); + } else { + transaction = timeoutEvent.getClientTransaction(); + } + System.out.println("state = " + transaction.getState()); + System.out.println("dialog = " + transaction.getDialog()); + System.out.println("dialogState = " + + transaction.getDialog().getState()); + System.out.println("Transaction Time out"); + } + + public void init(String stackName, String transport) { + if(transport == null) { + transport = ListeningPoint.UDP; + } + this.transport = transport; + SipFactory sipFactory = null; + sipStack = null; + sipFactory = SipFactory.getInstance(); + sipFactory.setPathName("gov.nist"); + Properties properties = new Properties(); + properties.setProperty("javax.sip.STACK_NAME", stackName); + // You need 16 for logging traces. 32 for debug + traces. + // Your code will limp at 32 but it is best for debugging. + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "32"); + properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", + "target/logs/debug"+stackName+".txt"); + properties.setProperty("gov.nist.javax.sip.SERVER_LOG", + "target/logs/" + stackName + ".xml"); + + try { + // Create SipStack object + sipStack = sipFactory.createSipStack(properties); + System.out.println("sipStack = " + sipStack); + } catch (PeerUnavailableException e) { + // could not find + // gov.nist.jain.protocol.ip.sip.SipStackImpl + // in the classpath + e.printStackTrace(); + System.err.println(e.getMessage()); + if (e.getCause() != null) + e.getCause().printStackTrace(); + System.exit(0); + } + + try { + headerFactory = sipFactory.createHeaderFactory(); + addressFactory = sipFactory.createAddressFactory(); + messageFactory = sipFactory.createMessageFactory(); + ListeningPoint lp = sipStack.createListeningPoint("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", + myPort, transport); + + Shootme listener = this; + + sipProvider = sipStack.createSipProvider(lp); + System.out.println("udp provider " + sipProvider); + sipProvider.addSipListener(listener); + + } catch (Exception ex) { + System.out.println(ex.getMessage()); + ex.printStackTrace(); + usage(); + } + + } + + public void processIOException(IOExceptionEvent exceptionEvent) { + System.out.println("IOException"); + + } + + public void processTransactionTerminated( + TransactionTerminatedEvent transactionTerminatedEvent) { + if (transactionTerminatedEvent.isServerTransaction()) + System.out.println("Transaction terminated event recieved" + + transactionTerminatedEvent.getServerTransaction()); + else + System.out.println("Transaction terminated " + + transactionTerminatedEvent.getClientTransaction()); + + } + + public void processDialogTerminated( + DialogTerminatedEvent dialogTerminatedEvent) { + System.out.println("Dialog terminated event recieved"); + Dialog d = dialogTerminatedEvent.getDialog(); + System.out.println("Local Party = " + d.getLocalParty()); + + } + + public void destroy() { + logger.info("Destroying following sip stack " + sipStack.getStackName()); + HashSet hashSet = new HashSet(); + + for (SipProvider sipProvider : hashSet) { + hashSet.add(sipProvider); + } + try { + for (SipProvider sipProvider : hashSet) { + for (int j = 0; j < 5; j++) { + try { + sipStack.deleteSipProvider(sipProvider); + } catch (ObjectInUseException ex) { + try { + Thread.sleep(1000); + } catch (Exception e) { + } + + } + } + } + + sipStack.stop(); + } catch (Throwable e) { + e.printStackTrace(); + } + } + + private void processPrack(RequestEvent requestEvent, + ServerTransaction serverTransactionId) { + try { + System.out.println("shootme: got an PRACK! "); + System.out.println("Dialog State = " + dialog.getState()); + + /** + * JvB: First, send 200 OK for PRACK + */ + Request prack = requestEvent.getRequest(); + Response prackOk = messageFactory.createResponse( 200, prack ); + serverTransactionId.sendResponse( prackOk ); + + /** + * Send a 200 OK response to complete the 3 way handshake for the + * INIVTE. + */ + Response response = messageFactory.createResponse(200, + inviteRequest); + ToHeader to = (ToHeader) response.getHeader(ToHeader.NAME); + to.setTag(this.toTag); + Address address = addressFactory.createAddress("sip:" + + myAddress + ":" + myPort + ";transport=" + transport); + ContactHeader contactHeader = headerFactory + .createContactHeader(address); + response.addHeader(contactHeader); + inviteTid.sendResponse(response); + } catch (Exception ex) { + ex.printStackTrace(); + + } + + } + + public void setTimeToWaitBeforeAnswer(long timeToWaitBeforeAnswer) { + this.timeToWaitBeforeAnswer = timeToWaitBeforeAnswer; + } + + public long getTimeToWaitBeforeAnswer() { + return timeToWaitBeforeAnswer; + } + + /** + * @return the inviteRequest + */ + public Request getInviteRequest() { + return inviteRequest; + } + + /** + * @param inviteRequest the inviteRequest to set + */ + public void setInviteRequest(Request inviteRequest) { + this.inviteRequest = inviteRequest; + } + + public int getMyPort() { + return myPort; + } + + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/SpeedDialJunitTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/SpeedDialJunitTest.java index 9fa84479d2..c9ac27e334 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/SpeedDialJunitTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/SpeedDialJunitTest.java @@ -1,329 +1,371 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.proxy; - -import java.util.Iterator; - -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.catalina.deploy.ApplicationParameter; -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -//non regression test for Issue 823 -public class SpeedDialJunitTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(SpeedDialJunitTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender; - TestSipListener receiver; - TestSipListener receiver2; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - ProtocolObjects receiver2ProtocolObjects; - - public SpeedDialJunitTest(String name) { - super(name); - autoDeployOnStartup = false; - } - - @Override - public void deployApplication() { - - } - - public void deploySpeedDial(String name, String value) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/speed-dial-servlet/src/main/sipapp"); - context.setName("speed-dial-context"); - context.setPath("speed-dial"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(name); - applicationParameter.setValue(value); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/proxy/speeddial-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects = new ProtocolObjects("sender", - "gov.nist", TRANSPORT, AUTODIALOG, "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070", null, null); - receiverProtocolObjects = new ProtocolObjects("receiver", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - receiver2ProtocolObjects = new ProtocolObjects("receiver2", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - } - - public void testSpeedDialCallerSendBye() throws Exception { - deploySpeedDial("record_route", "false"); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - sender.setSendSubsequentRequestsThroughSipProvider(true); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "sender"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "9"; - String toHost = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); -// assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - } - - public void testSpeedDialErrorResponse() throws Exception { - deploySpeedDial("record_route", "false"); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - sender.setSendSubsequentRequestsThroughSipProvider(true); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - receiver.setRespondWithError(408); - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "sender-expect-408"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "9"; - String toHost = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isServerErrorReceived()); - } - /** - * Assert compliance with JSR 289 Section 10.2.4.2 Correlating responses to proxy branches - * Issue 2474 and 2475 - */ - public void testDoBranchResponseAndDoResponseCallBacks() throws Exception { - deploySpeedDial("record_route", "true"); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - sender.setSendSubsequentRequestsThroughSipProvider(true); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - senderProvider.addSipListener(sender); - senderProtocolObjects.start(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - receiverProvider.addSipListener(receiver); - receiver.setRespondWithError(408); - receiverProtocolObjects.start(); - - receiver2 = new TestSipListener(5091, 5070, receiver2ProtocolObjects, false); - receiver2.setRecordRoutingProxyTesting(true); - SipProvider receiver2Provider = receiver2.createProvider(); - receiver2Provider.addSipListener(receiver2); - receiver2ProtocolObjects.start(); - receiver2.setWaitBeforeFinalResponse(1000); - - String fromName = "sender-expect-408"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "test-callResponseBacks"; - String toHost = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT*2); - assertEquals(200, sender.getFinalResponseStatus()); - logger.info("all messages received :"); - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertTrue(sender.getAllMessagesContent().contains("allResponsesReceivedCorrectlyOnEachCallBack")); - } - - public void testSpeedDialDeclineErrorResponse() throws Exception { - deploySpeedDial("record_route", "false"); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - sender.setSendSubsequentRequestsThroughSipProvider(true); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - receiver.setRespondWithError(603); - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "sender-expect-603"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "9"; - String toHost = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); - Thread.sleep(TIMEOUT); - assertTrue(sender.isServerErrorReceived()); - } - - public void testSpeedDialCalleeSendBye() throws Exception { - deploySpeedDial("record_route", "false"); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - sender.setSendSubsequentRequestsThroughSipProvider(true); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, true); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "sender"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "9"; - String toHost = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getOkToByeReceived()); - assertTrue(sender.getByeReceived()); - } - - public void testCancelSpeedDial() throws Exception { - deploySpeedDial("record_route", "false"); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - sender.setSendSubsequentRequestsThroughSipProvider(true); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, true); - receiver.setRecordRoutingProxyTesting(true); - receiver.setWaitForCancel(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "sender"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "9"; - String toHost = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(500); - sender.sendCancel(); - Thread.sleep(TIMEOUT); - assertTrue(sender.isCancelOkReceived()); - assertTrue(sender.isRequestTerminatedReceived()); - assertTrue(receiver.isCancelReceived()); - Thread.sleep(TIMEOUT); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - if(receiver2ProtocolObjects != null) { - receiver2ProtocolObjects.destroy(); - } - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite.proxy; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import javax.sip.SipProvider; +import javax.sip.address.SipURI; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +//non regression test for Issue 823 +public class SpeedDialJunitTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(SpeedDialJunitTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + TestSipListener receiver; + TestSipListener receiver2; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + ProtocolObjects receiver2ProtocolObjects; + + public SpeedDialJunitTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/proxy/speeddial-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects("sender", + "gov.nist", TRANSPORT, AUTODIALOG, "" + + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + containerPort, null, null); + receiverProtocolObjects = new ProtocolObjects("receiver", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + receiver2ProtocolObjects = new ProtocolObjects("receiver2", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + } + + public void testSpeedDialCallerSendBye() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + sender.setSendSubsequentRequestsThroughSipProvider(true); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(senderPort)); + params.put( "receiverPort", String.valueOf(receiverPort)); + params.put("record_route", "false"); + deployApplication(projectHome + "/sip-servlets-test-suite/applications/speed-dial-servlet/src/main/sipapp" + , params, null); + + String fromName = "sender"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "9"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); +// assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + } + + public void testSpeedDialErrorResponse() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + sender.setSendSubsequentRequestsThroughSipProvider(true); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + receiver.setRespondWithError(408); + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(senderPort)); + params.put( "receiverPort", String.valueOf(receiverPort)); + params.put("record_route", "false"); + deployApplication(projectHome + "/sip-servlets-test-suite/applications/speed-dial-servlet/src/main/sipapp" + , params, null); + + String fromName = "sender-expect-408"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "9"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isServerErrorReceived()); + } + /** + * Assert compliance with JSR 289 Section 10.2.4.2 Correlating responses to proxy branches + * Issue 2474 and 2475 + */ + public void testDoBranchResponseAndDoResponseCallBacks() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + sender.setSendSubsequentRequestsThroughSipProvider(true); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + receiver.setRespondWithError(408); + receiverProtocolObjects.start(); + + int receiver2Port = NetworkPortAssigner.retrieveNextPort(); + receiver2 = new TestSipListener(receiver2Port, containerPort, receiver2ProtocolObjects, false); + receiver2.setRecordRoutingProxyTesting(true); + SipProvider receiver2Provider = receiver2.createProvider(); + receiver2Provider.addSipListener(receiver2); + receiver2ProtocolObjects.start(); + receiver2.setWaitBeforeFinalResponse(1000); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(senderPort)); + params.put( "receiverPort", String.valueOf(receiverPort)); + params.put( "cutmePort", String.valueOf(receiver2Port)); + params.put("record_route", "false"); + deployApplication(projectHome + "/sip-servlets-test-suite/applications/speed-dial-servlet/src/main/sipapp" + , params, null); + + String fromName = "sender-expect-408"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "test-callResponseBacks"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT*2); + assertEquals(200, sender.getFinalResponseStatus()); + logger.info("all messages received :"); + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertTrue(sender.getAllMessagesContent().contains("allResponsesReceivedCorrectlyOnEachCallBack")); + } + + public void testSpeedDialDeclineErrorResponse() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + sender.setSendSubsequentRequestsThroughSipProvider(true); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + receiver.setRespondWithError(603); + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(senderPort)); + params.put( "receiverPort", String.valueOf(receiverPort)); + params.put("record_route", "false"); + deployApplication(projectHome + "/sip-servlets-test-suite/applications/speed-dial-servlet/src/main/sipapp" + , params, null); + + String fromName = "sender-expect-603"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "9"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); + Thread.sleep(TIMEOUT); + assertTrue(sender.isServerErrorReceived()); + } + + public void testSpeedDialCalleeSendBye() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + sender.setSendSubsequentRequestsThroughSipProvider(true); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, true); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(senderPort)); + params.put( "receiverPort", String.valueOf(receiverPort)); + params.put("record_route", "false"); + deployApplication(projectHome + "/sip-servlets-test-suite/applications/speed-dial-servlet/src/main/sipapp" + , params, null); + + String fromName = "sender"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "9"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getOkToByeReceived()); + assertTrue(sender.getByeReceived()); + } + + public void testCancelSpeedDial() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + sender.setSendSubsequentRequestsThroughSipProvider(true); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, true); + receiver.setRecordRoutingProxyTesting(true); + receiver.setWaitForCancel(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(senderPort)); + params.put( "receiverPort", String.valueOf(receiverPort)); + params.put("record_route", "false"); + deployApplication(projectHome + "/sip-servlets-test-suite/applications/speed-dial-servlet/src/main/sipapp" + , params, null); + + String fromName = "sender"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "9"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(500); + sender.sendCancel(); + Thread.sleep(TIMEOUT); + assertTrue(sender.isCancelOkReceived()); + assertTrue(sender.isRequestTerminatedReceived()); + assertTrue(receiver.isCancelReceived()); + Thread.sleep(TIMEOUT); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + if(receiver2ProtocolObjects != null) { + receiver2ProtocolObjects.destroy(); + } + logger.info("Test completed"); + super.tearDown(); + } + + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/forking/ForkingProxyDerivedSessions.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/forking/ForkingProxyDerivedSessions.java index 738229d2be..664640b768 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/forking/ForkingProxyDerivedSessions.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/forking/ForkingProxyDerivedSessions.java @@ -1,131 +1,148 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.proxy.forking; - -import java.util.Properties; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.catalina.SipStandardService; -import org.mobicents.servlet.sip.testsuite.proxy.Shootist; -import org.mobicents.servlet.sip.testsuite.proxy.Shootme; - -/** - * This tests aims to fork to 2 differents destinations each one returning a 200 OK - * tuhs creating a derived session and check the behavior - * @author Jean Deruelle - * - */ -public class ForkingProxyDerivedSessions extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(ForkingProxyDerivedSessions.class); - - protected Shootist shootist; - - protected Shootme ua1; - - protected Shootme ua2; - - private static final int TIMEOUT = 5000; - - private static final int receiversCount = 1; - - public ForkingProxyDerivedSessions(String name) { - super(name); - - this.sipIpAddress="0.0.0.0"; - } - - @Override - public void setUp() throws Exception { - super.setUp(); - this.shootist = new Shootist(true, null); - this.ua1 = new Shootme(5057); - this.ua2 = new Shootme(5056); - } - - public void testProxy() { - this.ua1.init("ua1stackName", null); - this.ua2.init("ua2stackName", null); - this.ua2.waitFinalResponse = 2000; - this.shootist.init("useHostName", false, null); - for (int q = 0; q < 20; q++) { - if (!shootist.ended && !ua1.ended) { - logger.info("loop number " + q); - try { - Thread.sleep(TIMEOUT); - } catch (InterruptedException e) {} - } - } - assertTrue("Conversation not complete!", shootist.ended); - assertTrue("Conversation not complete!", ua1.ended || ua1.cancelled); - assertTrue("Conversation not complete!", ua2.ended || ua2.cancelled); - } - - @Override - public void tearDown() throws Exception { - shootist.destroy(); - ua1.destroy(); - ua2.destroy(); - super.tearDown(); - } - - @Override - public void deployApplication() { - assertTrue(tomcat - .deployContext( - projectHome - + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/proxy/simple-sip-servlet-dar.properties"; - } - - @Override - protected Properties getSipStackProperties() { - Properties sipStackProperties = new Properties(); - sipStackProperties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", - "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", - "32"); - sipStackProperties.setProperty(SipStandardService.DEBUG_LOG_STACK_PROP, - tomcatBasePath + "/" + "mss-jsip-" + getName() +"-debug.txt"); - sipStackProperties.setProperty(SipStandardService.SERVER_LOG_STACK_PROP, - tomcatBasePath + "/" + "mss-jsip-" + getName() +"-messages.xml"); - sipStackProperties.setProperty("javax.sip.STACK_NAME", "mss-" + getName()); - sipStackProperties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", "off"); - sipStackProperties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.THREAD_POOL_SIZE", "64"); - sipStackProperties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.MAX_FORK_TIME_SECONDS", "1"); - sipStackProperties.setProperty(SipStandardService.LOOSE_DIALOG_VALIDATION, "true"); - sipStackProperties.setProperty(SipStandardService.PASS_INVITE_NON_2XX_ACK_TO_LISTENER, "true"); - return sipStackProperties; - } -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite.proxy.forking; + +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.catalina.SipStandardService; +import org.mobicents.servlet.sip.testsuite.proxy.Shootist; +import org.mobicents.servlet.sip.testsuite.proxy.Shootme; + +/** + * This tests aims to fork to 2 differents destinations each one returning a 200 OK + * tuhs creating a derived session and check the behavior + * @author Jean Deruelle + * + */ +public class ForkingProxyDerivedSessions extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ForkingProxyDerivedSessions.class); + + protected Shootist shootist; + + protected Shootme ua1; + + protected Shootme ua2; + + private static final int TIMEOUT = 5000; + + private static final int receiversCount = 1; + + public ForkingProxyDerivedSessions(String name) { + super(name); + + this.sipIpAddress="0.0.0.0"; + autoDeployOnStartup = false; + } + + @Override + public void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + int shootistPort = NetworkPortAssigner.retrieveNextPort(); + this.shootist = new Shootist(true, shootistPort, String.valueOf(containerPort)); + int shootmePort = NetworkPortAssigner.retrieveNextPort(); + this.ua1 = new Shootme(shootmePort); + int shootme2Port = NetworkPortAssigner.retrieveNextPort(); + this.ua2 = new Shootme(shootme2Port); + + Map params = new HashMap(); + params.put( "servletContainerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(shootistPort)); + params.put( "receiverPort", String.valueOf(shootmePort)); + params.put( "cutmePort", String.valueOf(shootme2Port)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + params, null); + } + + public void testProxy() { + this.ua1.init("ua1stackName", null); + this.ua2.init("ua2stackName", null); + this.ua2.waitFinalResponse = 2000; + this.shootist.init("useHostName", false, null); + for (int q = 0; q < 20; q++) { + if (!shootist.ended && !ua1.ended) { + logger.info("loop number " + q); + try { + Thread.sleep(TIMEOUT); + } catch (InterruptedException e) {} + } + } + assertTrue("Conversation not complete!", shootist.ended); + assertTrue("Conversation not complete!", ua1.ended || ua1.cancelled); + assertTrue("Conversation not complete!", ua2.ended || ua2.cancelled); + } + + @Override + public void tearDown() throws Exception { + shootist.destroy(); + ua1.destroy(); + ua2.destroy(); + super.tearDown(); + } + + @Override + public void deployApplication() { + assertTrue(tomcat + .deployContext( + projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + "sip-test-context", "sip-test")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/proxy/simple-sip-servlet-dar.properties"; + } + + @Override + protected Properties getSipStackProperties() { + Properties sipStackProperties = new Properties(); + sipStackProperties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", + "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", + "32"); + sipStackProperties.setProperty(SipStandardService.DEBUG_LOG_STACK_PROP, + tomcatBasePath + "/" + "mss-jsip-" + getName() +"-debug.txt"); + sipStackProperties.setProperty(SipStandardService.SERVER_LOG_STACK_PROP, + tomcatBasePath + "/" + "mss-jsip-" + getName() +"-messages.xml"); + sipStackProperties.setProperty("javax.sip.STACK_NAME", "mss-" + getName()); + sipStackProperties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", "off"); + sipStackProperties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.THREAD_POOL_SIZE", "64"); + sipStackProperties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.MAX_FORK_TIME_SECONDS", "1"); + sipStackProperties.setProperty(SipStandardService.LOOSE_DIALOG_VALIDATION, "true"); + sipStackProperties.setProperty(SipStandardService.PASS_INVITE_NON_2XX_ACK_TO_LISTENER, "true"); + return sipStackProperties; + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/forking/ProxySipServletDownstreamProxyForkingTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/forking/ProxySipServletDownstreamProxyForkingTest.java index 527f9f551f..990cb4ca8c 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/forking/ProxySipServletDownstreamProxyForkingTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/proxy/forking/ProxySipServletDownstreamProxyForkingTest.java @@ -1,181 +1,142 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.proxy.forking; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Properties; - -import javax.sip.SipProvider; - -import org.apache.catalina.deploy.ApplicationParameter; -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.catalina.SipStandardService; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; -import org.mobicents.servlet.sip.testsuite.proxy.Shootist; -import org.mobicents.servlet.sip.testsuite.simple.forking.Proxy; -import org.mobicents.servlet.sip.testsuite.simple.forking.Shootme; - -public class ProxySipServletDownstreamProxyForkingTest extends SipServletTestCase { - private static transient Logger logger = Logger.getLogger(ProxySipServletDownstreamProxyForkingTest.class); - private static final int TIMEOUT = 40000; -// private static final int TIMEOUT = 100000000; - - public ProxySipServletDownstreamProxyForkingTest(String name) { - super(name); - startTomcatOnStartup = false; - autoDeployOnStartup = false; - addSipConnectorOnStartup = false; - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - public SipStandardContext deployApplication(String name, String value) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(name); - applicationParameter.setValue(value); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - return context; - } - - public SipStandardContext deployApplication(Map params) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - for (Entry param : params.entrySet()) { - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(param.getKey()); - applicationParameter.setValue(param.getValue()); - context.addApplicationParameter(applicationParameter); - } - assertTrue(tomcat.deployContext(context)); - return context; - } - - public SipStandardContext deployApplicationServletListenerTest() { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName("testServletListener"); - applicationParameter.setValue("true"); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - return context; - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/proxy/simple-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - } - - // non regression test for Issue 2390 http://code.google.com/p/mobicents/issues/detail?id=2390 - // Proxy implementation not forwarding additional 2xx responses from downstream fork - public void testDownstreamProxyForking() throws Exception { - Shootme shootme1 = new Shootme(5080, true, 1000); - SipProvider shootmeProvider = shootme1.createProvider(); - shootmeProvider.addSipListener(shootme1); - Shootme shootme2 = new Shootme(5081, true, 2500); - SipProvider shootme2Provider = shootme2.createProvider(); - shootme2Provider.addSipListener(shootme2); - shootme2.setWaitBeforeFinalResponse(9000); - Proxy proxy = new Proxy(5070,2); - SipProvider provider = proxy.createSipProvider(); - provider.addSipListener(proxy); - Shootist shootist = new Shootist(true, "5060"); - shootist.pauseBeforeBye = 20000; - shootist.setFromHost("sip-servlets.com"); - - sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, 5060, listeningPointTransport); - tomcat.startTomcat(); - Map params= new HashMap(); - params.put("route", "sip:" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070"); - params.put("timeToWaitForBye", "20000"); - params.put("dontSetRURI", "true"); - SipStandardContext sipContext = deployApplication(params); - shootist.init("forward-sender-downstream-proxy", false, null); - Thread.sleep(TIMEOUT); - proxy.stop(); - shootme1.stop(); - shootme2.stop(); - assertTrue(shootist.isForkedResponseReceived()); - assertTrue(shootme1.isAckSeen()); - } - - @Override - protected Properties getSipStackProperties() { - Properties sipStackProperties = new Properties(); - sipStackProperties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", - "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", - "32"); - sipStackProperties.setProperty(SipStandardService.DEBUG_LOG_STACK_PROP, - tomcatBasePath + "/" + "mss-jsip-" + getName() +"-debug.txt"); - sipStackProperties.setProperty(SipStandardService.SERVER_LOG_STACK_PROP, - tomcatBasePath + "/" + "mss-jsip-" + getName() +"-messages.xml"); - sipStackProperties.setProperty("javax.sip.STACK_NAME", "mss-" + getName()); - sipStackProperties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", "off"); - sipStackProperties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.THREAD_POOL_SIZE", "64"); - sipStackProperties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.MAX_FORK_TIME_SECONDS", "10"); - sipStackProperties.setProperty(SipStandardService.LOOSE_DIALOG_VALIDATION, "true"); - sipStackProperties.setProperty(SipStandardService.PASS_INVITE_NON_2XX_ACK_TO_LISTENER, "true"); - return sipStackProperties; - } - - @Override - protected void tearDown() throws Exception { - logger.info("Test completed"); - super.tearDown(); - } +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite.proxy.forking; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import javax.sip.SipProvider; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.catalina.SipStandardService; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.proxy.Shootist; +import org.mobicents.servlet.sip.testsuite.simple.forking.Proxy; +import org.mobicents.servlet.sip.testsuite.simple.forking.Shootme; + +public class ProxySipServletDownstreamProxyForkingTest extends SipServletTestCase { + private static transient Logger logger = Logger.getLogger(ProxySipServletDownstreamProxyForkingTest.class); + private static final int TIMEOUT = 40000; +// private static final int TIMEOUT = 100000000; + + public ProxySipServletDownstreamProxyForkingTest(String name) { + super(name); + startTomcatOnStartup = false; + autoDeployOnStartup = false; + addSipConnectorOnStartup = false; + } + + @Override + public void deployApplication() { + assertTrue(tomcat.deployContext( + projectHome + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + "sip-test-context", "sip-test")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/proxy/simple-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + } + + // non regression test for Issue 2390 http://code.google.com/p/mobicents/issues/detail?id=2390 + // Proxy implementation not forwarding additional 2xx responses from downstream fork + public void testDownstreamProxyForking() throws Exception { + int shootme1Port = NetworkPortAssigner.retrieveNextPort(); + Shootme shootme1 = new Shootme(shootme1Port, true, 1000); + SipProvider shootmeProvider = shootme1.createProvider(); + shootmeProvider.addSipListener(shootme1); + int shootme2Port = NetworkPortAssigner.retrieveNextPort(); + Shootme shootme2 = new Shootme(shootme2Port, true, 2500); + SipProvider shootme2Provider = shootme2.createProvider(); + shootme2Provider.addSipListener(shootme2); + shootme2.setWaitBeforeFinalResponse(9000); + int proxyPort = NetworkPortAssigner.retrieveNextPort(); + Proxy proxy = new Proxy(proxyPort,new int[]{shootme1Port, shootme2Port}); + SipProvider provider = proxy.createSipProvider(); + provider.addSipListener(proxy); + int shootistPort = NetworkPortAssigner.retrieveNextPort(); + int cont2Port = NetworkPortAssigner.retrieveNextPort(); + Shootist shootist = new Shootist(true,shootistPort, String.valueOf(cont2Port)); + shootist.pauseBeforeBye = 20000; + shootist.setFromHost("sip-servlets.com"); + + sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, cont2Port, listeningPointTransport); + tomcat.startTomcat(); + Map params= new HashMap(); + params.put("route", "sip:" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + proxyPort); + params.put("timeToWaitForBye", "20000"); + params.put("dontSetRURI", "true"); + params.put( "servletContainerPort", String.valueOf(cont2Port)); + params.put( "testPort", String.valueOf(shootistPort)); + params.put( "receiverPort", String.valueOf(proxyPort)); + SipStandardContext sipContext = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + params, null); + shootist.init("forward-sender-downstream-proxy", false, null); + Thread.sleep(TIMEOUT); + proxy.stop(); + shootme1.stop(); + shootme2.stop(); + assertTrue(shootist.isForkedResponseReceived()); + assertTrue(shootme1.isAckSeen()); + } + + @Override + protected Properties getSipStackProperties() { + Properties sipStackProperties = new Properties(); + sipStackProperties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", + "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", + "32"); + sipStackProperties.setProperty(SipStandardService.DEBUG_LOG_STACK_PROP, + tomcatBasePath + "/" + "mss-jsip-" + getName() +"-debug.txt"); + sipStackProperties.setProperty(SipStandardService.SERVER_LOG_STACK_PROP, + tomcatBasePath + "/" + "mss-jsip-" + getName() +"-messages.xml"); + sipStackProperties.setProperty("javax.sip.STACK_NAME", "mss-" + getName()); + sipStackProperties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", "off"); + sipStackProperties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.THREAD_POOL_SIZE", "64"); + sipStackProperties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.MAX_FORK_TIME_SECONDS", "10"); + sipStackProperties.setProperty(SipStandardService.LOOSE_DIALOG_VALIDATION, "true"); + sipStackProperties.setProperty(SipStandardService.PASS_INVITE_NON_2XX_ACK_TO_LISTENER, "true"); + return sipStackProperties; + } + + @Override + protected void tearDown() throws Exception { + logger.info("Test completed"); + super.tearDown(); + } } \ No newline at end of file diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/publish/PublishSipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/publish/PublishSipServletTest.java index b77ad39b7a..17b9d75fe2 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/publish/PublishSipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/publish/PublishSipServletTest.java @@ -1,183 +1,196 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.publish; - -import gov.nist.javax.sip.header.SubscriptionState; - -import java.text.ParseException; -import java.util.Iterator; - -import javax.sip.InvalidArgumentException; -import javax.sip.SipException; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; -import javax.sip.message.Request; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; -/** - * This tests the PUBLISH SIP extension see RFC 3903 - * - * @author Jean Deruelle - * - */ -public class PublishSipServletTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(PublishSipServletTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 5000; -// private static final int TIMEOUT = 100000000; - - private static final String[] SUBSCRIPTION_STATES = new String[]{ - SubscriptionState.ACTIVE.toLowerCase() - }; - private static final String[] PUBLISH_STATES = new String[]{ - "Initial", "Modify" - }; - - TestSipListener watcher; - ProtocolObjects watcherProtocolObjects; - - TestSipListener pua; - ProtocolObjects puaProtocolObjects; - - - public PublishSipServletTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/publish-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/publish/publish-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - watcherProtocolObjects =new ProtocolObjects( - "watcher", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - watcher = new TestSipListener(5080, 5070, watcherProtocolObjects, true); - SipProvider senderProvider = watcher.createProvider(); - - senderProvider.addSipListener(watcher); - - watcherProtocolObjects.start(); - - puaProtocolObjects =new ProtocolObjects( - "pua", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - pua = new TestSipListener(5090, 5070, puaProtocolObjects, true); - SipProvider puaProvider = pua.createProvider(); - - puaProvider.addSipListener(pua); - - puaProtocolObjects.start(); - } - - /** - * Call flow tested : See RFC 3903 Page 23 - * in this test, Sip Servlet is acting as PA(ESC) - */ - public void testSipServletReceivesPublish() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "watcher"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = watcherProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = watcherProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - watcher.setPublishEvent("presence"); - watcher.sendSipRequest(Request.SUBSCRIBE, fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertEquals(1, watcher.getAllSubscriptionState().size()); - for (String subscriptionState : SUBSCRIPTION_STATES) { - assertTrue(subscriptionState + " not present",watcher.getAllSubscriptionState().contains(subscriptionState)); - } - watcher.getAllSubscriptionState().clear(); - pua.setPublishEvent("presence"); - pua.setPublishContentMessage("Initial"); - pua.sendSipRequest(Request.PUBLISH, fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertEquals(1, watcher.getAllSubscriptionState().size()); - for (String subscriptionState : SUBSCRIPTION_STATES) { - assertTrue(subscriptionState + " not present",watcher.getAllSubscriptionState().contains(subscriptionState)); - } - watcher.getAllSubscriptionState().clear(); - pua.setPublishContentMessage(null); - pua.sendSipRequest(Request.PUBLISH, fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertEquals(0, watcher.getAllSubscriptionState().size()); - pua.setPublishContentMessage("Modify"); - pua.sendSipRequest(Request.PUBLISH, fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertEquals(1, watcher.getAllSubscriptionState().size()); - for (String subscriptionState : SUBSCRIPTION_STATES) { - assertTrue(subscriptionState + " not present",watcher.getAllSubscriptionState().contains(subscriptionState)); - } - watcher.getAllSubscriptionState().clear(); - } - - /** - * Call flow tested : See RFC 3903 Page 23 - * in this test, Sip Servlet is acting as PUA(EPA) - */ - public void testSipServletSendsPublish() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - Thread.sleep(TIMEOUT); - Iterator allMessagesIterator = watcher.getAllMessagesContent().iterator(); - logger.info("all messages received : "); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - for (int i = 0; i < PUBLISH_STATES.length; i++) { - assertTrue(watcher.getAllMessagesContent().contains(PUBLISH_STATES[i])); - } - } - - @Override - protected void tearDown() throws Exception { - watcherProtocolObjects.destroy(); - puaProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.publish; + +import gov.nist.javax.sip.header.SubscriptionState; + +import java.text.ParseException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import javax.sip.InvalidArgumentException; +import javax.sip.SipException; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import javax.sip.message.Request; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +/** + * This tests the PUBLISH SIP extension see RFC 3903 + * + * @author Jean Deruelle + * + */ +public class PublishSipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(PublishSipServletTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 5000; +// private static final int TIMEOUT = 100000000; + + private static final String[] SUBSCRIPTION_STATES = new String[]{ + SubscriptionState.ACTIVE.toLowerCase() + }; + private static final String[] PUBLISH_STATES = new String[]{ + "Initial", "Modify" + }; + + TestSipListener watcher; + ProtocolObjects watcherProtocolObjects; + + TestSipListener pua; + ProtocolObjects puaProtocolObjects; + + public PublishSipServletTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + public SipStandardContext deployApplication(Map params) { + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/publish-sip-servlet/src/main/sipapp", + "sip-test", + params, + null); + assertTrue(ctx.getAvailable()); + return ctx; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/publish/publish-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + watcherProtocolObjects = new ProtocolObjects( + "watcher", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int watcherPort = NetworkPortAssigner.retrieveNextPort(); + watcher = new TestSipListener(watcherPort, containerPort, watcherProtocolObjects, true); + SipProvider senderProvider = watcher.createProvider(); + senderProvider.addSipListener(watcher); + watcherProtocolObjects.start(); + + puaProtocolObjects = new ProtocolObjects( + "pua", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int puaPort = NetworkPortAssigner.retrieveNextPort(); + pua = new TestSipListener(puaPort, containerPort, puaProtocolObjects, true); + SipProvider puaProvider = pua.createProvider(); + puaProvider.addSipListener(pua); + puaProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(watcherPort)); + deployApplication(params); + } + + /** + * Call flow tested : See RFC 3903 Page 23 in this test, Sip Servlet is + * acting as PA(ESC) + */ + public void testSipServletReceivesPublish() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "watcher"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = watcherProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = watcherProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + watcher.setPublishEvent("presence"); + watcher.sendSipRequest(Request.SUBSCRIBE, fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertEquals(1, watcher.getAllSubscriptionState().size()); + for (String subscriptionState : SUBSCRIPTION_STATES) { + assertTrue(subscriptionState + " not present", watcher.getAllSubscriptionState().contains(subscriptionState)); + } + watcher.getAllSubscriptionState().clear(); + pua.setPublishEvent("presence"); + pua.setPublishContentMessage("Initial"); + pua.sendSipRequest(Request.PUBLISH, fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertEquals(1, watcher.getAllSubscriptionState().size()); + for (String subscriptionState : SUBSCRIPTION_STATES) { + assertTrue(subscriptionState + " not present", watcher.getAllSubscriptionState().contains(subscriptionState)); + } + watcher.getAllSubscriptionState().clear(); + pua.setPublishContentMessage(null); + pua.sendSipRequest(Request.PUBLISH, fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertEquals(0, watcher.getAllSubscriptionState().size()); + pua.setPublishContentMessage("Modify"); + pua.sendSipRequest(Request.PUBLISH, fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertEquals(1, watcher.getAllSubscriptionState().size()); + for (String subscriptionState : SUBSCRIPTION_STATES) { + assertTrue(subscriptionState + " not present", watcher.getAllSubscriptionState().contains(subscriptionState)); + } + watcher.getAllSubscriptionState().clear(); + } + + /** + * Call flow tested : See RFC 3903 Page 23 in this test, Sip Servlet is + * acting as PUA(EPA) + */ + public void testSipServletSendsPublish() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + Thread.sleep(TIMEOUT); + Iterator allMessagesIterator = watcher.getAllMessagesContent().iterator(); + logger.info("all messages received : "); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + for (int i = 0; i < PUBLISH_STATES.length; i++) { + assertTrue(watcher.getAllMessagesContent().contains(PUBLISH_STATES[i])); + } + } + + @Override + protected void tearDown() throws Exception { + watcherProtocolObjects.destroy(); + puaProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/refer/ReferSipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/refer/ReferSipServletTest.java index 80ce37ac03..9a78e4c517 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/refer/ReferSipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/refer/ReferSipServletTest.java @@ -1,272 +1,291 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.refer; - -import java.text.ParseException; -import java.util.Iterator; - -import javax.sip.InvalidArgumentException; -import javax.sip.SipException; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; -import javax.sip.message.Request; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -/** - * This tests the REFER SIP extension see RFC 3515 - * - * @author Jean Deruelle - * - */ -public class ReferSipServletTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(ReferSipServletTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; -// private static final int TIMEOUT = 100000000; - - private static final String[] NOTIFICATIONS = new String[]{ - "SIP/2.0 100 Trying", "SIP/2.0 200 OK" - }; - - private static final String[] INDIALOG_NOTIFICATIONS = new String[]{ - "SIP/2.0 100 Subsequent" - }; - - private static final String SESSION_INVALIDATED = new String("sipSessionReadyToBeInvalidated"); - - - TestSipListener sender; - ProtocolObjects senderProtocolObjects; - - TestSipListener referTo; - ProtocolObjects referToProtocolObjects; - - - public ReferSipServletTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/refer-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/refer/refer-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - senderProvider.addSipListener(sender); - senderProtocolObjects.start(); - - referToProtocolObjects =new ProtocolObjects( - "referTo", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - referTo = new TestSipListener(5090, 5070, referToProtocolObjects, true); - SipProvider referToProvider = referTo.createProvider(); - referToProvider.addSipListener(referTo); - referToProtocolObjects.start(); - - } - - /** - * Call flow tested : See RFC 3515 Page 11-13 - * in this test, Sip Servlet is receiving the REFERs (Acts as Agent B in the RFC) - */ - public void testSipServletsReceivesReferOutOfDialog() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest(Request.REFER, fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT*2); - assertTrue(referTo.isAckReceived()); - logger.info("all messages received : "); - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertTrue("session not invalidated after receiving Terminated Subscription State", sender.getAllMessagesContent().contains(SESSION_INVALIDATED)); - while(sender.getAllMessagesContent().contains(SESSION_INVALIDATED)) { - sender.getAllMessagesContent().remove(SESSION_INVALIDATED); - } - assertEquals(NOTIFICATIONS.length, sender.getAllMessagesContent().size()); - for (String subscriptionState : NOTIFICATIONS) { - assertTrue(subscriptionState + " not present",sender.getAllMessagesContent().contains(subscriptionState)); - } - assertTrue(referTo.getOkToByeReceived()); - - } - - /** - * Call flow tested : See RFC 3515 Page 11-13 - * in this test, Sip Servlet is sending the REFERs (Acts as Agent A in the RFC) - */ - public void testSipServletsSendsReferOutOfDialog() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - - Thread.sleep(TIMEOUT * 2); - logger.info("all messages received : "); - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertTrue("session not invalidated after receiving Terminated Subscription State", sender.getAllMessagesContent().contains(SESSION_INVALIDATED)); - while(sender.getAllMessagesContent().contains(SESSION_INVALIDATED)) { - sender.getAllMessagesContent().remove(SESSION_INVALIDATED); - } - assertEquals(NOTIFICATIONS.length, sender.getAllMessagesContent().size()); - for (String subscriptionState : NOTIFICATIONS) { - assertTrue(subscriptionState + " not present",sender.getAllMessagesContent().contains(subscriptionState)); - } - } - - /** - * Call flow tested : See RFC 3515 Page 13-15 - * in this test, Sip Servlet is receiving the REFERs (Acts as Agent B in the RFC) - */ - public void testSipServletsReceivesReferInDialog() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest(Request.INVITE, fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - - sender.sendInDialogSipRequest(Request.REFER, null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertTrue(referTo.isAckReceived()); - logger.info("all messages received : "); - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertEquals(NOTIFICATIONS.length, sender.getAllMessagesContent().size()); - for (String subscriptionState : NOTIFICATIONS) { - assertTrue(subscriptionState + " not present",sender.getAllMessagesContent().contains(subscriptionState)); - } - assertTrue(referTo.getOkToByeReceived()); - sender.getAllMessagesContent().clear(); - sender.sendInDialogSipRequest(Request.REFER, null, null, null, null, null); - Thread.sleep(TIMEOUT); - logger.info("all messages received : "); - allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertTrue("session not invalidated after receiving Terminated Subscription State", sender.getAllMessagesContent().contains(SESSION_INVALIDATED)); - while(sender.getAllMessagesContent().contains(SESSION_INVALIDATED)) { - sender.getAllMessagesContent().remove(SESSION_INVALIDATED); - } - assertEquals(INDIALOG_NOTIFICATIONS.length, sender.getAllMessagesContent().size()); - for (String subscriptionState : INDIALOG_NOTIFICATIONS) { - assertTrue(subscriptionState + " not present",sender.getAllMessagesContent().contains(subscriptionState)); - } - sender.sendBye(); - Thread.sleep(TIMEOUT); - assertTrue(sender.getOkToByeReceived()); - } - - /** - * Call flow tested : See RFC 3515 Page 13-15 - * in this test, Sip Servlet is receiving the REFERs (Acts as Agent B in the RFC) - */ - public void testSipServletsReceivesReferInDialogByeSentBeforeTermSubscription() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest(Request.INVITE, fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - - sender.setSendByeBeforeTerminatingNotify(true); - sender.sendInDialogSipRequest(Request.REFER, null, null, null, null, null); - Thread.sleep(TIMEOUT*2); - assertTrue(referTo.isAckReceived()); - logger.info("all messages received : "); - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertTrue("session not invalidated after receiving Terminated Subscription State", sender.getAllMessagesContent().contains(SESSION_INVALIDATED)); - while(sender.getAllMessagesContent().contains(SESSION_INVALIDATED)) { - sender.getAllMessagesContent().remove(SESSION_INVALIDATED); - } - assertEquals(NOTIFICATIONS.length, sender.getAllMessagesContent().size()); - for (String subscriptionState : NOTIFICATIONS) { - assertTrue(subscriptionState + " not present",sender.getAllMessagesContent().contains(subscriptionState)); - } - assertTrue(sender.getOkToByeReceived()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - referToProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.refer; + +import java.text.ParseException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import javax.servlet.ServletContext; + +import javax.sip.InvalidArgumentException; +import javax.sip.SipException; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import javax.sip.message.Request; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +/** + * This tests the REFER SIP extension see RFC 3515 + * + * @author Jean Deruelle + * + */ +public class ReferSipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ReferSipServletTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; +// private static final int TIMEOUT = 100000000; + + private static final String[] NOTIFICATIONS = new String[]{ + "SIP/2.0 100 Trying", "SIP/2.0 200 OK" + }; + + private static final String[] INDIALOG_NOTIFICATIONS = new String[]{ + "SIP/2.0 100 Subsequent" + }; + + private static final String SESSION_INVALIDATED = new String("sipSessionReadyToBeInvalidated"); + + TestSipListener sender; + ProtocolObjects senderProtocolObjects; + + TestSipListener referTo; + ProtocolObjects referToProtocolObjects; + + public ReferSipServletTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + public SipStandardContext deployApplication(Map params) { + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/refer-sip-servlet/src/main/sipapp", + "sip-test", + params, + null); + assertTrue(ctx.getAvailable()); + return ctx; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/refer/refer-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + referToProtocolObjects = new ProtocolObjects( + "referTo", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int referPort = NetworkPortAssigner.retrieveNextPort(); + referTo = new TestSipListener(referPort, containerPort, referToProtocolObjects, true); + SipProvider referToProvider = referTo.createProvider(); + referToProvider.addSipListener(referTo); + referToProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + params.put("referPort", String.valueOf(referPort)); + deployApplication(params); + + } + + /** + * Call flow tested : See RFC 3515 Page 11-13 in this test, Sip Servlet is + * receiving the REFERs (Acts as Agent B in the RFC) + */ + public void testSipServletsReceivesReferOutOfDialog() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest(Request.REFER, fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT * 2); + assertTrue(referTo.isAckReceived()); + logger.info("all messages received : "); + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertTrue("session not invalidated after receiving Terminated Subscription State", sender.getAllMessagesContent().contains(SESSION_INVALIDATED)); + while (sender.getAllMessagesContent().contains(SESSION_INVALIDATED)) { + sender.getAllMessagesContent().remove(SESSION_INVALIDATED); + } + assertEquals(NOTIFICATIONS.length, sender.getAllMessagesContent().size()); + for (String subscriptionState : NOTIFICATIONS) { + assertTrue(subscriptionState + " not present", sender.getAllMessagesContent().contains(subscriptionState)); + } + assertTrue(referTo.getOkToByeReceived()); + + } + + /** + * Call flow tested : See RFC 3515 Page 11-13 in this test, Sip Servlet is + * sending the REFERs (Acts as Agent A in the RFC) + */ + public void testSipServletsSendsReferOutOfDialog() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + + Thread.sleep(TIMEOUT * 2); + logger.info("all messages received : "); + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertTrue("session not invalidated after receiving Terminated Subscription State", sender.getAllMessagesContent().contains(SESSION_INVALIDATED)); + while (sender.getAllMessagesContent().contains(SESSION_INVALIDATED)) { + sender.getAllMessagesContent().remove(SESSION_INVALIDATED); + } + assertEquals(NOTIFICATIONS.length, sender.getAllMessagesContent().size()); + for (String subscriptionState : NOTIFICATIONS) { + assertTrue(subscriptionState + " not present", sender.getAllMessagesContent().contains(subscriptionState)); + } + } + + /** + * Call flow tested : See RFC 3515 Page 13-15 in this test, Sip Servlet is + * receiving the REFERs (Acts as Agent B in the RFC) + */ + public void testSipServletsReceivesReferInDialog() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest(Request.INVITE, fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + + sender.sendInDialogSipRequest(Request.REFER, null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertTrue(referTo.isAckReceived()); + logger.info("all messages received : "); + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertEquals(NOTIFICATIONS.length, sender.getAllMessagesContent().size()); + for (String subscriptionState : NOTIFICATIONS) { + assertTrue(subscriptionState + " not present", sender.getAllMessagesContent().contains(subscriptionState)); + } + assertTrue(referTo.getOkToByeReceived()); + sender.getAllMessagesContent().clear(); + sender.sendInDialogSipRequest(Request.REFER, null, null, null, null, null); + Thread.sleep(TIMEOUT); + logger.info("all messages received : "); + allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertTrue("session not invalidated after receiving Terminated Subscription State", sender.getAllMessagesContent().contains(SESSION_INVALIDATED)); + while (sender.getAllMessagesContent().contains(SESSION_INVALIDATED)) { + sender.getAllMessagesContent().remove(SESSION_INVALIDATED); + } + assertEquals(INDIALOG_NOTIFICATIONS.length, sender.getAllMessagesContent().size()); + for (String subscriptionState : INDIALOG_NOTIFICATIONS) { + assertTrue(subscriptionState + " not present", sender.getAllMessagesContent().contains(subscriptionState)); + } + sender.sendBye(); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + } + + /** + * Call flow tested : See RFC 3515 Page 13-15 in this test, Sip Servlet is + * receiving the REFERs (Acts as Agent B in the RFC) + */ + public void testSipServletsReceivesReferInDialogByeSentBeforeTermSubscription() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest(Request.INVITE, fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + + sender.setSendByeBeforeTerminatingNotify(true); + sender.sendInDialogSipRequest(Request.REFER, null, null, null, null, null); + Thread.sleep(TIMEOUT * 2); + assertTrue(referTo.isAckReceived()); + logger.info("all messages received : "); + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertTrue("session not invalidated after receiving Terminated Subscription State", sender.getAllMessagesContent().contains(SESSION_INVALIDATED)); + while (sender.getAllMessagesContent().contains(SESSION_INVALIDATED)) { + sender.getAllMessagesContent().remove(SESSION_INVALIDATED); + } + assertEquals(NOTIFICATIONS.length, sender.getAllMessagesContent().size()); + for (String subscriptionState : NOTIFICATIONS) { + assertTrue(subscriptionState + " not present", sender.getAllMessagesContent().contains(subscriptionState)); + } + assertTrue(sender.getOkToByeReceived()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + referToProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/reinvite/CallForwardingB2BUAReInviteJunitTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/reinvite/CallForwardingB2BUAReInviteJunitTest.java index 2336d00b94..5d56aa00cb 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/reinvite/CallForwardingB2BUAReInviteJunitTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/reinvite/CallForwardingB2BUAReInviteJunitTest.java @@ -1,469 +1,538 @@ -/* - * TeleStax, Open Source Cloud Communications Copyright 2012. - * and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.reinvite; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; - -import javax.sip.SipProvider; -import javax.sip.address.SipURI; -import javax.sip.header.AllowHeader; -import javax.sip.header.Header; -import javax.sip.header.MaxForwardsHeader; -import javax.sip.header.UserAgentHeader; -import javax.sip.message.Response; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -/* - * - * Added for Issue 1409 http://code.google.com/p/mobicents/issues/detail?id=1409 - */ -public class CallForwardingB2BUAReInviteJunitTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(CallForwardingB2BUAReInviteJunitTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 20000; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender; - TestSipListener receiver; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - - public CallForwardingB2BUAReInviteJunitTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", - "sip-test-context", - "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/callcontroller/call-forwarding-b2bua-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects = new ProtocolObjects("forward-sender", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - receiverProtocolObjects = new ProtocolObjects("receiver", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - } - - public void testCallForwardingCallerSendBye() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - receiver.setSendReinvite(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isInviteReceived()); - assertTrue(sender.isAckReceived()); - assertNotNull(sender.getInviteRequest().getHeader("ReInvite")); - MaxForwardsHeader maxForwardsHeader = (MaxForwardsHeader) receiver.getInviteRequest().getHeader(MaxForwardsHeader.NAME); - assertNotNull(maxForwardsHeader); - // Non Regression test for http://code.google.com/p/mobicents/issues/detail?id=1490 - // B2buaHelper.createRequest does not decrement Max-forwards - assertEquals(69, maxForwardsHeader.getMaxForwards()); - sender.sendInDialogSipRequest("BYE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - assertTrue(sender.getOkToByeReceived()); - assertEquals(1,sender.bindings); //http://code.google.com/p/mobicents/issues/detail?id=2100 - maxForwardsHeader = (MaxForwardsHeader) receiver.getByeRequestReceived().getHeader(MaxForwardsHeader.NAME); - assertNotNull(maxForwardsHeader); - // Non Regression test for http://code.google.com/p/mobicents/issues/detail?id=1490 - // B2buaHelper.createRequest does not decrement Max-forwards - assertEquals(69, maxForwardsHeader.getMaxForwards()); - } - - // Issue 2500 http://code.google.com/p/mobicents/issues/detail?id=2500 - // B2buaHelper.createRequest() throws a NullPointerException if the request contains an empty header - public void testCallForwardingCallerSendReInviteSendBye() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[] {AllowHeader.NAME}, new String[] {"INVITE, CANCEL, BYE, ACK, OPTIONS"}, true); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isInviteReceived()); - assertTrue(receiver.isAckReceived()); - MaxForwardsHeader maxForwardsHeader = (MaxForwardsHeader) receiver.getInviteRequest().getHeader(MaxForwardsHeader.NAME); - assertNotNull(maxForwardsHeader); - // Non Regression test for http://code.google.com/p/mobicents/issues/detail?id=1490 - // B2buaHelper.createRequest does not decrement Max-forwards - assertEquals(69, maxForwardsHeader.getMaxForwards()); - - ListIterator allowHeaderIt = receiver.getInviteRequest().getHeaders(AllowHeader.NAME); - int i = 0; - while (allowHeaderIt.hasNext()) { - allowHeaderIt.next(); - i++; - } - assertEquals(5, i); - - Header methodHeader = receiverProtocolObjects.headerFactory.createHeader("Supported", ""); - // Non Regression for Issue 184 http://code.google.com/p/sipservlets/issues/detail?id=184 - Header allowHeader = receiverProtocolObjects.headerFactory.createAllowHeader("INVITE, CANCEL, BYE, ACK, OPTIONS"); - List
headers = new ArrayList
(); - headers.add(methodHeader); - headers.add(allowHeader); - - sender.sendInDialogSipRequest("INVITE", null, null, null, headers, null); - receiver.setInviteReceived(false); - receiver.setAckReceived(false); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isInviteReceived()); - assertTrue(receiver.isAckReceived()); - allowHeaderIt = receiver.getInviteRequest().getHeaders(AllowHeader.NAME); - i = 0; - while (allowHeaderIt.hasNext()) { - allowHeaderIt.next(); - i++; - } - assertEquals(5, i); - sender.sendInDialogSipRequest("BYE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - assertTrue(sender.getOkToByeReceived()); - } - - /** - * Non Regression test for - * http://code.google.com/p/mobicents/issues/detail?id=2230 - * BYE is routed to unexpected IP - */ - public void testCallForwardingCallerSendBye408onReinvite() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-sender-408"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isInviteReceived()); - assertTrue(receiver.isAckReceived()); - MaxForwardsHeader maxForwardsHeader = (MaxForwardsHeader) receiver.getInviteRequest().getHeader(MaxForwardsHeader.NAME); - assertNotNull(maxForwardsHeader); - receiver.setFinalResponseToSend(Response.REQUEST_TIMEOUT); - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isInviteReceived()); - assertTrue(receiver.isAckReceived()); - - // Non Regression test for http://code.google.com/p/mobicents/issues/detail?id=1490 - // B2buaHelper.createRequest does not decrement Max-forwards - assertEquals(69, maxForwardsHeader.getMaxForwards()); - sender.sendInDialogSipRequest("BYE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - assertTrue(sender.getOkToByeReceived()); - } - - /** - * Non Regression test for - * http://code.google.com/p/mobicents/issues/detail?id=2230 - * BYE is routed to unexpected IP - */ - public void testCallForwardingCallerSendBye408onReinviteBYENewThread() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-sender-408-new-thread"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isInviteReceived()); - assertTrue(receiver.isAckReceived()); - MaxForwardsHeader maxForwardsHeader = (MaxForwardsHeader) receiver.getInviteRequest().getHeader(MaxForwardsHeader.NAME); - assertNotNull(maxForwardsHeader); - receiver.setProvisionalResponsesToSend(new ArrayList()); - receiver.setFinalResponseToSend(Response.REQUEST_TIMEOUT); - Header methodHeader = receiverProtocolObjects.headerFactory.createHeader("Method", "BYE"); - List
headers = new ArrayList
(); - headers.add(methodHeader); - sender.sendInDialogSipRequest("INVITE", null, null, null, headers, null); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isInviteReceived()); - assertTrue(receiver.isAckReceived()); - - receiver.sendInDialogSipRequest("UPDATE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isInviteReceived()); - assertTrue(receiver.isAckReceived()); - - sender.sendInDialogSipRequest("BYE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - assertTrue(sender.getOkToByeReceived()); - } - - /** - * Non Regression test for - * http://code.google.com/p/mobicents/issues/detail?id=2230 - * BYE is routed to unexpected IP - */ - public void testCallForwardingCallerSendBye408onReinviteUPDATENewThread() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-sender-408-new-thread"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isInviteReceived()); - assertTrue(receiver.isAckReceived()); - MaxForwardsHeader maxForwardsHeader = (MaxForwardsHeader) receiver.getInviteRequest().getHeader(MaxForwardsHeader.NAME); - assertNotNull(maxForwardsHeader); - receiver.setProvisionalResponsesToSend(new ArrayList()); - receiver.setFinalResponseToSend(Response.REQUEST_TIMEOUT); - Header methodHeader = receiverProtocolObjects.headerFactory.createHeader("Method", "UPDATE"); - List
headers = new ArrayList
(); - headers.add(methodHeader); - sender.sendInDialogSipRequest("INVITE", null, null, null, headers, null); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isInviteReceived()); - assertTrue(receiver.isAckReceived()); - - receiver.sendInDialogSipRequest("UPDATE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isInviteReceived()); - assertTrue(receiver.isAckReceived()); - - sender.sendInDialogSipRequest("BYE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertTrue(sender.getOkToByeReceived()); - - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertTrue(sender.getAllMessagesContent().contains("IllegalStateException")); - } - - /** - * Non Regression test for - * http://code.google.com/p/mobicents/issues/detail?id=1445 - * "Bad Request Method. CANCEL" during sending CANCEL to re-INVITE - */ - public void testCallForwardingCallerReInviteCancel() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - receiver.setWaitForCancel(true); - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - Thread.sleep(500); - sender.sendCancel(); - Thread.sleep(TIMEOUT); - assertTrue(sender.isCancelOkReceived()); - assertTrue(sender.isRequestTerminatedReceived()); - assertTrue(receiver.isCancelReceived()); - sender.setCancelOkReceived(false); - sender.setRequestTerminatedReceived(false); - receiver.setCancelReceived(false); - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - Thread.sleep(500); - sender.sendCancel(); - Thread.sleep(TIMEOUT); - assertTrue(sender.isCancelOkReceived()); - assertTrue(sender.isRequestTerminatedReceived()); - assertTrue(receiver.isCancelReceived()); - } - - /** - * Non Regression test for - * http://code.google.com/p/mobicents/issues/detail?id=1837 - * ACK was received by JAIN-SIP but was not routed to application - */ - public void testCallForwardingCallerReInviteAckRaceInfo() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - receiver.setDisableSequenceNumberValidation(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-pending-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setTimeToWaitBeforeAck(9000); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(8000); - receiver.sendInDialogSipRequest("UPDATE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isAckReceived()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * TeleStax, Open Source Cloud Communications Copyright 2012. + * and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.reinvite; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; + +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import javax.sip.header.AllowHeader; +import javax.sip.header.Header; +import javax.sip.header.MaxForwardsHeader; +import javax.sip.header.UserAgentHeader; +import javax.sip.message.Response; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +/* + * + * Added for Issue 1409 http://code.google.com/p/mobicents/issues/detail?id=1409 + */ +public class CallForwardingB2BUAReInviteJunitTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(CallForwardingB2BUAReInviteJunitTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 20000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + TestSipListener receiver; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + + public CallForwardingB2BUAReInviteJunitTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + + } + + public SipStandardContext deployApplication(Map params) { + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + "sip-test", + params, + null); + assertTrue(ctx.getAvailable()); + return ctx; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/callcontroller/call-forwarding-b2bua-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects("forward-sender", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects("receiver", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + } + + public void testCallForwardingCallerSendBye() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setSendReinvite(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployApplication(params); + + String fromName = "forward-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isInviteReceived()); + assertTrue(sender.isAckReceived()); + assertNotNull(sender.getInviteRequest().getHeader("ReInvite")); + MaxForwardsHeader maxForwardsHeader = (MaxForwardsHeader) receiver.getInviteRequest().getHeader(MaxForwardsHeader.NAME); + assertNotNull(maxForwardsHeader); + // Non Regression test for http://code.google.com/p/mobicents/issues/detail?id=1490 + // B2buaHelper.createRequest does not decrement Max-forwards + assertEquals(69, maxForwardsHeader.getMaxForwards()); + sender.sendInDialogSipRequest("BYE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + assertTrue(sender.getOkToByeReceived()); + assertEquals(1, sender.bindings); //http://code.google.com/p/mobicents/issues/detail?id=2100 + maxForwardsHeader = (MaxForwardsHeader) receiver.getByeRequestReceived().getHeader(MaxForwardsHeader.NAME); + assertNotNull(maxForwardsHeader); + // Non Regression test for http://code.google.com/p/mobicents/issues/detail?id=1490 + // B2buaHelper.createRequest does not decrement Max-forwards + assertEquals(69, maxForwardsHeader.getMaxForwards()); + } + + // Issue 2500 http://code.google.com/p/mobicents/issues/detail?id=2500 + // B2buaHelper.createRequest() throws a NullPointerException if the request contains an empty header + public void testCallForwardingCallerSendReInviteSendBye() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployApplication(params); + + String fromName = "forward-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[]{AllowHeader.NAME}, new String[]{"INVITE, CANCEL, BYE, ACK, OPTIONS"}, true); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isInviteReceived()); + assertTrue(receiver.isAckReceived()); + MaxForwardsHeader maxForwardsHeader = (MaxForwardsHeader) receiver.getInviteRequest().getHeader(MaxForwardsHeader.NAME); + assertNotNull(maxForwardsHeader); + // Non Regression test for http://code.google.com/p/mobicents/issues/detail?id=1490 + // B2buaHelper.createRequest does not decrement Max-forwards + assertEquals(69, maxForwardsHeader.getMaxForwards()); + + ListIterator allowHeaderIt = receiver.getInviteRequest().getHeaders(AllowHeader.NAME); + int i = 0; + while (allowHeaderIt.hasNext()) { + allowHeaderIt.next(); + i++; + } + assertEquals(5, i); + + Header methodHeader = receiverProtocolObjects.headerFactory.createHeader("Supported", ""); + // Non Regression for Issue 184 http://code.google.com/p/sipservlets/issues/detail?id=184 + Header allowHeader = receiverProtocolObjects.headerFactory.createAllowHeader("INVITE, CANCEL, BYE, ACK, OPTIONS"); + List
headers = new ArrayList
(); + headers.add(methodHeader); + headers.add(allowHeader); + + //reset state before sending signalling + receiver.setInviteReceived(false); + receiver.setAckReceived(false); + sender.sendInDialogSipRequest("INVITE", null, null, null, headers, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isInviteReceived()); + assertTrue(receiver.isAckReceived()); + allowHeaderIt = receiver.getInviteRequest().getHeaders(AllowHeader.NAME); + i = 0; + while (allowHeaderIt.hasNext()) { + allowHeaderIt.next(); + i++; + } + assertEquals(5, i); + sender.sendInDialogSipRequest("BYE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + assertTrue(sender.getOkToByeReceived()); + } + + /** + * Non Regression test for + * http://code.google.com/p/mobicents/issues/detail?id=2230 BYE is routed to + * unexpected IP + */ + public void testCallForwardingCallerSendBye408onReinvite() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployApplication(params); + + String fromName = "forward-sender-408"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isInviteReceived()); + assertTrue(receiver.isAckReceived()); + MaxForwardsHeader maxForwardsHeader = (MaxForwardsHeader) receiver.getInviteRequest().getHeader(MaxForwardsHeader.NAME); + assertNotNull(maxForwardsHeader); + receiver.setFinalResponseToSend(Response.REQUEST_TIMEOUT); + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isInviteReceived()); + assertTrue(receiver.isAckReceived()); + + // Non Regression test for http://code.google.com/p/mobicents/issues/detail?id=1490 + // B2buaHelper.createRequest does not decrement Max-forwards + assertEquals(69, maxForwardsHeader.getMaxForwards()); + sender.sendInDialogSipRequest("BYE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + assertTrue(sender.getOkToByeReceived()); + } + + /** + * Non Regression test for + * http://code.google.com/p/mobicents/issues/detail?id=2230 BYE is routed to + * unexpected IP + */ + public void testCallForwardingCallerSendBye408onReinviteBYENewThread() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployApplication(params); + + String fromName = "forward-sender-408-new-thread"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isInviteReceived()); + assertTrue(receiver.isAckReceived()); + MaxForwardsHeader maxForwardsHeader = (MaxForwardsHeader) receiver.getInviteRequest().getHeader(MaxForwardsHeader.NAME); + assertNotNull(maxForwardsHeader); + receiver.setProvisionalResponsesToSend(new ArrayList()); + receiver.setFinalResponseToSend(Response.REQUEST_TIMEOUT); + Header methodHeader = receiverProtocolObjects.headerFactory.createHeader("Method", "BYE"); + List
headers = new ArrayList
(); + headers.add(methodHeader); + sender.sendInDialogSipRequest("INVITE", null, null, null, headers, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isInviteReceived()); + assertTrue(receiver.isAckReceived()); + + receiver.sendInDialogSipRequest("UPDATE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isInviteReceived()); + assertTrue(receiver.isAckReceived()); + + sender.sendInDialogSipRequest("BYE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + assertTrue(sender.getOkToByeReceived()); + } + + /** + * Non Regression test for + * http://code.google.com/p/mobicents/issues/detail?id=2230 BYE is routed to + * unexpected IP + */ + public void testCallForwardingCallerSendBye408onReinviteUPDATENewThread() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployApplication(params); + + String fromName = "forward-sender-408-new-thread"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isInviteReceived()); + assertTrue(receiver.isAckReceived()); + MaxForwardsHeader maxForwardsHeader = (MaxForwardsHeader) receiver.getInviteRequest().getHeader(MaxForwardsHeader.NAME); + assertNotNull(maxForwardsHeader); + receiver.setProvisionalResponsesToSend(new ArrayList()); + receiver.setFinalResponseToSend(Response.REQUEST_TIMEOUT); + Header methodHeader = receiverProtocolObjects.headerFactory.createHeader("Method", "UPDATE"); + List
headers = new ArrayList
(); + headers.add(methodHeader); + sender.sendInDialogSipRequest("INVITE", null, null, null, headers, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isInviteReceived()); + assertTrue(receiver.isAckReceived()); + + receiver.sendInDialogSipRequest("UPDATE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isInviteReceived()); + assertTrue(receiver.isAckReceived()); + + sender.sendInDialogSipRequest("BYE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertTrue(sender.getAllMessagesContent().contains("IllegalStateException")); + } + + /** + * Non Regression test for + * http://code.google.com/p/mobicents/issues/detail?id=1445 "Bad Request + * Method. CANCEL" during sending CANCEL to re-INVITE + */ + public void testCallForwardingCallerReInviteCancel() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployApplication(params); + + String fromName = "forward-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + receiver.setWaitForCancel(true); + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + Thread.sleep(500); + sender.sendCancel(); + Thread.sleep(TIMEOUT); + assertTrue(sender.isCancelOkReceived()); + assertTrue(sender.isRequestTerminatedReceived()); + assertTrue(receiver.isCancelReceived()); + sender.setCancelOkReceived(false); + sender.setRequestTerminatedReceived(false); + receiver.setCancelReceived(false); + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + Thread.sleep(500); + sender.sendCancel(); + Thread.sleep(TIMEOUT); + assertTrue(sender.isCancelOkReceived()); + assertTrue(sender.isRequestTerminatedReceived()); + assertTrue(receiver.isCancelReceived()); + } + + /** + * Non Regression test for + * http://code.google.com/p/mobicents/issues/detail?id=1837 ACK was received + * by JAIN-SIP but was not routed to application + */ + public void testCallForwardingCallerReInviteAckRaceInfo() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setDisableSequenceNumberValidation(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployApplication(params); + + String fromName = "forward-pending-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setTimeToWaitBeforeAck(9000); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(8000); + receiver.sendInDialogSipRequest("UPDATE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isAckReceived()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/reinvite/LocationServiceReInviteSipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/reinvite/LocationServiceReInviteSipServletTest.java index 8b089e3016..bd1ac48d8c 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/reinvite/LocationServiceReInviteSipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/reinvite/LocationServiceReInviteSipServletTest.java @@ -1,154 +1,174 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.reinvite; - -import java.text.ParseException; - -import javax.sip.InvalidArgumentException; -import javax.sip.SipException; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; -import javax.sip.address.URI; -import javax.sip.header.ContactHeader; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -/** - * Testing of RFC3665-3.7 -- Session with re-INVITE - * - * @author Jean Deruelle - * - */ -public class LocationServiceReInviteSipServletTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(LocationServiceReInviteSipServletTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 20000; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender; - TestSipListener receiver; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - - - public LocationServiceReInviteSipServletTest(String name) { - super(name); -// createTomcatOnStartup = false; - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/location-service-servlet/src/main/sipapp", - "location-service-context", - "location-service")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/reinvite/locationservice-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects =new ProtocolObjects( - "reinvite", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - receiverProtocolObjects = new ProtocolObjects("receiver", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - senderProvider.addSipListener(sender); - senderProtocolObjects.start(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - receiverProvider.addSipListener(receiver); - receiverProtocolObjects.start(); - } - - public void testReInvite() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "reinvite"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver-failover"; - String toSipAddress = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - receiver.setSendReinvite(true); - receiver.setWaitBeforeFinalResponse(2000); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); - Thread.sleep(TIMEOUT); - assertTrue(sender.isInviteReceived()); - URI requestUri = sender.getInviteRequest().getRequestURI(); - // https://code.google.com/p/sipservlets/issues/detail?id=275 - assertEquals("sip:reinvite@127.0.0.1:5080;transport=udp;lr", requestUri.toString().trim()); - sender.sendInDialogSipRequest("BYE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - assertTrue(sender.getOkToByeReceived()); - } - - public void testReInviteSending() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "isendreinvite"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver-failover"; - String toSipAddress = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5090"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setSendReinvite(true); - sender.setSendBye(true); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - assertTrue(sender.getOkToByeReceived()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.reinvite; + +import java.text.ParseException; +import java.util.HashMap; +import java.util.Map; + +import javax.sip.InvalidArgumentException; +import javax.sip.SipException; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import javax.sip.address.URI; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +/** + * Testing of RFC3665-3.7 -- Session with re-INVITE + * + * @author Jean Deruelle + * + */ +public class LocationServiceReInviteSipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(LocationServiceReInviteSipServletTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 20000; +// private static final int TIMEOUT = 100000000; + private int senderPort = 5080; + private int receiverPort = 5090; + + TestSipListener sender; + TestSipListener receiver; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + + public LocationServiceReInviteSipServletTest(String name) { + super(name); +// createTomcatOnStartup = false; + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + + } + + public SipStandardContext deployApplication(Map params) { + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/location-service-servlet/src/main/sipapp", + "location-service", + params, + null); + assertTrue(ctx.getAvailable()); + return ctx; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/reinvite/locationservice-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects( + "reinvite", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects("receiver", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployApplication(params); + } + + public void testReInvite() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "reinvite"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver-failover"; + String toSipAddress = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + receiverPort; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + receiver.setSendReinvite(true); + receiver.setWaitBeforeFinalResponse(2000); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); + Thread.sleep(TIMEOUT); + assertTrue(sender.isInviteReceived()); + URI requestUri = sender.getInviteRequest().getRequestURI(); + // https://code.google.com/p/sipservlets/issues/detail?id=275 + assertEquals("sip:reinvite@127.0.0.1:" + senderPort + ";transport=udp;lr", requestUri.toString().trim()); + sender.sendInDialogSipRequest("BYE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + assertTrue(sender.getOkToByeReceived()); + } + + public void testReInviteSending() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "isendreinvite"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver-failover"; + String toSipAddress = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + receiverPort; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setSendReinvite(true); + sender.setSendBye(true); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + assertTrue(sender.getOkToByeReceived()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/reinvite/ReInviteSipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/reinvite/ReInviteSipServletTest.java index ee8c98b5fd..818515940c 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/reinvite/ReInviteSipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/reinvite/ReInviteSipServletTest.java @@ -1,244 +1,260 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.reinvite; - -import javax.sip.ListeningPoint; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; -import javax.sip.message.Request; - -import org.apache.catalina.deploy.ApplicationParameter; -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -/** - * Testing of RFC3665-3.7 -- Session with re-INVITE - * - * @author Jean Deruelle - * - */ -public class ReInviteSipServletTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(ReInviteSipServletTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender; - - ProtocolObjects senderProtocolObjects; - - - public ReInviteSipServletTest(String name) { - super(name); - autoDeployOnStartup = false; - } - - public SipStandardContext deployApplication(String name, String value) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(name); - applicationParameter.setValue(value); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - return context; - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/simple/simple-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.sipIpAddress="0.0.0.0"; - super.setUp(); - } - - public void testReInvite() throws Exception { - senderProtocolObjects =new ProtocolObjects( - "reinvite", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - - String fromName = "reinvite"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - deployApplication(); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.getByeReceived()); - } - - public void testReInviteSending() throws Exception { - senderProtocolObjects =new ProtocolObjects( - "reinvite", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - - deployApplication(); - - String fromName = "isendreinvite"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setSendReinvite(true); - sender.setSendBye(true); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.getOkToByeReceived()); - } - - /* - * Non regression test for Issue 1456 http://code.google.com/p/mobicents/issues/detail?id=1456 - * java.lang.RuntimeException: Unexpected internal error FIXME!! Cannot create ACK - no ListeningPoint for transport towards next hop found:UDP - * Test comment 18 of the Issue - */ - public void testReInviteTCPSending() throws Exception { - senderProtocolObjects =new ProtocolObjects( - "reinvite", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - sender = new TestSipListener(5081, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - tomcat.addSipConnector(serverName, super.sipIpAddress, 5070, ListeningPoint.TCP); - String fromName = "SSsendBye"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.addListeningPoint("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", 5081, ListeningPoint.TCP); - senderProtocolObjects.start(); - - sender.setSendBye(false); - sender.setTransport(false); - - deployApplication(); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - sender.sendInDialogSipRequest(Request.INFO, null, null, null, null, ListeningPoint.TCP); - Thread.sleep(TIMEOUT * 2); - assertTrue(sender.getByeReceived()); - } - - /* - * Non regression test for Issue 1822 - * http://code.google.com/p/mobicents/issues/detail?id=1822 - */ - public void testNoAckOnReInvite() throws Exception { - senderProtocolObjects =new ProtocolObjects( - "reinvite", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - String fromName = "SSsendBye"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - senderProtocolObjects.start(); - - sender.setSendBye(false); - sender.setTransport(false); - - deployApplication("byeDelay", "50000"); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertEquals(sender.getFinalResponseStatus(), 200); - sender.setSendAck(false); - sender.sendInDialogSipRequest(Request.INVITE, null, null, null, null, ListeningPoint.UDP); - Thread.sleep(TIMEOUT * 6); - assertTrue(sender.getAllMessagesContent().contains("noAckReceived")); - assertTrue(sender.getByeReceived()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.reinvite; + +import java.util.HashMap; +import java.util.Map; +import javax.sip.ListeningPoint; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import javax.sip.message.Request; +import static junit.framework.Assert.assertTrue; + +import org.apache.catalina.deploy.ApplicationParameter; +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.catalina.SipStandardManager; +import org.mobicents.servlet.sip.startup.SipContextConfig; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +/** + * Testing of RFC3665-3.7 -- Session with re-INVITE + * + * @author Jean Deruelle + * + */ +public class ReInviteSipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ReInviteSipServletTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + + ProtocolObjects senderProtocolObjects; + + public ReInviteSipServletTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + public SipStandardContext deployApplication(Map params) { + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp", + "sip-tes", + params, + null); + assertTrue(ctx.getAvailable()); + return ctx; + } + + @Override + public void deployApplication() { + + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/simple/simple-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + super.sipIpAddress = "0.0.0.0"; + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + } + + public void testReInvite() throws Exception { + senderProtocolObjects = new ProtocolObjects( + "reinvite", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + + String fromName = "reinvite"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployApplication(params); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.getByeReceived()); + } + + public void testReInviteSending() throws Exception { + senderProtocolObjects = new ProtocolObjects( + "reinvite", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployApplication(params); + + String fromName = "isendreinvite"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setSendReinvite(true); + sender.setSendBye(true); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + } + + /* + * Non regression test for Issue 1456 http://code.google.com/p/mobicents/issues/detail?id=1456 + * java.lang.RuntimeException: Unexpected internal error FIXME!! Cannot create ACK - no ListeningPoint for transport towards next hop found:UDP + * Test comment 18 of the Issue + */ + public void testReInviteTCPSending() throws Exception { + senderProtocolObjects = new ProtocolObjects( + "reinvite", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + + senderProvider.addSipListener(sender); + + tomcat.addSipConnector(serverName, super.sipIpAddress, containerPort, ListeningPoint.TCP); + String fromName = "SSsendBye"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.addListeningPoint("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", senderPort, ListeningPoint.TCP); + senderProtocolObjects.start(); + + sender.setSendBye(false); + sender.setTransport(false); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployApplication(params); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + sender.sendInDialogSipRequest(Request.INFO, null, null, null, null, ListeningPoint.TCP); + Thread.sleep(TIMEOUT * 2); + assertTrue(sender.getByeReceived()); + } + + /* + * Non regression test for Issue 1822 + * http://code.google.com/p/mobicents/issues/detail?id=1822 + */ + public void testNoAckOnReInvite() throws Exception { + senderProtocolObjects = new ProtocolObjects( + "reinvite", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + + senderProvider.addSipListener(sender); + + String fromName = "SSsendBye"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + senderProtocolObjects.start(); + + sender.setSendBye(false); + sender.setTransport(false); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + params.put("senderPort", String.valueOf(senderPort)); + params.put("byeDelay", "50000"); + deployApplication(params); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertEquals(sender.getFinalResponseStatus(), 200); + sender.setSendAck(false); + sender.sendInDialogSipRequest(Request.INVITE, null, null, null, null, ListeningPoint.UDP); + Thread.sleep(TIMEOUT * 6); + assertTrue(sender.getAllMessagesContent().contains("noAckReceived")); + assertTrue(sender.getByeReceived()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/reinvite/UACReInviteSipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/reinvite/UACReInviteSipServletTest.java index 97409783ac..561d42a371 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/reinvite/UACReInviteSipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/reinvite/UACReInviteSipServletTest.java @@ -1,202 +1,196 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.reinvite; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.Map.Entry; - -import javax.sip.SipProvider; -import javax.sip.header.Header; -import javax.sip.header.RecordRouteHeader; -import javax.sip.message.Response; - -import org.apache.catalina.deploy.ApplicationParameter; -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class UACReInviteSipServletTest extends SipServletTestCase { - private static transient Logger logger = Logger.getLogger(UACReInviteSipServletTest.class); - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; -// private static final int TIMEOUT = 100000000; - - TestSipListener receiver; - - ProtocolObjects receiverProtocolObjects; - - public UACReInviteSipServletTest(String name) { - super(name); - startTomcatOnStartup = false; - autoDeployOnStartup = false; - } - - @Override - public void deployApplication() { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName("username"); - applicationParameter.setValue("reinvite"); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - } - - public SipStandardContext deployApplication(Map params) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - for (Entry param : params.entrySet()) { - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(param.getKey()); - applicationParameter.setValue(param.getValue()); - context.addApplicationParameter(applicationParameter); - } - assertTrue(tomcat.deployContext(context)); - return context; - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/simple/shootist-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - } - - public void testShootistReInvite() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - deployApplication(); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - } - - /** - * Non Regression test for - * http://code.google.com/p/mobicents/issues/detail?id=2066 - * Miss Record-Route in Response - */ - public void testShootistReInviteRecordRouteHeaders() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "recordrouteeinvite", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - Map params = new HashMap(); - params.put("username", "recordrouteeinvite"); - params.put("timeToWaitForBye", "15000"); - deployApplication(params); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isAckReceived()); - - List
headers = new ArrayList
(); - headers.add(receiverProtocolObjects.headerFactory.createHeader(RecordRouteHeader.NAME, "sip:" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080")); - receiver.sendInDialogSipRequest("INVITE", null, null, null, headers, null); - Thread.sleep(TIMEOUT); - - Response reinviteOKResponse = receiver.getInviteOkResponse(); - ListIterator
recordRouteHeaders = reinviteOKResponse.getHeaders(RecordRouteHeader.NAME); - assertTrue(recordRouteHeaders.hasNext()); - - assertTrue(receiver.getByeReceived()); - } - - /** - * Non Regression test for - * http://code.google.com/p/mobicents/issues/detail?id=2066 - * Miss Record-Route in Response - */ - public void testShootistReInviteNonRecordRouteHeaders() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "recordrouteeinvite", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - Map params = new HashMap(); - params.put("username", "nonrecordrouteeinvite"); - params.put("timeToWaitForBye", "15000"); - deployApplication(params); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isAckReceived()); - - List
headers = new ArrayList
(); - headers.add(receiverProtocolObjects.headerFactory.createHeader(RecordRouteHeader.NAME, "sip:" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080")); - receiver.sendInDialogSipRequest("INVITE", null, null, null, headers, null); - Thread.sleep(TIMEOUT); - - Response reinviteOKResponse = receiver.getInviteOkResponse(); - ListIterator
recordRouteHeaders = reinviteOKResponse.getHeaders(RecordRouteHeader.NAME); - assertFalse(recordRouteHeaders.hasNext()); - - assertTrue(receiver.getByeReceived()); - } - - @Override - protected void tearDown() throws Exception { - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } -} \ No newline at end of file +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.reinvite; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; + +import javax.sip.SipProvider; +import javax.sip.header.Header; +import javax.sip.header.RecordRouteHeader; +import javax.sip.message.Response; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class UACReInviteSipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(UACReInviteSipServletTest.class); + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; +// private static final int TIMEOUT = 100000000; + + TestSipListener receiver; + + ProtocolObjects receiverProtocolObjects; + + public UACReInviteSipServletTest(String name) { + super(name); + startTomcatOnStartup = false; + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + public SipStandardContext deployApplication(Map params) { + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp", + "sip-tes", + params, + null); + assertTrue(ctx.getAvailable()); + return ctx; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/simple/shootist-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + } + + public void testShootistReInvite() throws Exception { +// receiver.sendInvite(); + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("username","reinvite"); + deployApplication(params); + + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + } + + /** + * Non Regression test for + * http://code.google.com/p/mobicents/issues/detail?id=2066 Miss + * Record-Route in Response + */ + public void testShootistReInviteRecordRouteHeaders() throws Exception { +// receiver.sendInvite(); + receiverProtocolObjects = new ProtocolObjects( + "recordrouteeinvite", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + Map params = new HashMap(); + params.put("username", "recordrouteeinvite"); + params.put("timeToWaitForBye", "15000"); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + deployApplication(params); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isAckReceived()); + + List
headers = new ArrayList
(); + headers.add(receiverProtocolObjects.headerFactory.createHeader(RecordRouteHeader.NAME, "sip:" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + receiverPort)); + receiver.sendInDialogSipRequest("INVITE", null, null, null, headers, null); + Thread.sleep(TIMEOUT); + + Response reinviteOKResponse = receiver.getInviteOkResponse(); + ListIterator
recordRouteHeaders = reinviteOKResponse.getHeaders(RecordRouteHeader.NAME); + assertTrue(recordRouteHeaders.hasNext()); + + assertTrue(receiver.getByeReceived()); + } + + /** + * Non Regression test for + * http://code.google.com/p/mobicents/issues/detail?id=2066 Miss + * Record-Route in Response + */ + public void testShootistReInviteNonRecordRouteHeaders() throws Exception { +// receiver.sendInvite(); + receiverProtocolObjects = new ProtocolObjects( + "recordrouteeinvite", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + Map params = new HashMap(); + params.put("username", "nonrecordrouteeinvite"); + params.put("timeToWaitForBye", "15000"); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + deployApplication(params); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isAckReceived()); + + List
headers = new ArrayList
(); + headers.add(receiverProtocolObjects.headerFactory.createHeader(RecordRouteHeader.NAME, "sip:" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + receiverPort)); + receiver.sendInDialogSipRequest("INVITE", null, null, null, headers, null); + Thread.sleep(TIMEOUT); + + Response reinviteOKResponse = receiver.getInviteOkResponse(); + ListIterator
recordRouteHeaders = reinviteOKResponse.getHeaders(RecordRouteHeader.NAME); + assertFalse(recordRouteHeaders.hasNext()); + + assertTrue(receiver.getByeReceived()); + } + + @Override + protected void tearDown() throws Exception { + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/replaces/ReplacesSipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/replaces/ReplacesSipServletTest.java index edce7544da..be4c96be00 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/replaces/ReplacesSipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/replaces/ReplacesSipServletTest.java @@ -1,188 +1,223 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.replaces; - -import gov.nist.javax.sip.header.extensions.ReplacesHeader; - -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -/** - * Test the behavior of Mobicents Sip Servlets with regard to Replaces (RFC 3891) Support - * @author jean.deruelle@gmail.com - * - */ -public class ReplacesSipServletTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(ReplacesSipServletTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 30000; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender; - TestSipListener receiver; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - - public ReplacesSipServletTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/replaces-sip-servlet/src/main/sipapp", - "replaces-context", - "replaces-dial")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/replaces/replaces-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects = new ProtocolObjects("sender", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - receiverProtocolObjects = new ProtocolObjects("receiver", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - } - - public void testSipServletSendsReplaces() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - receiver.setWaitBeforeFinalResponse(2000); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "sender"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "replaces"; - String toHost = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isReplacesRequestReceived()); - assertTrue(receiver.getOkToByeReceived()); - assertTrue(sender.getByeReceived()); - } - - public void testSipServletReceivesReplaces() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "sender"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "replaces-receiver"; - String toHost = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertNotNull(receiver.getLastMessageContent()); - assertFalse(receiver.isServerErrorReceived()); - assertTrue(receiver.getByeReceived()); - assertTrue(sender.getByeReceived()); - } - - /* - * Non regression test for Issue 2048 - */ - public void testSipServletReceivesReplacesNoDialog() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - - String fromName = "sender"; - String fromHost = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromHost); - - String toUser = "replaces-no-dialog"; - String toHost = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toHost); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[] {ReplacesHeader.NAME}, new String[] {"YWJiMDVhYWQ5ZmRmNDdmMGZmZjU4MDE0MzY0ODRlZWQ.;from-tag=61190912_4d8055f4_51b2ad2b-94d2-4b51-bfbe-fc8381cf5857;to-tag=243e7a12"}, true); - Thread.sleep(TIMEOUT); - assertTrue(sender.isFinalResponseReceived()); - assertFalse(sender.isServerErrorReceived()); - assertTrue(sender.getOkToByeReceived()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.replaces; + +import gov.nist.javax.sip.header.extensions.ReplacesHeader; +import java.util.HashMap; +import java.util.Map; + +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +/** + * Test the behavior of Mobicents Sip Servlets with regard to Replaces (RFC + * 3891) Support + * + * @author jean.deruelle@gmail.com + * + */ +public class ReplacesSipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ReplacesSipServletTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 30000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + TestSipListener receiver; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + + public ReplacesSipServletTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + public SipStandardContext deployApplication(Map params) { + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/replaces-sip-servlet/src/main/sipapp", + "sip-test", + params, + null); + assertTrue(ctx.getAvailable()); + return ctx; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/replaces/replaces-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects("sender", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects("receiver", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + } + + public void testSipServletSendsReplaces() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + receiver.setWaitBeforeFinalResponse(2000); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployApplication(params); + + String fromName = "sender"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "replaces"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isReplacesRequestReceived()); + assertTrue(receiver.getOkToByeReceived()); + assertTrue(sender.getByeReceived()); + } + + public void testSipServletReceivesReplaces() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployApplication(params); + + String fromName = "sender"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "replaces-receiver"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertNotNull(receiver.getLastMessageContent()); + assertFalse(receiver.isServerErrorReceived()); + assertTrue(receiver.getByeReceived()); + assertTrue(sender.getByeReceived()); + } + + /* + * Non regression test for Issue 2048 + */ + public void testSipServletReceivesReplacesNoDialog() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployApplication(params); + + String fromName = "sender"; + String fromHost = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromHost); + + String toUser = "replaces-no-dialog"; + String toHost = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toHost); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[]{ReplacesHeader.NAME}, new String[]{"YWJiMDVhYWQ5ZmRmNDdmMGZmZjU4MDE0MzY0ODRlZWQ.;from-tag=61190912_4d8055f4_51b2ad2b-94d2-4b51-bfbe-fc8381cf5857;to-tag=243e7a12"}, true); + Thread.sleep(TIMEOUT); + assertTrue(sender.isFinalResponseReceived()); + assertFalse(sender.isServerErrorReceived()); + assertTrue(sender.getOkToByeReceived()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/routing/ExternalApplicationRoutingTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/routing/ExternalApplicationRoutingTest.java index 73b822f1e9..9e7bffeda6 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/routing/ExternalApplicationRoutingTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/routing/ExternalApplicationRoutingTest.java @@ -1,215 +1,231 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.routing; - -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class ExternalApplicationRoutingTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(ExternalApplicationRoutingTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender; - TestSipListener receiver; - - ProtocolObjects senderProtocolObjects; - ProtocolObjects recieverProtocolObjects; - - public ExternalApplicationRoutingTest(String name) { - super(name); - startTomcatOnStartup = false; - autoDeployOnStartup = false; - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/simple/simple-sip-servlet-dar.properties"; - } - - protected String getEmptyDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/routing/external/empty-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - - - recieverProtocolObjects =new ProtocolObjects( - "registerReciever", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5058, 5070, recieverProtocolObjects, false); - SipProvider registerRecieverProvider = receiver.createProvider(); - - registerRecieverProvider.addSipListener(receiver); - - recieverProtocolObjects.start(); - } - - - // If an app is called even if it just send an informational response nothing make sure it is not forwarded outside - public void testExternalRoutingWithoutFinalResponse() throws Exception { - tomcat.startTomcat(); - deployApplication(); - - String fromName = "testExternalRouting"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - String r = "requestUri"; - String ra = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5058"; - SipURI requestUri = senderProtocolObjects.addressFactory.createSipURI( - r, ra); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, null, null, requestUri); - Thread.sleep(TIMEOUT); - assertTrue(sender.getOkToByeReceived()); - assertFalse(receiver.isInviteReceived()); - } - - // If an app is called even if it does nothing make sure it is not forwarded outside - public void testExternalRoutingWithoutInfoResponse() throws Exception { - tomcat.startTomcat(); - deployApplication(); - - String fromName = "testExternalRoutingNoInfo"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - String r = "requestUri"; - String ra = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5058"; - SipURI requestUri = senderProtocolObjects.addressFactory.createSipURI( - r, ra); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, null, null, requestUri); - Thread.sleep(TIMEOUT); - assertTrue(sender.getOkToByeReceived()); - assertFalse(receiver.isInviteReceived()); - } - - // If no app is called make sure it is forwarded outside - public void testExternalRoutingNoAppCalled() throws Exception { - tomcat.setDarConfigurationFilePath(getEmptyDarConfigurationFile()); - tomcat.startTomcat(); - - String fromName = "testExternalRoutingNoAppCalled"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - String r = "requestUri"; - String ra = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5058"; - SipURI requestUri = senderProtocolObjects.addressFactory.createSipURI( - r, ra); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, null, null, requestUri); - Thread.sleep(TIMEOUT); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.isInviteReceived()); - assertTrue(receiver.getByeReceived()); - } - - // If no app is called make sure it is forwarded outside even for ReInvite - public void testExternalRoutingNoAppCalledReInvite() throws Exception { - tomcat.setDarConfigurationFilePath(getEmptyDarConfigurationFile()); - tomcat.startTomcat(); - - String fromName = "testExternalRoutingNoAppCalled"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - String r = "requestUri"; - String ra = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5058"; - SipURI requestUri = senderProtocolObjects.addressFactory.createSipURI( - r, ra); - - sender.setSendReinvite(true); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, null, null, requestUri); - Thread.sleep(TIMEOUT); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.isInviteReceived()); - assertTrue(receiver.getByeReceived()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - recieverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.routing; + +import java.util.HashMap; +import java.util.Map; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class ExternalApplicationRoutingTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ExternalApplicationRoutingTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + TestSipListener receiver; + + ProtocolObjects senderProtocolObjects; + ProtocolObjects recieverProtocolObjects; + + private int receiverPort; + private int senderPort; + + public ExternalApplicationRoutingTest(String name) { + super(name); + startTomcatOnStartup = false; + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + public SipStandardContext deployApplication(Map params) { + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp", + "sip-test", + params, + null); + assertTrue(ctx.getAvailable()); + return ctx; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/simple/simple-sip-servlet-dar.properties"; + } + + protected String getEmptyDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/routing/external/empty-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + recieverProtocolObjects = new ProtocolObjects( + "registerReciever", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, recieverProtocolObjects, false); + SipProvider registerRecieverProvider = receiver.createProvider(); + registerRecieverProvider.addSipListener(receiver); + recieverProtocolObjects.start(); + } + + // If an app is called even if it just send an informational response nothing make sure it is not forwarded outside + public void testExternalRoutingWithoutFinalResponse() throws Exception { + tomcat.startTomcat(); + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployApplication(params); + + String fromName = "testExternalRouting"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + String r = "requestUri"; + String ra = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + receiverPort; + SipURI requestUri = senderProtocolObjects.addressFactory.createSipURI( + r, ra); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, null, null, requestUri); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + assertFalse(receiver.isInviteReceived()); + } + + // If an app is called even if it does nothing make sure it is not forwarded outside + public void testExternalRoutingWithoutInfoResponse() throws Exception { + tomcat.startTomcat(); + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployApplication(params); + + String fromName = "testExternalRoutingNoInfo"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + String r = "requestUri"; + String ra = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + receiverPort; + SipURI requestUri = senderProtocolObjects.addressFactory.createSipURI( + r, ra); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, null, null, requestUri); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + assertFalse(receiver.isInviteReceived()); + } + + // If no app is called make sure it is forwarded outside + public void testExternalRoutingNoAppCalled() throws Exception { + tomcat.setDarConfigurationFilePath(getEmptyDarConfigurationFile()); + tomcat.startTomcat(); + + String fromName = "testExternalRoutingNoAppCalled"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + String r = "requestUri"; + String ra = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + receiverPort; + SipURI requestUri = senderProtocolObjects.addressFactory.createSipURI( + r, ra); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, null, null, requestUri); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.isInviteReceived()); + assertTrue(receiver.getByeReceived()); + } + + // If no app is called make sure it is forwarded outside even for ReInvite + public void testExternalRoutingNoAppCalledReInvite() throws Exception { + tomcat.setDarConfigurationFilePath(getEmptyDarConfigurationFile()); + tomcat.startTomcat(); + + String fromName = "testExternalRoutingNoAppCalled"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + String r = "requestUri"; + String ra = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + receiverPort; + SipURI requestUri = senderProtocolObjects.addressFactory.createSipURI( + r, ra); + + sender.setSendReinvite(true); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, null, null, requestUri); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.isInviteReceived()); + assertTrue(receiver.getByeReceived()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + recieverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/routing/ExternalRoutingServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/routing/ExternalRoutingServletTest.java index 061e6b9962..034227680e 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/routing/ExternalRoutingServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/routing/ExternalRoutingServletTest.java @@ -1,153 +1,233 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.routing; - -import java.io.File; -import java.util.Properties; - -import javax.sip.ListeningPoint; - -import org.apache.log4j.Logger; -import org.cafesip.sipunit.SipPhone; -import org.cafesip.sipunit.SipStack; -import org.mobicents.servlet.sip.SipEmbedded; -import org.mobicents.servlet.sip.SipUnitServletTestCase; - -/** - * This test starts 2 sip servlets container - * one on 5069 that has the AR setup to ROUTE to the other server - * on port 5070 that has the LocationServiceSipServlet application installed. - * - * Then the test sends a REGISTER that goes through server 1 that routes it to server 2 - * Location Service sends back OK and it is routed back to UAC => test green - * - * @author Jean Deruelle - * - */ -public class ExternalRoutingServletTest extends SipUnitServletTestCase { - - private static transient Logger logger = Logger.getLogger(ExternalRoutingServletTest.class); - - private static final int TIMEOUT = 5000; - - private SipStack sipStackSender; - private SipPhone sipPhoneSender; - SipEmbedded closestTomcat; - - public ExternalRoutingServletTest(String name) { - super(name); - autoDeployOnStartup = false; - startTomcatOnStartup = false; - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/location-service-servlet/src/main/sipapp", - "location-service-context", - "location-service")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/routing/locationservice-dar.properties"; - } - - protected String getDarConfigurationFileForClosestServer() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/routing/externalrouting-dar.properties"; - } - - @Override - public void setUp() throws Exception { - super.setUp(); - System.setProperty("javax.servlet.sip.ar.spi.SipApplicationRouterProvider", "org.mobicents.servlet.sip.router.DefaultApplicationRouterProvider"); - } - - public SipStack makeStack(String transport, int port) throws Exception { - Properties properties = new Properties(); - String peerHostPort1 = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5069"; - properties.setProperty("javax.sip.OUTBOUND_PROXY", peerHostPort1 + "/" - + "udp"); - properties.setProperty("javax.sip.STACK_NAME", "UAC_" + transport + "_" - + port); - properties.setProperty("sipunit.BINDADDR", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); - properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", - "logs/callforwarding_debug_" + port + ".txt"); - properties.setProperty("gov.nist.javax.sip.SERVER_LOG", - "logs/callforwarding_server_" + port + ".txt"); - properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "32"); - - return new SipStack(transport, port, properties); - } - - public void setupPhone(String fromAddress, String toAddress) throws Exception { - sipStackSender = makeStack(SipStack.PROTOCOL_UDP, 5080); - sipPhoneSender = sipStackSender.createSipPhone("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", - SipStack.PROTOCOL_UDP, 5069, fromAddress); - } - - public void testExternalRouting() throws Exception { - //start the most remote server first - tomcat.startTomcat(); - deployApplication(); - //create and start the closest server - //starting tomcat - closestTomcat = new SipEmbedded("SIP-Servlet-Closest-Tomcat-Server", serviceFullClassName); - closestTomcat.setLoggingFilePath( - projectHome + File.separatorChar + "sip-servlets-test-suite" + - File.separatorChar + "testsuite" + - File.separatorChar + "src" + - File.separatorChar + "test" + - File.separatorChar + "resources" + File.separatorChar); - logger.info("Log4j path is : " + closestTomcat.getLoggingFilePath()); - closestTomcat.setDarConfigurationFilePath(getDarConfigurationFileForClosestServer()); - closestTomcat.initTomcat(tomcatBasePath, null); - closestTomcat.addSipConnector("SIP-Servlet-Closest-Tomcat-Server", sipIpAddress, 5069, ListeningPoint.UDP); - closestTomcat.startTomcat(); - Thread.sleep(TIMEOUT); - setupPhone("sip:sender@sip-servlets.com", "sip:receiver@sip-servlets.com"); - boolean registerOK = sipPhoneSender.register(null, 3600); - assertTrue(registerOK); - } - - @Override - public void tearDown() throws Exception { - Thread.sleep(1000); - if(sipPhoneSender != null) { - sipPhoneSender.dispose(); - } - if(sipStackSender != null) { - sipStackSender.dispose(); - } - closestTomcat.stopTomcat(); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.routing; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.Writer; +import java.util.HashMap; +import java.util.Map; + +import javax.sip.ListeningPoint; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import static junit.framework.Assert.assertTrue; +import org.apache.catalina.deploy.ApplicationParameter; + +import org.apache.log4j.Logger; +import org.cafesip.sipunit.SipStack; +import org.junit.Ignore; +import org.junit.Test; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipEmbedded; +import org.mobicents.servlet.sip.SipUnitServletTestCase; +import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; +import org.mobicents.servlet.sip.catalina.SipStandardManager; +import org.mobicents.servlet.sip.startup.SipContextConfig; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +/** + * This test starts 2 sip servlets container one on 5069 that has the AR setup + * to ROUTE to the other server on port 5070 that has the + * LocationServiceSipServlet application installed. + * + * Then the test sends a REGISTER that goes through server 1 that routes it to + * server 2 Location Service sends back OK and it is routed back to UAC => test + * green + * + * @author Jean Deruelle + * + */ +public class ExternalRoutingServletTest extends SipUnitServletTestCase { + + private static transient Logger logger = Logger.getLogger(ExternalRoutingServletTest.class); + + private static final int TIMEOUT = 5000; + + private SipStack sipStackSender; + SipEmbedded closestTomcat; + private int closestTomcatPort; + + public ExternalRoutingServletTest(String name) { + super(name); + autoDeployOnStartup = false; + startTomcatOnStartup = false; + } + + @Override + public void deployApplication() { + + } + + public SipStandardContext deployApplication(Map params) { + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/location-service-servlet/src/main/sipapp", + "location-service", + params, + null); + assertTrue(ctx.getAvailable()); + return ctx; + } + + protected SipStandardContext deployApplicationInClosest(SipEmbedded closestTomcat, + String docBase, String name, Map params, ConcurrencyControlMode concurrencyControlMode) { + SipStandardContext context = new SipStandardContext(); + context.setDocBase(docBase); + context.setName(name); + context.setPath("/" + name); + context.addLifecycleListener(new SipContextConfig()); + context.setManager(new SipStandardManager()); + if (concurrencyControlMode != null) { + context.setConcurrencyControlMode(concurrencyControlMode); + } + if (params != null) { + for (Map.Entry param : params.entrySet()) { + ApplicationParameter applicationParameter = new ApplicationParameter(); + applicationParameter.setName(param.getKey()); + applicationParameter.setValue(param.getValue()); + context.addApplicationParameter(applicationParameter); + } + } + ctx = context; + assertTrue(closestTomcat.deployContext(context)); + return context; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/routing/locationservice-dar.properties"; + } + + protected String getDarConfigurationFileForClosestServer(int port) throws Exception { + String dar = "REGISTER: (\"org.mobicents.servlet.sip.testsuite.LocationServiceApplication\", \"DAR:From\", \"ORIGINATING\", \"sip:127.0.0.1:" + port + "\", \"ROUTE\", \"0\")"; + File darFile = new File("target/temp_dar.properties"); + FileWriter fWriter = new FileWriter(darFile); + Writer output; + output = new BufferedWriter(fWriter); + output.append(dar); + output.close(); + String filePath = darFile.toURL().toString(); + //TODO ugly fix for windows test + if (filePath.startsWith("file:/C")) { + filePath = "file:///" + darFile.getAbsolutePath(); + } else if (filePath.startsWith("file:/")) { + //for linux make sure file protocol is as expected + filePath = "file://" + darFile.getAbsolutePath(); + } + return filePath; + } + + @Override + public void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + System.setProperty("javax.servlet.sip.ar.spi.SipApplicationRouterProvider", "org.mobicents.servlet.sip.router.DefaultApplicationRouterProvider"); + } + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + TestSipListener sender; + int senderPort; + ProtocolObjects senderProtocolObjects; + + public void testExternalRouting() throws Exception { + //start the most remote server first + tomcat.startTomcat(); + + //create and start the closest server + closestTomcatPort = NetworkPortAssigner.retrieveNextPort(); + //starting tomcat + closestTomcat = new SipEmbedded("SIP-Servlet-Closest-Tomcat-Server", serviceFullClassName); + closestTomcat.setLoggingFilePath( + projectHome + File.separatorChar + "sip-servlets-test-suite" + + File.separatorChar + "testsuite" + + File.separatorChar + "src" + + File.separatorChar + "test" + + File.separatorChar + "resources" + + File.separatorChar + "org" + + File.separatorChar + "mobicents" + + File.separatorChar + "servlet" + + File.separatorChar + "sip" + + File.separatorChar + "testsuite" + + File.separatorChar + "routing" + + File.separatorChar + "closest" + + File.separatorChar + ); + logger.info("Log4j path is : " + closestTomcat.getLoggingFilePath()); + closestTomcat.setDarConfigurationFilePath(getDarConfigurationFileForClosestServer(containerPort)); + closestTomcat.initTomcat(tomcatBasePath, null); + closestTomcat.addSipConnector("SIP-Servlet-Closest-Tomcat-Server", sipIpAddress, closestTomcatPort, ListeningPoint.UDP); + closestTomcat.startTomcat(); + Thread.sleep(TIMEOUT); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("senderPort", String.valueOf(senderPort)); + deployApplication(params); + + deployApplicationInClosest(closestTomcat, + projectHome + "/sip-servlets-test-suite/applications/location-service-servlet/src/main/sipapp", + "location-service", + params, null); + + int senderPort = NetworkPortAssigner.retrieveNextPort(); + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, closestTomcatPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("REGISTER", fromAddress, toAddress, null, null, false, null, null, true); + Thread.sleep(TIMEOUT); + assertEquals("REGISTER correctly answered", 200, sender.getFinalResponseStatus()); + } + + @Override + public void tearDown() throws Exception { + Thread.sleep(1000); + senderProtocolObjects.destroy(); + if (sipStackSender != null) { + sipStackSender.dispose(); + } + closestTomcat.stopTomcat(); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/routing/RegexApplicationRoutingTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/routing/RegexApplicationRoutingTest.java index 407511a02d..d907be14b4 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/routing/RegexApplicationRoutingTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/routing/RegexApplicationRoutingTest.java @@ -1,159 +1,181 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.routing; - -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; -import org.mobicents.servlet.sip.testsuite.simple.ShootmeSipServletTest; - -/** - * This test starts 1 sip servlets container - * on port 5070 that has 2 services Shootme and Shootist. - * - * Then the shootist sends an INVITE that goes to Shootme. - * - * @author Jean Deruelle - * - */ -public class RegexApplicationRoutingTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(ShootmeSipServletTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; -// private static final int TIMEOUT = 100000000; - - - TestSipListener sender; - TestSipListener registerReciever; - - ProtocolObjects senderProtocolObjects; - ProtocolObjects registerRecieverProtocolObjects; - - boolean ok = true; - - public RegexApplicationRoutingTest(String name) { - super(name); - createTomcatOnStartup = false; - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - if(ok) { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/routing/regex-ok-sip-servlet-dar.properties"; - } else { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/routing/regex-ko-sip-servlet-dar.properties"; - } - } - - - @Override - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - - - registerRecieverProtocolObjects =new ProtocolObjects( - "registerReciever", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - registerReciever = new TestSipListener(5058, 5070, registerRecieverProtocolObjects, true); - SipProvider registerRecieverProvider = registerReciever.createProvider(); - - registerRecieverProvider.addSipListener(registerReciever); - - registerRecieverProtocolObjects.start(); - } - - public void testRegexMatching() throws Exception { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - createTomcat(); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - } - - public void testRegexNotMatching() throws Exception { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - ok = false; - createTomcat(); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[] {"additionalParameterableHeader","nonParameterableHeader"}, new String[] {"none","none"}, true); - Thread.sleep(TIMEOUT); - assertEquals(404,sender.getFinalResponseStatus()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - registerRecieverProtocolObjects.destroy(); - tomcat.stopTomcat(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.routing; + +import java.util.HashMap; +import java.util.Map; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; +import org.mobicents.servlet.sip.testsuite.simple.ShootmeSipServletTest; + +/** + * This test starts 1 sip servlets container on port 5070 that has 2 services + * Shootme and Shootist. + * + * Then the shootist sends an INVITE that goes to Shootme. + * + * @author Jean Deruelle + * + */ +public class RegexApplicationRoutingTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ShootmeSipServletTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + TestSipListener registerReciever; + + ProtocolObjects senderProtocolObjects; + ProtocolObjects registerRecieverProtocolObjects; + + boolean ok = true; + + private int registerPort; + private int senderPort; + + public RegexApplicationRoutingTest(String name) { + super(name); + createTomcatOnStartup = false; + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + + } + + public SipStandardContext deployApplication(Map params) { + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp", + "sip-test", + params, + null); + assertTrue(ctx.getAvailable()); + return ctx; + } + + @Override + protected String getDarConfigurationFile() { + if (ok) { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/routing/regex-ok-sip-servlet-dar.properties"; + } else { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/routing/regex-ko-sip-servlet-dar.properties"; + } + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + registerRecieverProtocolObjects = new ProtocolObjects( + "registerReciever", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + registerPort = NetworkPortAssigner.retrieveNextPort(); + registerReciever = new TestSipListener(registerPort, containerPort, registerRecieverProtocolObjects, true); + SipProvider registerRecieverProvider = registerReciever.createProvider(); + registerRecieverProvider.addSipListener(registerReciever); + registerRecieverProtocolObjects.start(); + + } + + public void testRegexMatching() throws Exception { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + createTomcat(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("registerPort", String.valueOf(registerPort)); + params.put("testPort", String.valueOf(senderPort)); + deployApplication(params); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + } + + public void testRegexNotMatching() throws Exception { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + ok = false; + createTomcat(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("registerPort", String.valueOf(registerPort)); + params.put("testPort", String.valueOf(senderPort)); + deployApplication(params); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[]{"additionalParameterableHeader", "nonParameterableHeader"}, new String[]{"none", "none"}, true); + Thread.sleep(TIMEOUT); + assertEquals(404, sender.getFinalResponseStatus()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + registerRecieverProtocolObjects.destroy(); + tomcat.stopTomcat(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/routing/SameContainerRoutingServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/routing/SameContainerRoutingServletTest.java index d2715c5ad7..56721ef682 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/routing/SameContainerRoutingServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/routing/SameContainerRoutingServletTest.java @@ -1,151 +1,165 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.routing; - -import java.util.ArrayList; -import java.util.List; - -import javax.sip.SipProvider; - -import org.apache.catalina.deploy.ApplicationParameter; -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -/** - * This test starts 1 sip servlets container - * on port 5070 that has 2 services Shootme and Shootist. - * - * Then the shootist sends an INVITE that goes to Shootme. - * - * @author Jean Deruelle - * - */ -public class SameContainerRoutingServletTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(SameContainerRoutingServletTest.class); - - private static final int TIMEOUT = 60000; - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - - TestSipListener sender; - ProtocolObjects senderProtocolObjects; - - public SameContainerRoutingServletTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/notifier-servlet/src/main/sipapp", - "notifier-context", - "notifier-service")); - } - - public void deployShootistApplication(List applicationParameterList) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/subscriber-servlet/src/main/sipapp"); - context.setName("subscriber-context"); - context.setPath("subscriber-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - for (ApplicationParameter applicationParameter : applicationParameterList) { - context.addApplicationParameter(applicationParameter); - } - assertTrue(tomcat.deployContext(context)); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/routing/samecontainer-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - senderProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070", null, null); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - senderProvider.addSipListener(sender); - senderProtocolObjects.start(); - } - - public void testSameContainerRouting() throws Exception { - List appParamList = new ArrayList(); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName("requestURI"); - applicationParameter.setValue("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070"); - appParamList.add(applicationParameter); - deployShootistApplication(appParamList); - Thread.sleep(TIMEOUT); - assertTrue(sender.getAllMessagesContent().size() > 0); - boolean dialogCompletedReceived =false; - for (String messageContent : sender.getAllMessagesContent()) { - if(messageContent.equalsIgnoreCase("dialogCompleted")) { - dialogCompletedReceived = true; - } - } - assertTrue(dialogCompletedReceived); - } - - public void testSameContainerRoutingNo200ToNotify() throws Exception { - List appParamList = new ArrayList(); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName("requestURI"); - applicationParameter.setValue("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070"); - ApplicationParameter applicationParameter2 = new ApplicationParameter(); - applicationParameter2.setName("no200OKToNotify"); - applicationParameter2.setValue("true"); - appParamList.add(applicationParameter); - appParamList.add(applicationParameter2); - deployShootistApplication(appParamList); - Thread.sleep(TIMEOUT); - assertTrue(sender.getAllMessagesContent().size() > 0); - boolean dialogCompletedReceived =false; - for (String messageContent : sender.getAllMessagesContent()) { - if(messageContent.equalsIgnoreCase("dialogCompleted")) { - dialogCompletedReceived = true; - } - } - assertTrue(dialogCompletedReceived); - } - - @Override - public void tearDown() throws Exception { - senderProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.routing; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.sip.SipProvider; +import static junit.framework.Assert.assertTrue; + +import org.apache.catalina.deploy.ApplicationParameter; +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.catalina.SipStandardManager; +import org.mobicents.servlet.sip.startup.SipContextConfig; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +/** + * This test starts 1 sip servlets container on port 5070 that has 2 services + * Shootme and Shootist. + * + * Then the shootist sends an INVITE that goes to Shootme. + * + * @author Jean Deruelle + * + */ +public class SameContainerRoutingServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(SameContainerRoutingServletTest.class); + + private static final int TIMEOUT = 60000; + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + + TestSipListener sender; + ProtocolObjects senderProtocolObjects; + + private int senderPort; + + public SameContainerRoutingServletTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + public SipStandardContext deployNotifierApplication(Map params) { + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/notifier-servlet/src/main/sipapp", + "notifier-test", + params, + null); + assertTrue(ctx.getAvailable()); + return ctx; + } + + public SipStandardContext deployShootistApplication(Map params) { + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/subscriber-servlet/src/main/sipapp", + "subscriber-test", + params, + null); + assertTrue(ctx.getAvailable()); + return ctx; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/routing/samecontainer-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + containerPort, null, null); + senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + } + + public void testSameContainerRouting() throws Exception { + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + + deployNotifierApplication(params); + + params.put("requestURI", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + containerPort); + deployShootistApplication(params); + + Thread.sleep(TIMEOUT); + assertTrue(sender.getAllMessagesContent().size() > 0); + boolean dialogCompletedReceived = false; + for (String messageContent : sender.getAllMessagesContent()) { + if (messageContent.equalsIgnoreCase("dialogCompleted")) { + dialogCompletedReceived = true; + } + } + assertTrue(dialogCompletedReceived); + } + + public void testSameContainerRoutingNo200ToNotify() throws Exception { + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + + deployNotifierApplication(params); + + params.put("requestURI", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + containerPort); + params.put("no200OKToNotify", "true"); + deployShootistApplication(params); + + Thread.sleep(TIMEOUT); + assertTrue(sender.getAllMessagesContent().size() > 0); + boolean dialogCompletedReceived = false; + for (String messageContent : sender.getAllMessagesContent()) { + if (messageContent.equalsIgnoreCase("dialogCompleted")) { + dialogCompletedReceived = true; + } + } + assertTrue(dialogCompletedReceived); + } + + @Override + public void tearDown() throws Exception { + senderProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/security/CallForwardingB2BUAAuthTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/security/CallForwardingB2BUAAuthTest.java index 522816fbb7..89c32ca106 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/security/CallForwardingB2BUAAuthTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/security/CallForwardingB2BUAAuthTest.java @@ -19,190 +19,226 @@ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ - package org.mobicents.servlet.sip.testsuite.security; +import java.util.HashMap; import java.util.ListIterator; +import java.util.Map; import javax.sip.SipProvider; import javax.sip.address.SipURI; import javax.sip.header.Header; +import static junit.framework.Assert.assertTrue; import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; import org.mobicents.servlet.sip.testsuite.ProtocolObjects; import org.mobicents.servlet.sip.testsuite.TestSipListener; public class CallForwardingB2BUAAuthTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(CallForwardingB2BUAAuthTest.class); - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; + private static transient Logger logger = Logger.getLogger(CallForwardingB2BUAAuthTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; // private static final int TIMEOUT = 100000000; - - TestSipListener sender; - TestSipListener receiver; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - - public CallForwardingB2BUAAuthTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", - "sip-test-context", - "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/callcontroller/call-forwarding-b2bua-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects = new ProtocolObjects("forward-sender", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - receiverProtocolObjects = new ProtocolObjects("receiver", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - } - - public void testCallForwardingAuth() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - receiver.setChallengeRequests(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[] {"Remote-Party-ID"}, new String[] {";screen=yes;privacy=off;party=calling;-call-initiator=5016;-call-initiator-location=int;-redirected-by;-int-ext=5016;-ent-name=Acro;-direction=ext;-call-id=55665"}, true); - Thread.sleep(TIMEOUT); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - // Non Regression test for http://code.google.com/p/mobicents/issues/detail?id=2094 - // B2b re-invite for authentication will duplicate Remote-Party-ID header - ListIterator
it = receiver.getInviteRequest().getHeaders("Remote-Party-ID"); - int nbHeaders= 0; - while (it.hasNext()) { - Header header = it.next(); - nbHeaders++; - } - assertEquals(1, nbHeaders); - } - - // Non regression test for issues 19 http://code.google.com/p/sipservlets/issues/detail?id=19 - // and http://code.google.com/p/sipservlets/issues/detail?id=161 - public void testCallForwardingShootmeAuthEarlyDialog() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - receiver.sendProvisionalResponseBeforeChallenge(true); - receiver.setChallengeRequests(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-sender-auth-early-dialog"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "forward-receiver-auth-early-dialog"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[] {"Remote-Party-ID"}, new String[] {";screen=yes;privacy=off;party=calling;-call-initiator=5016;-call-initiator-location=int;-redirected-by;-int-ext=5016;-ent-name=Acro;-direction=ext;-call-id=55665"}, true); - Thread.sleep(TIMEOUT*2); - assertTrue(sender.getOkToByeReceived()); - assertTrue(receiver.getByeReceived()); - // Non Regression test for http://code.google.com/p/mobicents/issues/detail?id=2094 - // B2b re-invite for authentication will duplicate Remote-Party-ID header - ListIterator
it = receiver.getInviteRequest().getHeaders("Remote-Party-ID"); - int nbHeaders= 0; - while (it.hasNext()) { - Header header = it.next(); - nbHeaders++; - } - assertEquals(1, nbHeaders); - } - - /* + + TestSipListener sender; + TestSipListener receiver; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + + public CallForwardingB2BUAAuthTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + + } + + public SipStandardContext deployApplication(Map params) { + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + "sip-test", + params, + null); + assertTrue(ctx.getAvailable()); + return ctx; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/callcontroller/call-forwarding-b2bua-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects("forward-sender", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects("receiver", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + } + + public void testCallForwardingAuth() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setChallengeRequests(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("senderPort", String.valueOf(senderPort)); + params.put("testPort", String.valueOf(receiverPort)); + deployApplication(params); + + String fromName = "forward-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[]{"Remote-Party-ID"}, new String[]{";screen=yes;privacy=off;party=calling;-call-initiator=5016;-call-initiator-location=int;-redirected-by;-int-ext=5016;-ent-name=Acro;-direction=ext;-call-id=55665"}, true); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + // Non Regression test for http://code.google.com/p/mobicents/issues/detail?id=2094 + // B2b re-invite for authentication will duplicate Remote-Party-ID header + ListIterator
it = receiver.getInviteRequest().getHeaders("Remote-Party-ID"); + int nbHeaders = 0; + while (it.hasNext()) { + Header header = it.next(); + nbHeaders++; + } + assertEquals(1, nbHeaders); + } + + // Non regression test for issues 19 http://code.google.com/p/sipservlets/issues/detail?id=19 + // and http://code.google.com/p/sipservlets/issues/detail?id=161 + public void testCallForwardingShootmeAuthEarlyDialog() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.sendProvisionalResponseBeforeChallenge(true); + receiver.setChallengeRequests(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("senderPort", String.valueOf(senderPort)); + params.put("testPort", String.valueOf(receiverPort)); + deployApplication(params); + + String fromName = "forward-sender-auth-early-dialog"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "forward-receiver-auth-early-dialog"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[]{"Remote-Party-ID"}, new String[]{";screen=yes;privacy=off;party=calling;-call-initiator=5016;-call-initiator-location=int;-redirected-by;-int-ext=5016;-ent-name=Acro;-direction=ext;-call-id=55665"}, true); + Thread.sleep(TIMEOUT * 2); + assertTrue(sender.getOkToByeReceived()); + assertTrue(receiver.getByeReceived()); + // Non Regression test for http://code.google.com/p/mobicents/issues/detail?id=2094 + // B2b re-invite for authentication will duplicate Remote-Party-ID header + ListIterator
it = receiver.getInviteRequest().getHeaders("Remote-Party-ID"); + int nbHeaders = 0; + while (it.hasNext()) { + Header header = it.next(); + nbHeaders++; + } + assertEquals(1, nbHeaders); + } + + /* * Non regression test for Issue http://code.google.com/p/mobicents/issues/detail?id=2114 * In B2b servlet, after re-INVITE, and try to create CANCEL will get "final response already sent!" exception. - */ - public void testCallForwardingAuthCancel() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - sender.setSendCancelOn1xx(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - receiver.setChallengeRequests(true); - receiver.setWaitForCancel(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[] {"Remote-Party-ID"}, new String[] {";screen=yes;privacy=off;party=calling;-call-initiator=5016;-call-initiator-location=int;-redirected-by;-int-ext=5016;-ent-name=Acro;-direction=ext;-call-id=55665"}, true); - Thread.sleep(TIMEOUT); - assertTrue(sender.isCancelOkReceived()); - assertTrue(sender.isRequestTerminatedReceived()); - assertTrue(receiver.isCancelReceived()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - + */ + public void testCallForwardingAuthCancel() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + sender.setSendCancelOn1xx(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setChallengeRequests(true); + receiver.setWaitForCancel(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("senderPort", String.valueOf(senderPort)); + params.put("testPort", String.valueOf(receiverPort)); + deployApplication(params); + + String fromName = "forward-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[]{"Remote-Party-ID"}, new String[]{";screen=yes;privacy=off;party=calling;-call-initiator=5016;-call-initiator-location=int;-redirected-by;-int-ext=5016;-ent-name=Acro;-direction=ext;-call-id=55665"}, true); + Thread.sleep(TIMEOUT); + assertTrue(sender.isCancelOkReceived()); + assertTrue(sender.isRequestTerminatedReceived()); + assertTrue(receiver.isCancelReceived()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } } diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/security/PAssertedIdentityAuthTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/security/PAssertedIdentityAuthTest.java index c783496f5d..e716eccd49 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/security/PAssertedIdentityAuthTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/security/PAssertedIdentityAuthTest.java @@ -19,125 +19,129 @@ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ - package org.mobicents.servlet.sip.testsuite.security; import java.text.ParseException; +import java.util.HashMap; +import java.util.Map; import javax.sip.InvalidArgumentException; import javax.sip.SipException; import javax.sip.SipProvider; import javax.sip.address.SipURI; +import static junit.framework.Assert.assertTrue; -import org.apache.catalina.deploy.ApplicationParameter; import org.apache.catalina.realm.MemoryRealm; import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.startup.SipContextConfig; import org.mobicents.servlet.sip.startup.SipStandardContext; import org.mobicents.servlet.sip.testsuite.ProtocolObjects; import org.mobicents.servlet.sip.testsuite.TestSipListener; public class PAssertedIdentityAuthTest extends SipServletTestCase { - private static transient Logger logger = Logger.getLogger(ShootmeSipServletAuthTest.class); + private static transient Logger logger = Logger.getLogger(ShootmeSipServletAuthTest.class); - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 5000; + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 5000; // private static final int TIMEOUT = 100000000; - TestSipListener sender; - - ProtocolObjects senderProtocolObjects; - - public PAssertedIdentityAuthTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - SipStandardContext context = new SipStandardContext(); - context - .setDocBase(projectHome - + "/sip-servlets-test-suite/applications/shootme-sip-servlet-auth/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName("testContextApplicationParameter"); - applicationParameter.setValue("OK"); - context.addApplicationParameter(applicationParameter); - MemoryRealm realm = new MemoryRealm(); - realm - .setPathname(projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/security/tomcat-users.xml"); - context.setRealm(realm); - assertTrue(tomcat.deployContext(context)); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/security/shootme-sip-servlet-auth-dar.properties"; - } - - @Override - protected void setUp() { - try { - super.setUp(); - - senderProtocolObjects = new ProtocolObjects("sender", "gov.nist", - TRANSPORT, AUTODIALOG, null, null, null); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, - true); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - } catch (Exception ex) { - ex.printStackTrace(); - fail("unexpected exception "); - } - } - - public void testShootme() throws InterruptedException, SipException, - ParseException, InvalidArgumentException { - String fromName = "p-asserted-user"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - String[] headerNames = new String[] {"P-Asserted-Identity"}; - String[] headerContents = new String[] {"\"User One\" "}; - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, - false, headerNames, headerContents, true); - - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - assertTrue(!sender.isAuthenticationErrorReceived()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } + TestSipListener sender; + + ProtocolObjects senderProtocolObjects; + + public PAssertedIdentityAuthTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + public SipStandardContext deployApplication(Map params) { + + MemoryRealm realm = new MemoryRealm(); + realm + .setPathname(projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/security/tomcat-users.xml"); + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/shootme-sip-servlet-auth/src/main/sipapp", + "sip-test", + params, + null, + realm); + assertTrue(ctx.getAvailable()); + return ctx; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/security/shootme-sip-servlet-auth-dar.properties"; + } + + @Override + protected void setUp() { + try { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects("sender", "gov.nist", + TRANSPORT, AUTODIALOG, null, null, null); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, + true); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + params.put("testContextApplicationParameter", "OK"); + deployApplication(params); + } catch (Exception ex) { + ex.printStackTrace(); + fail("unexpected exception "); + } + } + + public void testShootme() throws InterruptedException, SipException, + ParseException, InvalidArgumentException { + String fromName = "p-asserted-user"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + String[] headerNames = new String[]{"P-Asserted-Identity"}; + String[] headerContents = new String[]{"\"User One\" "}; + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, + false, headerNames, headerContents, true); + + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + assertTrue(!sender.isAuthenticationErrorReceived()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } } diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/security/ShootistSipServletAuthTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/security/ShootistSipServletAuthTest.java index 3849adee1e..f96978a1f3 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/security/ShootistSipServletAuthTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/security/ShootistSipServletAuthTest.java @@ -1,380 +1,397 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.security; -import gov.nist.javax.sip.message.MessageExt; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.Map.Entry; - -import javax.sip.SipProvider; -import javax.sip.header.Header; -import javax.sip.header.ProxyAuthorizationHeader; -import javax.sip.message.Response; - -import org.apache.catalina.deploy.ApplicationParameter; -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class ShootistSipServletAuthTest extends SipServletTestCase { - private static transient Logger logger = Logger.getLogger(ShootistSipServletAuthTest.class); - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 30000; - private static final int TIME_TO_WAIT_BETWEEN_PROV_RESPONSES = 7000; -// private static final int TIMEOUT = 100000000; - - TestSipListener receiver; - - ProtocolObjects receiverProtocolObjects; - - public ShootistSipServletAuthTest(String name) { - super(name); - startTomcatOnStartup = false; - autoDeployOnStartup = false; - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet-auth/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - public SipStandardContext deployApplication(Map params) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet-auth/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - for (Entry entry : params.entrySet()) { - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(entry.getKey()); - applicationParameter.setValue(entry.getValue()); - context.addApplicationParameter(applicationParameter); - } - assertTrue(tomcat.deployContext(context)); - return context; - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/security/shootist-sip-servlet-auth-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - } - - public void testShootist() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - receiver.setChallengeRequests(true); - List provisionalResponsesToSend = new ArrayList(); - provisionalResponsesToSend.add(Response.TRYING); - provisionalResponsesToSend.add(Response.SESSION_PROGRESS); - receiver.setProvisionalResponsesToSend(provisionalResponsesToSend); - receiver.setTimeToWaitBetweenProvisionnalResponse(TIME_TO_WAIT_BETWEEN_PROV_RESPONSES); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - - tomcat.startTomcat(); - deployApplication(); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isAckReceived()); - assertTrue(receiver.getByeReceived()); - } - /* - * Non regression test for Issue 1832 : http://code.google.com/p/mobicents/issues/detail?id=1832 - * Authorization header is growing when nonce become stale - */ - public void testShootistReinviteChallengeStale() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender-app-send-reinvite", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - receiver.setChallengeRequests(true); - receiver.setMultipleChallengeInResponse(true); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - - tomcat.startTomcat(); - Map params = new HashMap(); - params.put("METHOD", "REGISTER"); - deployApplication(params); - Thread.sleep(TIMEOUT); - ListIterator
proxyAuthHeaders = receiver.getRegisterReceived().getHeaders(ProxyAuthorizationHeader.NAME); - int proxyAuthHeaderNumber = 0; - while (proxyAuthHeaders.hasNext()) { - proxyAuthHeaders.next(); - proxyAuthHeaderNumber++; - } - assertEquals("The stale auth header should not be taken into account", 1, proxyAuthHeaderNumber); - } - - /* - * Non regression test for Issue 2173 - * http://code.google.com/p/mobicents/issues/detail?id=2173 - * Handle Header [Authentication-Info: nextnonce="xyz"] in sip authorization responses - */ - public void testShootistReinviteNextNonce() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender-app-send-reinvite-cache-credentials", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - receiver.setChallengeRequests(true); - receiver.setTestNextNonce(true); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - - tomcat.startTomcat(); - Map params = new HashMap(); - params.put("from", "sender-app-send-reinvite-cache-credentials"); - params.put("nbSubsequentReq","4"); - params.put("METHOD", "REGISTER"); - deployApplication(params); - Thread.sleep(TIMEOUT); - assertEquals(4, receiver.getLastRegisterCSeqNumber()); - } - - /* - * Non regression test for https://code.google.com/p/sipservlets/issues/detail?id=278 - */ - public void testShootistReinviteCheckSDP() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender-app-send-reinvite-cache-credentials", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - receiver.setChallengeRequests(true); - receiver.setCheckSDPNullOnChallengeRequests(true); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - - tomcat.startTomcat(); - Map params = new HashMap(); - params.put("from", "sender-app-send-reinvite-cache-credentials"); - params.put("nbSubsequentReq","4"); - params.put("METHOD", "INVITE"); - deployApplication(params); - Thread.sleep(TIMEOUT); - assertEquals(4, ((MessageExt)receiver.getFinalResponse()).getCSeqHeader().getSeqNumber()); - assertNull(receiver.getInviteRequest().getContent()); - } - - /* - * Non regression test for Issue 2505 - * http://code.google.com/p/mobicents/issues/detail?id=2505 - * update nc in Authorization header for subsequent requests - */ - public void testShootistReinviteNextNonceAndNc() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender-app-send-reinvite-cache-credentials", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - receiver.setChallengeRequests(true); - receiver.setTestNextNonce(true); - receiver.setTestNC(true); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - - tomcat.startTomcat(); - Map params = new HashMap(); - params.put("from", "sender-app-send-reinvite-cache-credentials"); - params.put("nbSubsequentReq","4"); - params.put("METHOD", "REGISTER"); - deployApplication(params); - Thread.sleep(TIMEOUT); - assertEquals(4, receiver.getLastRegisterCSeqNumber()); - } - - - /* - * Non regression test for Issue 1836 - * http://code.google.com/p/mobicents/issues/detail?id=1836 - * Exception thrown when creating a cancel after a "Proxy Authentication required" response - */ - public void testShootistCancelChallengeOn1xx() throws Exception { - receiverProtocolObjects =new ProtocolObjects( - "cancelChallenge", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - receiver.setChallengeRequests(true); - receiver.setWaitForCancel(true); - List provisionalResponsesToSend = new ArrayList(); - provisionalResponsesToSend.add(Response.TRYING); - provisionalResponsesToSend.add(Response.SESSION_PROGRESS); - receiver.setProvisionalResponsesToSend(provisionalResponsesToSend); - receiver.setTimeToWaitBetweenProvisionnalResponse(TIME_TO_WAIT_BETWEEN_PROV_RESPONSES); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - - tomcat.startTomcat(); - Map params = new HashMap(); - params.put("from", "cancelChallenge"); - deployApplication(params); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isCancelReceived()); - } - - /* - * Non regression test for Issue 1836 - * http://code.google.com/p/mobicents/issues/detail?id=1836 - * Exception thrown when creating a cancel after a "Proxy Authentication required" response - */ - public void testShootistCancelChallengeBefore1xx() throws Exception { - receiverProtocolObjects =new ProtocolObjects( - "cancelChallengeBefore1xx", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - receiver.setChallengeRequests(true); - receiver.setWaitForCancel(true); - List provisionalResponsesToSend = new ArrayList(); - provisionalResponsesToSend.add(Response.TRYING); - provisionalResponsesToSend.add(Response.SESSION_PROGRESS); - receiver.setProvisionalResponsesToSend(provisionalResponsesToSend); - receiver.setTimeToWaitBetweenProvisionnalResponse(TIME_TO_WAIT_BETWEEN_PROV_RESPONSES); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - - tomcat.startTomcat(); - Map params = new HashMap(); - params.put("from", "cancelChallengeBefore1xx"); - deployApplication(params); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isCancelReceived()); - } - - /* - * Non regression test for Issue 1836 - * http://code.google.com/p/mobicents/issues/detail?id=1836 - * Exception thrown when creating a cancel after a "Proxy Authentication required" response - */ - public void testShootistReInviteCancel() throws Exception { - receiverProtocolObjects =new ProtocolObjects( - "reinvite", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - receiver.setChallengeRequests(true); - List provisionalResponsesToSend = new ArrayList(); - provisionalResponsesToSend.add(Response.TRYING); - provisionalResponsesToSend.add(Response.SESSION_PROGRESS); - receiver.setProvisionalResponsesToSend(provisionalResponsesToSend); - receiver.setTimeToWaitBetweenProvisionnalResponse(TIME_TO_WAIT_BETWEEN_PROV_RESPONSES); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - - tomcat.startTomcat(); - Map params = new HashMap(); - params.put("from", "reinvite"); - deployApplication(params); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isAckReceived()); - receiver.setWaitForCancel(true); - receiver.setChallengeRequests(false); - receiver.sendInDialogSipRequest("INFO", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isCancelReceived()); - } - - /* - * Non regression test for Issue 2116 - * http://code.google.com/p/mobicents/issues/detail?id=2116 - * Making sure no derived sessions are created - */ - public void testShootistReREGISTER() throws Exception { - receiverProtocolObjects =new ProtocolObjects( - "reregister", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - receiver.setChallengeRequests(true); - receiver.setMultipleChallengeInResponse(true); - SipProvider receiverProvider = receiver.createProvider(); - receiverProvider.addSipListener(receiver); - receiverProtocolObjects.start(); - - tomcat.startTomcat(); - Map params = new HashMap(); - params.put("METHOD", "REGISTER"); - params.put("from", "reregister"); - params.put("nbSubsequentReq", "4"); - deployApplication(params); - - Thread.sleep(TIMEOUT); - Iterator allMessagesIterator = receiver.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertEquals(0, receiver.getAllMessagesContent().size()); - } - - @Override - protected void tearDown() throws Exception { - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } -} \ No newline at end of file +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.security; + +import gov.nist.javax.sip.message.MessageExt; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; + +import javax.sip.SipProvider; +import javax.sip.header.Header; +import javax.sip.header.ProxyAuthorizationHeader; +import javax.sip.message.Response; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class ShootistSipServletAuthTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ShootistSipServletAuthTest.class); + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 30000; + private static final int TIME_TO_WAIT_BETWEEN_PROV_RESPONSES = 7000; +// private static final int TIMEOUT = 100000000; + + TestSipListener receiver; + + ProtocolObjects receiverProtocolObjects; + + public ShootistSipServletAuthTest(String name) { + super(name); + startTomcatOnStartup = false; + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + public SipStandardContext deployApplication(Map params) { + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet-auth/src/main/sipapp", + "sip-test", + params, + null); + assertTrue(ctx.getAvailable()); + return ctx; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/security/shootist-sip-servlet-auth-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + } + + public void testShootist() throws Exception { +// receiver.sendInvite(); + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setChallengeRequests(true); + List provisionalResponsesToSend = new ArrayList(); + provisionalResponsesToSend.add(Response.TRYING); + provisionalResponsesToSend.add(Response.SESSION_PROGRESS); + receiver.setProvisionalResponsesToSend(provisionalResponsesToSend); + receiver.setTimeToWaitBetweenProvisionnalResponse(TIME_TO_WAIT_BETWEEN_PROV_RESPONSES); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + + tomcat.startTomcat(); + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + deployApplication(params); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isAckReceived()); + assertTrue(receiver.getByeReceived()); + } + + /* + * Non regression test for Issue 1832 : http://code.google.com/p/mobicents/issues/detail?id=1832 + * Authorization header is growing when nonce become stale + */ + public void testShootistReinviteChallengeStale() throws Exception { +// receiver.sendInvite(); + receiverProtocolObjects = new ProtocolObjects( + "sender-app-send-reinvite", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setChallengeRequests(true); + receiver.setMultipleChallengeInResponse(true); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + + tomcat.startTomcat(); + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("METHOD", "REGISTER"); + deployApplication(params); + Thread.sleep(TIMEOUT); + ListIterator
proxyAuthHeaders = receiver.getRegisterReceived().getHeaders(ProxyAuthorizationHeader.NAME); + int proxyAuthHeaderNumber = 0; + while (proxyAuthHeaders.hasNext()) { + proxyAuthHeaders.next(); + proxyAuthHeaderNumber++; + } + assertEquals("The stale auth header should not be taken into account", 1, proxyAuthHeaderNumber); + } + + /* + * Non regression test for Issue 2173 + * http://code.google.com/p/mobicents/issues/detail?id=2173 + * Handle Header [Authentication-Info: nextnonce="xyz"] in sip authorization responses + */ + public void testShootistReinviteNextNonce() throws Exception { +// receiver.sendInvite(); + receiverProtocolObjects = new ProtocolObjects( + "sender-app-send-reinvite-cache-credentials", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setChallengeRequests(true); + receiver.setTestNextNonce(true); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + + tomcat.startTomcat(); + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("from", "sender-app-send-reinvite-cache-credentials"); + params.put("nbSubsequentReq", "4"); + params.put("METHOD", "REGISTER"); + deployApplication(params); + Thread.sleep(TIMEOUT); + assertEquals(4, receiver.getLastRegisterCSeqNumber()); + } + + /* + * Non regression test for https://code.google.com/p/sipservlets/issues/detail?id=278 + */ + public void testShootistReinviteCheckSDP() throws Exception { +// receiver.sendInvite(); + receiverProtocolObjects = new ProtocolObjects( + "sender-app-send-reinvite-cache-credentials", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setChallengeRequests(true); + receiver.setCheckSDPNullOnChallengeRequests(true); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + + tomcat.startTomcat(); + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("from", "sender-app-send-reinvite-cache-credentials"); + params.put("nbSubsequentReq", "4"); + params.put("METHOD", "INVITE"); + deployApplication(params); + Thread.sleep(TIMEOUT); + assertEquals(4, ((MessageExt) receiver.getFinalResponse()).getCSeqHeader().getSeqNumber()); + assertNull(receiver.getInviteRequest().getContent()); + } + + /* + * Non regression test for Issue 2505 + * http://code.google.com/p/mobicents/issues/detail?id=2505 + * update nc in Authorization header for subsequent requests + */ + public void testShootistReinviteNextNonceAndNc() throws Exception { +// receiver.sendInvite(); + receiverProtocolObjects = new ProtocolObjects( + "sender-app-send-reinvite-cache-credentials", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setChallengeRequests(true); + receiver.setTestNextNonce(true); + receiver.setTestNC(true); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + + tomcat.startTomcat(); + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("from", "sender-app-send-reinvite-cache-credentials"); + params.put("nbSubsequentReq", "4"); + params.put("METHOD", "REGISTER"); + deployApplication(params); + Thread.sleep(TIMEOUT); + assertEquals(4, receiver.getLastRegisterCSeqNumber()); + } + + /* + * Non regression test for Issue 1836 + * http://code.google.com/p/mobicents/issues/detail?id=1836 + * Exception thrown when creating a cancel after a "Proxy Authentication required" response + */ + public void testShootistCancelChallengeOn1xx() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "cancelChallenge", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setChallengeRequests(true); + receiver.setWaitForCancel(true); + List provisionalResponsesToSend = new ArrayList(); + provisionalResponsesToSend.add(Response.TRYING); + provisionalResponsesToSend.add(Response.SESSION_PROGRESS); + receiver.setProvisionalResponsesToSend(provisionalResponsesToSend); + receiver.setTimeToWaitBetweenProvisionnalResponse(TIME_TO_WAIT_BETWEEN_PROV_RESPONSES); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + + tomcat.startTomcat(); + Map params = new HashMap(); + params.put("from", "cancelChallenge"); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + deployApplication(params); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isCancelReceived()); + } + + /* + * Non regression test for Issue 1836 + * http://code.google.com/p/mobicents/issues/detail?id=1836 + * Exception thrown when creating a cancel after a "Proxy Authentication required" response + */ + public void testShootistCancelChallengeBefore1xx() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "cancelChallengeBefore1xx", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setChallengeRequests(true); + receiver.setWaitForCancel(true); + List provisionalResponsesToSend = new ArrayList(); + provisionalResponsesToSend.add(Response.TRYING); + provisionalResponsesToSend.add(Response.SESSION_PROGRESS); + receiver.setProvisionalResponsesToSend(provisionalResponsesToSend); + receiver.setTimeToWaitBetweenProvisionnalResponse(TIME_TO_WAIT_BETWEEN_PROV_RESPONSES); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + + tomcat.startTomcat(); + Map params = new HashMap(); + params.put("from", "cancelChallengeBefore1xx"); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + deployApplication(params); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isCancelReceived()); + } + + /* + * Non regression test for Issue 1836 + * http://code.google.com/p/mobicents/issues/detail?id=1836 + * Exception thrown when creating a cancel after a "Proxy Authentication required" response + */ + public void testShootistReInviteCancel() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "reinvite", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setChallengeRequests(true); + List provisionalResponsesToSend = new ArrayList(); + provisionalResponsesToSend.add(Response.TRYING); + provisionalResponsesToSend.add(Response.SESSION_PROGRESS); + receiver.setProvisionalResponsesToSend(provisionalResponsesToSend); + receiver.setTimeToWaitBetweenProvisionnalResponse(TIME_TO_WAIT_BETWEEN_PROV_RESPONSES); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + + tomcat.startTomcat(); + Map params = new HashMap(); + params.put("from", "reinvite"); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + deployApplication(params); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isAckReceived()); + receiver.setWaitForCancel(true); + receiver.setChallengeRequests(false); + receiver.sendInDialogSipRequest("INFO", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isCancelReceived()); + } + + /* + * Non regression test for Issue 2116 + * http://code.google.com/p/mobicents/issues/detail?id=2116 + * Making sure no derived sessions are created + */ + public void testShootistReREGISTER() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "reregister", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setChallengeRequests(true); + receiver.setMultipleChallengeInResponse(true); + SipProvider receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + + tomcat.startTomcat(); + Map params = new HashMap(); + params.put("METHOD", "REGISTER"); + params.put("from", "reregister"); + params.put("nbSubsequentReq", "4"); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + deployApplication(params); + + Thread.sleep(TIMEOUT); + Iterator allMessagesIterator = receiver.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertEquals(0, receiver.getAllMessagesContent().size()); + } + + @Override + protected void tearDown() throws Exception { + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/security/ShootmeSipServletAuthTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/security/ShootmeSipServletAuthTest.java index 66061e0f5f..46764497c3 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/security/ShootmeSipServletAuthTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/security/ShootmeSipServletAuthTest.java @@ -1,181 +1,188 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.security; - -import java.text.ParseException; - -import javax.sip.InvalidArgumentException; -import javax.sip.SipException; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.catalina.deploy.ApplicationParameter; -import org.apache.catalina.realm.MemoryRealm; -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class ShootmeSipServletAuthTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(ShootmeSipServletAuthTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 5000; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender; - - ProtocolObjects senderProtocolObjects; - - public ShootmeSipServletAuthTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - SipStandardContext context = new SipStandardContext(); - context - .setDocBase(projectHome - + "/sip-servlets-test-suite/applications/shootme-sip-servlet-auth/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName("testContextApplicationParameter"); - applicationParameter.setValue("OK"); - context.addApplicationParameter(applicationParameter); - MemoryRealm realm = new MemoryRealm(); - realm - .setPathname(projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/security/tomcat-users.xml"); - context.setRealm(realm); - assertTrue(tomcat.deployContext(context)); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/security/shootme-sip-servlet-auth-dar.properties"; - } - - @Override - protected void setUp() { - try { - super.setUp(); - - senderProtocolObjects = new ProtocolObjects("sender", "gov.nist", - TRANSPORT, AUTODIALOG, null, null, null); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, - true); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - } catch (Exception ex) { - ex.printStackTrace(); - fail("unexpected exception "); - } - } - - public void testShootme() throws InterruptedException, SipException, - ParseException, InvalidArgumentException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, - false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - } - - // non regression test for http://code.google.com/p/sipservlets/issues/detail?id=88 - public void testShootmeBadUser() throws InterruptedException, SipException, - ParseException, InvalidArgumentException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setSecurityUser("baduser"); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, - false); - Thread.sleep(TIMEOUT); - assertFalse(sender.isAckSent()); - assertFalse(sender.getOkToByeReceived()); - assertEquals(401, sender.getFinalResponseStatus()); - } - - // Testing bad pwd making sure it returns 401 - public void testShootmeBadPassword() throws InterruptedException, SipException, - ParseException, InvalidArgumentException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setSecurityPwd("badpwd"); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, - false); - Thread.sleep(TIMEOUT); - assertFalse(sender.isAckSent()); - assertFalse(sender.getOkToByeReceived()); - assertEquals(401, sender.getFinalResponseStatus()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.security; + +import java.text.ParseException; +import java.util.HashMap; +import java.util.Map; + +import javax.sip.InvalidArgumentException; +import javax.sip.SipException; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import static junit.framework.Assert.assertTrue; + +import org.apache.catalina.deploy.ApplicationParameter; +import org.apache.catalina.realm.MemoryRealm; +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.catalina.SipStandardManager; +import org.mobicents.servlet.sip.startup.SipContextConfig; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class ShootmeSipServletAuthTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ShootmeSipServletAuthTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 5000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + + ProtocolObjects senderProtocolObjects; + + public ShootmeSipServletAuthTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + public SipStandardContext deployApplication(Map params) { + + MemoryRealm realm = new MemoryRealm(); + realm + .setPathname(projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/security/tomcat-users.xml"); + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/shootme-sip-servlet-auth/src/main/sipapp", + "sip-test", + params, + null, + realm); + assertTrue(ctx.getAvailable()); + return ctx; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/security/shootme-sip-servlet-auth-dar.properties"; + } + + @Override + protected void setUp() { + try { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects("sender", "gov.nist", + TRANSPORT, AUTODIALOG, null, null, null); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, + true); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + params.put("testContextApplicationParameter", "OK"); + deployApplication(params); + } catch (Exception ex) { + ex.printStackTrace(); + fail("unexpected exception "); + } + } + + public void testShootme() throws InterruptedException, SipException, + ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, + false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + } + + // non regression test for http://code.google.com/p/sipservlets/issues/detail?id=88 + public void testShootmeBadUser() throws InterruptedException, SipException, + ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setSecurityUser("baduser"); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, + false); + Thread.sleep(TIMEOUT); + assertFalse(sender.isAckSent()); + assertFalse(sender.getOkToByeReceived()); + assertEquals(401, sender.getFinalResponseStatus()); + } + + // Testing bad pwd making sure it returns 401 + public void testShootmeBadPassword() throws InterruptedException, SipException, + ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setSecurityPwd("badpwd"); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, + false); + Thread.sleep(TIMEOUT); + assertFalse(sender.isAckSent()); + assertFalse(sender.getOkToByeReceived()); + assertEquals(401, sender.getFinalResponseStatus()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/session/RequestDispatcherSipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/session/RequestDispatcherSipServletTest.java index 7c94c592c6..71147f4311 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/session/RequestDispatcherSipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/session/RequestDispatcherSipServletTest.java @@ -1,156 +1,160 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.session; - -import java.text.ParseException; -import java.util.Iterator; - -import javax.sip.InvalidArgumentException; -import javax.sip.SipException; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -/** - * This test is aimed to test the JSR 289 Section 6.2.5 The Request Dispatcher - * - * @author Jean Deruelle - * - */ -public class RequestDispatcherSipServletTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(RequestDispatcherSipServletTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 2000; - private static final int TIMEOUT_BYE = 6000; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender; - ProtocolObjects senderProtocolObjects; - - public RequestDispatcherSipServletTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/dispatcher-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/session/dispatcher-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects =new ProtocolObjects( - "sender1Chat1", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - senderProvider.addSipListener(sender); - senderProtocolObjects.start(); - } - - /** - * This test check to see if the correct handler handled the correct SIP request or response. - * - * - * @throws InterruptedException - * @throws SipException - * @throws ParseException - * @throws InvalidArgumentException - */ - public void testRequestDispatching() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - Thread.sleep(TIMEOUT_BYE); - sender.sendBye(); - Thread.sleep(TIMEOUT); - assertTrue(sender.getOkToByeReceived()); - Thread.sleep(TIMEOUT); - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - logger.info("all messages received from sender : "); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertEquals(1, sender.getAllMessagesContent().size()); - assertTrue(sender.getAllMessagesContent().contains("Dispatch OK")); - } - - /** - * This test check that this is not possible to pas a bad handler name in the setHandler method - * @throws InterruptedException - * @throws SipException - * @throws ParseException - * @throws InvalidArgumentException - */ - public void testBadRequestDispatching() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "badHandler"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isFinalResponseReceived()); - assertTrue(!sender.isAckSent()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.session; + +import java.text.ParseException; +import java.util.Iterator; + +import javax.sip.InvalidArgumentException; +import javax.sip.SipException; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +/** + * This test is aimed to test the JSR 289 Section 6.2.5 The Request Dispatcher + * + * @author Jean Deruelle + * + */ +public class RequestDispatcherSipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(RequestDispatcherSipServletTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 2000; + private static final int TIMEOUT_BYE = 6000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + ProtocolObjects senderProtocolObjects; + + public RequestDispatcherSipServletTest(String name) { + super(name); + } + + @Override + public void deployApplication() { + assertTrue(tomcat.deployContext( + projectHome + "/sip-servlets-test-suite/applications/dispatcher-sip-servlet/src/main/sipapp", + "sip-test-context", "sip-test")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/session/dispatcher-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects( + "sender1Chat1", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + } + + /** + * This test check to see if the correct handler handled the correct SIP + * request or response. + * + * + * @throws InterruptedException + * @throws SipException + * @throws ParseException + * @throws InvalidArgumentException + */ + public void testRequestDispatching() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + Thread.sleep(TIMEOUT_BYE); + sender.sendBye(); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + Thread.sleep(TIMEOUT); + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + logger.info("all messages received from sender : "); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertEquals(1, sender.getAllMessagesContent().size()); + assertTrue(sender.getAllMessagesContent().contains("Dispatch OK")); + } + + /** + * This test check that this is not possible to pas a bad handler name in + * the setHandler method + * + * @throws InterruptedException + * @throws SipException + * @throws ParseException + * @throws InvalidArgumentException + */ + public void testBadRequestDispatching() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "badHandler"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isFinalResponseReceived()); + assertTrue(!sender.isAckSent()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/session/SessionHandlerSipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/session/SessionHandlerSipServletTest.java index 9db0bb3a8d..c716638672 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/session/SessionHandlerSipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/session/SessionHandlerSipServletTest.java @@ -1,159 +1,163 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.session; - -import java.text.ParseException; -import java.util.Iterator; - -import javax.sip.InvalidArgumentException; -import javax.sip.SipException; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -/** - * This test is aimed to test the JSR 289 Section 6.2.6 The SipSession Handler - * - * @author Jean Deruelle - * - */ -public class SessionHandlerSipServletTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(SessionHandlerSipServletTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 2000; - private static final int TIMEOUT_BYE = 6000; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender; - ProtocolObjects senderProtocolObjects; - - public SessionHandlerSipServletTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/handler-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/session/handler-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects =new ProtocolObjects( - "sender1Chat1", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - senderProvider.addSipListener(sender); - senderProtocolObjects.start(); - } - - /** - * This test check to see if the correct handler handled the correct SIP request or response. - * - * - * @throws InterruptedException - * @throws SipException - * @throws ParseException - * @throws InvalidArgumentException - */ - public void testSessionHandler() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - Thread.sleep(TIMEOUT_BYE); - sender.sendBye(); - Thread.sleep(TIMEOUT); - assertTrue(sender.getOkToByeReceived()); - Thread.sleep(TIMEOUT); - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - logger.info("all messages received from sender : "); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertEquals(4, sender.getAllMessagesContent().size()); - assertTrue(sender.getAllMessagesContent().contains("SecondaryHandler : Subsequent request received")); - assertTrue(sender.getAllMessagesContent().contains("SecondaryHandler : response OK")); - assertTrue(sender.getAllMessagesContent().contains("SecondaryHandler : testing MainHandler")); - assertTrue(sender.getAllMessagesContent().contains("MainHandler : response OK")); - } - - /** - * This test check that this is not possible to pas a bad handler name in the setHandler method - * @throws InterruptedException - * @throws SipException - * @throws ParseException - * @throws InvalidArgumentException - */ - public void testBadSessionHandler() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "badHandler"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isFinalResponseReceived()); - assertTrue(!sender.isAckSent()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.session; + +import java.text.ParseException; +import java.util.Iterator; + +import javax.sip.InvalidArgumentException; +import javax.sip.SipException; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +/** + * This test is aimed to test the JSR 289 Section 6.2.6 The SipSession Handler + * + * @author Jean Deruelle + * + */ +public class SessionHandlerSipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(SessionHandlerSipServletTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 2000; + private static final int TIMEOUT_BYE = 6000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + ProtocolObjects senderProtocolObjects; + + public SessionHandlerSipServletTest(String name) { + super(name); + } + + @Override + public void deployApplication() { + assertTrue(tomcat.deployContext( + projectHome + "/sip-servlets-test-suite/applications/handler-sip-servlet/src/main/sipapp", + "sip-test-context", "sip-test")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/session/handler-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects( + "sender1Chat1", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + } + + /** + * This test check to see if the correct handler handled the correct SIP + * request or response. + * + * + * @throws InterruptedException + * @throws SipException + * @throws ParseException + * @throws InvalidArgumentException + */ + public void testSessionHandler() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + Thread.sleep(TIMEOUT_BYE); + sender.sendBye(); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + Thread.sleep(TIMEOUT); + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + logger.info("all messages received from sender : "); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertEquals(4, sender.getAllMessagesContent().size()); + assertTrue(sender.getAllMessagesContent().contains("SecondaryHandler : Subsequent request received")); + assertTrue(sender.getAllMessagesContent().contains("SecondaryHandler : response OK")); + assertTrue(sender.getAllMessagesContent().contains("SecondaryHandler : testing MainHandler")); + assertTrue(sender.getAllMessagesContent().contains("MainHandler : response OK")); + } + + /** + * This test check that this is not possible to pas a bad handler name in + * the setHandler method + * + * @throws InterruptedException + * @throws SipException + * @throws ParseException + * @throws InvalidArgumentException + */ + public void testBadSessionHandler() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "badHandler"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isFinalResponseReceived()); + assertTrue(!sender.isAckSent()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/session/SessionStateUACSipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/session/SessionStateUACSipServletTest.java index 6bc98356bf..fd16532dea 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/session/SessionStateUACSipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/session/SessionStateUACSipServletTest.java @@ -1,229 +1,236 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.session; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import javax.servlet.sip.SipSession; -import javax.sip.SipProvider; -import javax.sip.message.Response; - -import org.apache.catalina.deploy.ApplicationParameter; -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class SessionStateUACSipServletTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(SessionStateUACSipServletTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - - private List send_1xx_4xx_sessionStateList; - private List send_subsequent_487_sessionStateList; - - private static final int TIMEOUT = 35000; - private static final int TIMEOUT_EXPIRATION = 70000; - - TestSipListener receiver; - - ProtocolObjects receiverProtocolObjects; - - public SessionStateUACSipServletTest(String name) { - super(name); - autoDeployOnStartup = false; - } - - @Override - protected void deployApplication() { - deployApplication(null, null, ConcurrencyControlMode.None); - } - - public void deployApplication(String name, String value, ConcurrencyControlMode concurrencyControlMode) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/session-state-uac/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - context.setConcurrencyControlMode(concurrencyControlMode); - if(name != null) { - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(name); - applicationParameter.setValue(value); - context.addApplicationParameter(applicationParameter); - } - assertTrue(tomcat.deployContext(context)); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/session/session-state-uac-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - send_1xx_4xx_sessionStateList = new ArrayList(); - send_1xx_4xx_sessionStateList.add(SipSession.State.INITIAL.toString()); - send_1xx_4xx_sessionStateList.add(SipSession.State.EARLY.toString()); - send_1xx_4xx_sessionStateList.add(SipSession.State.INITIAL.toString()); - - send_subsequent_487_sessionStateList = new ArrayList(); - send_subsequent_487_sessionStateList.add(SipSession.State.INITIAL.toString()); - send_subsequent_487_sessionStateList.add(SipSession.State.EARLY.toString()); - send_subsequent_487_sessionStateList.add(SipSession.State.CONFIRMED.toString()); - send_subsequent_487_sessionStateList.add(SipSession.State.CONFIRMED.toString()); - send_subsequent_487_sessionStateList.add(SipSession.State.TERMINATED.toString()); - - super.setUp(); - } - - public void testSessionStateUAC_1xx_4xx() throws Exception { - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - List provisionalResponsesToSend = receiver.getProvisionalResponsesToSend(); - provisionalResponsesToSend.clear(); - provisionalResponsesToSend.add(Response.RINGING); - receiver.setFinalResponseToSend(Response.FORBIDDEN); - - SipProvider receiverProvider = receiver.createProvider(); - receiverProvider.addSipListener(receiver); - receiverProtocolObjects.start(); - - deployApplication(); - - Thread.sleep(TIMEOUT); - - Iterator allMessagesIterator = receiver.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - - assertEquals(send_1xx_4xx_sessionStateList.size(), receiver.getAllMessagesContent().size()); - for (int i = 0; i < send_1xx_4xx_sessionStateList.size(); i++) { - assertTrue(receiver.getAllMessagesContent().contains(send_1xx_4xx_sessionStateList.get(i))); - } - } - - /** - * http://code.google.com/p/mobicents/issues/detail?id=1438 - * Sip Session become TERMINATED after receiving 487 response to subsequent request - */ - public void testSessionStateUAC_Subsequent_487() throws Exception { - receiverProtocolObjects =new ProtocolObjects( - "Subsequent_487", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - List provisionalResponsesToSend = receiver.getProvisionalResponsesToSend(); - provisionalResponsesToSend.clear(); - provisionalResponsesToSend.add(Response.RINGING); - receiver.setFinalResponseToSend(Response.OK); - receiver.setReferResponseToSend(487); - receiver.setSendNotifyForRefer(false); - - SipProvider receiverProvider = receiver.createProvider(); - receiverProvider.addSipListener(receiver); - receiverProtocolObjects.start(); - - deployApplication(); - - Thread.sleep(TIMEOUT); - receiver.sendBye(); - Thread.sleep(5000); - - Iterator allMessagesIterator = receiver.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - - int numberOfTerminated = 0; - int numberOfConfirmed = 0; - assertEquals(send_subsequent_487_sessionStateList.size(), receiver.getAllMessagesContent().size()); - for (int i = 0; i < send_subsequent_487_sessionStateList.size(); i++) { - String messageContent = receiver.getAllMessagesContent().get(i); - assertTrue(receiver.getAllMessagesContent().contains(messageContent)); - if(messageContent.equalsIgnoreCase(SipSession.State.CONFIRMED.toString())) { - numberOfConfirmed++; - } - if(messageContent.equalsIgnoreCase(SipSession.State.TERMINATED.toString())) { - numberOfTerminated++; - } - } - assertEquals(2, numberOfConfirmed); - assertEquals(1, numberOfTerminated); - } - - // Test for SS spec 11.1.6 transaction timeout notification - // Also Tests Issue 1470 http://code.google.com/p/mobicents/issues/detail?id=1470 - // Also Tests Issue 1693 http://code.google.com/p/mobicents/issues/detail?id=1693 - public void testTransactionTimeoutResponse() throws Exception { - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - List provisionalResponsesToSend = receiver.getProvisionalResponsesToSend(); - provisionalResponsesToSend.clear(); - provisionalResponsesToSend.add(Response.RINGING); - receiver.setFinalResponseToSend(Response.FORBIDDEN); - - SipProvider receiverProvider = receiver.createProvider(); - receiverProvider.addSipListener(receiver); - receiverProtocolObjects.start(); - - deployApplication("testTimeout", "true", ConcurrencyControlMode.SipSession); - - Thread.sleep(TIMEOUT); - - Iterator allMessagesIterator = receiver.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - - } - assertTrue(receiver.getAllMessagesContent().contains("sipSessionReadyToInvalidate")); - assertTrue(receiver.getAllMessagesContent().contains("sipAppSessionReadyToInvalidate")); - assertTrue(receiver.txTimeoutReceived); - } - - @Override - protected void tearDown() throws Exception { - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.session; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.servlet.sip.SipSession; +import javax.sip.SipProvider; +import javax.sip.message.Response; + +import org.apache.catalina.deploy.ApplicationParameter; +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; +import org.mobicents.servlet.sip.catalina.SipStandardManager; +import org.mobicents.servlet.sip.startup.SipContextConfig; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class SessionStateUACSipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(SessionStateUACSipServletTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + + private List send_1xx_4xx_sessionStateList; + private List send_subsequent_487_sessionStateList; + + private static final int TIMEOUT = 35000; + private static final int TIMEOUT_EXPIRATION = 70000; + + TestSipListener receiver; + + ProtocolObjects receiverProtocolObjects; + + public SessionStateUACSipServletTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + protected void deployApplication() { + } + + public void deployApplication(Map params, ConcurrencyControlMode concurrencyControlMode) { + SipStandardContext context = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/session-state-uac/src/main/sipapp", + params, concurrencyControlMode); + assertTrue(context.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/session/session-state-uac-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + send_1xx_4xx_sessionStateList = new ArrayList(); + send_1xx_4xx_sessionStateList.add(SipSession.State.INITIAL.toString()); + send_1xx_4xx_sessionStateList.add(SipSession.State.EARLY.toString()); + send_1xx_4xx_sessionStateList.add(SipSession.State.INITIAL.toString()); + + send_subsequent_487_sessionStateList = new ArrayList(); + send_subsequent_487_sessionStateList.add(SipSession.State.INITIAL.toString()); + send_subsequent_487_sessionStateList.add(SipSession.State.EARLY.toString()); + send_subsequent_487_sessionStateList.add(SipSession.State.CONFIRMED.toString()); + send_subsequent_487_sessionStateList.add(SipSession.State.CONFIRMED.toString()); + send_subsequent_487_sessionStateList.add(SipSession.State.TERMINATED.toString()); + + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + } + + public void testSessionStateUAC_1xx_4xx() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + List provisionalResponsesToSend = receiver.getProvisionalResponsesToSend(); + provisionalResponsesToSend.clear(); + provisionalResponsesToSend.add(Response.RINGING); + receiver.setFinalResponseToSend(Response.FORBIDDEN); + + SipProvider receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("receiverPort", String.valueOf(receiverPort)); + deployApplication(params, ConcurrencyControlMode.None); + + Thread.sleep(TIMEOUT); + + Iterator allMessagesIterator = receiver.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + + assertEquals(send_1xx_4xx_sessionStateList.size(), receiver.getAllMessagesContent().size()); + for (int i = 0; i < send_1xx_4xx_sessionStateList.size(); i++) { + assertTrue(receiver.getAllMessagesContent().contains(send_1xx_4xx_sessionStateList.get(i))); + } + } + + /** + * http://code.google.com/p/mobicents/issues/detail?id=1438 Sip Session + * become TERMINATED after receiving 487 response to subsequent request + */ + public void testSessionStateUAC_Subsequent_487() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "Subsequent_487", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + List provisionalResponsesToSend = receiver.getProvisionalResponsesToSend(); + provisionalResponsesToSend.clear(); + provisionalResponsesToSend.add(Response.RINGING); + receiver.setFinalResponseToSend(Response.OK); + receiver.setReferResponseToSend(487); + receiver.setSendNotifyForRefer(false); + + SipProvider receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("receiverPort", String.valueOf(receiverPort)); + deployApplication(params, ConcurrencyControlMode.None); + + Thread.sleep(TIMEOUT); + receiver.sendBye(); + Thread.sleep(5000); + + Iterator allMessagesIterator = receiver.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + + int numberOfTerminated = 0; + int numberOfConfirmed = 0; + assertEquals(send_subsequent_487_sessionStateList.size(), receiver.getAllMessagesContent().size()); + for (int i = 0; i < send_subsequent_487_sessionStateList.size(); i++) { + String messageContent = receiver.getAllMessagesContent().get(i); + assertTrue(receiver.getAllMessagesContent().contains(messageContent)); + if (messageContent.equalsIgnoreCase(SipSession.State.CONFIRMED.toString())) { + numberOfConfirmed++; + } + if (messageContent.equalsIgnoreCase(SipSession.State.TERMINATED.toString())) { + numberOfTerminated++; + } + } + assertEquals(2, numberOfConfirmed); + assertEquals(1, numberOfTerminated); + } + + // Test for SS spec 11.1.6 transaction timeout notification + // Also Tests Issue 1470 http://code.google.com/p/mobicents/issues/detail?id=1470 + // Also Tests Issue 1693 http://code.google.com/p/mobicents/issues/detail?id=1693 + public void testTransactionTimeoutResponse() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + List provisionalResponsesToSend = receiver.getProvisionalResponsesToSend(); + provisionalResponsesToSend.clear(); + provisionalResponsesToSend.add(Response.RINGING); + receiver.setFinalResponseToSend(Response.FORBIDDEN); + + SipProvider receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("receiverPort", String.valueOf(receiverPort)); + params.put("testTimeout", "true"); + deployApplication(params, ConcurrencyControlMode.SipSession); + + Thread.sleep(TIMEOUT); + + Iterator allMessagesIterator = receiver.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + + } + assertTrue(receiver.getAllMessagesContent().contains("sipSessionReadyToInvalidate")); + assertTrue(receiver.getAllMessagesContent().contains("sipAppSessionReadyToInvalidate")); + assertTrue(receiver.txTimeoutReceived); + } + + @Override + protected void tearDown() throws Exception { + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/session/SessionStateUASSipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/session/SessionStateUASSipServletTest.java index c8c17f9fee..22cb846335 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/session/SessionStateUASSipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/session/SessionStateUASSipServletTest.java @@ -1,304 +1,321 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.session; - -import java.text.ParseException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import javax.servlet.sip.SipSession; -import javax.sip.InvalidArgumentException; -import javax.sip.SipException; -import javax.sip.SipProvider; -import javax.sip.TransactionDoesNotExistException; -import javax.sip.TransactionUnavailableException; -import javax.sip.address.SipURI; -import javax.sip.message.Request; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class SessionStateUASSipServletTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(SessionStateUASSipServletTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final String SEND_1XX_2XX = "send1xx_2xx"; - private static final String SEND_1XX_4XX = "send1xx_4xx"; - private static final String SEND_4XX = "send4xx"; - private static final String SEND_2XX = "send2xx"; - private static final String TEST_TIMEOUT = "test_timeout"; - private static final String STX_408_RECEIVED = "408 received on STX"; - - private List send_1xx_2xx_sessionStateList; - private List send_1xx_4xx_sessionStateList; - private List send_4xx_sessionStateList; - private List send_2xx_sessionStateList; - private List send_subsequent_487_sessionStateList; - private static final int TIMEOUT = 20000; - private static final int TIMEOUT_EXPIRATION = 70000; - - TestSipListener sender; - ProtocolObjects senderProtocolObjects; - - TestSipListener receiver; - ProtocolObjects receiverProtocolObjects; - - public SessionStateUASSipServletTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/session-state-uas/src/main/sipapp", - "sip-test-context", - "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/session/session-state-uas-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - send_1xx_2xx_sessionStateList = new ArrayList(); - send_1xx_2xx_sessionStateList.add(SipSession.State.INITIAL.toString()); - send_1xx_2xx_sessionStateList.add(SipSession.State.EARLY.toString()); - send_1xx_2xx_sessionStateList.add(SipSession.State.CONFIRMED.toString()); - send_1xx_2xx_sessionStateList.add(SipSession.State.TERMINATED.toString()); - - send_1xx_4xx_sessionStateList = new ArrayList(); - send_1xx_4xx_sessionStateList.add(SipSession.State.INITIAL.toString()); - send_1xx_4xx_sessionStateList.add(SipSession.State.EARLY.toString()); - send_1xx_4xx_sessionStateList.add(SipSession.State.TERMINATED.toString()); - - send_2xx_sessionStateList = new ArrayList(); - send_2xx_sessionStateList.add(SipSession.State.INITIAL.toString()); - send_2xx_sessionStateList.add(SipSession.State.CONFIRMED.toString()); - send_2xx_sessionStateList.add(SipSession.State.TERMINATED.toString()); - - send_4xx_sessionStateList = new ArrayList(); - send_4xx_sessionStateList.add(SipSession.State.INITIAL.toString()); - send_4xx_sessionStateList.add(SipSession.State.TERMINATED.toString()); - - send_subsequent_487_sessionStateList = new ArrayList(); - send_subsequent_487_sessionStateList.add(SipSession.State.INITIAL.toString()); - send_subsequent_487_sessionStateList.add(SipSession.State.CONFIRMED.toString()); - send_subsequent_487_sessionStateList.add(SipSession.State.CONFIRMED.toString()); - send_subsequent_487_sessionStateList.add(SipSession.State.TERMINATED.toString()); - } - - public void testSessionStateUAS_1xx_2xx() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - createAndExecuteCall(SEND_1XX_2XX, true); - - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - - assertEquals(send_1xx_2xx_sessionStateList.size(), sender.getAllMessagesContent().size()); - for (int i = 0; i < send_1xx_2xx_sessionStateList.size(); i++) { - assertTrue(sender.getAllMessagesContent().contains(send_1xx_2xx_sessionStateList.get(i))); - } - } - - public void testSessionStateUAS_1xx_4xx() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - createAndExecuteCall(SEND_1XX_4XX, false); - - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - - assertEquals(send_1xx_4xx_sessionStateList.size(), sender.getAllMessagesContent().size()); - for (int i = 0; i < send_1xx_4xx_sessionStateList.size(); i++) { - assertTrue(sender.getAllMessagesContent().contains(send_1xx_4xx_sessionStateList.get(i))); - } - } - - public void testSessionStateUAS_2xx() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - createAndExecuteCall(SEND_2XX, true); - - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - - assertEquals(send_2xx_sessionStateList.size(), sender.getAllMessagesContent().size()); - for (int i = 0; i < send_2xx_sessionStateList.size(); i++) { - assertTrue(sender.getAllMessagesContent().contains(send_2xx_sessionStateList.get(i))); - } - } - - public void testSessionStateUAS_4xx() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - createAndExecuteCall(SEND_4XX, false); - - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - - assertEquals(send_4xx_sessionStateList.size(), sender.getAllMessagesContent().size()); - for (int i = 0; i < send_4xx_sessionStateList.size(); i++) { - assertTrue(sender.getAllMessagesContent().contains(send_4xx_sessionStateList.get(i))); - } - } - - /** - * http://code.google.com/p/mobicents/issues/detail?id=1438 - * Sip Session become TERMINATED after receiving 487 response to subsequent request - */ - public void testSessionStateUAS_SubsequentRequest_FinalResponse() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - createAndExecuteCall(SEND_2XX, false); - - sender.sendInDialogSipRequest(Request.REFER, null, null, null, null, null); - - Thread.sleep(TIMEOUT); - sender.sendBye(); - Thread.sleep(TIMEOUT); - - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - - int numberOfTerminated = 0; - int numberOfConfirmed = 0; - assertEquals(send_subsequent_487_sessionStateList.size(), sender.getAllMessagesContent().size()); - for (int i = 0; i < send_subsequent_487_sessionStateList.size(); i++) { - String messageContent = sender.getAllMessagesContent().get(i); - assertTrue(sender.getAllMessagesContent().contains(messageContent)); - if(messageContent.equalsIgnoreCase(SipSession.State.CONFIRMED.toString())) { - numberOfConfirmed++; - } - if(messageContent.equalsIgnoreCase(SipSession.State.TERMINATED.toString())) { - numberOfTerminated++; - } - } - assertEquals(2, numberOfConfirmed); - assertEquals(1, numberOfTerminated); - } - - /** - * @param sendBye TODO - * @throws ParseException - * @throws SipException - * @throws InvalidArgumentException - * @throws InterruptedException - * @throws TransactionUnavailableException - * @throws TransactionDoesNotExistException - */ - private void createAndExecuteCall(String messageContent, boolean sendBye) throws ParseException, SipException, - InvalidArgumentException, InterruptedException, - TransactionUnavailableException, TransactionDoesNotExistException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, messageContent, null, false); - Thread.sleep(TIMEOUT); - if(sendBye) { - assertTrue(sender.isAckSent()); - Thread.sleep(TIMEOUT); - sender.sendBye(); - Thread.sleep(TIMEOUT); - assertTrue(sender.getOkToByeReceived()); - } else { - assertTrue(sender.isFinalResponseReceived()); - } - } - - // Test for SS spec 11.1.6 transaction timeout notification - // Also Tests Issue 1618 http://code.google.com/p/mobicents/issues/detail?id=1618 - public void testTransactionTimeoutResponse() throws Exception { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setSendAck(false); - sender.sendSipRequest("INVITE", fromAddress, toAddress, TEST_TIMEOUT, null, false); - senderProtocolObjects.destroy(); - - receiverProtocolObjects =new ProtocolObjects( - "receiver", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - receiverProvider.addSipListener(receiver); - receiverProtocolObjects.start(); - - Thread.sleep(TIMEOUT_EXPIRATION); - - Iterator allMessagesIterator = receiver.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - - } - assertFalse(receiver.getAllMessagesContent().contains(STX_408_RECEIVED)); - receiverProtocolObjects.destroy(); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.session; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.servlet.sip.SipSession; +import javax.sip.InvalidArgumentException; +import javax.sip.SipException; +import javax.sip.SipProvider; +import javax.sip.TransactionDoesNotExistException; +import javax.sip.TransactionUnavailableException; +import javax.sip.address.SipURI; +import javax.sip.message.Request; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class SessionStateUASSipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(SessionStateUASSipServletTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final String SEND_1XX_2XX = "send1xx_2xx"; + private static final String SEND_1XX_4XX = "send1xx_4xx"; + private static final String SEND_4XX = "send4xx"; + private static final String SEND_2XX = "send2xx"; + private static final String TEST_TIMEOUT = "test_timeout"; + private static final String STX_408_RECEIVED = "408 received on STX"; + + private List send_1xx_2xx_sessionStateList; + private List send_1xx_4xx_sessionStateList; + private List send_4xx_sessionStateList; + private List send_2xx_sessionStateList; + private List send_subsequent_487_sessionStateList; + private static final int TIMEOUT = 20000; + private static final int TIMEOUT_EXPIRATION = 70000; + + TestSipListener sender; + ProtocolObjects senderProtocolObjects; + + TestSipListener receiver; + ProtocolObjects receiverProtocolObjects; + + public SessionStateUASSipServletTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + public void deployApplication(Map params) { + SipStandardContext context = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/session-state-uas/src/main/sipapp", + params, null); + assertTrue(context.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/session/session-state-uas-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + deployApplication(params); + + send_1xx_2xx_sessionStateList = new ArrayList(); + send_1xx_2xx_sessionStateList.add(SipSession.State.INITIAL.toString()); + send_1xx_2xx_sessionStateList.add(SipSession.State.EARLY.toString()); + send_1xx_2xx_sessionStateList.add(SipSession.State.CONFIRMED.toString()); + send_1xx_2xx_sessionStateList.add(SipSession.State.TERMINATED.toString()); + + send_1xx_4xx_sessionStateList = new ArrayList(); + send_1xx_4xx_sessionStateList.add(SipSession.State.INITIAL.toString()); + send_1xx_4xx_sessionStateList.add(SipSession.State.EARLY.toString()); + send_1xx_4xx_sessionStateList.add(SipSession.State.TERMINATED.toString()); + + send_2xx_sessionStateList = new ArrayList(); + send_2xx_sessionStateList.add(SipSession.State.INITIAL.toString()); + send_2xx_sessionStateList.add(SipSession.State.CONFIRMED.toString()); + send_2xx_sessionStateList.add(SipSession.State.TERMINATED.toString()); + + send_4xx_sessionStateList = new ArrayList(); + send_4xx_sessionStateList.add(SipSession.State.INITIAL.toString()); + send_4xx_sessionStateList.add(SipSession.State.TERMINATED.toString()); + + send_subsequent_487_sessionStateList = new ArrayList(); + send_subsequent_487_sessionStateList.add(SipSession.State.INITIAL.toString()); + send_subsequent_487_sessionStateList.add(SipSession.State.CONFIRMED.toString()); + send_subsequent_487_sessionStateList.add(SipSession.State.CONFIRMED.toString()); + send_subsequent_487_sessionStateList.add(SipSession.State.TERMINATED.toString()); + } + + public void testSessionStateUAS_1xx_2xx() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + createAndExecuteCall(SEND_1XX_2XX, true); + + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + + assertEquals(send_1xx_2xx_sessionStateList.size(), sender.getAllMessagesContent().size()); + for (int i = 0; i < send_1xx_2xx_sessionStateList.size(); i++) { + assertTrue(sender.getAllMessagesContent().contains(send_1xx_2xx_sessionStateList.get(i))); + } + } + + public void testSessionStateUAS_1xx_4xx() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + createAndExecuteCall(SEND_1XX_4XX, false); + + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + + assertEquals(send_1xx_4xx_sessionStateList.size(), sender.getAllMessagesContent().size()); + for (int i = 0; i < send_1xx_4xx_sessionStateList.size(); i++) { + assertTrue(sender.getAllMessagesContent().contains(send_1xx_4xx_sessionStateList.get(i))); + } + } + + public void testSessionStateUAS_2xx() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + createAndExecuteCall(SEND_2XX, true); + + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + + assertEquals(send_2xx_sessionStateList.size(), sender.getAllMessagesContent().size()); + for (int i = 0; i < send_2xx_sessionStateList.size(); i++) { + assertTrue(sender.getAllMessagesContent().contains(send_2xx_sessionStateList.get(i))); + } + } + + public void testSessionStateUAS_4xx() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + createAndExecuteCall(SEND_4XX, false); + + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + + assertEquals(send_4xx_sessionStateList.size(), sender.getAllMessagesContent().size()); + for (int i = 0; i < send_4xx_sessionStateList.size(); i++) { + assertTrue(sender.getAllMessagesContent().contains(send_4xx_sessionStateList.get(i))); + } + } + + /** + * http://code.google.com/p/mobicents/issues/detail?id=1438 Sip Session + * become TERMINATED after receiving 487 response to subsequent request + */ + public void testSessionStateUAS_SubsequentRequest_FinalResponse() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + createAndExecuteCall(SEND_2XX, false); + + sender.sendInDialogSipRequest(Request.REFER, null, null, null, null, null); + + Thread.sleep(TIMEOUT); + sender.sendBye(); + Thread.sleep(TIMEOUT); + + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + + int numberOfTerminated = 0; + int numberOfConfirmed = 0; + assertEquals(send_subsequent_487_sessionStateList.size(), sender.getAllMessagesContent().size()); + for (int i = 0; i < send_subsequent_487_sessionStateList.size(); i++) { + String messageContent = sender.getAllMessagesContent().get(i); + assertTrue(sender.getAllMessagesContent().contains(messageContent)); + if (messageContent.equalsIgnoreCase(SipSession.State.CONFIRMED.toString())) { + numberOfConfirmed++; + } + if (messageContent.equalsIgnoreCase(SipSession.State.TERMINATED.toString())) { + numberOfTerminated++; + } + } + assertEquals(2, numberOfConfirmed); + assertEquals(1, numberOfTerminated); + } + + /** + * @param sendBye TODO + * @throws ParseException + * @throws SipException + * @throws InvalidArgumentException + * @throws InterruptedException + * @throws TransactionUnavailableException + * @throws TransactionDoesNotExistException + */ + private void createAndExecuteCall(String messageContent, boolean sendBye) throws ParseException, SipException, + InvalidArgumentException, InterruptedException, + TransactionUnavailableException, TransactionDoesNotExistException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, messageContent, null, false); + Thread.sleep(TIMEOUT); + if (sendBye) { + assertTrue(sender.isAckSent()); + Thread.sleep(TIMEOUT); + sender.sendBye(); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + } else { + assertTrue(sender.isFinalResponseReceived()); + } + } + + // Test for SS spec 11.1.6 transaction timeout notification + // Also Tests Issue 1618 http://code.google.com/p/mobicents/issues/detail?id=1618 + public void testTransactionTimeoutResponse() throws Exception { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setSendAck(false); + sender.sendSipRequest("INVITE", fromAddress, toAddress, TEST_TIMEOUT, null, false); + senderProtocolObjects.destroy(); + + receiverProtocolObjects = new ProtocolObjects( + "receiver", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + + Thread.sleep(TIMEOUT_EXPIRATION); + + Iterator allMessagesIterator = receiver.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + + } + assertFalse(receiver.getAllMessagesContent().contains(STX_408_RECEIVED)); + receiverProtocolObjects.destroy(); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/session/SipAppSessionTerminationTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/session/SipAppSessionTerminationTest.java index 4cc4e6b7c6..e139968775 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/session/SipAppSessionTerminationTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/session/SipAppSessionTerminationTest.java @@ -19,139 +19,162 @@ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ - package org.mobicents.servlet.sip.testsuite.session; import java.io.InputStream; import java.net.URL; +import java.util.HashMap; import java.util.Iterator; +import java.util.Map; import javax.sip.SipProvider; +import static junit.framework.Assert.assertTrue; import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; import org.mobicents.servlet.sip.testsuite.ProtocolObjects; import org.mobicents.servlet.sip.testsuite.TestSipListener; public class SipAppSessionTerminationTest extends SipServletTestCase { - private String CLICK2DIAL_URL; - private String CLICK2DIAL_PARAMS; - private static transient Logger logger = Logger.getLogger(SipAppSessionTerminationTest.class); - - TestSipListener receiver; - ProtocolObjects receiverProtocolObjects; - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - - private static final int TIMEOUT = 10000; - - public SipAppSessionTerminationTest(String name) { - super(name); - } - - @Override - public void setUp() throws Exception { - super.setUp(); - - CLICK2DIAL_URL = "http://" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":8080/click2call/call"; - CLICK2DIAL_PARAMS = "?from=sip:sipAppTest@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5056&to=sip:to@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5057"; - - receiverProtocolObjects =new ProtocolObjects( - "receiver", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5057, 5070, receiverProtocolObjects, true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - } - - @Override - public void tearDown() throws Exception { - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - @Override - public void deployApplication() { - assertTrue(tomcat - .deployContext( - projectHome - + "/sip-servlets-test-suite/applications/click-to-call-servlet/src/main/sipapp", - "click2call-context", "/click2call")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/click2call/click-to-call-dar.properties"; - } - - /** - * Test that the sip app session is not invalidated and destroyed when only the sip session is invalidated and not the http session - * @throws Exception - */ - public void testSipAppSessionTerminationHttpSessionStillAlive() - throws Exception { - - logger.info("Trying to reach url : " + CLICK2DIAL_URL - + CLICK2DIAL_PARAMS); - - URL url = new URL(CLICK2DIAL_URL + CLICK2DIAL_PARAMS); - InputStream in = url.openConnection().getInputStream(); - - byte[] buffer = new byte[10000]; - int len = in.read(buffer); - String httpResponse = ""; - for (int q = 0; q < len; q++) - httpResponse += (char) buffer[q]; - logger.info("Received the follwing HTTP response: " + httpResponse); - - Thread.sleep(TIMEOUT); - assertTrue(receiver.getOkToByeReceived()); - Thread.sleep(TIMEOUT); - Iterator allMessagesIterator = receiver.getAllMessagesContent().iterator(); - logger.info("all messages received : "); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertFalse(receiver.getAllMessagesContent().contains("sipAppSessionDestroyed")); - } - - /** - * Test if the sip app session is invalidated and destroyed when both the sip session and http session are invalidated - * @throws Exception - */ - public void testSipAppSessionTerminationHttpSessionInvalidated() throws Exception { - - logger.info("Trying to reach url : " + CLICK2DIAL_URL - + CLICK2DIAL_PARAMS + "&invalidateHttpSession=true"); - - URL url = new URL(CLICK2DIAL_URL + CLICK2DIAL_PARAMS + "&invalidateHttpSession=true"); - InputStream in = url.openConnection().getInputStream(); - - byte[] buffer = new byte[10000]; - int len = in.read(buffer); - String httpResponse = ""; - for (int q = 0; q < len; q++) - httpResponse += (char) buffer[q]; - logger.info("Received the follwing HTTP response: " + httpResponse); - - Thread.sleep(TIMEOUT); - assertTrue(receiver.getOkToByeReceived()); - Thread.sleep(TIMEOUT); - Iterator allMessagesIterator = receiver.getAllMessagesContent().iterator(); - logger.info("all messages received : "); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertTrue(receiver.getAllMessagesContent().contains("sipAppSessionDestroyed")); - } + private String CLICK2DIAL_URL; + private String CLICK2DIAL_PARAMS; + private static transient Logger logger = Logger.getLogger(SipAppSessionTerminationTest.class); + + TestSipListener receiver; + ProtocolObjects receiverProtocolObjects; + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + + private static final int TIMEOUT = 10000; + + public SipAppSessionTerminationTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + CLICK2DIAL_URL = "http://" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + httpContainerPort + "/click2call/call"; + + receiverProtocolObjects = new ProtocolObjects( + "receiver", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, true); + SipProvider receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + + CLICK2DIAL_PARAMS = "?from=sip:sipAppTest@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5056&to=sip:to@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + receiverPort; + + + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + deployApplication(params); + } + + @Override + public void tearDown() throws Exception { + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + + @Override + public void deployApplication() { + } + + public void deployApplication(Map params) { + SipStandardContext context = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/click-to-call-servlet/src/main/sipapp", + "click2call", + params, + null); + assertTrue(context.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/click2call/click-to-call-dar.properties"; + } + + /** + * Test that the sip app session is not invalidated and destroyed when only + * the sip session is invalidated and not the http session + * + * @throws Exception + */ + public void testSipAppSessionTerminationHttpSessionStillAlive() + throws Exception { + + logger.info("Trying to reach url : " + CLICK2DIAL_URL + + CLICK2DIAL_PARAMS); + + URL url = new URL(CLICK2DIAL_URL + CLICK2DIAL_PARAMS); + InputStream in = url.openConnection().getInputStream(); + + byte[] buffer = new byte[10000]; + int len = in.read(buffer); + String httpResponse = ""; + for (int q = 0; q < len; q++) { + httpResponse += (char) buffer[q]; + } + logger.info("Received the follwing HTTP response: " + httpResponse); + + Thread.sleep(TIMEOUT); + assertTrue(receiver.getOkToByeReceived()); + Thread.sleep(TIMEOUT); + Iterator allMessagesIterator = receiver.getAllMessagesContent().iterator(); + logger.info("all messages received : "); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertFalse(receiver.getAllMessagesContent().contains("sipAppSessionDestroyed")); + } + + /** + * Test if the sip app session is invalidated and destroyed when both the + * sip session and http session are invalidated + * + * @throws Exception + */ + public void testSipAppSessionTerminationHttpSessionInvalidated() throws Exception { + + logger.info("Trying to reach url : " + CLICK2DIAL_URL + + CLICK2DIAL_PARAMS + "&invalidateHttpSession=true"); + + URL url = new URL(CLICK2DIAL_URL + CLICK2DIAL_PARAMS + "&invalidateHttpSession=true"); + InputStream in = url.openConnection().getInputStream(); + + byte[] buffer = new byte[10000]; + int len = in.read(buffer); + String httpResponse = ""; + for (int q = 0; q < len; q++) { + httpResponse += (char) buffer[q]; + } + logger.info("Received the follwing HTTP response: " + httpResponse); + + Thread.sleep(TIMEOUT); + assertTrue(receiver.getOkToByeReceived()); + Thread.sleep(TIMEOUT); + Iterator allMessagesIterator = receiver.getAllMessagesContent().iterator(); + logger.info("all messages received : "); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertTrue(receiver.getAllMessagesContent().contains("sipAppSessionDestroyed")); + } } diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ENUM/ShootistSipServletENUMTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ENUM/ShootistSipServletENUMTest.java index 4268536077..e83fc0375d 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ENUM/ShootistSipServletENUMTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ENUM/ShootistSipServletENUMTest.java @@ -1,166 +1,153 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.simple.ENUM; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import javax.sip.SipProvider; - -import org.apache.catalina.deploy.ApplicationParameter; -import org.apache.log4j.Logger; -import org.mobicents.ext.javax.sip.dns.DNSLookupPerformer; -import org.mobicents.ext.javax.sip.dns.DefaultDNSLookupPerformer; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; -import org.xbill.DNS.DClass; -import org.xbill.DNS.NAPTRRecord; -import org.xbill.DNS.Name; -import org.xbill.DNS.TextParseException; - -public class ShootistSipServletENUMTest extends SipServletTestCase { - private static transient Logger logger = Logger.getLogger(ShootistSipServletENUMTest.class); - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 20000; -// private static final int TIMEOUT = 100000000; - - TestSipListener receiver; - ProtocolObjects receiverProtocolObjects; - - TestSipListener badReceiver; - ProtocolObjects badReceiverProtocolObjects; - - public ShootistSipServletENUMTest(String name) { - super(name); - startTomcatOnStartup = false; - autoDeployOnStartup = false; - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - public SipStandardContext deployApplication(Map params) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - for (Entry param : params.entrySet()) { - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(param.getKey()); - applicationParameter.setValue(param.getValue()); - context.addApplicationParameter(applicationParameter); - } - assertTrue(tomcat.deployContext(context)); - return context; - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/simple/shootist-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - } - - /* - * testing the DNSResolver MSS extension - */ - public void testShootist() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "receiver", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - receiverProvider.addSipListener(receiver); - receiverProtocolObjects.start(); - - badReceiverProtocolObjects =new ProtocolObjects( - "bad-receiver", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - badReceiver = new TestSipListener(5081, 5070, badReceiverProtocolObjects, false); - SipProvider badReceiverProvider = badReceiver.createProvider(); - badReceiverProvider.addSipListener(badReceiver); - badReceiverProtocolObjects.start(); - badReceiver.setDropRequest(true); - String host = "+358-555-1234567"; - - tomcat.startTomcat(); - - mockDNSLookup(host); - - Map params = new HashMap(); - params.put("enum", host); - params.put("urlType", "tel"); - deployApplication(params); - - Thread.sleep(TIMEOUT); - assertFalse(badReceiver.getByeReceived()); - assertTrue(receiver.getByeReceived()); - assertEquals("sip:jean@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080", receiver.getInviteRequest().getRequestURI().toString()); - } - - private void mockDNSLookup(String host) throws TextParseException { - DNSLookupPerformer dnsLookupPerformer = mock(DefaultDNSLookupPerformer.class); - //mocking the DNS Lookups to match our test cases - tomcat.getSipService().getSipApplicationDispatcher().getDNSServerLocator().setDnsLookupPerformer(dnsLookupPerformer); - - Set supportedTransports = new HashSet(); - supportedTransports.add(TRANSPORT.toUpperCase()); - - List mockedNAPTRRecords = new LinkedList(); - // mocking the name because " + System.getProperty("org.mobicents.testsuite.testhostaddr") + " is not absolute and " + System.getProperty("org.mobicents.testsuite.testhostaddr") + ". cannot be resolved - Name name = mock(Name.class); - when(name.isAbsolute()).thenReturn(true); - when(name.toString()).thenReturn("!^.*$!sip:jean@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080!"); - mockedNAPTRRecords.add(new NAPTRRecord(new Name("7.6.5.4.3.2.1.5.5.5.8.5.3.e164.arpa" + "."), DClass.IN, 1000, 0, 0, "s", "E2U+sip", "!^.*$!sip:jean@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080!", name)); - when(dnsLookupPerformer.performNAPTRLookup("7.6.5.4.3.2.1.5.5.5.8.5.3.e164.arpa", false, supportedTransports)).thenReturn(mockedNAPTRRecords); - } - - @Override - protected void tearDown() throws Exception { - receiverProtocolObjects.destroy(); - badReceiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } -} \ No newline at end of file +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.simple.ENUM; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.sip.SipProvider; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.ext.javax.sip.dns.DNSLookupPerformer; +import org.mobicents.ext.javax.sip.dns.DefaultDNSLookupPerformer; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; +import org.xbill.DNS.DClass; +import org.xbill.DNS.NAPTRRecord; +import org.xbill.DNS.Name; +import org.xbill.DNS.TextParseException; + +public class ShootistSipServletENUMTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ShootistSipServletENUMTest.class); + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 20000; +// private static final int TIMEOUT = 100000000; + + TestSipListener receiver; + ProtocolObjects receiverProtocolObjects; + int receiverPort; + + TestSipListener badReceiver; + ProtocolObjects badReceiverProtocolObjects; + + public ShootistSipServletENUMTest(String name) { + super(name); + startTomcatOnStartup = false; + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + assertTrue(tomcat.deployContext( + projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp", + "sip-test-context", "sip-test")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/simple/shootist-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + } + + /* + * testing the DNSResolver MSS extension + */ + public void testShootist() throws Exception { + String host = "+358-555-1234567"; + + receiverProtocolObjects = new ProtocolObjects( + "receiver", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + + int badReceiverPort = NetworkPortAssigner.retrieveNextPort(); + badReceiverProtocolObjects = new ProtocolObjects( + "bad-receiver", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + badReceiver = new TestSipListener(badReceiverPort, containerPort, badReceiverProtocolObjects, false); + SipProvider badReceiverProvider = badReceiver.createProvider(); + badReceiverProvider.addSipListener(badReceiver); + badReceiverProtocolObjects.start(); + badReceiver.setDropRequest(true); + tomcat.startTomcat(); + + mockDNSLookup(host); + + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(receiverPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + + ctxAtts.put("enum", host); + ctxAtts.put("urlType", "tel"); + deployShootist(ctxAtts, null); + + Thread.sleep(TIMEOUT); + assertFalse(badReceiver.getByeReceived()); + assertTrue(receiver.getByeReceived()); + assertEquals("sip:jean@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + receiverPort, receiver.getInviteRequest().getRequestURI().toString()); + } + + private void mockDNSLookup(String host) throws TextParseException { + DNSLookupPerformer dnsLookupPerformer = mock(DefaultDNSLookupPerformer.class); + //mocking the DNS Lookups to match our test cases + tomcat.getSipService().getSipApplicationDispatcher().getDNSServerLocator().setDnsLookupPerformer(dnsLookupPerformer); + + Set supportedTransports = new HashSet(); + supportedTransports.add(TRANSPORT.toUpperCase()); + + List mockedNAPTRRecords = new LinkedList(); + // mocking the name because " + System.getProperty("org.mobicents.testsuite.testhostaddr") + " is not absolute and " + System.getProperty("org.mobicents.testsuite.testhostaddr") + ". cannot be resolved + Name name = mock(Name.class); + when(name.isAbsolute()).thenReturn(true); + when(name.toString()).thenReturn("!^.*$!sip:jean@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + receiverPort + "!"); + mockedNAPTRRecords.add(new NAPTRRecord(new Name("7.6.5.4.3.2.1.5.5.5.8.5.3.e164.arpa" + "."), DClass.IN, 1000, 0, 0, "s", "E2U+sip", "!^.*$!sip:jean@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + receiverPort + "!", name)); + when(dnsLookupPerformer.performNAPTRLookup("7.6.5.4.3.2.1.5.5.5.8.5.3.e164.arpa", false, supportedTransports)).thenReturn(mockedNAPTRRecords); + } + + @Override + protected void tearDown() throws Exception { + receiverProtocolObjects.destroy(); + badReceiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/LyncInteropShootistSipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/LyncInteropShootistSipServletTest.java index f987a657d8..ea7aa2f167 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/LyncInteropShootistSipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/LyncInteropShootistSipServletTest.java @@ -1,227 +1,156 @@ -/* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2014, Telestax Inc and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - */ - -package org.mobicents.servlet.sip.testsuite.simple; - -import gov.nist.javax.sip.message.RequestExt; - -import java.io.File; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Properties; - -import javax.sip.SipProvider; -import javax.sip.header.ViaHeader; -import javax.sip.message.Request; - -import org.apache.catalina.deploy.ApplicationParameter; -import org.apache.log4j.Logger; -import org.junit.After; -import org.junit.Before; -import org.mobicents.servlet.sip.SipEmbedded; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -/** - * Non regression test for https://github.com/Mobicents/sip-servlets/issues/50 - * @author jean - * - */ -public class LyncInteropShootistSipServletTest extends SipServletTestCase { - private static transient Logger logger = Logger.getLogger(LyncInteropShootistSipServletTest.class); - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; - private static final int DIALOG_TIMEOUT = 40000; -// private static final int TIMEOUT = 100000000; - - TestSipListener receiver; - - ProtocolObjects receiverProtocolObjects; - - public LyncInteropShootistSipServletTest(String name) { - super(name); - initTomcatOnStartup = false; - createTomcatOnStartup = false; - startTomcatOnStartup = false; - autoDeployOnStartup = false; - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - public SipStandardContext deployApplication(String name, String value) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("/sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - context.setConcurrencyControlMode(ConcurrencyControlMode.SipApplicationSession); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(name); - applicationParameter.setValue(value); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - return context; - } - - public SipStandardContext deployApplication(Map params) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("/sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setConcurrencyControlMode(ConcurrencyControlMode.SipApplicationSession); - context.setManager(new SipStandardManager()); - for (Entry param : params.entrySet()) { - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(param.getKey()); - applicationParameter.setValue(param.getValue()); - context.addApplicationParameter(applicationParameter); - } - assertTrue(tomcat.deployContext(context)); - return context; - } - - - public SipStandardContext deployApplication(Map params,ConcurrencyControlMode concurrencyControlMode) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("/sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - if(concurrencyControlMode != null) { - context.setConcurrencyControlMode(concurrencyControlMode); - } - for (Entry param : params.entrySet()) { - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(param.getKey()); - applicationParameter.setValue(param.getValue()); - context.addApplicationParameter(applicationParameter); - } - assertTrue(tomcat.deployContext(context)); - return context; - } - - public SipStandardContext deployApplicationServletListenerTest() { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("/sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName("testServletListener"); - applicationParameter.setValue("true"); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - return context; - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/simple/shootist-sip-servlet-dar.properties"; - } - - @Override - @Before - protected void setUp() throws Exception { - - System.setProperty( "javax.net.ssl.keyStore", LyncInteropShootistSipServletTest.class.getResource("testkeys").getPath() ); - System.setProperty( "javax.net.ssl.trustStore", LyncInteropShootistSipServletTest.class.getResource("testkeys").getPath() ); - System.setProperty( "javax.net.ssl.keyStorePassword", "passphrase" ); - System.setProperty( "javax.net.ssl.keyStoreType", "jks" ); - super.setUp(); - createLyncCompliantTomcat(); - - } - /** - * https://github.com/Mobicents/sip-servlets/issues/50 - * Test Lync Interop and reduction of tag and call id sizes - * @throws Exception - */ - protected void createLyncCompliantTomcat() throws Exception { - tomcat = new SipEmbedded(serverName, serviceFullClassName, 32, 10); - tomcat.setLoggingFilePath( - projectHome + File.separatorChar + "sip-servlets-test-suite" + - File.separatorChar + "testsuite" + - File.separatorChar + "src" + - File.separatorChar + "test" + - File.separatorChar + "resources" + File.separatorChar); - logger.info("Log4j path is : " + tomcat.getLoggingFilePath()); - String darConfigurationFile = getDarConfigurationFile(); - tomcat.setDarConfigurationFilePath(darConfigurationFile); - Properties sipStackProperties = getSipStackProperties(); - tomcat.initTomcat(tomcatBasePath, sipStackProperties); - tomcat.addHttpConnector(httpIpAddress, 8080); - /* - * - */ - if(addSipConnectorOnStartup) { - sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, 5070, listeningPointTransport); - } - if(startTomcatOnStartup) { - tomcat.startTomcat(); - } - if(autoDeployOnStartup) { - deployApplication(); - } - } - - public void testShootist() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - receiverProvider.addSipListener(receiver); - receiverProtocolObjects.start(); - tomcat.startTomcat(); - deployApplication(); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - assertEquals(32,((RequestExt)receiver.getInviteRequest()).getCallIdHeader().getCallId().trim().length()); - assertEquals(10,((RequestExt)receiver.getInviteRequest()).getFromHeader().getTag().trim().length()); - } - - @Override - @After - protected void tearDown() throws Exception { - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } -} \ No newline at end of file +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2014, Telestax Inc and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + */ +package org.mobicents.servlet.sip.testsuite.simple; + +import gov.nist.javax.sip.message.RequestExt; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import javax.sip.SipProvider; +import org.apache.log4j.Logger; +import org.junit.After; +import org.junit.Before; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipEmbedded; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +/** + * Non regression test for https://github.com/Mobicents/sip-servlets/issues/50 + * + * @author jean + * + */ +public class LyncInteropShootistSipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(LyncInteropShootistSipServletTest.class); + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; + private static final int DIALOG_TIMEOUT = 40000; +// private static final int TIMEOUT = 100000000; + + TestSipListener receiver; + + ProtocolObjects receiverProtocolObjects; + + public LyncInteropShootistSipServletTest(String name) { + super(name); + initTomcatOnStartup = false; + createTomcatOnStartup = false; + startTomcatOnStartup = false; + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + assertTrue(tomcat.deployContext( + projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp", + "sip-test-context", "sip-test")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/simple/shootist-sip-servlet-dar.properties"; + } + + @Override + @Before + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + System.setProperty("javax.net.ssl.keyStore", LyncInteropShootistSipServletTest.class.getResource("testkeys").getPath()); + System.setProperty("javax.net.ssl.trustStore", LyncInteropShootistSipServletTest.class.getResource("testkeys").getPath()); + System.setProperty("javax.net.ssl.keyStorePassword", "passphrase"); + System.setProperty("javax.net.ssl.keyStoreType", "jks"); + super.setUp(); + createLyncCompliantTomcat(); + + } + + /** + * https://github.com/Mobicents/sip-servlets/issues/50 Test Lync Interop and + * reduction of tag and call id sizes + * + * @throws Exception + */ + protected void createLyncCompliantTomcat() throws Exception { + tomcat = new SipEmbedded(serverName, serviceFullClassName, 32, 10); + tomcat.setLoggingFilePath( + projectHome + File.separatorChar + "sip-servlets-test-suite" + + File.separatorChar + "testsuite" + + File.separatorChar + "src" + + File.separatorChar + "test" + + File.separatorChar + "resources" + File.separatorChar); + logger.info("Log4j path is : " + tomcat.getLoggingFilePath()); + String darConfigurationFile = getDarConfigurationFile(); + tomcat.setDarConfigurationFilePath(darConfigurationFile); + Properties sipStackProperties = getSipStackProperties(); + tomcat.initTomcat(tomcatBasePath, sipStackProperties); + tomcat.addHttpConnector(httpIpAddress, httpContainerPort); + /* + * + */ + if (addSipConnectorOnStartup) { + sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, containerPort, listeningPointTransport); + } + if (startTomcatOnStartup) { + tomcat.startTomcat(); + } + if (autoDeployOnStartup) { + deployApplication(); + } + } + + public void testShootist() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + assertEquals(32, ((RequestExt) receiver.getInviteRequest()).getCallIdHeader().getCallId().trim().length()); + assertEquals(10, ((RequestExt) receiver.getInviteRequest()).getFromHeader().getTag().trim().length()); + } + + @Override + @After + protected void tearDown() throws Exception { + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/MultiHomeUACTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/MultiHomeUACTest.java index e5bd00ed95..533839661a 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/MultiHomeUACTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/MultiHomeUACTest.java @@ -1,108 +1,99 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.simple; -import javax.sip.SipProvider; - -import org.apache.catalina.deploy.ApplicationParameter; -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class MultiHomeUACTest extends SipServletTestCase { - private static transient Logger logger = Logger.getLogger(MultiHomeUACTest.class); - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; -// private static final int TIMEOUT = 100000000; - - TestSipListener receiver; - - ProtocolObjects receiverProtocolObjects; - - public MultiHomeUACTest(String name) { - super(name); - startTomcatOnStartup = false; - autoDeployOnStartup = false; - this.sipIpAddress="0.0.0.0"; - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - public void deployApplicationSetToParam(String name, String value) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(name); - applicationParameter.setValue(value); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/simple/shootist-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - } - - public void testShootist() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - deployApplication(); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - } - - @Override - protected void tearDown() throws Exception { - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } -} \ No newline at end of file +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.simple; + +import java.util.HashMap; +import java.util.Map; +import javax.sip.SipProvider; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class MultiHomeUACTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(MultiHomeUACTest.class); + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; +// private static final int TIMEOUT = 100000000; + + TestSipListener receiver; + + ProtocolObjects receiverProtocolObjects; + + public MultiHomeUACTest(String name) { + super(name); + startTomcatOnStartup = false; + autoDeployOnStartup = false; + this.sipIpAddress = "0.0.0.0"; + } + + @Override + public void deployApplication() { + assertTrue(tomcat.deployContext( + projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp", + "sip-test-context", "sip-test")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/simple/shootist-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + } + + public void testShootist() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + } + + @Override + protected void tearDown() throws Exception { + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/MultiHomeUASTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/MultiHomeUASTest.java index f0314b3b40..8d767130f7 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/MultiHomeUASTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/MultiHomeUASTest.java @@ -1,101 +1,120 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.simple; - -import java.text.ParseException; - -import javax.sip.InvalidArgumentException; -import javax.sip.SipException; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class MultiHomeUASTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(MultiHomeUASTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender; - ProtocolObjects senderProtocolObjects; - - public MultiHomeUASTest(String name) { - super(name); - this.sipIpAddress="0.0.0.0"; - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/simple/simple-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - senderProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - senderProvider.addSipListener(sender); - senderProtocolObjects.start(); - } - - public void testShootme() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.simple; + +import java.text.ParseException; +import java.util.HashMap; +import java.util.Map; + +import javax.sip.InvalidArgumentException; +import javax.sip.SipException; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class MultiHomeUASTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(MultiHomeUASTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + ProtocolObjects senderProtocolObjects; + + public MultiHomeUASTest(String name) { + super(name); + this.sipIpAddress = "0.0.0.0"; + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + + } + + public void deployApplication(Map params) { + SipStandardContext context = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp", + "sip-test", + params, + null); + assertTrue(context.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/simple/simple-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int myPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(myPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(myPort)); + deployApplication(params); + } + + public void testShootme() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/QuotedParameterSipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/QuotedParameterSipServletTest.java new file mode 100644 index 0000000000..0b0e956ef9 --- /dev/null +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/QuotedParameterSipServletTest.java @@ -0,0 +1,188 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2014, Telestax Inc and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + */ +package org.mobicents.servlet.sip.testsuite.simple; + +import gov.nist.javax.sip.message.MessageExt; + +import java.util.HashMap; +import java.util.Map; +import javax.sip.SipProvider; +import org.apache.log4j.Logger; +import org.junit.After; +import org.junit.Before; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class QuotedParameterSipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(QuotedParameterSipServletTest.class); + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; + private static final int DIALOG_TIMEOUT = 40000; +// private static final int TIMEOUT = 100000000; + + TestSipListener receiver; + + ProtocolObjects receiverProtocolObjects; + + public QuotedParameterSipServletTest(String name) { + super(name); + startTomcatOnStartup = false; + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + assertTrue(tomcat.deployContext( + projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp", + "sip-test-context", "sip-test")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/simple/simple-sip-servlet-dar.properties"; + } + + @Override + @Before + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + System.setProperty("javax.net.ssl.keyStore", ShootistSipServletTest.class.getResource("testkeys").getPath()); + System.setProperty("javax.net.ssl.trustStore", ShootistSipServletTest.class.getResource("testkeys").getPath()); + System.setProperty("javax.net.ssl.keyStorePassword", "passphrase"); + System.setProperty("javax.net.ssl.keyStoreType", "jks"); + super.setUp(); + } + + public void testQuotedFromHeaderParam() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + String userName = "sip:+34666666666@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080;pres-list=mylist"; + ctxAtts.put("username", userName); + ctxAtts.put("testFromHeader", "true"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + // qparam1 and qparam3 are being defined in sip.xml as the parameters which its value need to be quoted. + assertTrue(((MessageExt) receiver.getInviteRequest()).getFromHeader().toString().contains("param0=value0;")); + assertTrue(((MessageExt) receiver.getInviteRequest()).getFromHeader().toString().contains(";qparam1=\"value1\";")); + assertTrue(((MessageExt) receiver.getInviteRequest()).getFromHeader().toString().contains(";param2=value2;")); + assertTrue(((MessageExt) receiver.getInviteRequest()).getFromHeader().toString().contains(";qparam3=\"value3\"")); + } + + public void testQuotedToHeaderParam() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + String userName = "sip:+34666666666@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080;pres-list=mylist"; + ctxAtts.put("username", userName); + ctxAtts.put("testToHeader", "true"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + // qparam1 and qparam3 are being defined in sip.xml as the parameters which its value need to be quoted. + assertTrue(((MessageExt) receiver.getInviteRequest()).getToHeader().toString().contains("param0=value0;")); + assertTrue(((MessageExt) receiver.getInviteRequest()).getToHeader().toString().contains(";qparam1=\"value1\";")); + assertTrue(((MessageExt) receiver.getInviteRequest()).getToHeader().toString().contains(";param2=value2;")); + assertTrue(((MessageExt) receiver.getInviteRequest()).getToHeader().toString().contains(";qparam3=\"value3\"")); + } + + public void testQuotedContactHeaderParam() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + String userName = "sip:+34666666666@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080;pres-list=mylist"; + ctxAtts.put("username", userName); + ctxAtts.put("testContactHeader", "true"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + // qparam1 and qparam3 are being defined in sip.xml as the parameters which its value need to be quoted. + assertTrue(((MessageExt) receiver.getInviteRequest()).getHeader("Contact").toString().contains("param0=value0;")); + assertTrue(((MessageExt) receiver.getInviteRequest()).getHeader("Contact").toString().contains(";qparam1=\"value1\";")); + assertTrue(((MessageExt) receiver.getInviteRequest()).getHeader("Contact").toString().contains(";param2=value2;")); + assertTrue(((MessageExt) receiver.getInviteRequest()).getHeader("Contact").toString().contains(";qparam3=\"value3\"")); + } + + public void testQuotedViaHeaderParam() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + String userName = "sip:+34666666666@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080;pres-list=mylist"; + ctxAtts.put("username", userName); + ctxAtts.put("testViaHeader", "true"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + // qparam1 and qparam3 are being defined in sip.xml as the parameters which its value need to be quoted. + assertTrue(((MessageExt) receiver.getInviteRequest()).getTopmostViaHeader().toString().contains("param0=value0;")); + assertTrue(((MessageExt) receiver.getInviteRequest()).getTopmostViaHeader().toString().contains(";qparam1=\"value1\";")); + assertTrue(((MessageExt) receiver.getInviteRequest()).getTopmostViaHeader().toString().contains(";param2=value2;")); + assertTrue(((MessageExt) receiver.getInviteRequest()).getTopmostViaHeader().toString().contains(";qparam3=\"value3\"")); + } + + @Override + @After + protected void tearDown() throws Exception { + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootistRegisterTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootistRegisterTest.java new file mode 100644 index 0000000000..45c6949460 --- /dev/null +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootistRegisterTest.java @@ -0,0 +1,211 @@ +package org.mobicents.servlet.sip.testsuite.simple; + +import java.util.HashMap; +import java.util.Map; +import javax.sip.ListeningPoint; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import javax.sip.header.ContactHeader; +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertNull; +import static junit.framework.Assert.assertTrue; +import org.apache.log4j.Logger; +import org.junit.Before; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class ShootistRegisterTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ShootistSipServletTest.class); + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; + private static final int DIALOG_TIMEOUT = 40000; +// private static final int TIMEOUT = 100000000; + + TestSipListener receiver; + + ProtocolObjects receiverProtocolObjects; + + public ShootistRegisterTest(String name) { + super(name); + startTomcatOnStartup = false; + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + ctx = tomcat.deployAppContext( + projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp", + "sip-test-context", "sip-test"); + assertTrue(ctx.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/simple/shootist-sip-servlet-dar.properties"; + } + + @Override + @Before + protected void setUp() throws Exception { + + System.setProperty("javax.net.ssl.keyStore", ShootistSipServletTest.class.getResource("testkeys").getPath()); + System.setProperty("javax.net.ssl.trustStore", ShootistSipServletTest.class.getResource("testkeys").getPath()); + System.setProperty("javax.net.ssl.keyStorePassword", "passphrase"); + System.setProperty("javax.net.ssl.keyStoreType", "jks"); + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + } + + /** + * non regression test for Issue 1412 + * http://code.google.com/p/mobicents/issues/detail?id=1412 Contact header + * is added to REGISTER request by container + */ + public void testShootistRegister() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("method", "REGISTER"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertNull(receiver.getRegisterReceived().getHeader(ContactHeader.NAME)); + } + + /** + * non regression test for + * https://github.com/Mobicents/sip-servlets/issues/36 REGISTER CSeq + * Increase for UAC use cases using session.createRequest("REGISTER") + */ + public void testShootistRegisterCSeqIncrease() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("method", "REGISTER"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(DIALOG_TIMEOUT); + assertNull(receiver.getRegisterReceived().getHeader(ContactHeader.NAME)); + assertTrue(receiver.getLastRegisterCSeqNumber() >= 2); + } + + /** + * non regression test for + * https://github.com/Mobicents/sip-servlets/issues/51 Contact header with + * gruu is added to REGISTER request + */ + public void testShootistRegisterGruu() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("method", "REGISTER"); + ctxAtts.put("testGruu", "true"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + ContactHeader contactHeader = (ContactHeader) receiver.getRegisterReceived().getHeader(ContactHeader.NAME); + assertNotNull(contactHeader); + assertEquals("Contact: ", + contactHeader.toString().trim()); + } + + /** + * non regression test for Issue 2269 + * http://code.google.com/p/mobicents/issues/detail?id=2269 Wrong Contact + * header scheme URI in case TLS call with request URI 'sip:' scheme and + * contact is uri is secure with "sips" + */ + public void testShootistRegisterContactNonSecureURITlsTransport() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "tls_receiver", "gov.nist", "TLS", AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("transportRURI", "tls"); + ctxAtts.put("method", "REGISTER"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, 5071, ListeningPoint.TCP); + sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, 5072, ListeningPoint.TLS); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + tomcat.startTomcat(); + Thread.sleep(TIMEOUT); + ContactHeader contactHeader = (ContactHeader) receiver.getRegisterReceived().getHeader(ContactHeader.NAME); + assertNotNull(contactHeader); + assertTrue(((SipURI) contactHeader.getAddress().getURI()).toString().contains("sip:")); + assertTrue(((SipURI) contactHeader.getAddress().getURI()).toString().contains(String.valueOf(myPort))); + assertTrue(((SipURI) contactHeader.getAddress().getURI()).toString().toLowerCase().contains("transport=tls")); + } + + /** + * non regression test for Issue 156 + * http://code.google.com/p/sipservlets/issues/detail?id=156 Contact header + * in REGISTER overwritten by container + */ + public void testShootistRegisterSetContact() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("setRandomContact", "true"); + ctxAtts.put("method", "REGISTER"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + ContactHeader contactHeader = (ContactHeader) receiver.getRegisterReceived().getHeader(ContactHeader.NAME); + assertNotNull(contactHeader); + assertEquals(((SipURI) contactHeader.getAddress().getURI()).toString(), "sip:random@172.172.172.172:3289"); + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootistSipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootistSipServletTest.java index b9fdcd5dd5..8fc139027f 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootistSipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootistSipServletTest.java @@ -1,1221 +1,1153 @@ -/* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2014, Telestax Inc and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - */ - -package org.mobicents.servlet.sip.testsuite.simple; - -import gov.nist.javax.sip.message.MessageExt; - -import java.io.File; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Properties; - -import javax.sip.ListeningPoint; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; -import javax.sip.header.AuthorizationHeader; -import javax.sip.header.ContactHeader; -import javax.sip.header.FromHeader; -import javax.sip.header.Header; -import javax.sip.header.ProxyAuthenticateHeader; -import javax.sip.header.ProxyAuthorizationHeader; -import javax.sip.header.ReasonHeader; -import javax.sip.header.RecordRouteHeader; -import javax.sip.header.ToHeader; -import javax.sip.header.UserAgentHeader; -import javax.sip.header.ViaHeader; -import javax.sip.message.Request; -import javax.sip.message.Response; - -import org.apache.catalina.deploy.ApplicationParameter; -import org.apache.log4j.Logger; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.mobicents.servlet.sip.SipEmbedded; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.address.RFC2396UrlDecoder; -import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class ShootistSipServletTest extends SipServletTestCase { - private static transient Logger logger = Logger.getLogger(ShootistSipServletTest.class); - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; - private static final int DIALOG_TIMEOUT = 40000; -// private static final int TIMEOUT = 100000000; - - TestSipListener receiver; - - ProtocolObjects receiverProtocolObjects; - - public ShootistSipServletTest(String name) { - super(name); - startTomcatOnStartup = false; - autoDeployOnStartup = false; - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - public SipStandardContext deployApplication(String name, String value) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("/sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - context.setConcurrencyControlMode(ConcurrencyControlMode.SipApplicationSession); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(name); - applicationParameter.setValue(value); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - return context; - } - - public SipStandardContext deployApplication(Map params) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("/sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setConcurrencyControlMode(ConcurrencyControlMode.SipApplicationSession); - context.setManager(new SipStandardManager()); - for (Entry param : params.entrySet()) { - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(param.getKey()); - applicationParameter.setValue(param.getValue()); - context.addApplicationParameter(applicationParameter); - } - assertTrue(tomcat.deployContext(context)); - return context; - } - - - public SipStandardContext deployApplication(Map params,ConcurrencyControlMode concurrencyControlMode) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("/sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - if(concurrencyControlMode != null) { - context.setConcurrencyControlMode(concurrencyControlMode); - } - for (Entry param : params.entrySet()) { - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(param.getKey()); - applicationParameter.setValue(param.getValue()); - context.addApplicationParameter(applicationParameter); - } - assertTrue(tomcat.deployContext(context)); - return context; - } - - public SipStandardContext deployApplicationServletListenerTest() { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("/sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName("testServletListener"); - applicationParameter.setValue("true"); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - return context; - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/simple/shootist-sip-servlet-dar.properties"; - } - - @Override - @Before - protected void setUp() throws Exception { - - System.setProperty( "javax.net.ssl.keyStore", ShootistSipServletTest.class.getResource("testkeys").getPath() ); - System.setProperty( "javax.net.ssl.trustStore", ShootistSipServletTest.class.getResource("testkeys").getPath() ); - System.setProperty( "javax.net.ssl.keyStorePassword", "passphrase" ); - System.setProperty( "javax.net.ssl.keyStoreType", "jks" ); - super.setUp(); - } - - public void testShootist() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - receiverProvider.addSipListener(receiver); - receiverProtocolObjects.start(); - tomcat.startTomcat(); - deployApplication(); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - // Non regression test for http://code.google.com/p/sipservlets/issues/detail?id=31 - assertNotNull(((ViaHeader)receiver.getInviteRequest().getHeader(ViaHeader.NAME)).getParameter("rport")); - assertNotNull(((ViaHeader)receiver.getByeRequestReceived().getHeader(ViaHeader.NAME)).getParameter("rport")); - assertEquals(1,tomcat.getSipService().getSipApplicationDispatcher().getRequestsSentByMethod(Request.INVITE)); - assertEquals(1,tomcat.getSipService().getSipApplicationDispatcher().getRequestsSentByMethod(Request.ACK)); - assertEquals(1,tomcat.getSipService().getSipApplicationDispatcher().getRequestsSentByMethod(Request.BYE)); - assertEquals(2,tomcat.getSipService().getSipApplicationDispatcher().getResponsesProcessedByStatusCode("2XX")); - } - // Also Tests Issue 1693 http://code.google.com/p/mobicents/issues/detail?id=1693 - public void testShootistCancel() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - receiver.setWaitForCancel(true); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - deployApplication("cancel", "true"); - Thread.sleep(DIALOG_TIMEOUT + TIMEOUT); - assertTrue(receiver.isCancelReceived()); - List allMessagesContent = receiver.getAllMessagesContent(); - assertTrue(allMessagesContent.size() >= 2); - assertTrue("sipSessionReadyToInvalidate", allMessagesContent.contains("sipSessionReadyToInvalidate")); - assertTrue("sipAppSessionReadyToInvalidate", allMessagesContent.contains("sipAppSessionReadyToInvalidate")); - assertEquals(1,tomcat.getSipService().getSipApplicationDispatcher().getRequestsSentByMethod(Request.INVITE)); - assertEquals(1,tomcat.getSipService().getSipApplicationDispatcher().getRequestsSentByMethod(Request.CANCEL)); - assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getResponsesProcessedByStatusCode("1XX")>0); - assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getResponsesProcessedByStatusCode("2XX")>0); - assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getResponsesProcessedByStatusCode("4XX")>0); - } - - public void testShootistCancelServletTimerCancelConcurrency() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - receiver.setWaitForCancel(true); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - - Map params = new HashMap(); - params.put("cancel", "true"); - params.put("servletTimer", "500"); - deployApplication(params, ConcurrencyControlMode.SipApplicationSession); - - Thread.sleep(DIALOG_TIMEOUT + TIMEOUT); - assertTrue(receiver.isCancelReceived()); - List allMessagesContent = receiver.getAllMessagesContent(); - assertEquals(2,allMessagesContent.size()); - assertTrue("sipSessionReadyToInvalidate", allMessagesContent.contains("sipSessionReadyToInvalidate")); - assertTrue("sipAppSessionReadyToInvalidate", allMessagesContent.contains("sipAppSessionReadyToInvalidate")); - } - - /* - * Non regression test for Issue http://code.google.com/p/mobicents/issues/detail?id=2450 - */ - public void testShootistCancelServletTimerConcurrency() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - receiver.setWaitForCancel(true); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - - Map params = new HashMap(); - params.put("cancel", "true"); - params.put("servletTimer", "0"); - deployApplication(params, ConcurrencyControlMode.SipApplicationSession); - - Thread.sleep(DIALOG_TIMEOUT + TIMEOUT); - assertTrue(receiver.isCancelReceived()); - List allMessagesContent = receiver.getAllMessagesContent(); - assertEquals(2,allMessagesContent.size()); - assertTrue("sipSessionReadyToInvalidate", allMessagesContent.contains("sipSessionReadyToInvalidate")); - assertTrue("sipAppSessionReadyToInvalidate", allMessagesContent.contains("sipAppSessionReadyToInvalidate")); - } - - public void testShootistEarlyMediaChange() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - LinkedList responses = new LinkedList(); - responses.add(180); - responses.add(183); - responses.add(183); - responses.add(183); - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - - receiver.setProvisionalResponsesToSend(responses); - receiver.setWaitForCancel(true); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - deployApplication("cancel", "true"); - Thread.sleep(DIALOG_TIMEOUT + TIMEOUT); - assertTrue(receiver.isCancelReceived()); - List allMessagesContent = receiver.getAllMessagesContent(); - - assertTrue("earlyMedia", receiver.getMessageRequest().getHeader("EarlyMediaResponses").toString().contains("3")); - assertTrue(allMessagesContent.size() >= 2); - assertTrue("sipSessionReadyToInvalidate", allMessagesContent.contains("sipSessionReadyToInvalidate")); - assertTrue("sipAppSessionReadyToInvalidate", allMessagesContent.contains("sipAppSessionReadyToInvalidate")); - } - - public void testShootistSetContact() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - deployApplication(); - Thread.sleep(TIMEOUT); - assertTrue((receiver.getInviteRequest().getHeader("Contact").toString().contains("uriparam=urivalue"))); - assertTrue((receiver.getInviteRequest().getHeader("Contact").toString().contains("headerparam1=headervalue1"))); - assertTrue(receiver.getByeReceived()); - } - - /** - * non regression test for Issue 676 http://code.google.com/p/mobicents/issues/detail?id=676 - * Tags not removed when using SipFactory.createRequest() - */ - public void testShootistSetToTag() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - deployApplication("toTag", "callernwPort1241042500479"); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - } - - /** - * non regression test for Issue 732 http://code.google.com/p/mobicents/issues/detail?id=732 - * duplicate parameters when using sipFactory.createAddress(uri) with a uri having parameters - */ - public void testShootistSetToParam() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - deployApplication("toParam", "http://yaris.research.att.com:23280/vxml/test.jsp"); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - } - - /** - * non regression test for Issue 1105 http://code.google.com/p/mobicents/issues/detail?id=1105 - * sipFactory.createRequest(sipApplicationSession, "METHOD", fromString, toString) function does not handle URI parameters properly - */ - public void testShootistSetToWithParam() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - Map params = new HashMap(); - String userName = "sip:+34666666666@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080;pres-list=mylist"; - params.put("username", userName); - params.put("useStringFactory", "true"); - deployApplication(params); - Thread.sleep(TIMEOUT); - ToHeader toHeader = (ToHeader) receiver.getInviteRequest().getHeader(ToHeader.NAME); - assertEquals("To: ", toHeader.toString().trim()); - assertTrue(receiver.getByeReceived()); - } - - /** - * non regression test for Issue 145 http://code.google.com/p/sipservlets/issues/detail?id=145 - */ - public void testShootistUserNameNull() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - Map params = new HashMap(); - String userName = "nullTest"; - params.put("username", userName); - deployApplication(params); - Thread.sleep(TIMEOUT); - FromHeader fromHeader = (FromHeader) receiver.getInviteRequest().getHeader(FromHeader.NAME); - assertEquals("sip:here.com", fromHeader.getAddress().getURI().toString().trim()); - assertTrue(receiver.getByeReceived()); - } - - /** - * non regression test for Issue 755 http://code.google.com/p/mobicents/issues/detail?id=755 - * SipURI parameters not escaped - */ - public void testShootistSetEscapedParam() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - String toParamValue = "http://yaris.research.att.com:23280/vxml/test.jsp?toto=tata"; - deployApplication("toParam", toParamValue); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - ToHeader toHeader = (ToHeader) receiver.getInviteRequest().getHeader(ToHeader.NAME); - String toParam = ((SipURI)toHeader.getAddress().getURI()).getParameter("toParam"); - logger.info(toParam); - assertEquals(toParamValue , RFC2396UrlDecoder.decode(toParam)); - } - - /** - * non regression test for Issue 859 http://code.google.com/p/mobicents/issues/detail?id=859 - * JAIN SIP ACK Creation not interoperable with Microsoft OCS - */ - public void testJainSipAckCreationViaParams() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - receiver.setTestAckViaParam(true); - SipProvider receiverProvider = receiver.createProvider(); - receiverProvider.addSipListener(receiver); - receiverProtocolObjects.start(); - tomcat.startTomcat(); - deployApplication(); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - } - - /** - * non regression test for Issue 1025 http://code.google.com/p/mobicents/issues/detail?id=1025 - * sipservletlistner called twice on redeploy - */ - public void testShootistSipServletListener() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - SipStandardContext context = deployApplicationServletListenerTest(); - Thread.sleep(TIMEOUT); - tomcat.undeployContext(context); - Thread.sleep(TIMEOUT); - context = deployApplicationServletListenerTest(); - Thread.sleep(TIMEOUT); - assertEquals(2, receiver.getAllMessagesContent().size()); - context.reload(); - Thread.sleep(TIMEOUT); - assertEquals(3, receiver.getAllMessagesContent().size()); - } - - /** - * non regression test for Issue 1090 http://code.google.com/p/mobicents/issues/detail?id=1090 - * Content-Type is not mandatory if Content-Length is 0 - */ - public void testShootistContentLength() throws Exception { - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - deployApplication("testContentLength", "testContentLength"); - Thread.sleep(TIMEOUT); - assertNotNull(receiver.getMessageRequest()); - } - - - public void testShootistCallerSendsBye() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, true); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - deployApplication(); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getOkToByeReceived()); - } - - public void testShootistUserAgentHeader() throws Exception { - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.removeConnector(sipConnector); - tomcat.startTomcat(); - tomcat.stopTomcat(); - - Properties sipStackProperties = new Properties(); - sipStackProperties.setProperty("javax.sip.STACK_NAME", "mss-" - + sipIpAddress + "-" + 5070); - sipStackProperties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", - "off"); - sipStackProperties.setProperty( - "gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.THREAD_POOL_SIZE", - "64"); - sipStackProperties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", - "true"); - sipStackProperties.setProperty("org.mobicents.servlet.sip.USER_AGENT_HEADER", - "MobicentsSipServletsUserAgent"); - - tomcat = new SipEmbedded(serverName, serviceFullClassName); - tomcat.setLoggingFilePath( - projectHome + File.separatorChar + "sip-servlets-test-suite" + - File.separatorChar + "testsuite" + - File.separatorChar + "src" + - File.separatorChar + "test" + - File.separatorChar + "resources" + File.separatorChar); - logger.info("Log4j path is : " + tomcat.getLoggingFilePath()); - String darConfigurationFile = getDarConfigurationFile(); - tomcat.setDarConfigurationFilePath(darConfigurationFile); - if(initTomcatOnStartup) { - tomcat.initTomcat(tomcatBasePath, sipStackProperties); - tomcat.addHttpConnector(httpIpAddress, 8080); - if(addSipConnectorOnStartup) { - sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, 5070, listeningPointTransport); - } - } - - tomcat.startTomcat(); - deployApplication(); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - Request invite = receiver.getInviteRequest(); - UserAgentHeader userAgentHeader = (UserAgentHeader) invite.getHeader(UserAgentHeader.NAME); - assertNotNull(userAgentHeader); - assertTrue(userAgentHeader.toString().contains("MobicentsSipServletsUserAgent")); - } - - /** - * non regression test for Issue 1150 http://code.google.com/p/mobicents/issues/detail?id=1150 - * Contact header contains "transport" parameter even when there are two connectors (UDP and TCP) - */ - public void testShootistContactTransport() throws Exception { - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, 5071, ListeningPoint.TCP); - tomcat.startTomcat(); - deployApplication(); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - ContactHeader contactHeader = (ContactHeader) receiver.getInviteRequest().getHeader(ContactHeader.NAME); - assertFalse(((SipURI)contactHeader.getAddress().getURI()).toString().contains("transport=udp")); - String contact = contactHeader.getAddress().toString(); - assertTrue(contact.contains("BigGuy@")); - assertTrue(contact.contains("from display")); - } - - public void testShootistContactTlsTransport() throws Exception { - receiverProtocolObjects =new ProtocolObjects( - "tls_receiver", "gov.nist", "TLS", AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, 5071, ListeningPoint.TCP); - sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, 5072, ListeningPoint.TLS); - tomcat.startTomcat(); - deployApplication("secureRURI", "true"); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - ContactHeader contactHeader = (ContactHeader) receiver.getInviteRequest().getHeader(ContactHeader.NAME); - assertTrue(((SipURI)contactHeader.getAddress().getURI()).toString().contains("sips:")); - assertTrue(((SipURI)contactHeader.getAddress().getURI()).toString().contains("5072")); - assertTrue(((SipURI)contactHeader.getAddress().getURI()).toString().toLowerCase().contains("transport=tls")); - String viaString = receiver.getInviteRequest().getHeader(ViaHeader.NAME).toString(); - assertTrue(viaString.toLowerCase().contains("tls")); - assertTrue(viaString.toLowerCase().contains("5072")); - } - - /** - * non regression test for Issue 2269 http://code.google.com/p/mobicents/issues/detail?id=2269 - * Wrong Contact header scheme URI in case TLS call with 'sip:' scheme - */ - public void testShootistContactNonSecureURITlsTransport() throws Exception { - receiverProtocolObjects =new ProtocolObjects( - "tls_receiver", "gov.nist", "TLS", AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, 5071, ListeningPoint.TCP); - sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, 5072, ListeningPoint.TLS); - tomcat.startTomcat(); - deployApplication("transportRURI", "tls"); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - ContactHeader contactHeader = (ContactHeader) receiver.getInviteRequest().getHeader(ContactHeader.NAME); - assertTrue(((SipURI)contactHeader.getAddress().getURI()).toString().contains("sip:")); - assertTrue(((SipURI)contactHeader.getAddress().getURI()).toString().contains("5072")); - assertTrue(((SipURI)contactHeader.getAddress().getURI()).toString().toLowerCase().contains("transport=tls")); - String viaString = receiver.getInviteRequest().getHeader(ViaHeader.NAME).toString(); - assertTrue(viaString.toLowerCase().contains("tls")); - assertTrue(viaString.toLowerCase().contains("5072")); - } - - /** - * non regression test for Issue 1150 http://code.google.com/p/mobicents/issues/detail?id=1150 - * Contact header contains "transport" parameter even when there are two connectors (UDP and TCP) - */ - public void testShootistOutboundInterfaceTransport() throws Exception { - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", ListeningPoint.TCP, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, 5071, ListeningPoint.TCP); - tomcat.startTomcat(); - deployApplication("outboundInterface", "tcp"); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - ContactHeader contactHeader = (ContactHeader) receiver.getInviteRequest().getHeader(ContactHeader.NAME); - assertFalse(((SipURI)contactHeader.getAddress().getURI()).toString().contains("transport=udp")); - } - - /** - * non regression test for Issue 1412 http://code.google.com/p/mobicents/issues/detail?id=1412 - * Contact header is added to REGISTER request by container - */ - public void testShootistRegister() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - deployApplication("method", "REGISTER"); - Thread.sleep(TIMEOUT); - assertNull(receiver.getRegisterReceived().getHeader(ContactHeader.NAME)); - } - - /** - * non regression test for https://github.com/Mobicents/sip-servlets/issues/36 - * REGISTER CSeq Increase for UAC use cases using session.createRequest("REGISTER") - */ - public void testShootistRegisterCSeqIncrease() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - deployApplication("method", "REGISTER"); - Thread.sleep(DIALOG_TIMEOUT); - assertNull(receiver.getRegisterReceived().getHeader(ContactHeader.NAME)); - assertTrue(receiver.getLastRegisterCSeqNumber() >= 2); - } - - /** - * non regression test for https://github.com/Mobicents/sip-servlets/issues/51 - * Contact header with gruu is added to REGISTER request - */ - public void testShootistRegisterGruu() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - Map params = new HashMap(); - params.put("method", "REGISTER"); - params.put("testGruu", "true"); - deployApplication(params); - Thread.sleep(TIMEOUT); - ContactHeader contactHeader = (ContactHeader) receiver.getRegisterReceived().getHeader(ContactHeader.NAME); - assertNotNull(contactHeader); - assertEquals("Contact: ", - contactHeader.toString().trim()); - } - - /** - * non regression test for https://github.com/Mobicents/sip-servlets/issues/51 - * Contact header with gruu is added to INVITE request - */ - public void testShootistInviteGruu() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - Map params = new HashMap(); - params.put("method", "INVITE"); - params.put("testGruu", "true"); - deployApplication(params); - Thread.sleep(TIMEOUT); - ContactHeader contactHeader = (ContactHeader) receiver.getInviteRequest().getHeader(ContactHeader.NAME); - assertNotNull(contactHeader); - assertEquals("Contact: ", - contactHeader.toString().trim()); - } - - /** - * non regression test for http://code.google.com/p/mobicents/issues/detail?id=2288 - * SipServletRequest.send() throws IllegalStateException instead of IOException - */ - public void testShootistIOException() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - deployApplication("testIOException", "djsklfhdfkdfhdk.com"); - Thread.sleep(TIMEOUT); - List allMessagesContent = receiver.getAllMessagesContent(); - assertEquals(1,allMessagesContent.size()); - assertTrue("IOException not thrown", allMessagesContent.contains("IOException thrown")); - } - - /** - * non regression test for http://code.google.com/p/mobicents/issues/detail?id=2288 - * SipServletRequest.send() throws IllegalStateException instead of IOException - */ - public void testShootistIOExceptionTransportChange() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.addSipConnector(serverName, sipIpAddress, 5070, ListeningPoint.TCP); - tomcat.startTomcat(); - Map params = new HashMap(); - params.put("transportRURI", "tcp"); - params.put("testIOException", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); - deployApplication(params); - Thread.sleep(TIMEOUT); - List allMessagesContent = receiver.getAllMessagesContent(); - assertEquals(1,allMessagesContent.size()); - assertTrue("IOException not thrown", allMessagesContent.contains("IOException thrown")); - } - - /** - * - */ -// public void testShootistWSTransport() throws Exception { -//// receiver.sendInvite(); -// receiverProtocolObjects =new ProtocolObjects( -// "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); -// -// receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); -// SipProvider senderProvider = receiver.createProvider(); -// -// senderProvider.addSipListener(receiver); -// -// receiverProtocolObjects.start(); -// tomcat.addSipConnector(serverName, sipIpAddress, 5070, ListeningPoint.TCP); -// tomcat.startTomcat(); -// Map params = new HashMap(); -// params.put("transportRURI", "ws"); -// deployApplication(params); -// Thread.sleep(TIMEOUT); -// List allMessagesContent = receiver.getAllMessagesContent(); -// assertEquals(1,allMessagesContent.size()); -// assertTrue("IOException not thrown", allMessagesContent.contains("IOException thrown")); -// } -// - /** - * non regression test for Issue 2269 http://code.google.com/p/mobicents/issues/detail?id=2269 - * Wrong Contact header scheme URI in case TLS call with request URI 'sip:' scheme and contact is uri is secure with "sips" - */ - public void testShootistRegisterContactNonSecureURITlsTransport() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "tls_receiver", "gov.nist", "TLS", AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, 5071, ListeningPoint.TCP); - sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, 5072, ListeningPoint.TLS); - tomcat.startTomcat(); - Map params = new HashMap(); - params.put("transportRURI", "tls"); - params.put("method", "REGISTER"); - deployApplication(params); - tomcat.startTomcat(); - Thread.sleep(TIMEOUT); - ContactHeader contactHeader = (ContactHeader) receiver.getRegisterReceived().getHeader(ContactHeader.NAME); - assertNotNull(contactHeader); - assertTrue(((SipURI)contactHeader.getAddress().getURI()).toString().contains("sip:")); - assertTrue(((SipURI)contactHeader.getAddress().getURI()).toString().contains("5080")); - assertTrue(((SipURI)contactHeader.getAddress().getURI()).toString().toLowerCase().contains("transport=tls")); - } - - /** - * non regression test for Issue 156 http://code.google.com/p/sipservlets/issues/detail?id=156 - * Contact header in REGISTER overwritten by container - */ - public void testShootistRegisterSetContact() throws Exception { - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - Map params = new HashMap(); - params.put("setRandomContact", "true"); - params.put("method", "REGISTER"); - deployApplication(params); - Thread.sleep(TIMEOUT); - ContactHeader contactHeader = (ContactHeader) receiver.getRegisterReceived().getHeader(ContactHeader.NAME); - assertNotNull(contactHeader); - assertEquals(((SipURI)contactHeader.getAddress().getURI()).toString(),"sip:random@172.172.172.172:3289"); - } - - /** - * non regression test for Issue 172 http://code.google.com/p/sipservlets/issues/detail?id=172 - * Possible to add params to Contact header - */ - @Test - public void testShootistOptionsSetContact() throws Exception { - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - Map params = new HashMap(); - params.put("setRandomContact", "true"); - params.put("method", "OPTIONS"); - deployApplication(params); - Thread.sleep(TIMEOUT); - ContactHeader contactHeader = (ContactHeader) receiver.getOptionsRequest().getHeader(ContactHeader.NAME); - assertNotNull(contactHeader); - assertNotNull(contactHeader.getParameter("optionParam")); - assertEquals(contactHeader.getParameter("optionParam"),"optionValue"); - assertEquals(((SipURI)contactHeader.getAddress().getURI()).getUser(), "optionUser"); - } - - /** - * non regression test for Github Issue 48 https://github.com/Mobicents/sip-servlets/issues/48 - * Possible to add params to Contact header for Message - */ - @Test - public void testShootistMessageSetContact() throws Exception { - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - Map params = new HashMap(); - params.put("setRandomContact", "true"); - params.put("method", "MESSAGE"); - deployApplication(params); - Thread.sleep(TIMEOUT); - ContactHeader contactHeader = (ContactHeader) receiver.getMessageRequest().getHeader(ContactHeader.NAME); - assertNotNull(contactHeader); - assertNotNull(contactHeader.getParameter("optionParam")); - assertEquals(contactHeader.getParameter("optionParam"),"optionValue"); - assertEquals(((SipURI)contactHeader.getAddress().getURI()).getUser(), "optionUser"); - } - - - /** - * non regression test for Issue 1547 http://code.google.com/p/mobicents/issues/detail?id=1547 - * Can't add a Proxy-Authorization using SipServletMessage.addHeader - */ - public void testShootistProxyAuthorization() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - Map params = new HashMap(); - params.put("auth-header", "Digest username=\"1001\", realm=\"172.16.0.37\", algorithm=MD5, uri=\"sip:66621@172.16.0.37;user=phone\", qop=auth, nc=00000001, cnonce=\"b70b470bedf75db7\", nonce=\"1276678944:394f0b0b049fbbda8c94ae28d08f2301\", response=\"561389d4ce5cb38020749b8a27798343\""); - params.put("headerToAdd", "Proxy-Authorization"); - deployApplication(params); - Thread.sleep(TIMEOUT); - assertNotNull(receiver.getInviteRequest().getHeader(ProxyAuthorizationHeader.NAME)); - assertNotNull(receiver.getInviteRequest().getHeader(ProxyAuthenticateHeader.NAME)); - } - - /** - * non regression test for Issue 2798 http://code.google.com/p/mobicents/issues/detail?id=2798 - * Can't add an Authorization using SipServletMessage.addHeader - */ - public void testShootistAuthorization() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - Map params = new HashMap(); - params.put("auth-header", "Digest username=\"1001\", realm=\"172.16.0.37\", algorithm=MD5, uri=\"sip:66621@172.16.0.37;user=phone\", qop=auth, nc=00000001, cnonce=\"b70b470bedf75db7\", nonce=\"1276678944:394f0b0b049fbbda8c94ae28d08f2301\", response=\"561389d4ce5cb38020749b8a27798343\""); - params.put("headerToAdd", "Authorization"); - deployApplication(params); - Thread.sleep(TIMEOUT); - assertNotNull(receiver.getInviteRequest().getHeader(AuthorizationHeader.NAME)); - } - - // Tests Issue 1693 http://code.google.com/p/mobicents/issues/detail?id=1693 - public void testShootistErrorResponse() throws Exception { - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - receiver.setProvisionalResponsesToSend(new ArrayList()); - receiver.setFinalResponseToSend(Response.SERVER_INTERNAL_ERROR); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - deployApplication("testErrorResponse", "true"); - Thread.sleep(DIALOG_TIMEOUT + TIMEOUT); - List allMessagesContent = receiver.getAllMessagesContent(); - assertEquals(2,allMessagesContent.size()); - assertTrue("sipSessionReadyToInvalidate", allMessagesContent.contains("sipSessionReadyToInvalidate")); - assertTrue("sipAppSessionReadyToInvalidate", allMessagesContent.contains("sipAppSessionReadyToInvalidate")); - } - - // Tests Issue 1693 http://code.google.com/p/mobicents/issues/detail?id=1693 - public void testShootistOptionsTimeout() throws Exception { - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - receiver.setProvisionalResponsesToSend(new ArrayList()); - receiver.setWaitForCancel(true); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - Map params = new HashMap(); - params.put("testErrorResponse", "true"); - params.put("method", "OPTIONS"); - deployApplication(params); - Thread.sleep(DIALOG_TIMEOUT + TIMEOUT); - List allMessagesContent = receiver.getAllMessagesContent(); - assertEquals(1,allMessagesContent.size()); -// assertTrue("sipSessionReadyToInvalidate", allMessagesContent.contains("sipSessionReadyToInvalidate")); -// assertTrue("sipAppSessionReadyToInvalidate", allMessagesContent.contains("sipAppSessionReadyToInvalidate")); - assertTrue("408 received", allMessagesContent.contains("408 received")); - } - - // Tests Issue 143 http://code.google.com/p/mobicents/issues/detail?id=143 - public void testShootist422Response() throws Exception { - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - receiver.setProvisionalResponsesToSend(new ArrayList()); - receiver.setFinalResponseToSend(422); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - deployApplication("testErrorResponse", "true"); - Thread.sleep(TIMEOUT); - receiver.setFinalResponseToSend(200); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isAckReceived()); - } - - - // Test for SS spec 11.1.6 transaction timeout notification - // Test Issue 2580 http://code.google.com/p/mobicents/issues/detail?id=2580 - public void testTransactionTimeoutResponse() throws Exception { - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - receiver.setDropRequest(true); - List provisionalResponsesToSend = receiver.getProvisionalResponsesToSend(); - provisionalResponsesToSend.clear(); - - SipProvider receiverProvider = receiver.createProvider(); - receiverProvider.addSipListener(receiver); - receiverProtocolObjects.start(); - - tomcat.startTomcat(); - deployApplication(); - - Thread.sleep(DIALOG_TIMEOUT); - - Iterator allMessagesIterator = receiver.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - - } - assertTrue(receiver.txTimeoutReceived); - } - - /* - * http://code.google.com/p/mobicents/issues/detail?id=2902 - */ - public void testShootistRemoteAddrAndPort() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - receiverProvider.addSipListener(receiver); - receiverProtocolObjects.start(); - tomcat.startTomcat(); - deployApplication("testRemoteAddrAndPort", "true"); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - } - - // https://code.google.com/p/sipservlets/issues/detail?id=169 - public void testShootistMultipartBytes() throws Exception { - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - receiver.setProvisionalResponsesToSend(new ArrayList()); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - deployApplication("testMultipartBytes", "true"); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - } - - // https://code.google.com/p/sipservlets/issues/detail?id=216 - public void testShootistMutlipleReasonHeaders() throws Exception { - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - receiver.setProvisionalResponsesToSend(new ArrayList()); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - deployApplication("testMultipleReasonHeaders", "true"); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - ListIterator
listIt = receiver.getInviteRequest().getHeaders(ReasonHeader.NAME); - int i = 0; - while (listIt.hasNext()) { - listIt.next(); - i++; - } - assertEquals(2, i); - } - - /* - * https://code.google.com/p/sipservlets/issues/detail?id=245 - */ - public void testShootistAddressParam() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - receiverProvider.addSipListener(receiver); - receiverProtocolObjects.start(); - tomcat.startTomcat(); - deployApplication("testAddressParam", "true"); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - assertEquals("00112233", ((MessageExt)receiver.getInviteRequest()).getFromHeader().getParameter("epid")); - assertEquals("33221100", ((MessageExt)receiver.getInviteRequest()).getToHeader().getParameter("epid")); - } - - @Override - @After - protected void tearDown() throws Exception { - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } -} \ No newline at end of file +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2014, Telestax Inc and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + */ +package org.mobicents.servlet.sip.testsuite.simple; + +import gov.nist.javax.sip.message.MessageExt; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.Properties; + +import javax.sip.ListeningPoint; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import javax.sip.header.AuthorizationHeader; +import javax.sip.header.ContactHeader; +import javax.sip.header.FromHeader; +import javax.sip.header.Header; +import javax.sip.header.ProxyAuthenticateHeader; +import javax.sip.header.ProxyAuthorizationHeader; +import javax.sip.header.ReasonHeader; +import javax.sip.header.ToHeader; +import javax.sip.header.UserAgentHeader; +import javax.sip.header.ViaHeader; +import javax.sip.message.Request; +import javax.sip.message.Response; + +import org.apache.log4j.Logger; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipEmbedded; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.address.RFC2396UrlDecoder; +import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class ShootistSipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ShootistSipServletTest.class); + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; + private static final int DIALOG_TIMEOUT = 40000; +// private static final int TIMEOUT = 100000000; + + TestSipListener receiver; + + ProtocolObjects receiverProtocolObjects; + + public ShootistSipServletTest(String name) { + super(name); + startTomcatOnStartup = false; + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + ctx = tomcat.deployAppContext( + projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp", + "sip-test-context", "sip-test"); + assertTrue(ctx.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/simple/shootist-sip-servlet-dar.properties"; + } + + @Override + @Before + protected void setUp() throws Exception { + + System.setProperty("javax.net.ssl.keyStore", ShootistSipServletTest.class.getResource("testkeys").getPath()); + System.setProperty("javax.net.ssl.trustStore", ShootistSipServletTest.class.getResource("testkeys").getPath()); + System.setProperty("javax.net.ssl.keyStorePassword", "passphrase"); + System.setProperty("javax.net.ssl.keyStoreType", "jks"); + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + } + + public void testShootist() throws Exception { + + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + // Non regression test for http://code.google.com/p/sipservlets/issues/detail?id=31 + assertNotNull(((ViaHeader) receiver.getInviteRequest().getHeader(ViaHeader.NAME)).getParameter("rport")); + assertNotNull(((ViaHeader) receiver.getByeRequestReceived().getHeader(ViaHeader.NAME)).getParameter("rport")); + assertEquals(1, tomcat.getSipService().getSipApplicationDispatcher().getRequestsSentByMethod(Request.INVITE)); + assertEquals(1, tomcat.getSipService().getSipApplicationDispatcher().getRequestsSentByMethod(Request.ACK)); + assertEquals(1, tomcat.getSipService().getSipApplicationDispatcher().getRequestsSentByMethod(Request.BYE)); + assertEquals(2, tomcat.getSipService().getSipApplicationDispatcher().getResponsesProcessedByStatusCode("2XX")); + } + // Also Tests Issue 1693 http://code.google.com/p/mobicents/issues/detail?id=1693 + + public void testShootistCancel() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("cancel", "true"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + receiver.setWaitForCancel(true); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(DIALOG_TIMEOUT + TIMEOUT); + assertTrue(receiver.isCancelReceived()); + List allMessagesContent = receiver.getAllMessagesContent(); + assertTrue(allMessagesContent.size() >= 2); + assertTrue("sipSessionReadyToInvalidate", allMessagesContent.contains("sipSessionReadyToInvalidate")); + assertTrue("sipAppSessionReadyToInvalidate", allMessagesContent.contains("sipAppSessionReadyToInvalidate")); + assertEquals(1, tomcat.getSipService().getSipApplicationDispatcher().getRequestsSentByMethod(Request.INVITE)); + assertEquals(1, tomcat.getSipService().getSipApplicationDispatcher().getRequestsSentByMethod(Request.CANCEL)); + assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getResponsesProcessedByStatusCode("1XX") > 0); + assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getResponsesProcessedByStatusCode("2XX") > 0); + assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getResponsesProcessedByStatusCode("4XX") > 0); + } + + public void testShootistCancelServletTimerCancelConcurrency() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("cancel", "true"); + ctxAtts.put("servletTimer", "500"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + receiver.setWaitForCancel(true); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + + deployShootist(ctxAtts, ConcurrencyControlMode.SipApplicationSession); + + Thread.sleep(DIALOG_TIMEOUT + TIMEOUT); + assertTrue(receiver.isCancelReceived()); + List allMessagesContent = receiver.getAllMessagesContent(); + assertEquals(2, allMessagesContent.size()); + assertTrue("sipSessionReadyToInvalidate", allMessagesContent.contains("sipSessionReadyToInvalidate")); + assertTrue("sipAppSessionReadyToInvalidate", allMessagesContent.contains("sipAppSessionReadyToInvalidate")); + } + + /* + * Non regression test for Issue http://code.google.com/p/mobicents/issues/detail?id=2450 + */ + public void testShootistCancelServletTimerConcurrency() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("cancel", "true"); + ctxAtts.put("servletTimer", "0"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + receiver.setWaitForCancel(true); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + + deployShootist(ctxAtts, ConcurrencyControlMode.SipApplicationSession); + + Thread.sleep(DIALOG_TIMEOUT + TIMEOUT); + assertTrue(receiver.isCancelReceived()); + List allMessagesContent = receiver.getAllMessagesContent(); + assertEquals(2, allMessagesContent.size()); + assertTrue("sipSessionReadyToInvalidate", allMessagesContent.contains("sipSessionReadyToInvalidate")); + assertTrue("sipAppSessionReadyToInvalidate", allMessagesContent.contains("sipAppSessionReadyToInvalidate")); + } + + public void testShootistEarlyMediaChange() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + LinkedList responses = new LinkedList(); + responses.add(180); + responses.add(183); + responses.add(183); + responses.add(183); + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("cancel", "true"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + + receiver.setProvisionalResponsesToSend(responses); + receiver.setWaitForCancel(true); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(DIALOG_TIMEOUT + TIMEOUT); + assertTrue(receiver.isCancelReceived()); + List allMessagesContent = receiver.getAllMessagesContent(); + + String earlyMedia = receiver.getMessageRequest().getHeader("EarlyMediaResponses").toString(); + assertTrue("earlyMediaIs3", earlyMedia.contains("EarlyMediaResponses: 3")); + assertTrue(allMessagesContent.size() >= 2); + assertTrue("sipSessionReadyToInvalidate", allMessagesContent.contains("sipSessionReadyToInvalidate")); + assertTrue("sipAppSessionReadyToInvalidate", allMessagesContent.contains("sipAppSessionReadyToInvalidate")); + } + + public void testShootistSetContact() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertTrue((receiver.getInviteRequest().getHeader("Contact").toString().contains("uriparam=urivalue"))); + assertTrue((receiver.getInviteRequest().getHeader("Contact").toString().contains("headerparam1=headervalue1"))); + assertTrue(receiver.getByeReceived()); + } + + /** + * non regression test for Issue 676 + * http://code.google.com/p/mobicents/issues/detail?id=676 Tags not removed + * when using SipFactory.createRequest() + */ + public void testShootistSetToTag() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("toTag", "callernwPort1241042500479"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + } + + /** + * non regression test for Issue 732 + * http://code.google.com/p/mobicents/issues/detail?id=732 duplicate + * parameters when using sipFactory.createAddress(uri) with a uri having + * parameters + */ + public void testShootistSetToParam() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("toParam", "http://yaris.research.att.com:23280/vxml/test.jsp"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + } + + /** + * non regression test for Issue 1105 + * http://code.google.com/p/mobicents/issues/detail?id=1105 + * sipFactory.createRequest(sipApplicationSession, "METHOD", fromString, + * toString) function does not handle URI parameters properly + */ + public void testShootistSetToWithParam() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + String userName = "sip:+34666666666@" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080;pres-list=mylist"; + ctxAtts.put("username", userName); + ctxAtts.put("useStringFactory", "true"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + ToHeader toHeader = (ToHeader) receiver.getInviteRequest().getHeader(ToHeader.NAME); + assertEquals("To: ", toHeader.toString().trim()); + assertTrue(receiver.getByeReceived()); + } + + /** + * non regression test for Issue 145 + * http://code.google.com/p/sipservlets/issues/detail?id=145 + */ + public void testShootistUserNameNull() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + String userName = "nullTest"; + ctxAtts.put("username", userName); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + FromHeader fromHeader = (FromHeader) receiver.getInviteRequest().getHeader(FromHeader.NAME); + assertEquals("sip:here.com", fromHeader.getAddress().getURI().toString().trim()); + assertTrue(receiver.getByeReceived()); + } + + /** + * non regression test for Issue 755 + * http://code.google.com/p/mobicents/issues/detail?id=755 SipURI parameters + * not escaped + */ + public void testShootistSetEscapedParam() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + String toParamValue = "http://yaris.research.att.com:23280/vxml/test.jsp?toto=tata"; + ctxAtts.put("toParam", toParamValue); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + ToHeader toHeader = (ToHeader) receiver.getInviteRequest().getHeader(ToHeader.NAME); + String toParam = ((SipURI) toHeader.getAddress().getURI()).getParameter("toParam"); + logger.info(toParam); + assertEquals(toParamValue, RFC2396UrlDecoder.decode(toParam)); + } + + /** + * non regression test for Issue 859 + * http://code.google.com/p/mobicents/issues/detail?id=859 JAIN SIP ACK + * Creation not interoperable with Microsoft OCS + */ + public void testJainSipAckCreationViaParams() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + receiver.setTestAckViaParam(true); + SipProvider receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + } + + /** + * non regression test for Issue 1025 + * http://code.google.com/p/mobicents/issues/detail?id=1025 + * sipservletlistner called twice on redeploy + */ + public void testShootistSipServletListener() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("testServletListener", "true"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + SipStandardContext context = deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + tomcat.undeployContext(context); + Thread.sleep(TIMEOUT); + context = deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertEquals(2, receiver.getAllMessagesContent().size()); + context.reload(); + Thread.sleep(TIMEOUT); + assertEquals(3, receiver.getAllMessagesContent().size()); + } + + /** + * non regression test for Issue 1090 + * http://code.google.com/p/mobicents/issues/detail?id=1090 Content-Type is + * not mandatory if Content-Length is 0 + */ + public void testShootistContentLength() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("testContentLength", "testContentLength"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertNotNull(receiver.getMessageRequest()); + } + + public void testShootistCallerSendsBye() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, true); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getOkToByeReceived()); + } + + public void testShootistUserAgentHeader() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.removeConnector(sipConnector); + tomcat.startTomcat(); + tomcat.stopTomcat(); + + Properties sipStackProperties = new Properties(); + sipStackProperties.setProperty("javax.sip.STACK_NAME", "mss-" + + sipIpAddress + "-" + containerPort); + sipStackProperties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", + "off"); + sipStackProperties.setProperty( + "gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.THREAD_POOL_SIZE", + "64"); + sipStackProperties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", + "true"); + sipStackProperties.setProperty("org.mobicents.servlet.sip.USER_AGENT_HEADER", + "MobicentsSipServletsUserAgent"); + + tomcat = new SipEmbedded(serverName, serviceFullClassName); + tomcat.setLoggingFilePath( + projectHome + File.separatorChar + "sip-servlets-test-suite" + + File.separatorChar + "testsuite" + + File.separatorChar + "src" + + File.separatorChar + "test" + + File.separatorChar + "resources" + File.separatorChar); + logger.info("Log4j path is : " + tomcat.getLoggingFilePath()); + String darConfigurationFile = getDarConfigurationFile(); + tomcat.setDarConfigurationFilePath(darConfigurationFile); + if (initTomcatOnStartup) { + tomcat.initTomcat(tomcatBasePath, sipStackProperties); + tomcat.addHttpConnector(httpIpAddress, httpContainerPort); + if (addSipConnectorOnStartup) { + sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, containerPort, listeningPointTransport); + } + } + + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + Request invite = receiver.getInviteRequest(); + UserAgentHeader userAgentHeader = (UserAgentHeader) invite.getHeader(UserAgentHeader.NAME); + assertNotNull(userAgentHeader); + assertTrue(userAgentHeader.toString().contains("MobicentsSipServletsUserAgent")); + } + + /** + * non regression test for Issue 1150 + * http://code.google.com/p/mobicents/issues/detail?id=1150 Contact header + * contains "transport" parameter even when there are two connectors (UDP + * and TCP) + */ + public void testShootistContactTransport() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, 5071, ListeningPoint.TCP); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + ContactHeader contactHeader = (ContactHeader) receiver.getInviteRequest().getHeader(ContactHeader.NAME); + assertFalse(((SipURI) contactHeader.getAddress().getURI()).toString().contains("transport=udp")); + String contact = contactHeader.getAddress().toString(); + assertTrue(contact.contains("BigGuy@")); + assertTrue(contact.contains("from display")); + } + + public void testShootistContactTlsTransport() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "tls_receiver", "gov.nist", "TLS", AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("secureRURI", "true"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + int tcpPort = NetworkPortAssigner.retrieveNextPort(); + int tlsPort = NetworkPortAssigner.retrieveNextPort(); + String tlsPortStr = String.valueOf(tlsPort); + sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, tcpPort, ListeningPoint.TCP); + sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, tlsPort, ListeningPoint.TLS); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + ContactHeader contactHeader = (ContactHeader) receiver.getInviteRequest().getHeader(ContactHeader.NAME); + assertTrue(((SipURI) contactHeader.getAddress().getURI()).toString().contains("sips:")); + assertTrue(((SipURI) contactHeader.getAddress().getURI()).toString().contains(tlsPortStr)); + assertTrue(((SipURI) contactHeader.getAddress().getURI()).toString().toLowerCase().contains("transport=tls")); + String viaString = receiver.getInviteRequest().getHeader(ViaHeader.NAME).toString(); + assertTrue(viaString.toLowerCase().contains("tls")); + assertTrue(viaString.toLowerCase().contains(tlsPortStr)); + } + + /** + * non regression test for Issue 2269 + * http://code.google.com/p/mobicents/issues/detail?id=2269 Wrong Contact + * header scheme URI in case TLS call with 'sip:' scheme + */ + public void testShootistContactNonSecureURITlsTransport() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "tls_receiver", "gov.nist", "TLS", AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("transportRURI", "tls"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + int tcpPort = NetworkPortAssigner.retrieveNextPort(); + int tlsPort = NetworkPortAssigner.retrieveNextPort(); + String tlsPortStr = String.valueOf(tlsPort); + sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, tcpPort, ListeningPoint.TCP); + sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, tlsPort, ListeningPoint.TLS); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + ContactHeader contactHeader = (ContactHeader) receiver.getInviteRequest().getHeader(ContactHeader.NAME); + assertTrue(((SipURI) contactHeader.getAddress().getURI()).toString().contains("sip:")); + assertTrue(((SipURI) contactHeader.getAddress().getURI()).toString().contains(tlsPortStr)); + assertTrue(((SipURI) contactHeader.getAddress().getURI()).toString().toLowerCase().contains("transport=tls")); + String viaString = receiver.getInviteRequest().getHeader(ViaHeader.NAME).toString(); + assertTrue(viaString.toLowerCase().contains("tls")); + assertTrue(viaString.toLowerCase().contains(tlsPortStr)); + } + + /** + * non regression test for Issue 1150 + * http://code.google.com/p/mobicents/issues/detail?id=1150 Contact header + * contains "transport" parameter even when there are two connectors (UDP + * and TCP) + */ + public void testShootistOutboundInterfaceTransport() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", ListeningPoint.TCP, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("outboundInterface", "tcp"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + int tcpPort = NetworkPortAssigner.retrieveNextPort(); + sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, tcpPort, ListeningPoint.TCP); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + + assertTrue(receiver.getByeReceived()); + ContactHeader contactHeader = (ContactHeader) receiver.getInviteRequest().getHeader(ContactHeader.NAME); + assertFalse(((SipURI) contactHeader.getAddress().getURI()).toString().contains("transport=udp")); + } + + /** + * non regression test for + * https://github.com/Mobicents/sip-servlets/issues/51 Contact header with + * gruu is added to INVITE request + */ + public void testShootistInviteGruu() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("method", "INVITE"); + ctxAtts.put("testGruu", "true"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + ContactHeader contactHeader = (ContactHeader) receiver.getInviteRequest().getHeader(ContactHeader.NAME); + assertNotNull(contactHeader); + assertEquals("Contact: ", + contactHeader.toString().trim()); + } + + /** + * non regression test for + * http://code.google.com/p/mobicents/issues/detail?id=2288 + * SipServletRequest.send() throws IllegalStateException instead of + * IOException + */ + public void testShootistIOException() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("testIOException", "djsklfhdfkdfhdk.com"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + List allMessagesContent = receiver.getAllMessagesContent(); + assertEquals(1, allMessagesContent.size()); + assertTrue("IOException not thrown", allMessagesContent.contains("IOException thrown")); + } + + /** + * non regression test for + * http://code.google.com/p/mobicents/issues/detail?id=2288 + * SipServletRequest.send() throws IllegalStateException instead of + * IOException + */ + public void testShootistIOExceptionTransportChange() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("transportRURI", "tcp"); + ctxAtts.put("testIOException", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.addSipConnector(serverName, sipIpAddress, containerPort, ListeningPoint.TCP); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + List allMessagesContent = receiver.getAllMessagesContent(); + assertEquals(1, allMessagesContent.size()); + assertTrue("IOException not thrown", allMessagesContent.contains("IOException thrown")); + } + + /** + * non regression test for Issue 172 + * http://code.google.com/p/sipservlets/issues/detail?id=172 Possible to add + * params to Contact header + */ + @Test + public void testShootistOptionsSetContact() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("setRandomContact", "true"); + ctxAtts.put("method", "OPTIONS"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + ContactHeader contactHeader = (ContactHeader) receiver.getOptionsRequest().getHeader(ContactHeader.NAME); + assertNotNull(contactHeader); + assertNotNull(contactHeader.getParameter("optionParam")); + assertEquals(contactHeader.getParameter("optionParam"), "optionValue"); + assertEquals(((SipURI) contactHeader.getAddress().getURI()).getUser(), "optionUser"); + } + + /** + * non regression test for Github Issue 48 + * https://github.com/Mobicents/sip-servlets/issues/48 Possible to add + * params to Contact header for Message + */ + @Test + public void testShootistMessageSetContact() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("setRandomContact", "true"); + ctxAtts.put("method", "MESSAGE"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + ContactHeader contactHeader = (ContactHeader) receiver.getMessageRequest().getHeader(ContactHeader.NAME); + assertNotNull(contactHeader); + assertNotNull(contactHeader.getParameter("optionParam")); + assertEquals(contactHeader.getParameter("optionParam"), "optionValue"); + assertEquals(((SipURI) contactHeader.getAddress().getURI()).getUser(), "optionUser"); + } + + /** + * non regression test for Issue 1547 + * http://code.google.com/p/mobicents/issues/detail?id=1547 Can't add a + * Proxy-Authorization using SipServletMessage.addHeader + */ + public void testShootistProxyAuthorization() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("auth-header", "Digest username=\"1001\", realm=\"172.16.0.37\", algorithm=MD5, uri=\"sip:66621@172.16.0.37;user=phone\", qop=auth, nc=00000001, cnonce=\"b70b470bedf75db7\", nonce=\"1276678944:394f0b0b049fbbda8c94ae28d08f2301\", response=\"561389d4ce5cb38020749b8a27798343\""); + ctxAtts.put("headerToAdd", "Proxy-Authorization"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertNotNull(receiver.getInviteRequest().getHeader(ProxyAuthorizationHeader.NAME)); + assertNotNull(receiver.getInviteRequest().getHeader(ProxyAuthenticateHeader.NAME)); + } + + /** + * non regression test for Issue 2798 + * http://code.google.com/p/mobicents/issues/detail?id=2798 Can't add an + * Authorization using SipServletMessage.addHeader + */ + public void testShootistAuthorization() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("auth-header", "Digest username=\"1001\", realm=\"172.16.0.37\", algorithm=MD5, uri=\"sip:66621@172.16.0.37;user=phone\", qop=auth, nc=00000001, cnonce=\"b70b470bedf75db7\", nonce=\"1276678944:394f0b0b049fbbda8c94ae28d08f2301\", response=\"561389d4ce5cb38020749b8a27798343\""); + ctxAtts.put("headerToAdd", "Authorization"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertNotNull(receiver.getInviteRequest().getHeader(AuthorizationHeader.NAME)); + } + + // Tests Issue 1693 http://code.google.com/p/mobicents/issues/detail?id=1693 + public void testShootistErrorResponse() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("testErrorResponse", "true"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + receiver.setProvisionalResponsesToSend(new ArrayList()); + receiver.setFinalResponseToSend(Response.SERVER_INTERNAL_ERROR); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(DIALOG_TIMEOUT + TIMEOUT); + List allMessagesContent = receiver.getAllMessagesContent(); + assertEquals(2, allMessagesContent.size()); + assertTrue("sipSessionReadyToInvalidate", allMessagesContent.contains("sipSessionReadyToInvalidate")); + assertTrue("sipAppSessionReadyToInvalidate", allMessagesContent.contains("sipAppSessionReadyToInvalidate")); + } + + // Tests Issue 1693 http://code.google.com/p/mobicents/issues/detail?id=1693 + public void testShootistOptionsTimeout() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("testErrorResponse", "true"); + ctxAtts.put("method", "OPTIONS"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + receiver.setProvisionalResponsesToSend(new ArrayList()); + receiver.setWaitForCancel(true); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(DIALOG_TIMEOUT + TIMEOUT); + List allMessagesContent = receiver.getAllMessagesContent(); + assertEquals(1, allMessagesContent.size()); + assertTrue("408 received", allMessagesContent.contains("408 received")); + } + + // Tests Issue 143 http://code.google.com/p/mobicents/issues/detail?id=143 + public void testShootist422Response() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("testErrorResponse", "true"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + receiver.setProvisionalResponsesToSend(new ArrayList()); + receiver.setFinalResponseToSend(422); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + receiver.setFinalResponseToSend(200); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isAckReceived()); + } + + // Test for SS spec 11.1.6 transaction timeout notification + // Test Issue 2580 http://code.google.com/p/mobicents/issues/detail?id=2580 + public void testTransactionTimeoutResponse() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + receiver.setDropRequest(true); + List provisionalResponsesToSend = receiver.getProvisionalResponsesToSend(); + provisionalResponsesToSend.clear(); + + SipProvider receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + + Thread.sleep(DIALOG_TIMEOUT); + + Iterator allMessagesIterator = receiver.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + + } + assertTrue(receiver.txTimeoutReceived); + } + + /* + * http://code.google.com/p/mobicents/issues/detail?id=2902 + */ + public void testShootistRemoteAddrAndPort() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("testRemoteAddrAndPort", "true"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + } + + // https://code.google.com/p/sipservlets/issues/detail?id=169 + public void testShootistMultipartBytes() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("testMultipartBytes", "true"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + receiver.setProvisionalResponsesToSend(new ArrayList()); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + } + + // https://code.google.com/p/sipservlets/issues/detail?id=216 + public void testShootistMutlipleReasonHeaders() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("testMultipleReasonHeaders", "true"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + receiver.setProvisionalResponsesToSend(new ArrayList()); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + ListIterator
listIt = receiver.getInviteRequest().getHeaders(ReasonHeader.NAME); + int i = 0; + while (listIt.hasNext()) { + listIt.next(); + i++; + } + assertEquals(2, i); + } + + /* + * https://code.google.com/p/sipservlets/issues/detail?id=245 + */ + public void testShootistAddressParam() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("testAddressParam", "true"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + assertEquals("00112233", ((MessageExt) receiver.getInviteRequest()).getFromHeader().getParameter("epid")); + assertEquals("33221100", ((MessageExt) receiver.getInviteRequest()).getToHeader().getParameter("epid")); + } + + @Override + @After + protected void tearDown() throws Exception { + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootistTelURLSipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootistTelURLSipServletTest.java index c4203151f4..c62ec2e5c1 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootistTelURLSipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootistTelURLSipServletTest.java @@ -1,167 +1,138 @@ -/* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2014, Telestax Inc and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - */ - -package org.mobicents.servlet.sip.testsuite.simple; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; - -import javax.sip.SipProvider; -import javax.sip.header.ToHeader; - -import org.apache.catalina.deploy.ApplicationParameter; -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class ShootistTelURLSipServletTest extends SipServletTestCase { - private static transient Logger logger = Logger.getLogger(ShootistTelURLSipServletTest.class); - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; -// private static final int TIMEOUT = 100000000; - - TestSipListener receiver; - - ProtocolObjects receiverProtocolObjects; - - public ShootistTelURLSipServletTest(String name) { - super(name); - startTomcatOnStartup = false; - autoDeployOnStartup = false; - } - - @Override - protected void deployApplication() { - // TODO Auto-generated method stub - - } - - public void deployApplication(String urlType) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName("urlType"); - applicationParameter.setValue(urlType); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - } - - public SipStandardContext deployApplication(String name, String value) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("/sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - context.setConcurrencyControlMode(ConcurrencyControlMode.SipApplicationSession); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(name); - applicationParameter.setValue(value); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - return context; - } - - public SipStandardContext deployApplication(Map params) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("/sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setConcurrencyControlMode(ConcurrencyControlMode.SipApplicationSession); - context.setManager(new SipStandardManager()); - for (Entry param : params.entrySet()) { - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(param.getKey()); - applicationParameter.setValue(param.getValue()); - context.addApplicationParameter(applicationParameter); - } - assertTrue(tomcat.deployContext(context)); - return context; - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/simple/shootist-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - } - - public void testShootistTelURL() throws Exception { -// receiver.sendInvite(); - tomcat.startTomcat(); - deployApplication("tel"); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - } - - /* - * https://code.google.com/p/sipservlets/issues/detail?id=170 - */ - public void testShootistTelURLFlagParameter() throws Exception { -// receiver.sendInvite(); - tomcat.startTomcat(); - Map params = new HashMap(); - params.put("urlType", "tel"); - params.put("flag", "ndpi"); - deployApplication(params); - Thread.sleep(TIMEOUT); - assertEquals("tel:+358-555-1234567;ndpi", ((ToHeader)receiver.getInviteRequest().getHeader(ToHeader.NAME)).getAddress().getURI().toString()); - assertTrue(receiver.getByeReceived()); - } - - public void testShootistTelURLAsSIP() throws Exception { -// receiver.sendInvite(); - tomcat.startTomcat(); - deployApplication("telAsSip"); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - } - - @Override - protected void tearDown() throws Exception { - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } -} \ No newline at end of file +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2014, Telestax Inc and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + */ +package org.mobicents.servlet.sip.testsuite.simple; + +import java.util.HashMap; +import java.util.Map; + +import javax.sip.SipProvider; +import javax.sip.header.ToHeader; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class ShootistTelURLSipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ShootistTelURLSipServletTest.class); + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; +// private static final int TIMEOUT = 100000000; + + TestSipListener receiver; + + ProtocolObjects receiverProtocolObjects; + + private int receiverPort; + + public ShootistTelURLSipServletTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + protected void deployApplication() { + // TODO Auto-generated method stub + + } + + public void deployApplication(Map params) { + SipStandardContext context = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp", + "sip-test", + params, + null); + assertTrue(context.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/simple/shootist-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + senderProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + } + + public void testShootistTelURL() throws Exception { + //tomcat.startTomcat(); + + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(receiverPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("urlType", "tel"); + deployShootist(ctxAtts, null); + + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + } + + /* + * https://code.google.com/p/sipservlets/issues/detail?id=170 + */ + public void testShootistTelURLFlagParameter() throws Exception { + //tomcat.startTomcat(); + + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(receiverPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("urlType", "tel"); + ctxAtts.put("flag", "ndpi"); + deployShootist(ctxAtts, null); + + Thread.sleep(TIMEOUT); + assertEquals("tel:+358-555-1234567;ndpi", ((ToHeader) receiver.getInviteRequest().getHeader(ToHeader.NAME)).getAddress().getURI().toString()); + assertTrue(receiver.getByeReceived()); + } + + public void testShootistTelURLAsSIP() throws Exception { + //tomcat.startTomcat(); + + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(receiverPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("urlType", "telAsSip"); + deployShootist(ctxAtts, null); + + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + } + + @Override + protected void tearDown() throws Exception { + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/Shootme491Test.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/Shootme491Test.java new file mode 100644 index 0000000000..75d640ccad --- /dev/null +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/Shootme491Test.java @@ -0,0 +1,162 @@ +package org.mobicents.servlet.sip.testsuite.simple; + +import java.text.ParseException; +import java.util.HashMap; +import java.util.Map; + +import javax.sip.InvalidArgumentException; +import javax.sip.SipException; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import javax.sip.message.Request; +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.junit.After; +import org.junit.Before; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.core.SipContext; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class Shootme491Test extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ShootmeSipServletTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; + + public final static String[] ALLOW_HEADERS = new String[]{"INVITE", "ACK", "CANCEL", "OPTIONS", "BYE", "SUBSCRIBE", "NOTIFY", "REFER"}; + + TestSipListener sender; + SipProvider senderProvider = null; + TestSipListener registerReciever; + SipContext sipContext; + + ProtocolObjects senderProtocolObjects; + ProtocolObjects registerRecieverProtocolObjects; + + public Shootme491Test(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + public void deployApplication(Map params) { + SipStandardContext context = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp", + "sip-test", + params, + null, + 1, + null); + assertTrue(context.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/simple/simple-sip-servlet-dar.properties"; + } + + @Override + @Before + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + registerRecieverProtocolObjects = new ProtocolObjects( + "registerReciever", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int registerPort = NetworkPortAssigner.retrieveNextPort(); + registerReciever = new TestSipListener(registerPort, containerPort, registerRecieverProtocolObjects, true); + SipProvider registerRecieverProvider = registerReciever.createProvider(); + registerRecieverProvider.addSipListener(registerReciever); + registerRecieverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + params.put("registerPort", String.valueOf(registerPort)); + deployApplication(params); + } + + public void testShootme491() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "normal"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setSendBye(false); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + Thread.sleep(12000); + assertTrue(sender.numberOf491s > 0); + assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getRequestsProcessedByMethod(Request.INVITE) > 1); + assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getResponsesSentByStatusCode("4XX") > 0); + } + + public void testShootme491withRetrans() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "normal"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setSendBye(false); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(2500); + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + Thread.sleep(6000); + int current = sender.numberOf491s; + System.out.println("number of 491 " + current); + assertTrue(sender.numberOf491s > 2); + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + Thread.sleep(1000); + assertEquals(current, sender.numberOf491s); + } + + @Override + @After + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + registerRecieverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootmeRegisterTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootmeRegisterTest.java new file mode 100644 index 0000000000..08dde3bf54 --- /dev/null +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootmeRegisterTest.java @@ -0,0 +1,199 @@ +package org.mobicents.servlet.sip.testsuite.simple; + +import java.util.HashMap; +import java.util.Map; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import javax.sip.header.ContactHeader; +import javax.sip.message.Request; +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertNull; +import static junit.framework.Assert.assertTrue; +import org.apache.log4j.Logger; +import org.junit.After; +import org.junit.Before; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.core.SipContext; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +/** + * + * @author jaime + */ +public class ShootmeRegisterTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ShootmeSipServletTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; +// private static final int TIMEOUT = 100000000; + private static final int TIMEOUT_CSEQ_INCREASE = 100000; + private static final int DIALOG_TIMEOUT = 40000; + + public final static String[] ALLOW_HEADERS = new String[]{"INVITE", "ACK", "CANCEL", "OPTIONS", "BYE", "SUBSCRIBE", "NOTIFY", "REFER"}; + + TestSipListener sender; + SipProvider senderProvider = null; + TestSipListener registerReciever; + SipContext sipContext; + + ProtocolObjects senderProtocolObjects; + ProtocolObjects registerRecieverProtocolObjects; + + public ShootmeRegisterTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + + } + + public void deployApplication(Map params) { + SipStandardContext context = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp", + "sip-test", + params, + null, + 1, + null); + assertTrue(context.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/simple/simple-sip-servlet-dar.properties"; + } + + @Override + @Before + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int myPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(myPort, containerPort, senderProtocolObjects, true); + senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + registerRecieverProtocolObjects = new ProtocolObjects( + "registerReciever", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int registerPort = NetworkPortAssigner.retrieveNextPort(); + registerReciever = new TestSipListener(registerPort, containerPort, registerRecieverProtocolObjects, true); + SipProvider registerRecieverProvider = registerReciever.createProvider(); + registerRecieverProvider.addSipListener(registerReciever); + registerRecieverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(myPort)); + params.put("registerPort", String.valueOf(registerPort)); + deployApplication(params); + } + + public void testShootmeRegister() throws Exception { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + sender.sendSipRequest("REGISTER", fromAddress, fromAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isFinalResponseReceived()); + assertEquals(200, sender.getFinalResponseStatus()); + assertEquals(1, tomcat.getSipService().getSipApplicationDispatcher().getRequestsProcessedByMethod(Request.REGISTER)); + assertEquals(1, tomcat.getSipService().getSipApplicationDispatcher().getResponsesSentByStatusCode("2XX")); + } + + /** + * non regression test for Issue 172 + * http://code.google.com/p/sipservlets/issues/detail?id=172 Possible to add + * contact Header to 200 OK to OPTIONS + */ + public void testShootmeOptions() throws Exception { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + sender.sendSipRequest("OPTIONS", fromAddress, fromAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isFinalResponseReceived()); + assertEquals(200, sender.getFinalResponseStatus()); + ContactHeader contactHeader = (ContactHeader) sender.getFinalResponse().getHeader(ContactHeader.NAME); + assertNotNull(contactHeader); + assertEquals(((SipURI) contactHeader.getAddress().getURI()).toString(), "sip:random@172.172.172.172:3289"); + } + + public void testShootmeRegisterNoContact() throws Exception { + String fromName = "testRegisterNoContact"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, fromAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertNull(registerReciever.getRegisterReceived().getHeader(ContactHeader.NAME)); + } + + public void testShootmeRegisterCSeqIncrease() throws Exception { + String fromName = "testRegisterCSeq"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, fromAddress, null, null, false); + Thread.sleep(TIMEOUT_CSEQ_INCREASE); + assertEquals(4, registerReciever.getLastRegisterCSeqNumber()); + assertTrue(sender.isFinalResponseReceived()); + } + + public void testShootmeRegisterCSeqIncreaseAuth() throws Exception { + String fromName = "testRegisterCSeq"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + registerReciever.setChallengeRequests(true); + sender.sendSipRequest("INVITE", fromAddress, fromAddress, null, null, false); + Thread.sleep(TIMEOUT_CSEQ_INCREASE); + assertEquals(4, registerReciever.getLastRegisterCSeqNumber()); + assertTrue(sender.isFinalResponseReceived()); + } + + public void testShootmeRegisterAuthSavedSession() throws Exception { + String fromName = "testRegisterSavedSession"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + registerReciever.setChallengeRequests(true); + registerReciever.setSendBye(false); + sender.setSendBye(false); + sender.sendSipRequest("INVITE", fromAddress, fromAddress, null, null, false); + Thread.sleep(TIMEOUT_CSEQ_INCREASE); + assertTrue(registerReciever.getLastRegisterCSeqNumber() == 4); + assertTrue(sender.isFinalResponseReceived()); + } + + @Override + @After + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + registerRecieverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + Thread.sleep(4000); +// FullThreadDump fullThreadDump = new FullThreadDump("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", 1090); +// fullThreadDump.dump(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootmeSendByeTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootmeSendByeTest.java new file mode 100644 index 0000000000..78a22291bb --- /dev/null +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootmeSendByeTest.java @@ -0,0 +1,202 @@ +package org.mobicents.servlet.sip.testsuite.simple; + +import gov.nist.javax.sip.header.extensions.SessionExpiresHeader; +import java.io.File; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.Properties; +import java.util.UUID; + +import javax.sip.InvalidArgumentException; +import javax.sip.SipException; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import javax.sip.address.URI; +import javax.sip.header.AllowHeader; +import javax.sip.header.AuthenticationInfoHeader; +import javax.sip.header.ContactHeader; +import javax.sip.header.ServerHeader; +import javax.sip.message.Request; +import javax.sip.message.Response; +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertNull; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.junit.After; +import org.junit.Before; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipEmbedded; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.core.SipContext; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class ShootmeSendByeTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ShootmeSipServletTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; +// private static final int TIMEOUT = 100000000; + private static final int TIMEOUT_CSEQ_INCREASE = 100000; + private static final int DIALOG_TIMEOUT = 40000; + + public final static String[] ALLOW_HEADERS = new String[]{"INVITE", "ACK", "CANCEL", "OPTIONS", "BYE", "SUBSCRIBE", "NOTIFY", "REFER"}; + + TestSipListener sender; + SipProvider senderProvider = null; + TestSipListener registerReciever; + SipContext sipContext; + + ProtocolObjects senderProtocolObjects; + ProtocolObjects registerRecieverProtocolObjects; + + public ShootmeSendByeTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + public void deployApplication(Map params) { + SipStandardContext context = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp", + "sip-test", + params, + null, + 1, + null); + assertTrue(context.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/simple/simple-sip-servlet-dar.properties"; + } + + @Override + @Before + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(myPort, containerPort, senderProtocolObjects, true); + senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + registerRecieverProtocolObjects = new ProtocolObjects( + "registerReciever", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int registerPort = NetworkPortAssigner.retrieveNextPort(); + registerReciever = new TestSipListener(registerPort, containerPort, registerRecieverProtocolObjects, true); + SipProvider registerRecieverProvider = registerReciever.createProvider(); + registerRecieverProvider.addSipListener(registerReciever); + registerRecieverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(myPort)); + params.put("registerPort", String.valueOf(registerPort)); + deployApplication(params); + } + + + public void testShootmeSendByeOnExpire() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "byeOnExpire"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setSendBye(false); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(5000); + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + Thread.sleep(70000); + assertTrue(sender.isAckSent()); + assertTrue(sender.getByeReceived()); + } + + + public void testShootmeSendBye() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "SSsendBye"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setSendBye(false); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT * 2); + assertTrue(sender.isAckSent()); + assertTrue(sender.getByeReceived()); + Thread.sleep(TIMEOUT * 4); + } + + /* + * https://code.google.com/p/sipservlets/issues/detail?id=194 + */ + public void testShootmeSendBye407Terminated() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "SSsendBye"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setByeResponse(407); + sender.setSendBye(false); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT * 2); + assertTrue(sender.isAckSent()); + assertTrue(sender.getByeReceived()); + Thread.sleep(TIMEOUT); + List allMessagesContent = sender.getAllMessagesContent(); + assertEquals(1, allMessagesContent.size()); + assertEquals("CONFIRMED", allMessagesContent.get(0)); + } + + + @Override + @After + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + registerRecieverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + Thread.sleep(4000); +// FullThreadDump fullThreadDump = new FullThreadDump("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", 1090); +// fullThreadDump.dump(); + } + +} + diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootmeServerHeaderTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootmeServerHeaderTest.java new file mode 100644 index 0000000000..3d266c1b96 --- /dev/null +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootmeServerHeaderTest.java @@ -0,0 +1,164 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2014, Telestax Inc and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + */ +package org.mobicents.servlet.sip.testsuite.simple; + +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import javax.sip.header.ServerHeader; +import javax.sip.message.Response; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.junit.After; +import org.junit.Before; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.core.SipContext; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class ShootmeServerHeaderTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ShootmeServerHeaderTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; + + public final static String[] ALLOW_HEADERS = new String[]{"INVITE", "ACK", "CANCEL", "OPTIONS", "BYE", "SUBSCRIBE", "NOTIFY", "REFER"}; + + TestSipListener sender; + SipProvider senderProvider = null; + TestSipListener registerReciever; + SipContext sipContext; + + ProtocolObjects senderProtocolObjects; + ProtocolObjects registerRecieverProtocolObjects; + + public ShootmeServerHeaderTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + public void deployApplication(Map params) { + SipStandardContext context = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp", + "sip-test", + params, + null, + 1, + null); + assertTrue(context.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/simple/simple-sip-servlet-dar.properties"; + } + + @Override + @Before + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(myPort, containerPort, senderProtocolObjects, true); + senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + registerRecieverProtocolObjects = new ProtocolObjects( + "registerReciever", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int registerPort = NetworkPortAssigner.retrieveNextPort(); + registerReciever = new TestSipListener(registerPort, containerPort, registerRecieverProtocolObjects, true); + SipProvider registerRecieverProvider = registerReciever.createProvider(); + registerRecieverProvider.addSipListener(registerReciever); + registerRecieverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(myPort)); + params.put("registerPort", String.valueOf(registerPort)); + deployApplication(params); + } + + @Override + protected Properties getSipStackProperties() { + Properties sipStackProperties = new Properties(); + sipStackProperties.setProperty("javax.sip.STACK_NAME", "mss-" + + sipIpAddress + "-" + containerPort); + sipStackProperties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", + "off"); + sipStackProperties.setProperty( + "gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.THREAD_POOL_SIZE", + "64"); + sipStackProperties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", + "true"); + sipStackProperties.setProperty("org.mobicents.servlet.sip.SERVER_HEADER", + "MobicentsSipServletsServer"); + return sipStackProperties; + } + + public void testShootmeServerHeader() throws Exception { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + + Response finalResponse = sender.getFinalResponse(); + ServerHeader serverHeader = (ServerHeader) finalResponse.getHeader(ServerHeader.NAME); + assertNotNull(serverHeader); + assertTrue(serverHeader.toString().contains("MobicentsSipServletsServer")); + } + + @Override + @After + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + registerRecieverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + Thread.sleep(4000); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootmeSipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootmeSipServletTest.java index 75bdd90d17..658a600c2e 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootmeSipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootmeSipServletTest.java @@ -1,860 +1,661 @@ -/* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2014, Telestax Inc and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - */ - -package org.mobicents.servlet.sip.testsuite.simple; - -import java.io.File; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.Properties; -import java.util.UUID; - -import javax.sip.InvalidArgumentException; -import javax.sip.SipException; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; -import javax.sip.address.URI; -import javax.sip.header.AllowHeader; -import javax.sip.header.AuthenticationInfoHeader; -import javax.sip.header.ContactHeader; -import javax.sip.header.ServerHeader; -import javax.sip.message.Request; -import javax.sip.message.Response; - -import org.apache.log4j.Logger; -import org.junit.After; -import org.junit.Before; -import org.mobicents.servlet.sip.SipEmbedded; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.core.SipContext; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class ShootmeSipServletTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(ShootmeSipServletTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; -// private static final int TIMEOUT = 100000000; - private static final int TIMEOUT_CSEQ_INCREASE = 100000; - private static final int DIALOG_TIMEOUT = 40000; - - public final static String[] ALLOW_HEADERS = new String[] {"INVITE","ACK","CANCEL","OPTIONS","BYE","SUBSCRIBE","NOTIFY","REFER"}; - - TestSipListener sender; - SipProvider senderProvider = null; - TestSipListener registerReciever; - SipContext sipContext; - - ProtocolObjects senderProtocolObjects; - ProtocolObjects registerRecieverProtocolObjects; - - public ShootmeSipServletTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - tomcat.getSipService().setDialogPendingRequestChecking(true); - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test", 1)); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/simple/simple-sip-servlet-dar.properties"; - } - - @Override - @Before - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - - - registerRecieverProtocolObjects =new ProtocolObjects( - "registerReciever", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - registerReciever = new TestSipListener(5058, 5070, registerRecieverProtocolObjects, true); - SipProvider registerRecieverProvider = registerReciever.createProvider(); - - registerRecieverProvider.addSipListener(registerReciever); - - registerRecieverProtocolObjects.start(); - } - - public void testShootme() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - // test non regression for Issue 1687 : Contact Header is present in SIP Message where it shouldn't - Response response = sender.getFinalResponse(); - assertNull(response.getHeader(ContactHeader.NAME)); - assertEquals(1,tomcat.getSipService().getSipApplicationDispatcher().getRequestsProcessedByMethod(Request.INVITE)); - assertEquals(1,tomcat.getSipService().getSipApplicationDispatcher().getRequestsProcessedByMethod(Request.ACK)); - assertEquals(1,tomcat.getSipService().getSipApplicationDispatcher().getRequestsProcessedByMethod(Request.BYE)); - assertEquals(2,tomcat.getSipService().getSipApplicationDispatcher().getResponsesSentByStatusCode("2XX")); - } - - /* - * https://code.google.com/p/sipservlets/issues/detail?id=264 - */ - public void testShootmeColumnInCallIdHeader() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[] {"Call-ID"}, new String[] {"jean:telestax:random:" + UUID.randomUUID() + "@localhost"}, true); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - // test non regression for Issue 1687 : Contact Header is present in SIP Message where it shouldn't - Response response = sender.getFinalResponse(); - assertNull(response.getHeader(ContactHeader.NAME)); - } - - /* - * Non regression test for Issue 2115 http://code.google.com/p/mobicents/issues/detail?id=2115 - * MSS unable to handle GenericURI URIs - */ - public void testShootmeGenericRURI() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - URI toAddress = senderProtocolObjects.addressFactory.createURI("urn:service:sos"); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); - sender.setUseToURIasRequestUri(false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - // test non regression for Issue 1687 : Contact Header is present in SIP Message where it shouldn't - Response response = sender.getFinalResponse(); - assertNull(response.getHeader(ContactHeader.NAME)); - } - - /* - * Non regression test for Issue 2522 http://code.google.com/p/mobicents/issues/detail?id=2522 - * Cloned URI is not modifiable - */ - public void testShootmeCloneURI() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "cloneURI"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertEquals(200, sender.getFinalResponseStatus()); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - } - - public void testShootmeSendByeOnExpire() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "byeOnExpire"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setSendBye(false); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(5000); - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - Thread.sleep(70000); - assertTrue(sender.isAckSent()); - assertTrue(sender.getByeReceived()); - } - - public void testShootmeExceptionOnExpirationCount() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - new File("expirationFailure.tmp").delete(); - assertFalse(new File("expirationFailure.tmp").exists()); - String fromName = "exceptionOnExpire"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setSendBye(false); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(150000); - assertFalse(new File("expirationFailure.tmp").exists()); - } - - public void testShootme491() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "normal"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setSendBye(false); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - Thread.sleep(12000); - assertTrue(sender.numberOf491s>0); - assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getRequestsProcessedByMethod(Request.INVITE)>1); - assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getResponsesSentByStatusCode("4XX")>0); - } - - public void testShootme491withRetrans() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "normal"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setSendBye(false); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(2500); - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - Thread.sleep(6000); - int current = sender.numberOf491s; - System.out.println("number of 491 " + current); - assertTrue(sender.numberOf491s>2); - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - Thread.sleep(1000); - assertEquals(current, sender.numberOf491s); - } - - public void testShootmeSendBye() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "SSsendBye"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setSendBye(false); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT* 2); - assertTrue(sender.isAckSent()); - assertTrue(sender.getByeReceived()); - Thread.sleep(TIMEOUT* 4); - } - - // Issue 1042 : Trying to simulate the 2 Invites arriving at the same time - public void testShootmeRetransTest() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - Request request = sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - senderProvider.sendRequest(request); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - } - - public void testShootmeParameterable() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[] {"additionalParameterableHeader","nonParameterableHeader"}, new String[] {"none","none"}, true); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - } - - /* - * Non regression test for https://code.google.com/p/sipservlets/issues/detail?id=260 - */ - public void testShootmeEventParameterable() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[] {"Event"}, new String[] {"field-value;param1=paramValue1;param2=paramValue2"}, true); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - } - - /** - * Non Regression Test for Issue http://code.google.com/p/mobicents/issues/detail?id=2201 - * javax.servlet.sip.ServletParseException: Impossible to parse the following header Remote-Party-ID as an address. - */ - public void testShootmeRemotePartyID() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "RemotePartyId"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[] {"Remote-Party-ID", "Remote-Party-ID2", "Remote-Party-ID3", "Remote-Party-ID4", "Remote-Party-ID5"}, new String[] {"\"KATE SMITH\"; party=calling; privacy=off; screen=yes", "sip:4162375543@47.135.223.88;user=phone; party=calling; privacy=off; screen=yes", "; party=calling; privacy=off; screen=yes", "\"KATE SMITH\"; party=calling; privacy=off; screen=yes", "; party=calling; privacy=off; screen=yes"}, true); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - } - - public void testGRUUContactHeader() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "gruuContact"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - Request request = sender.createSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[] {"Remote-Party-ID", "Remote-Party-ID2", "Remote-Party-ID3", "Remote-Party-ID4", "Remote-Party-ID5"}, new String[] {"\"KATE SMITH\"; party=calling; privacy=off; screen=yes", "sip:4162375543@47.135.223.88;user=phone; party=calling; privacy=off; screen=yes", "; party=calling; privacy=off; screen=yes", "\"KATE SMITH\"; party=calling; privacy=off; screen=yes", "; party=calling; privacy=off; screen=yes"}, toAddress); - - request.setHeader(sender.protocolObjects.headerFactory.createHeader("Contact", ";expires=500;+sip.instance=\"\";gruu=\"sip:100@ocs14.com;opaque=user:epid:xxxxxxxxxxxxxxxxxxxxxxxx;gruu\"")); - - //request.setHeader(sender.protocolObjects.headerFactory.createHeader("Contact", "sip:4162375543@47.135.223.88")); - sender.sendRequet(request); - Thread.sleep(TIMEOUT*2); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - } - - public void testShootmeRegister() throws Exception { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - sender.sendSipRequest("REGISTER", fromAddress, fromAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isFinalResponseReceived()); - assertEquals(200, sender.getFinalResponseStatus()); - assertEquals(1,tomcat.getSipService().getSipApplicationDispatcher().getRequestsProcessedByMethod(Request.REGISTER)); - assertEquals(1,tomcat.getSipService().getSipApplicationDispatcher().getResponsesSentByStatusCode("2XX")); - } - - /** - * non regression test for Issue 172 http://code.google.com/p/sipservlets/issues/detail?id=172 - * Possible to add contact Header to 200 OK to OPTIONS - */ - public void testShootmeOptions() throws Exception { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - sender.sendSipRequest("OPTIONS", fromAddress, fromAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isFinalResponseReceived()); - assertEquals(200, sender.getFinalResponseStatus()); - ContactHeader contactHeader = (ContactHeader) sender.getFinalResponse().getHeader(ContactHeader.NAME); - assertNotNull(contactHeader); - assertEquals(((SipURI)contactHeader.getAddress().getURI()).toString(),"sip:random@172.172.172.172:3289"); - } - - /** - * non regression test for Issue 1104 http://code.google.com/p/mobicents/issues/detail?id=1104 - * Cannot find the corresponding sip session to this subsequent request - * - * In conflict with Issue 1401 http://code.google.com/p/mobicents/issues/detail?id=1401 - * ACK request sent by sip client after receiving 488/reINVITE is passed to sip application - * Forbidden by SIP Spec "11.2.2 Receiving ACK" : - * "Applications are not notified of incoming ACKs for non-2xx final responses to INVITE." - * - */ - public void testShootmeErrorResponse() throws Exception { - String fromName = "testErrorResponse"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isFinalResponseReceived()); - assertEquals(486, sender.getFinalResponseStatus()); - assertTrue(!sender.getAllMessagesContent().contains("ackReceived")); - Thread.sleep(DIALOG_TIMEOUT); - List allMessagesContent = sender.getAllMessagesContent(); - assertEquals(2,allMessagesContent.size()); - assertTrue("sipSessionReadyToInvalidate", allMessagesContent.contains("sipSessionReadyToInvalidate")); - assertTrue("sipAppSessionReadyToInvalidate", allMessagesContent.contains("sipAppSessionReadyToInvalidate")); - } - - public void testShootmeRegisterNoContact() throws Exception { - String fromName = "testRegisterNoContact"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, fromAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertNull(registerReciever.getRegisterReceived().getHeader(ContactHeader.NAME)); - } - - public void testShootmeRegisterCSeqIncrease() throws Exception { - String fromName = "testRegisterCSeq"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, fromAddress, null, null, false); - Thread.sleep(TIMEOUT_CSEQ_INCREASE); - assertTrue(registerReciever.getLastRegisterCSeqNumber() == 4); - assertTrue(sender.isFinalResponseReceived()); - } - - public void testShootmeRegisterCSeqIncreaseAuth() throws Exception { - String fromName = "testRegisterCSeq"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - registerReciever.setChallengeRequests(true); - sender.sendSipRequest("INVITE", fromAddress, fromAddress, null, null, false); - Thread.sleep(TIMEOUT_CSEQ_INCREASE); - assertTrue(registerReciever.getLastRegisterCSeqNumber() == 4); - assertTrue(sender.isFinalResponseReceived()); - } - - public void testShootmeRegisterAuthSavedSession() throws Exception { - String fromName = "testRegisterSavedSession"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - registerReciever.setChallengeRequests(true); - registerReciever.setSendBye(false); - sender.setSendBye(false); - sender.sendSipRequest("INVITE", fromAddress, fromAddress, null, null, false); - Thread.sleep(TIMEOUT_CSEQ_INCREASE); - assertTrue(registerReciever.getLastRegisterCSeqNumber() == 4); - assertTrue(sender.isFinalResponseReceived()); - } - - public void testShootmeCancel() throws Exception { - String fromName = "cancel"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(500); - sender.sendCancel(); - Thread.sleep(TIMEOUT); - assertTrue(sender.isCancelOkReceived()); - assertTrue(sender.isRequestTerminatedReceived()); - Thread.sleep(TIMEOUT); - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertTrue(sender.getAllMessagesContent().contains("cancelReceived")); - assertEquals(1,tomcat.getSipService().getSipApplicationDispatcher().getRequestsProcessedByMethod(Request.INVITE)); - assertEquals(1,tomcat.getSipService().getSipApplicationDispatcher().getRequestsProcessedByMethod(Request.CANCEL)); - assertEquals(1,tomcat.getSipService().getSipApplicationDispatcher().getRequestsProcessedByMethod(Request.ACK)); - assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getResponsesSentByStatusCode("1XX")>0); - assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getResponsesSentByStatusCode("2XX")>0); - assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getResponsesSentByStatusCode("4XX")>0); - } - - public void testShootmeMultipleValueHeaders() throws Exception { - String fromName = "TestAllowHeader"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, fromAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isFinalResponseReceived()); - assertEquals(405, sender.getFinalResponseStatus()); - //Issue 1164 non regression test - ListIterator allowHeaders = (ListIterator) sender.getFinalResponse().getHeaders(AllowHeader.NAME); - assertNotNull(allowHeaders); - List allowHeadersList = new ArrayList(); - while (allowHeaders.hasNext()) { - allowHeadersList.add(allowHeaders.next().getMethod()); - } - assertTrue(Arrays.equals(ALLOW_HEADERS, (String[])allowHeadersList.toArray(new String[allowHeadersList.size()]))); - } - - // test for http://code.google.com/p/mobicents/issues/detail?id=676 - public void testShootmeToTag() throws Exception { - String fromName = "TestToTag"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, fromAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertEquals( 200, sender.getFinalResponseStatus()); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - } - - // test for http://code.google.com/p/mobicents/issues/detail?id=695 - public void testSubscriberURI() throws Exception { - String fromName = "testSubscriberUri"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, fromAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertEquals( 200, sender.getFinalResponseStatus()); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - } - - // test for http://code.google.com/p/mobicents/issues/detail?id=1010 - public void testFlagParameter() throws Exception { - String fromName = "testFlagParameter"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, fromAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertEquals( 200, sender.getFinalResponseStatus()); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - } - - // test for http://code.google.com/p/mobicents/issues/detail?id=1021 - public void testSessionRetrieval() throws Exception { - String fromName = "testSessionRetrieval"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - fromAddress.setParameter("fromParam", "whatever"); - - sender.sendSipRequest("INVITE", fromAddress, fromAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertEquals( 200, sender.getFinalResponseStatus()); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - } - - // test for http://code.google.com/p/mobicents/issues/detail?id=1061 - // Also test http://code.google.com/p/mobicents/issues/detail?id=1681 - public void testNoAckReceived() throws Exception { - String fromName = "noAckReceived"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - sender.setSendAck(false); - sender.setCountRetrans(true); - sender.sendSipRequest("INVITE", fromAddress, fromAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertEquals( 200, sender.getFinalResponseStatus()); - assertFalse(sender.isAckSent()); - Thread.sleep(DIALOG_TIMEOUT + TIMEOUT); - // test http://code.google.com/p/mobicents/issues/detail?id=1681 - // Make sure we get the 10 retrans for 200 to INVITE when no ACK is sent - // corresponding to Timer G - List allMessagesContent = sender.getAllMessagesContent(); - assertEquals(1,allMessagesContent.size()); - assertEquals("noAckReceived", allMessagesContent.get(0)); - logger.info("nb retrans received " + sender.getNbRetrans()); - assertTrue( sender.getNbRetrans() >= 9); - } - - // test for http://code.google.com/p/mobicents/issues/detail?id=2427 - public void testShootmeSerializationDeserialization() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "serialization"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - } - - // test for http://code.google.com/p/mobicents/issues/detail?id=2361 - public void testShootmeSystemHeaderModification() throws Exception { - String fromName = "systemHeaderModification"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertEquals(200, sender.getFinalResponseStatus()); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - } - - // test for http://code.google.com/p/mobicents/issues/detail?id=2563 - public void testShootmeFromToHeadersModification() throws Exception { - String fromName = "fromToHeaderModification"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertEquals(200, sender.getFinalResponseStatus()); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - } - - // test for http://code.google.com/p/mobicents/issues/detail?id=2578 - public void testShootmeAuthenticationInfoHeader() throws Exception { - String fromName = "authenticationInfoHeader"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setHandleAuthorization(false); - sender.sendSipRequest("REGISTER", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertEquals(401, sender.getFinalResponseStatus()); - AuthenticationInfoHeader authenticationInfoHeader = (AuthenticationInfoHeader) sender.getFinalResponse().getHeader(AuthenticationInfoHeader.NAME); - assertEquals("Authentication-Info: NTLM rspauth=\"01000000000000005CD422F0C750C7C6\",srand=\"0B9D33A2\",snum=\"1\",opaque=\"BCDC0C9D\",qop=\"auth\",targetname=\"server.contoso.com\",realm=\"SIP Communications Service\"", - authenticationInfoHeader.toString().trim()); - } - - public void testShootmeServerHeader() throws Exception { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - tomcat.removeConnector(sipConnector); - tomcat.startTomcat(); - tomcat.stopTomcat(); - - Properties sipStackProperties = new Properties(); - sipStackProperties.setProperty("javax.sip.STACK_NAME", "mss-" - + sipIpAddress + "-" + 5070); - sipStackProperties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", - "off"); - sipStackProperties.setProperty( - "gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.THREAD_POOL_SIZE", - "64"); - sipStackProperties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", - "true"); - sipStackProperties.setProperty("org.mobicents.servlet.sip.SERVER_HEADER", - "MobicentsSipServletsServer"); - - tomcat = new SipEmbedded(serverName, serviceFullClassName); - tomcat.setLoggingFilePath( - projectHome + File.separatorChar + "sip-servlets-test-suite" + - File.separatorChar + "testsuite" + - File.separatorChar + "src" + - File.separatorChar + "test" + - File.separatorChar + "resources" + File.separatorChar); - logger.info("Log4j path is : " + tomcat.getLoggingFilePath()); - String darConfigurationFile = getDarConfigurationFile(); - tomcat.setDarConfigurationFilePath(darConfigurationFile); - tomcat.initTomcat(tomcatBasePath, sipStackProperties); - tomcat.addHttpConnector(httpIpAddress, 8080); - if(addSipConnectorOnStartup) { - sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, 5070, listeningPointTransport); - } - tomcat.startTomcat(); - deployApplication(); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - - Response finalResponse = sender.getFinalResponse(); - ServerHeader serverHeader = (ServerHeader) finalResponse.getHeader(ServerHeader.NAME); - assertNotNull(serverHeader); - assertTrue(serverHeader.toString().contains("MobicentsSipServletsServer")); - } - - /* - * https://code.google.com/p/sipservlets/issues/detail?id=137 - */ - public void testShootmeResponseGetRemoteAddress() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "locallyGeneratedRemoteAddress"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setSendBye(false); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT*2); - assertTrue(sender.isAckSent()); - assertTrue(sender.getByeReceived()); - } - - /* - * https://code.google.com/p/sipservlets/issues/detail?id=194 - */ - public void testShootmeSendBye407Terminated() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "SSsendBye"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setByeResponse(407); - sender.setSendBye(false); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT * 2); - assertTrue(sender.isAckSent()); - assertTrue(sender.getByeReceived()); - Thread.sleep(TIMEOUT); - List allMessagesContent = sender.getAllMessagesContent(); - assertEquals(1,allMessagesContent.size()); - assertEquals("CONFIRMED", allMessagesContent.get(0)); - } - - @Override - @After - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - registerRecieverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - Thread.sleep(4000); -// FullThreadDump fullThreadDump = new FullThreadDump("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", 1090); -// fullThreadDump.dump(); - } - - -} +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2014, Telestax Inc and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + */ +package org.mobicents.servlet.sip.testsuite.simple; + +import gov.nist.javax.sip.header.extensions.SessionExpiresHeader; +import java.io.File; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.UUID; + +import javax.sip.InvalidArgumentException; +import javax.sip.SipException; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import javax.sip.address.URI; +import javax.sip.header.AllowHeader; +import javax.sip.header.AuthenticationInfoHeader; +import javax.sip.header.ContactHeader; +import javax.sip.message.Request; +import javax.sip.message.Response; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.junit.After; +import org.junit.Before; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.core.SipContext; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class ShootmeSipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ShootmeSipServletTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; +// private static final int TIMEOUT = 100000000; + private static final int TIMEOUT_CSEQ_INCREASE = 100000; + private static final int DIALOG_TIMEOUT = 40000; + + public final static String[] ALLOW_HEADERS = new String[]{"INVITE", "ACK", "CANCEL", "OPTIONS", "BYE", "SUBSCRIBE", "NOTIFY", "REFER"}; + + TestSipListener sender; + SipProvider senderProvider = null; + TestSipListener registerReciever; + SipContext sipContext; + + ProtocolObjects senderProtocolObjects; + ProtocolObjects registerRecieverProtocolObjects; + + public ShootmeSipServletTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + public void deployApplication(Map params) { + SipStandardContext context = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp", + "sip-test", + params, + null, + 1, + null); + assertTrue(context.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/simple/simple-sip-servlet-dar.properties"; + } + + @Override + @Before + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(myPort, containerPort, senderProtocolObjects, true); + senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + registerRecieverProtocolObjects = new ProtocolObjects( + "registerReciever", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int registerPort = NetworkPortAssigner.retrieveNextPort(); + registerReciever = new TestSipListener(registerPort, containerPort, registerRecieverProtocolObjects, true); + SipProvider registerRecieverProvider = registerReciever.createProvider(); + registerRecieverProvider.addSipListener(registerReciever); + registerRecieverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(myPort)); + params.put("registerPort", String.valueOf(registerPort)); + deployApplication(params); + } + + public void testShootme() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + // test non regression for Issue 1687 : Contact Header is present in SIP Message where it shouldn't + Response response = sender.getFinalResponse(); + assertNull(response.getHeader(ContactHeader.NAME)); + assertEquals(1, tomcat.getSipService().getSipApplicationDispatcher().getRequestsProcessedByMethod(Request.INVITE)); + assertEquals(1, tomcat.getSipService().getSipApplicationDispatcher().getRequestsProcessedByMethod(Request.ACK)); + assertEquals(1, tomcat.getSipService().getSipApplicationDispatcher().getRequestsProcessedByMethod(Request.BYE)); + assertEquals(2, tomcat.getSipService().getSipApplicationDispatcher().getResponsesSentByStatusCode("2XX")); + } + + /* + * https://code.google.com/p/sipservlets/issues/detail?id=264 + */ + public void testShootmeColumnInCallIdHeader() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[]{"Call-ID"}, new String[]{"jean:telestax:random:" + UUID.randomUUID() + "@localhost"}, true); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + // test non regression for Issue 1687 : Contact Header is present in SIP Message where it shouldn't + Response response = sender.getFinalResponse(); + assertNull(response.getHeader(ContactHeader.NAME)); + } + + /* + * Non regression test for Issue 2115 http://code.google.com/p/mobicents/issues/detail?id=2115 + * MSS unable to handle GenericURI URIs + */ + public void testShootmeGenericRURI() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + URI toAddress = senderProtocolObjects.addressFactory.createURI("urn:service:sos"); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); + sender.setUseToURIasRequestUri(false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + // test non regression for Issue 1687 : Contact Header is present in SIP Message where it shouldn't + Response response = sender.getFinalResponse(); + assertNull(response.getHeader(ContactHeader.NAME)); + } + + /* + * Non regression test for Issue 2522 http://code.google.com/p/mobicents/issues/detail?id=2522 + * Cloned URI is not modifiable + */ + public void testShootmeCloneURI() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "cloneURI"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertEquals(200, sender.getFinalResponseStatus()); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + } + + public void testShootmeExceptionOnExpirationCount() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + new File("expirationFailure.tmp").delete(); + assertFalse(new File("expirationFailure.tmp").exists()); + String fromName = "exceptionOnExpire"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setSendBye(false); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(150000); + assertFalse(new File("expirationFailure.tmp").exists()); + } + + // Issue 1042 : Trying to simulate the 2 Invites arriving at the same time + public void testShootmeRetransTest() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + Request request = sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + senderProvider.sendRequest(request); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + } + + public void testShootmeParameterable() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[]{"additionalParameterableHeader", "nonParameterableHeader"}, new String[]{"none", "none"}, true); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + } + + /* + * Non regression test for https://code.google.com/p/sipservlets/issues/detail?id=260 + */ + public void testShootmeEventParameterable() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[]{"Event"}, new String[]{"field-value;param1=paramValue1;param2=paramValue2"}, true); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + } + + /** + * Non Regression Test for Issue + * http://code.google.com/p/mobicents/issues/detail?id=2201 + * javax.servlet.sip.ServletParseException: Impossible to parse the + * following header Remote-Party-ID as an address. + */ + public void testShootmeRemotePartyID() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "RemotePartyId"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[]{"Remote-Party-ID", "Remote-Party-ID2", "Remote-Party-ID3", "Remote-Party-ID4", "Remote-Party-ID5"}, new String[]{"\"KATE SMITH\"; party=calling; privacy=off; screen=yes", "sip:4162375543@47.135.223.88;user=phone; party=calling; privacy=off; screen=yes", "; party=calling; privacy=off; screen=yes", "\"KATE SMITH\"; party=calling; privacy=off; screen=yes", "; party=calling; privacy=off; screen=yes"}, true); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + } + + public void testGRUUContactHeader() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "gruuContact"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + Request request = sender.createSipRequest("INVITE", fromAddress, toAddress, null, null, false, new String[]{"Remote-Party-ID", "Remote-Party-ID2", "Remote-Party-ID3", "Remote-Party-ID4", "Remote-Party-ID5"}, new String[]{"\"KATE SMITH\"; party=calling; privacy=off; screen=yes", "sip:4162375543@47.135.223.88;user=phone; party=calling; privacy=off; screen=yes", "; party=calling; privacy=off; screen=yes", "\"KATE SMITH\"; party=calling; privacy=off; screen=yes", "; party=calling; privacy=off; screen=yes"}, toAddress); + + request.setHeader(sender.protocolObjects.headerFactory.createHeader("Contact", ";expires=500;+sip.instance=\"\";gruu=\"sip:100@ocs14.com;opaque=user:epid:xxxxxxxxxxxxxxxxxxxxxxxx;gruu\"")); + + //request.setHeader(sender.protocolObjects.headerFactory.createHeader("Contact", "sip:4162375543@47.135.223.88")); + sender.sendRequet(request); + Thread.sleep(TIMEOUT * 2); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + } + + /** + * non regression test for Issue 1104 + * http://code.google.com/p/mobicents/issues/detail?id=1104 Cannot find the + * corresponding sip session to this subsequent request + * + * In conflict with Issue 1401 + * http://code.google.com/p/mobicents/issues/detail?id=1401 ACK request sent + * by sip client after receiving 488/reINVITE is passed to sip application + * Forbidden by SIP Spec "11.2.2 Receiving ACK" : "Applications are not + * notified of incoming ACKs for non-2xx final responses to INVITE." + * + */ + public void testShootmeErrorResponse() throws Exception { + String fromName = "testErrorResponse"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isFinalResponseReceived()); + assertEquals(486, sender.getFinalResponseStatus()); + assertTrue(!sender.getAllMessagesContent().contains("ackReceived")); + Thread.sleep(DIALOG_TIMEOUT); + List allMessagesContent = sender.getAllMessagesContent(); + assertEquals(2, allMessagesContent.size()); + assertTrue("sipSessionReadyToInvalidate", allMessagesContent.contains("sipSessionReadyToInvalidate")); + assertTrue("sipAppSessionReadyToInvalidate", allMessagesContent.contains("sipAppSessionReadyToInvalidate")); + } + + public void testShootmeCancel() throws Exception { + String fromName = "cancel"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(500); + sender.sendCancel(); + Thread.sleep(TIMEOUT); + assertTrue(sender.isCancelOkReceived()); + assertTrue(sender.isRequestTerminatedReceived()); + Thread.sleep(TIMEOUT); + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertTrue(sender.getAllMessagesContent().contains("cancelReceived")); + assertEquals(1, tomcat.getSipService().getSipApplicationDispatcher().getRequestsProcessedByMethod(Request.INVITE)); + assertEquals(1, tomcat.getSipService().getSipApplicationDispatcher().getRequestsProcessedByMethod(Request.CANCEL)); + assertEquals(1, tomcat.getSipService().getSipApplicationDispatcher().getRequestsProcessedByMethod(Request.ACK)); + assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getResponsesSentByStatusCode("1XX") > 0); + assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getResponsesSentByStatusCode("2XX") > 0); + assertTrue(tomcat.getSipService().getSipApplicationDispatcher().getResponsesSentByStatusCode("4XX") > 0); + } + + public void testShootmeMultipleValueHeaders() throws Exception { + String fromName = "TestAllowHeader"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, fromAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isFinalResponseReceived()); + assertEquals(405, sender.getFinalResponseStatus()); + //Issue 1164 non regression test + ListIterator allowHeaders = (ListIterator) sender.getFinalResponse().getHeaders(AllowHeader.NAME); + assertNotNull(allowHeaders); + List allowHeadersList = new ArrayList(); + while (allowHeaders.hasNext()) { + allowHeadersList.add(allowHeaders.next().getMethod()); + } + assertTrue(Arrays.equals(ALLOW_HEADERS, (String[]) allowHeadersList.toArray(new String[allowHeadersList.size()]))); + } + + // test for http://code.google.com/p/mobicents/issues/detail?id=676 + public void testShootmeToTag() throws Exception { + String fromName = "TestToTag"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, fromAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertEquals(200, sender.getFinalResponseStatus()); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + } + + // test for http://code.google.com/p/mobicents/issues/detail?id=695 + public void testSubscriberURI() throws Exception { + String fromName = "testSubscriberUri"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, fromAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertEquals(200, sender.getFinalResponseStatus()); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + } + + // test for http://code.google.com/p/mobicents/issues/detail?id=1010 + public void testFlagParameter() throws Exception { + String fromName = "testFlagParameter"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, fromAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertEquals(200, sender.getFinalResponseStatus()); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + } + + // test for http://code.google.com/p/mobicents/issues/detail?id=1021 + public void testSessionRetrieval() throws Exception { + String fromName = "testSessionRetrieval"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + fromAddress.setParameter("fromParam", "whatever"); + + sender.sendSipRequest("INVITE", fromAddress, fromAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertEquals(200, sender.getFinalResponseStatus()); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + } + + // test for http://code.google.com/p/mobicents/issues/detail?id=1061 + // Also test http://code.google.com/p/mobicents/issues/detail?id=1681 + public void testNoAckReceived() throws Exception { + String fromName = "noAckReceived"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + sender.setSendAck(false); + sender.setCountRetrans(true); + sender.sendSipRequest("INVITE", fromAddress, fromAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertEquals(200, sender.getFinalResponseStatus()); + assertFalse(sender.isAckSent()); + Thread.sleep(DIALOG_TIMEOUT + TIMEOUT); + // test http://code.google.com/p/mobicents/issues/detail?id=1681 + // Make sure we get the 10 retrans for 200 to INVITE when no ACK is sent + // corresponding to Timer G + List allMessagesContent = sender.getAllMessagesContent(); + assertEquals(1, allMessagesContent.size()); + assertEquals("noAckReceived", allMessagesContent.get(0)); + logger.info("nb retrans received " + sender.getNbRetrans()); + assertTrue(sender.getNbRetrans() >= 9); + } + + // test for http://code.google.com/p/mobicents/issues/detail?id=2427 + public void testShootmeSerializationDeserialization() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "serialization"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + } + + // test for http://code.google.com/p/mobicents/issues/detail?id=2361 + public void testShootmeSystemHeaderModification() throws Exception { + String fromName = "systemHeaderModification"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertEquals(200, sender.getFinalResponseStatus()); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + } + + // test for http://code.google.com/p/mobicents/issues/detail?id=2563 + public void testShootmeFromToHeadersModification() throws Exception { + String fromName = "fromToHeaderModification"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertEquals(200, sender.getFinalResponseStatus()); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + } + + public void testShootmeSessionExpiresParameterable() throws Exception { + String fromName = "testSessionExpiresParameterable"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertEquals(200, sender.getFinalResponseStatus()); + assertTrue(sender.getInviteOkResponse().getHeader(SessionExpiresHeader.NAME).toString().contains("session-param=value")); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + } + + // test for http://code.google.com/p/mobicents/issues/detail?id=2578 + public void testShootmeAuthenticationInfoHeader() throws Exception { + String fromName = "authenticationInfoHeader"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setHandleAuthorization(false); + sender.sendSipRequest("REGISTER", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertEquals(401, sender.getFinalResponseStatus()); + AuthenticationInfoHeader authenticationInfoHeader = (AuthenticationInfoHeader) sender.getFinalResponse().getHeader(AuthenticationInfoHeader.NAME); + assertEquals("Authentication-Info: NTLM rspauth=\"01000000000000005CD422F0C750C7C6\",srand=\"0B9D33A2\",snum=\"1\",opaque=\"BCDC0C9D\",qop=\"auth\",targetname=\"server.contoso.com\",realm=\"SIP Communications Service\"", + authenticationInfoHeader.toString().trim()); + } + + /* + * https://code.google.com/p/sipservlets/issues/detail?id=137 + */ + public void testShootmeResponseGetRemoteAddress() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "locallyGeneratedRemoteAddress"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setSendBye(false); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT * 2); + assertTrue(sender.isAckSent()); + assertTrue(sender.getByeReceived()); + } + + public void testErrorResponseCodeForNonExistingDialog() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiverWithTag"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setSendBye(false); + // This trick is for creating fake dialog at UA for sending sub sequence + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(2000); + sender.sendInDialogSipRequest("INFO", "1", "text", "plain", null, null); + Thread.sleep(100); + assertEquals(481, sender.getFinalResponse().getStatusCode()); + sender.sendBye(); + Thread.sleep(100); + assertTrue(!sender.getOkToByeReceived()); + assertTrue(sender.getFinalResponse().getStatusCode() == 481); + } + + @Override + @After + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + registerRecieverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + Thread.sleep(4000); +// FullThreadDump fullThreadDump = new FullThreadDump("" + System.getProperty("org.mobicents.testsuite.testhostaddr") + "", 1090); +// fullThreadDump.dump(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootmeSipServletTestTcp.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootmeSipServletTestTcp.java index 1868a36e60..eabe00a8b0 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootmeSipServletTestTcp.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootmeSipServletTestTcp.java @@ -1,149 +1,162 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.simple; - -import java.text.ParseException; -import java.util.Iterator; - -import javax.sip.InvalidArgumentException; -import javax.sip.ListeningPoint; -import javax.sip.SipException; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class ShootmeSipServletTestTcp extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(ShootmeSipServletTestTcp.class); - - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 5000; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender; - - ProtocolObjects senderProtocolObjects; - - - public ShootmeSipServletTestTcp(String name) { - super(name); - listeningPointTransport = ListeningPoint.TCP; - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/simple/simple-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", listeningPointTransport, AUTODIALOG, null, null, null); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - } - - public void testShootme() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - } - - - public void testShootmeRegister() throws Exception { - - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - sender.sendSipRequest("REGISTER", fromAddress, fromAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isFinalResponseReceived()); - } - - public void testShootmeCancel() throws Exception { - String fromName = "cancel"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(500); - sender.sendCancel(); - Thread.sleep(TIMEOUT); - assertTrue(sender.isCancelOkReceived()); - assertTrue(sender.isRequestTerminatedReceived()); - Thread.sleep(TIMEOUT); - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertTrue(sender.getAllMessagesContent().contains("cancelReceived")); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.simple; + +import java.text.ParseException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import javax.sip.InvalidArgumentException; +import javax.sip.ListeningPoint; +import javax.sip.SipException; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class ShootmeSipServletTestTcp extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ShootmeSipServletTestTcp.class); + + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 5000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + + ProtocolObjects senderProtocolObjects; + + public ShootmeSipServletTestTcp(String name) { + super(name); + listeningPointTransport = ListeningPoint.TCP; + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + public void deployApplication(Map params) { + SipStandardContext context = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp", + "sip-test", + params, + null); + assertTrue(context.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/simple/simple-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", listeningPointTransport, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(myPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(myPort)); + deployApplication(params); + } + + public void testShootme() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + } + + public void testShootmeRegister() throws Exception { + + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + sender.sendSipRequest("REGISTER", fromAddress, fromAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isFinalResponseReceived()); + } + + public void testShootmeCancel() throws Exception { + String fromName = "cancel"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(500); + sender.sendCancel(); + Thread.sleep(TIMEOUT); + assertTrue(sender.isCancelOkReceived()); + assertTrue(sender.isRequestTerminatedReceived()); + Thread.sleep(TIMEOUT); + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertTrue(sender.getAllMessagesContent().contains("cancelReceived")); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootmeTelURLSipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootmeTelURLSipServletTest.java index ca11a80173..71b4136f90 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootmeTelURLSipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/ShootmeTelURLSipServletTest.java @@ -1,113 +1,125 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.simple; - -import java.text.ParseException; - -import javax.sip.InvalidArgumentException; -import javax.sip.SipException; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; -import javax.sip.address.TelURL; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - - -public class ShootmeTelURLSipServletTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(ShootmeTelURLSipServletTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 5000; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender; - - ProtocolObjects senderProtocolObjects; - - - public ShootmeTelURLSipServletTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/simple/simple-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() { - try { - super.setUp(); - - senderProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070", null, null); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - } catch (Exception ex) { - ex.printStackTrace(); - fail("unexpected exception "); - } - } - - public void testShootme() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - TelURL toAddress = senderProtocolObjects.addressFactory.createTelURL("+358-555-1234567"); - - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.simple; + +import java.text.ParseException; +import java.util.HashMap; +import java.util.Map; + +import javax.sip.InvalidArgumentException; +import javax.sip.SipException; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import javax.sip.address.TelURL; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class ShootmeTelURLSipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ShootmeTelURLSipServletTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 5000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + + ProtocolObjects senderProtocolObjects; + + public ShootmeTelURLSipServletTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + public void deployApplication(Map params) { + SipStandardContext context = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp", + "sip-test", + params, + null); + assertTrue(context.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/simple/simple-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() { + try { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + containerPort, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(myPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(myPort)); + deployApplication(params); + } catch (Exception ex) { + ex.printStackTrace(); + fail("unexpected exception "); + } + } + + public void testShootme() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + TelURL toAddress = senderProtocolObjects.addressFactory.createTelURL("+358-555-1234567"); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, true); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/forking/Proxy.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/forking/Proxy.java index 34913e4ea5..f3a68c35bc 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/forking/Proxy.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/forking/Proxy.java @@ -69,7 +69,7 @@ public class Proxy implements SipListener { private static String host = "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""; - private int port = 5070; + private int port; private SipProvider sipProvider; @@ -88,6 +88,7 @@ public class Proxy implements SipListener { private SipStack sipStack; private int ntargets; + private int[] targetPorts; private void sendTo(ServerTransaction st, Request request, int targetPort) throws Exception { @@ -105,7 +106,7 @@ private void sendTo(ServerTransaction st, Request request, int targetPort) throw ClientTransaction ct1 = sipProvider.getNewClientTransaction(newRequest); sipUri = addressFactory.createSipURI("proxy", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ""); address = addressFactory.createAddress("proxy", sipUri); - sipUri.setPort(5070); + sipUri.setPort(port); sipUri.setLrParam(); RecordRouteHeader recordRoute = headerFactory.createRecordRouteHeader(address); newRequest.addHeader(recordRoute); @@ -132,14 +133,15 @@ public void processRequest(RequestEvent requestEvent) { } for ( int i = 0; i < ntargets; i++ ) { - this.sendTo(st,request,5080 + i); + this.sendTo(st,request, targetPorts[i]); } } else if (request.getMethod().equals(Request.CANCEL)) { - ClientTransaction clientTransaction = ((ClientTransaction)clientTxTable.get(new Integer(5081))); + //assuming 2 targets, take last port + ClientTransaction clientTransaction = ((ClientTransaction)clientTxTable.get(targetPorts[1])); Request cancelRequest = clientTransaction.createCancel(); sipProvider.sendRequest(cancelRequest); @@ -246,9 +248,10 @@ public void processDialogTerminated(DialogTerminatedEvent dialogTerminatedEvent) TestCase.fail("unexpected event"); } - public Proxy(int myPort, int ntargets) { + public Proxy(int myPort, int[] shootmePorts) { this.port = myPort; - this.ntargets = ntargets; + this.ntargets = shootmePorts.length; + targetPorts = shootmePorts; SipObjects sipObjects = new SipObjects(myPort, "proxy","off", true); addressFactory = sipObjects.addressFactory; messageFactory = sipObjects.messageFactory; diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/forking/ShootistSipServletForkingTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/forking/ShootistSipServletForkingTest.java index 8c9ab89f78..09cf5adbee 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/forking/ShootistSipServletForkingTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/forking/ShootistSipServletForkingTest.java @@ -1,173 +1,128 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.simple.forking; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Properties; - -import javax.sip.SipProvider; - -import org.apache.catalina.deploy.ApplicationParameter; -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.catalina.SipStandardService; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; - -public class ShootistSipServletForkingTest extends SipServletTestCase { - private static transient Logger logger = Logger.getLogger(ShootistSipServletForkingTest.class); - private static final int TIMEOUT = 30000; -// private static final int TIMEOUT = 100000000; - - public ShootistSipServletForkingTest(String name) { - super(name); - startTomcatOnStartup = false; - autoDeployOnStartup = false; - addSipConnectorOnStartup = false; - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - public SipStandardContext deployApplication(String name, String value) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(name); - applicationParameter.setValue(value); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - return context; - } - - public SipStandardContext deployApplication(Map params) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - for (Entry param : params.entrySet()) { - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(param.getKey()); - applicationParameter.setValue(param.getValue()); - context.addApplicationParameter(applicationParameter); - } - assertTrue(tomcat.deployContext(context)); - return context; - } - - public SipStandardContext deployApplicationServletListenerTest() { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName("testServletListener"); - applicationParameter.setValue("true"); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - return context; - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/simple/shootist-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - } - - // non regression test for Issue 1468 http://code.google.com/p/mobicents/issues/detail?id=1468 - // Extra 200 class responses to forked INVITE cause Null Pointer Exception - public void testShootistForking() throws Exception { - Shootme shootme1 = new Shootme(5080,true,400*2 - 200*0); - SipProvider shootmeProvider = shootme1.createProvider(); - shootmeProvider.addSipListener(shootme1); - Shootme shootme2 = new Shootme(5081,false,400*2 - 200*1); - SipProvider shootme2Provider = shootme2.createProvider(); - shootme2Provider.addSipListener(shootme2); - Proxy proxy = new Proxy(5070,2); - SipProvider provider = proxy.createSipProvider(); - provider.addSipListener(proxy); - - sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, 5060, listeningPointTransport); - tomcat.startTomcat(); - Map params= new HashMap(); - params.put("route", "sip:" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070"); - params.put("timeToWaitForBye", "20000"); - params.put("dontSetRURI", "true"); - deployApplication(params); - Thread.sleep(TIMEOUT); - proxy.stop(); - shootme1.stop(); - shootme2.stop(); - assertTrue(shootme2.isAckSeen()); - assertTrue(shootme2.checkBye()); - assertTrue(shootme1.isAckSeen()); - assertTrue(shootme1.checkBye()); - } - - @Override - protected Properties getSipStackProperties() { - Properties sipStackProperties = new Properties(); - sipStackProperties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", - "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", - "32"); - sipStackProperties.setProperty(SipStandardService.DEBUG_LOG_STACK_PROP, - tomcatBasePath + "/" + "mss-jsip-" + getName() +"-debug.txt"); - sipStackProperties.setProperty(SipStandardService.SERVER_LOG_STACK_PROP, - tomcatBasePath + "/" + "mss-jsip-" + getName() +"-messages.xml"); - sipStackProperties.setProperty("javax.sip.STACK_NAME", "mss-" + getName()); - sipStackProperties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", "off"); - sipStackProperties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.THREAD_POOL_SIZE", "64"); - sipStackProperties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.MAX_FORK_TIME_SECONDS", "2"); - sipStackProperties.setProperty(SipStandardService.LOOSE_DIALOG_VALIDATION, "true"); - sipStackProperties.setProperty(SipStandardService.PASS_INVITE_NON_2XX_ACK_TO_LISTENER, "true"); - return sipStackProperties; - } - - @Override - protected void tearDown() throws Exception { - logger.info("Test completed"); - super.tearDown(); - } -} \ No newline at end of file +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.simple.forking; + +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import javax.sip.SipProvider; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.catalina.SipStandardService; + +public class ShootistSipServletForkingTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ShootistSipServletForkingTest.class); + private static final int TIMEOUT = 30000; +// private static final int TIMEOUT = 100000000; + + public ShootistSipServletForkingTest(String name) { + super(name); + startTomcatOnStartup = false; + autoDeployOnStartup = false; + addSipConnectorOnStartup = false; + } + + @Override + public void deployApplication() { + assertTrue(tomcat.deployContext( + projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp", + "sip-test-context", "sip-test")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/simple/shootist-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + } + + // non regression test for Issue 1468 http://code.google.com/p/mobicents/issues/detail?id=1468 + // Extra 200 class responses to forked INVITE cause Null Pointer Exception + public void testShootistForking() throws Exception { + int shootme1Port = NetworkPortAssigner.retrieveNextPort(); + Shootme shootme1 = new Shootme(shootme1Port, true, 400 * 2 - 200 * 0); + SipProvider shootmeProvider = shootme1.createProvider(); + shootmeProvider.addSipListener(shootme1); + int shootme2Port = NetworkPortAssigner.retrieveNextPort(); + Shootme shootme2 = new Shootme(shootme2Port, false, 400 * 2 - 200 * 1); + SipProvider shootme2Provider = shootme2.createProvider(); + shootme2Provider.addSipListener(shootme2); + int proxyPort = NetworkPortAssigner.retrieveNextPort(); + Proxy proxy = new Proxy(proxyPort, new int[]{shootme1Port, shootme2Port}); + SipProvider provider = proxy.createSipProvider(); + provider.addSipListener(proxy); + + sipConnector = tomcat.addSipConnector(serverName, sipIpAddress, containerPort, listeningPointTransport); + tomcat.startTomcat(); + Map params = new HashMap(); + params.put("route", "sip:" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + proxyPort); + params.put("timeToWaitForBye", "20000"); + params.put("dontSetRURI", "true"); + deployShootist(params, null); + Thread.sleep(TIMEOUT); + proxy.stop(); + shootme1.stop(); + shootme2.stop(); + assertTrue(shootme2.isAckSeen()); + assertTrue(shootme2.checkBye()); + assertTrue(shootme1.isAckSeen()); + assertTrue(shootme1.checkBye()); + } + + @Override + protected Properties getSipStackProperties() { + Properties sipStackProperties = new Properties(); + sipStackProperties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", + "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", + "32"); + sipStackProperties.setProperty(SipStandardService.DEBUG_LOG_STACK_PROP, + tomcatBasePath + "/" + "mss-jsip-" + getName() + "-debug.txt"); + sipStackProperties.setProperty(SipStandardService.SERVER_LOG_STACK_PROP, + tomcatBasePath + "/" + "mss-jsip-" + getName() + "-messages.xml"); + sipStackProperties.setProperty("javax.sip.STACK_NAME", "mss-" + getName()); + sipStackProperties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", "off"); + sipStackProperties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.THREAD_POOL_SIZE", "64"); + sipStackProperties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.MAX_FORK_TIME_SECONDS", "2"); + sipStackProperties.setProperty(SipStandardService.LOOSE_DIALOG_VALIDATION, "true"); + sipStackProperties.setProperty(SipStandardService.PASS_INVITE_NON_2XX_ACK_TO_LISTENER, "true"); + return sipStackProperties; + } + + @Override + protected void tearDown() throws Exception { + logger.info("Test completed"); + super.tearDown(); + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/forking/Shootme.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/forking/Shootme.java index 96e6adcabc..2cfd84dd19 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/forking/Shootme.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/forking/Shootme.java @@ -93,7 +93,7 @@ public class Shootme implements SipListener { private int delay; - private int ringingDelay; + private int ringingDelay = 0; private boolean sendRinging; @@ -108,11 +108,32 @@ public class Shootme implements SipListener { private static Timer timer = new Timer(); private long waitBeforeFinalResponse = 0; - + private boolean waitForCancel = false; - + private String toTag = null; + class SendRinging extends TimerTask { + Response response; + ServerTransaction serverTx; + + + public SendRinging(ServerTransaction serverTx, Response res) { + logger.info("SendRinging "); + this.response = res; + this.serverTx = serverTx; + } + + public void run() { + try { + serverTx.sendResponse(response); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + } + class MyTimerTask extends TimerTask { RequestEvent requestEvent; String toTag; @@ -163,7 +184,7 @@ public void processResponse(ResponseEvent responseEvent) { */ public void processAck(RequestEvent requestEvent, ServerTransaction serverTransaction) { - logger.info("shootme: got an ACK! "); + logger.info("shootme:(" + myPort + "): got an ACK! "); logger.info("Dialog = " + requestEvent.getDialog()); if(requestEvent.getDialog() != null) { logger.info("Dialog State = " + requestEvent.getDialog().getState()); @@ -180,8 +201,8 @@ public void processInvite(RequestEvent requestEvent, SipProvider sipProvider = (SipProvider) requestEvent.getSource(); Request request = requestEvent.getRequest(); try { - logger.info("shootme: got an Invite sending Trying"); - // logger.info("shootme: " + request); + logger.info("shootme:(" + myPort + "): got an Invite sending Trying"); + // logger.info("shootme:(" + myPort + "): " + request); ServerTransaction st = requestEvent.getServerTransaction(); @@ -217,11 +238,15 @@ public void processInvite(RequestEvent requestEvent, ContactHeader contactHeader = headerFactory.createContactHeader(address); response.addHeader(contactHeader); ToHeader toHeader = (ToHeader) ringingResponse.getHeader(ToHeader.NAME); - String toTag = "" + System.nanoTime(); + String toTag = "" + myPort + "_" + System.nanoTime(); toHeader.setTag(toTag); if ( sendRinging ) { ringingResponse.addHeader(contactHeader); - st.sendResponse(ringingResponse); + if (ringingDelay > 0 ) { + timer.schedule(new SendRinging(st,ringingResponse), this.ringingDelay); + } else { + st.sendResponse(ringingResponse); + } } Dialog dialog = st.getDialog(); dialog.setApplicationData(st); @@ -239,7 +264,7 @@ private void sendInviteOK(RequestEvent requestEvent, ServerTransaction inviteTid try { logger.info("sendInviteOK: " + inviteTid); if (inviteTid.getState() != TransactionState.COMPLETED) { - logger.info("shootme: Dialog state before OK: " + logger.info("shootme:(" + myPort + "): Dialog state before OK: " + inviteTid.getDialog().getState()); SipProvider sipProvider = (SipProvider) requestEvent.getSource(); @@ -267,7 +292,7 @@ private void sendInviteOK(RequestEvent requestEvent, ServerTransaction inviteTid Thread.sleep(waitBeforeFinalResponse); logger.debug("sending back response " + okResponse); inviteTid.sendResponse(okResponse); - logger.info("shootme: Dialog state after OK: " + logger.info("shootme:(" + myPort + "): Dialog state after OK: " + inviteTid.getDialog().getState()); if(!waitForCancel) { // TestCase.assertEquals( DialogState.CONFIRMED , inviteTid.getDialog().getState() ); @@ -287,14 +312,14 @@ public void processBye(RequestEvent requestEvent, ServerTransaction serverTransactionId) { Request request = requestEvent.getRequest(); try { - logger.info("shootme: got a bye sending OK."); - logger.info("shootme: dialog = " + requestEvent.getDialog()); - logger.info("shootme: dialogState = " + requestEvent.getDialog().getState()); + logger.info("shootme:(" + myPort + "): got a bye sending OK."); + logger.info("shootme:(" + myPort + "): dialog = " + requestEvent.getDialog()); + logger.info("shootme:(" + myPort + "): dialogState = " + requestEvent.getDialog().getState()); Response response = messageFactory.createResponse(200, request); if ( serverTransactionId != null) { serverTransactionId.sendResponse(response); } - logger.info("shootme: dialogState = " + requestEvent.getDialog().getState()); + logger.info("shootme:(" + myPort + "): dialogState = " + requestEvent.getDialog().getState()); this.byeSeen = true; @@ -311,7 +336,7 @@ public void processCancel(RequestEvent requestEvent, Request request = requestEvent.getRequest(); SipProvider sipProvider = (SipProvider)requestEvent.getSource(); try { - logger.info("shootme: got a cancel. " ); + logger.info("shootme:(" + myPort + "): got a cancel. " ); // Because this is not an In-dialog request, you will get a null server Tx id here. if (serverTransactionId == null) { serverTransactionId = sipProvider.getNewServerTransaction(request); @@ -369,6 +394,11 @@ public SipProvider createProvider() { } + public Shootme( int myPort, boolean sendRinging, int ringingDelay, int delay ) { + this(myPort, sendRinging, delay); + this.ringingDelay = ringingDelay; + } + public Shootme( int myPort, boolean sendRinging, int delay ) { this.myPort = myPort; this.delay = delay; diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/forking/SipObjects.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/forking/SipObjects.java index c0198babd2..6cf488b017 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/forking/SipObjects.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/forking/SipObjects.java @@ -65,8 +65,8 @@ public SipObjects(int myPort, String stackName, String automaticDialog, boolean // Your code will limp at 32 but it is best for debugging. properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "32"); - String logFile = "logs/" + stackname + ".txt"; - String msgLogFile = "logs/msg-" + stackname + ".xml"; + String logFile = "target/logs/" + stackname + ".txt"; + String msgLogFile = "target/logs/msg-" + stackname + ".xml"; properties.setProperty("gov.nist.javax.sip.MAX_FORK_TIME_SECONDS", "32"); properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", logFile); @@ -81,7 +81,7 @@ public SipObjects(int myPort, String stackName, String automaticDialog, boolean try { // Create SipStack object sipStack = sipFactory.createSipStack(properties); - String logFileDirectory = "logs/"; + String logFileDirectory = "target/logs/"; /* SipFoundryAppender sfa = new SipFoundryAppender(new SipFoundryLayout(), logFileDirectory + "sip" + stackname + ".log"); diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/prack/ShootistPrackSipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/prack/ShootistPrackSipServletTest.java index a95df70a99..5cab479862 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/prack/ShootistPrackSipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/prack/ShootistPrackSipServletTest.java @@ -1,274 +1,232 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.simple.prack; -import java.util.LinkedList; -import java.util.List; - -import javax.sip.SipProvider; - -import org.apache.catalina.deploy.ApplicationParameter; -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class ShootistPrackSipServletTest extends SipServletTestCase { - private static transient Logger logger = Logger.getLogger(ShootistPrackSipServletTest.class); - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; - private static final int DIALOG_TIMEOUT = 40000; -// private static final int TIMEOUT = 100000000; - - TestSipListener receiver; - - ProtocolObjects receiverProtocolObjects; - - public ShootistPrackSipServletTest(String name) { - super(name); - startTomcatOnStartup = false; - autoDeployOnStartup = false; - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - public SipStandardContext deployApplicationPrack() { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName("prack"); - applicationParameter.setValue("true"); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - return context; - } - - public SipStandardContext deployApplicationPrackErrorResponse() { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName("prack"); - applicationParameter.setValue("true"); - context.addApplicationParameter(applicationParameter); - applicationParameter = new ApplicationParameter(); - applicationParameter.setName("testErrorResponse"); - applicationParameter.setValue("true"); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - return context; - } - - public SipStandardContext deployApplicationPrackCancel() { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName("prack"); - applicationParameter.setValue("true"); - context.addApplicationParameter(applicationParameter); - applicationParameter = new ApplicationParameter(); - applicationParameter.setName("cancel"); - applicationParameter.setValue("true"); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - return context; - } - - public SipStandardContext deployApplicationPrackRoute() { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName("prack"); - applicationParameter.setValue("true"); - context.addApplicationParameter(applicationParameter); - applicationParameter = new ApplicationParameter(); - applicationParameter.setName("route"); - applicationParameter.setValue("sip:127.0.0.1:5080"); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - return context; - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/simple/shootist-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - } - - public void testShootistPrack() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - deployApplicationPrack(); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isPrackReceived()); - assertTrue(receiver.getByeReceived()); - } - - public void testShootistPrackEarlyMediaChange() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - receiver.setTimeToWaitBeforeBye(DIALOG_TIMEOUT); - LinkedList responses = new LinkedList(); - responses.add(180); - responses.add(180); - responses.add(183); - responses.add(183); - responses.add(183); - receiver.setProvisionalResponsesToSend(responses); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - deployApplicationPrackErrorResponse(); - Thread.sleep(DIALOG_TIMEOUT + TIMEOUT); - assertTrue(receiver.isPrackReceived()); - List allMessagesContent = receiver.getAllMessagesContent(); - - assertNotNull(receiver.getMessageRequest()); - assertTrue("earlyMedia", receiver.getMessageRequest().getHeader("EarlyMediaResponses").toString().contains("3")); - assertTrue("earlyMedia", receiver.getMessageRequest().getHeader("EarlyMedia180Responses").toString().contains("2")); - assertTrue(allMessagesContent.size() >= 2); - assertTrue("sipSessionReadyToInvalidate", allMessagesContent.contains("sipSessionReadyToInvalidate")); - assertTrue("sipAppSessionReadyToInvalidate", allMessagesContent.contains("sipAppSessionReadyToInvalidate")); - } - - public void testShootistPrackIsAnyLocalAddress() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.removeConnector(sipConnector); - sipIpAddress = "0.0.0.0"; - tomcat.addSipConnector(serverName, sipIpAddress, 5070, listeningPointTransport); - tomcat.startTomcat(); - deployApplicationPrack(); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isPrackReceived()); - assertTrue(receiver.getByeReceived()); - } - - public void testShootistPrackCancel() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - deployApplicationPrackCancel(); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isPrackReceived()); - assertTrue(receiver.isCancelReceived()); - } - - public void testShootistPrackCallerSendsBye() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, true); - SipProvider senderProvider = receiver.createProvider(); - senderProvider.addSipListener(receiver); - receiverProtocolObjects.start(); - tomcat.startTomcat(); - deployApplicationPrack(); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getOkToByeReceived()); - } - - public void testShootistPrackCallerTestRoute() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, true); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - receiver.setAddRecordRouteForResponses(true); - receiverProtocolObjects.start(); - tomcat.startTomcat(); - deployApplicationPrackRoute(); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getOkToByeReceived()); - } - - @Override - protected void tearDown() throws Exception { - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } -} \ No newline at end of file +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.simple.prack; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import javax.sip.SipProvider; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class ShootistPrackSipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ShootistPrackSipServletTest.class); + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; + private static final int DIALOG_TIMEOUT = 40000; +// private static final int TIMEOUT = 100000000; + + TestSipListener receiver; + + ProtocolObjects receiverProtocolObjects; + + public ShootistPrackSipServletTest(String name) { + super(name); + startTomcatOnStartup = false; + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + assertTrue(tomcat.deployContext( + projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp", + "sip-test-context", "sip-test")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/simple/shootist-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + } + + public void testShootistPrack() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("prack", "true"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isPrackReceived()); + assertTrue(receiver.getByeReceived()); + } + + public void testShootistPrackEarlyMediaChange() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("prack", "true"); + ctxAtts.put("testErrorResponse", "true"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + receiver.setTimeToWaitBeforeBye(DIALOG_TIMEOUT); + LinkedList responses = new LinkedList(); + responses.add(180); + responses.add(180); + responses.add(183); + responses.add(183); + responses.add(183); + receiver.setProvisionalResponsesToSend(responses); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(DIALOG_TIMEOUT + TIMEOUT); + assertTrue(receiver.isPrackReceived()); + List allMessagesContent = receiver.getAllMessagesContent(); + + assertNotNull(receiver.getMessageRequest()); + assertTrue("earlyMedia", receiver.getMessageRequest().getHeader("EarlyMediaResponses").toString().contains("3")); + assertTrue("earlyMedia", receiver.getMessageRequest().getHeader("EarlyMedia180Responses").toString().contains("2")); + assertTrue(allMessagesContent.size() >= 2); + assertTrue("sipSessionReadyToInvalidate", allMessagesContent.contains("sipSessionReadyToInvalidate")); + assertTrue("sipAppSessionReadyToInvalidate", allMessagesContent.contains("sipAppSessionReadyToInvalidate")); + } + + public void testShootistPrackIsAnyLocalAddress() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("prack", "true"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.removeConnector(sipConnector); + sipIpAddress = "0.0.0.0"; + tomcat.addSipConnector(serverName, sipIpAddress, containerPort, listeningPointTransport); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isPrackReceived()); + assertTrue(receiver.getByeReceived()); + } + + public void testShootistPrackCancel() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("prack", "true"); + ctxAtts.put("cancel", "true"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isPrackReceived()); + assertTrue(receiver.isCancelReceived()); + } + + public void testShootistPrackCallerSendsBye() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("prack", "true"); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, true); + SipProvider senderProvider = receiver.createProvider(); + senderProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getOkToByeReceived()); + } + + public void testShootistPrackCallerTestRoute() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int myPort = NetworkPortAssigner.retrieveNextPort(); + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("prack", "true"); + ctxAtts.put("route", "sip:127.0.0.1:" + myPort); + receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, true); + SipProvider senderProvider = receiver.createProvider(); + + senderProvider.addSipListener(receiver); + receiver.setAddRecordRouteForResponses(true); + receiverProtocolObjects.start(); + tomcat.startTomcat(); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getOkToByeReceived()); + } + + @Override + protected void tearDown() throws Exception { + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/prack/ShootmePrackSipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/prack/ShootmePrackSipServletTest.java index 0d7e6a0ed3..177c21e2aa 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/prack/ShootmePrackSipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/prack/ShootmePrackSipServletTest.java @@ -1,258 +1,273 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.simple.prack; - -import gov.nist.javax.sip.header.SIPHeader; - -import java.text.ParseException; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; - -import javax.sip.InvalidArgumentException; -import javax.sip.SipException; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class ShootmePrackSipServletTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(ShootmePrackSipServletTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 20000; -// private static final int TIMEOUT = 100000000; - private static final int TIMEOUT_CSEQ_INCREASE = 100000; - - - TestSipListener sender; - SipProvider senderProvider = null; - ProtocolObjects senderProtocolObjects; - -// TestSipListener registerReciever; -// ProtocolObjects registerRecieverProtocolObjects; - - public ShootmePrackSipServletTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/simple/simple-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, "4", "true"); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - senderProvider = sender.createProvider(); - senderProvider.addSipListener(sender); - senderProtocolObjects.start(); - - -// registerRecieverProtocolObjects =new ProtocolObjects( -// "registerReciever", "gov.nist", TRANSPORT, AUTODIALOG, null); -// registerReciever = new TestSipListener(5058, 5070, registerRecieverProtocolObjects, true); -// SipProvider registerRecieverProvider = registerReciever.createProvider(); -// registerRecieverProvider.addSipListener(registerReciever); -// registerRecieverProtocolObjects.start(); - } - - public void testShootmePrack() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "prack"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - String[] headerNames = new String[]{"require"}; - String[] headerValues = new String[]{"100rel"}; - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, headerNames, headerValues, true); - Thread.sleep(TIMEOUT); - assertTrue(sender.isPrackSent()); - assertTrue(sender.isOkToPrackReceived()); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - } - - public void testShootmePrackAckReceivedTwice() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "prack-test2xACK"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - String[] headerNames = new String[]{"require"}; - String[] headerValues = new String[]{"100rel"}; - - sender.setSendBye(false); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, headerNames, headerValues, false); - sender.setTimeToWaitBeforeAck(1000); - Thread.sleep(TIMEOUT); - assertTrue(sender.isPrackSent()); - assertTrue(sender.isOkToPrackReceived()); - assertTrue(sender.isAckSent()); - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertEquals(1, sender.getAllMessagesContent().size()); -// assertTrue(sender.getOkToByeReceived()); - - } - - // non regression test for Issue 1552 http://code.google.com/p/mobicents/issues/detail?id=1552 - // Container does not recognise 100rel if there are other extensions on the Require or Supported line - public void testShootmePrackMultipleRequire() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "prack"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - String[] headerNames = new String[]{"Require", "Require"}; - String[] headerValues = new String[]{"timer", "100rel"}; - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, headerNames, headerValues, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isPrackSent()); - assertTrue(sender.isOkToPrackReceived()); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - } - - // non regression test for Issue 1564 : http://code.google.com/p/mobicents/issues/detail?id=1564 - // Send reliably can add a duplicate 100rel to the requires line - public void testShootmePrackRequirePresent() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "prack-require-present"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - String[] headerNames = new String[]{"Require"}; - String[] headerValues = new String[]{"100rel"}; - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, headerNames, headerValues, true); - Thread.sleep(TIMEOUT); - assertTrue(sender.isPrackSent()); - assertTrue(sender.isOkToPrackReceived()); - ListIterator iterator = sender.getInformationalResponse().getHeaders("Require"); - int nbRequire = 0; - while (iterator.hasNext()) { - SIPHeader sipHeader = iterator.next(); - nbRequire++; - } - assertEquals(1, nbRequire); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - } - - public void testShootmePrackReinvite() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "prackisendreinvite"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - String[] headerNames = new String[]{"require"}; - String[] headerValues = new String[]{"100rel"}; - - sender.setSendReinvite(true); - sender.setSendBye(true); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, headerNames, headerValues, true); - Thread.sleep(TIMEOUT); - assertTrue(sender.isPrackSent()); - assertTrue(sender.isOkToPrackReceived()); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - } - - public void xxxtestNoPrackReceived() throws Exception { - String fromName = "noAckReceived"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String[] headerNames = new String[]{"require"}; - String[] headerValues = new String[]{"100rel"}; - - sender.sendSipRequest("INVITE", fromAddress, fromAddress, null, null, false, headerNames, headerValues, true); - sender.setSendAck(false); - Thread.sleep(TIMEOUT); - assertEquals( 200, sender.getFinalResponseStatus()); - assertFalse(sender.isAckSent()); - Thread.sleep(TIMEOUT_CSEQ_INCREASE); - List allMessagesContent = sender.getAllMessagesContent(); - assertEquals(1,allMessagesContent.size()); - assertEquals("noAckReceived", allMessagesContent.get(0)); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); -// registerRecieverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.simple.prack; + +import gov.nist.javax.sip.header.SIPHeader; + +import java.text.ParseException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; + +import javax.sip.InvalidArgumentException; +import javax.sip.SipException; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class ShootmePrackSipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ShootmePrackSipServletTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 20000; +// private static final int TIMEOUT = 100000000; + private static final int TIMEOUT_CSEQ_INCREASE = 100000; + + TestSipListener sender; + SipProvider senderProvider = null; + ProtocolObjects senderProtocolObjects; + +// TestSipListener registerReciever; +// ProtocolObjects registerRecieverProtocolObjects; + public ShootmePrackSipServletTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + public void deployApplication(Map params) { + SipStandardContext context = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp", + "sip-test", + params, + null, + 1, + null); + assertTrue(context.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/simple/simple-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, "4", "true"); + int myPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(myPort, containerPort, senderProtocolObjects, true); + senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + +// registerRecieverProtocolObjects =new ProtocolObjects( +// "registerReciever", "gov.nist", TRANSPORT, AUTODIALOG, null); +// registerReciever = new TestSipListener(5058, 5070, registerRecieverProtocolObjects, true); +// SipProvider registerRecieverProvider = registerReciever.createProvider(); +// registerRecieverProvider.addSipListener(registerReciever); +// registerRecieverProtocolObjects.start(); + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(myPort)); + deployApplication(params); + } + + public void testShootmePrack() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "prack"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + String[] headerNames = new String[]{"require"}; + String[] headerValues = new String[]{"100rel"}; + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, headerNames, headerValues, true); + Thread.sleep(TIMEOUT); + assertTrue(sender.isPrackSent()); + assertTrue(sender.isOkToPrackReceived()); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + } + + public void testShootmePrackAckReceivedTwice() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "prack-test2xACK"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + String[] headerNames = new String[]{"require"}; + String[] headerValues = new String[]{"100rel"}; + + sender.setSendBye(false); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, headerNames, headerValues, false); + sender.setTimeToWaitBeforeAck(1000); + Thread.sleep(TIMEOUT); + assertTrue(sender.isPrackSent()); + assertTrue(sender.isOkToPrackReceived()); + assertTrue(sender.isAckSent()); + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertEquals(1, sender.getAllMessagesContent().size()); +// assertTrue(sender.getOkToByeReceived()); + + } + + // non regression test for Issue 1552 http://code.google.com/p/mobicents/issues/detail?id=1552 + // Container does not recognise 100rel if there are other extensions on the Require or Supported line + public void testShootmePrackMultipleRequire() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "prack"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + String[] headerNames = new String[]{"Require", "Require"}; + String[] headerValues = new String[]{"timer", "100rel"}; + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, headerNames, headerValues, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isPrackSent()); + assertTrue(sender.isOkToPrackReceived()); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + } + + // non regression test for Issue 1564 : http://code.google.com/p/mobicents/issues/detail?id=1564 + // Send reliably can add a duplicate 100rel to the requires line + public void testShootmePrackRequirePresent() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "prack-require-present"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + String[] headerNames = new String[]{"Require"}; + String[] headerValues = new String[]{"100rel"}; + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, headerNames, headerValues, true); + Thread.sleep(TIMEOUT); + assertTrue(sender.isPrackSent()); + assertTrue(sender.isOkToPrackReceived()); + ListIterator iterator = sender.getInformationalResponse().getHeaders("Require"); + int nbRequire = 0; + while (iterator.hasNext()) { + SIPHeader sipHeader = iterator.next(); + nbRequire++; + } + assertEquals(1, nbRequire); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + } + + public void testShootmePrackReinvite() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "prackisendreinvite"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + String[] headerNames = new String[]{"require"}; + String[] headerValues = new String[]{"100rel"}; + + sender.setSendReinvite(true); + sender.setSendBye(true); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, headerNames, headerValues, true); + Thread.sleep(TIMEOUT); + assertTrue(sender.isPrackSent()); + assertTrue(sender.isOkToPrackReceived()); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + } + + public void xxxtestNoPrackReceived() throws Exception { + String fromName = "noAckReceived"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String[] headerNames = new String[]{"require"}; + String[] headerValues = new String[]{"100rel"}; + + sender.sendSipRequest("INVITE", fromAddress, fromAddress, null, null, false, headerNames, headerValues, true); + sender.setSendAck(false); + Thread.sleep(TIMEOUT); + assertEquals(200, sender.getFinalResponseStatus()); + assertFalse(sender.isAckSent()); + Thread.sleep(TIMEOUT_CSEQ_INCREASE); + List allMessagesContent = sender.getAllMessagesContent(); + assertEquals(1, allMessagesContent.size()); + assertEquals("noAckReceived", allMessagesContent.get(0)); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); +// registerRecieverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/rfc3263/ShootistSipServletRFC3263Test.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/rfc3263/ShootistSipServletRFC3263Test.java index 46a585665b..1b04bb2789 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/rfc3263/ShootistSipServletRFC3263Test.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/rfc3263/ShootistSipServletRFC3263Test.java @@ -1,597 +1,570 @@ -/* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2014, Telestax Inc and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - */ -package org.mobicents.servlet.sip.testsuite.simple.rfc3263; - -import gov.nist.javax.sip.stack.HopImpl; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Queue; -import java.util.Set; -import java.util.concurrent.ConcurrentLinkedQueue; - -import javax.sip.ListeningPoint; -import javax.sip.SipProvider; -import javax.sip.address.Hop; -import javax.sip.header.ContactHeader; -import javax.sip.header.RouteHeader; -import javax.sip.message.Response; - -import org.apache.catalina.deploy.ApplicationParameter; -import org.apache.log4j.Logger; -import org.mobicents.ext.javax.sip.dns.DNSLookupPerformer; -import org.mobicents.ext.javax.sip.dns.DefaultDNSLookupPerformer; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.catalina.SipStandardService; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; -import org.mobicents.servlet.sip.testsuite.simple.ShootistSipServletTest; -import org.xbill.DNS.DClass; -import org.xbill.DNS.NAPTRRecord; -import org.xbill.DNS.Name; -import org.xbill.DNS.Record; -import org.xbill.DNS.SRVRecord; -import org.xbill.DNS.TextParseException; - -public class ShootistSipServletRFC3263Test extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(ShootistSipServletRFC3263Test.class); - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 80000; - private static final int DIALOG_TIMEOUT = 40000; -// private static final int TIMEOUT = 100000000; - - TestSipListener receiver; - ProtocolObjects receiverProtocolObjects; - - TestSipListener badReceiver; - ProtocolObjects badReceiverProtocolObjects; - - TestSipListener badReceiver2; - ProtocolObjects badReceiver2ProtocolObjects; - - TestSipListener badReceiver3; - ProtocolObjects badReceiver3ProtocolObjects; - - public ShootistSipServletRFC3263Test(String name) { - super(name); - startTomcatOnStartup = false; - autoDeployOnStartup = false; - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - public SipStandardContext deployApplication(String name, String value) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(name); - applicationParameter.setValue(value); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - return context; - } - - public SipStandardContext deployApplication(Map params) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - for (Entry param : params.entrySet()) { - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(param.getKey()); - applicationParameter.setValue(param.getValue()); - context.addApplicationParameter(applicationParameter); - } - assertTrue(tomcat.deployContext(context)); - return context; - } - - public SipStandardContext deployApplicationServletListenerTest() { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName("testServletListener"); - applicationParameter.setValue("true"); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - return context; - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/simple/shootist-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - System.setProperty("javax.net.ssl.keyStore", ShootistSipServletTest.class.getResource("testkeys").getPath()); - System.setProperty("javax.net.ssl.trustStore", ShootistSipServletTest.class.getResource("testkeys").getPath()); - System.setProperty("javax.net.ssl.keyStorePassword", "passphrase"); - System.setProperty("javax.net.ssl.keyStoreType", "jks"); - super.setUp(); - } - - /* - * Making sure the procedures of retrying the next hop of RFC 3263 are working - */ - public void testShootist() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects = new ProtocolObjects( - "receiver", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - receiverProvider.addSipListener(receiver); - receiverProtocolObjects.start(); - - badReceiverProtocolObjects = new ProtocolObjects( - "bad-receiver", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - badReceiver = new TestSipListener(5081, 5070, badReceiverProtocolObjects, false); - SipProvider badReceiverProvider = badReceiver.createProvider(); - badReceiverProvider.addSipListener(badReceiver); - badReceiverProtocolObjects.start(); - badReceiver.setDropRequest(true); - String host = "mobicents.org"; - - tomcat.startTomcat(); - - mockDNSLookup(host, "udp"); - - deployApplication("host", host); - Thread.sleep(TIMEOUT); - assertNotNull(receiver.getInviteRequest()); - RouteHeader routeHeader = (RouteHeader) receiver.getInviteRequest().getHeader(RouteHeader.NAME); - assertNull(routeHeader); - assertFalse(badReceiver.getByeReceived()); - assertTrue(receiver.getByeReceived()); - } - - /* - * Non Regression test for Issue http://code.google.com/p/mobicents/issues/detail?id=3140 - */ - public void testShootistTLSwithTLSConnector() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects = new ProtocolObjects( - "receiver", "gov.nist", ListeningPoint.TLS, AUTODIALOG, null, null, null); - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - receiverProvider.addSipListener(receiver); - receiverProtocolObjects.start(); - - badReceiverProtocolObjects = new ProtocolObjects( - "bad-receiver", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - badReceiver = new TestSipListener(5081, 5070, badReceiverProtocolObjects, false); - SipProvider badReceiverProvider = badReceiver.createProvider(); - badReceiverProvider.addSipListener(badReceiver); - badReceiverProtocolObjects.start(); - badReceiver.setDropRequest(true); - String host = "mobicents.org"; - - tomcat.startTomcat(); - tomcat.removeConnector(sipConnector); - tomcat.addSipConnector(serverName, sipIpAddress, 5071, ListeningPoint.TLS); - - mockDNSLookup(host, "tls"); - - Map params = new HashMap(); - params.put("host", host); - params.put("method", "REGISTER"); - params.put("secureRURI", "true"); - deployApplication(params); - - Thread.sleep(TIMEOUT); - assertNotNull(receiver.getRegisterReceived()); - RouteHeader routeHeader = (RouteHeader) receiver.getRegisterReceived().getHeader(RouteHeader.NAME); - assertNull(routeHeader); - assertNull(receiver.getRegisterReceived().getHeader(ContactHeader.NAME)); - } - - /* - * Non Regression test for Issue http://code.google.com/p/mobicents/issues/detail?id=3140 - */ - public void testShootistTLSwithTCPConnector() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects = new ProtocolObjects( - "receiver", "gov.nist", ListeningPoint.TCP, AUTODIALOG, null, null, null); - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - receiverProvider.addSipListener(receiver); - receiverProtocolObjects.start(); - - badReceiverProtocolObjects = new ProtocolObjects( - "bad-receiver", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - badReceiver = new TestSipListener(5081, 5070, badReceiverProtocolObjects, false); - SipProvider badReceiverProvider = badReceiver.createProvider(); - badReceiverProvider.addSipListener(badReceiver); - badReceiverProtocolObjects.start(); - badReceiver.setDropRequest(true); - String host = "mobicents.org"; - - tomcat.startTomcat(); - tomcat.removeConnector(sipConnector); - tomcat.addSipConnector(serverName, sipIpAddress, 5070, ListeningPoint.TCP); - - mockDNSLookup(host, "tcp"); - - Map params = new HashMap(); - params.put("host", host); - params.put("method", "REGISTER"); - params.put("secureRURI", "true"); - deployApplication(params); - - Thread.sleep(TIMEOUT); - RouteHeader routeHeader = (RouteHeader) receiver.getRegisterReceived().getHeader(RouteHeader.NAME); - assertNull(routeHeader); - assertNull(receiver.getRegisterReceived().getHeader(ContactHeader.NAME)); - } - - /* - * Non Regression test for Issue https://code.google.com/p/sipservlets/issues/detail?id=250 - */ - public void testShootistTCP() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects = new ProtocolObjects( - "receiver", "gov.nist", ListeningPoint.TCP, AUTODIALOG, null, null, null); - receiver = new TestSipListener(5081, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - receiverProvider.addSipListener(receiver); - receiverProtocolObjects.start(); - - badReceiverProtocolObjects = new ProtocolObjects( - "bad-receiver", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - badReceiver = new TestSipListener(5080, 5070, badReceiverProtocolObjects, false); - SipProvider badReceiverProvider = badReceiver.createProvider(); - badReceiverProvider.addSipListener(badReceiver); - badReceiverProtocolObjects.start(); - badReceiver.setDropRequest(true); - String host = "mobicents.org"; - - tomcat.startTomcat(); - tomcat.removeConnector(sipConnector); - tomcat.addSipConnector(serverName, sipIpAddress, 5070, ListeningPoint.TCP); - - mockDNSLookupTCP(host); - - Map params = new HashMap(); - params.put("host", host); - params.put("method", "REGISTER"); - params.put("route", "sip:mobicents.org;transport=tcp"); - deployApplication(params); - - Thread.sleep(TIMEOUT); - assertNotNull(receiver.getRegisterReceived()); - RouteHeader routeHeader = (RouteHeader) receiver.getRegisterReceived().getHeader(RouteHeader.NAME); - assertNull(routeHeader); - assertNull(receiver.getRegisterReceived().getHeader(ContactHeader.NAME)); - } - - /* - * Non Regression test for Issue http://code.google.com/p/mobicents/issues/detail?id=2346 - */ - public void testShootistRouteCheck() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects = new ProtocolObjects( - "receiver", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - receiverProvider.addSipListener(receiver); - receiverProtocolObjects.start(); - - String host = "mobicents.org"; - - tomcat.startTomcat(); - - Map params = new HashMap(); - params.put("host", host); - params.put("route", "sip:" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080;lr"); - deployApplication(params); - - Thread.sleep(TIMEOUT / 4); - ListIterator routeHeaders = receiver.getInviteRequest().getHeaders(RouteHeader.NAME); - assertNotNull(routeHeaders); - RouteHeader routeHeader = routeHeaders.next(); - assertFalse(routeHeaders.hasNext()); - assertEquals("sip:" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5080;lr", routeHeader.getAddress().getURI().toString()); - assertTrue(receiver.getByeReceived()); - } - - private void mockDNSLookup(String host, String transport) throws TextParseException { - DNSLookupPerformer dnsLookupPerformer = mock(DefaultDNSLookupPerformer.class); - //mocking the DNS Lookups to match our test cases - tomcat.getSipService().getSipApplicationDispatcher().getDNSServerLocator().setDnsLookupPerformer(dnsLookupPerformer); - - Set supportedTransports = new HashSet(); - supportedTransports.add(TRANSPORT.toUpperCase()); - supportedTransports.add(ListeningPoint.TCP.toUpperCase()); - supportedTransports.add(ListeningPoint.TLS.toUpperCase()); - - Queue hops = new ConcurrentLinkedQueue(); - hops = new ConcurrentLinkedQueue(); - //dont use "localhost" or DNS will not work (wouldnt be external) - hops.add(new HopImpl("127.0.0.1", 5080, transport)); - when(dnsLookupPerformer.locateHopsForNonNumericAddressWithPort("localhost", 5080, transport)).thenReturn(hops); - when(dnsLookupPerformer.locateHopsForNonNumericAddressWithPort("localhost", 5082, transport)).thenReturn(null); - when(dnsLookupPerformer.locateHopsForNonNumericAddressWithPort("localhost", 5081, transport)).thenReturn(null); - - List mockedNAPTRRecords = new LinkedList(); - // mocking the name because localhost is not absolute and localhost. cannot be resolved - Name name = mock(Name.class); - when(name.isAbsolute()).thenReturn(true); - when(name.toString()).thenReturn("localhost"); - mockedNAPTRRecords.add(new NAPTRRecord(new Name(host + "."), DClass.IN, 1000, 0, 0, "s", "SIP+D2U", "", new Name("_sip._" + TRANSPORT.toLowerCase() + "." + host + "."))); - when(dnsLookupPerformer.performNAPTRLookup(host, false, supportedTransports)).thenReturn(mockedNAPTRRecords); - List mockedSRVRecords = new LinkedList(); - mockedSRVRecords.add(new SRVRecord(new Name("_sip._" + TRANSPORT.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 1, 0, 5080, name)); - mockedSRVRecords.add(new SRVRecord(new Name("_sip._" + TRANSPORT.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 0, 0, 5081, name)); - when(dnsLookupPerformer.performSRVLookup("_sip._" + TRANSPORT.toLowerCase() + "." + host)).thenReturn(mockedSRVRecords); - List mockedSRVTCPRecords = new LinkedList(); - mockedSRVTCPRecords.add(new SRVRecord(new Name("_sips._" + ListeningPoint.TCP.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 1, 0, 5080, name)); - mockedSRVTCPRecords.add(new SRVRecord(new Name("_sips._" + ListeningPoint.TCP.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 0, 0, 5081, name)); -// mockedSRVTLSRecords.add(new SRVRecord(new Name("_sips._" + ListeningPoint.TLS.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 1, 0, 5081, name)); - when(dnsLookupPerformer.performSRVLookup("_sips._" + ListeningPoint.TCP.toLowerCase() + "." + host)).thenReturn(mockedSRVTCPRecords); - - List mockedSRVTLSRecords = new LinkedList(); - mockedSRVTLSRecords.add(new SRVRecord(new Name("_sips._" + ListeningPoint.TCP.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 1, 0, 5080, name)); - mockedSRVTLSRecords.add(new SRVRecord(new Name("_sips._" + ListeningPoint.TCP.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 0, 0, 5081, name)); -// mockedSRVTLSRecords.add(new SRVRecord(new Name("_sips._" + ListeningPoint.TLS.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 1, 0, 5081, name)); - when(dnsLookupPerformer.performSRVLookup("_sips._" + ListeningPoint.TLS.toLowerCase() + "." + host)).thenReturn(mockedSRVTLSRecords); - } - - private void mockDNSLookupTCP(String host) throws TextParseException { - DNSLookupPerformer dnsLookupPerformer = mock(DefaultDNSLookupPerformer.class); - //mocking the DNS Lookups to match our test cases - tomcat.getSipService().getSipApplicationDispatcher().getDNSServerLocator().setDnsLookupPerformer(dnsLookupPerformer); - - Set supportedTransports = new HashSet(); - supportedTransports.add(TRANSPORT.toUpperCase()); - supportedTransports.add(ListeningPoint.TCP.toUpperCase()); - - List mockedNAPTRRecords = new LinkedList(); - // mocking the name because localhost is not absolute and localhost. cannot be resolved - Name name = mock(Name.class); - when(name.isAbsolute()).thenReturn(true); - when(name.toString()).thenReturn("localhost"); - mockedNAPTRRecords.add(new NAPTRRecord(new Name(host + "."), DClass.IN, 1000, 0, 0, "s", "SIP+D2T", "", new Name("_sip._" + ListeningPoint.TCP.toLowerCase() + "." + host + "."))); - when(dnsLookupPerformer.performNAPTRLookup(host, false, supportedTransports)).thenReturn(mockedNAPTRRecords); - - Queue hops = new ConcurrentLinkedQueue(); - hops = new ConcurrentLinkedQueue(); - //dont use "localhost" or DNS will not work (wouldnt be external) - hops.add(new HopImpl("127.0.0.1", 5081, "tcp")); - when(dnsLookupPerformer.locateHopsForNonNumericAddressWithPort("localhost", 5080, "tcp")).thenReturn(null); - when(dnsLookupPerformer.locateHopsForNonNumericAddressWithPort("localhost", 5082, "tcp")).thenReturn(null); - when(dnsLookupPerformer.locateHopsForNonNumericAddressWithPort("localhost", 5081, "tcp")).thenReturn(hops); - - List mockedSRVTCPRecords = new LinkedList(); - mockedSRVTCPRecords.add(new SRVRecord(new Name("_sip._" + ListeningPoint.TCP.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 0, 0, 5080, name)); - mockedSRVTCPRecords.add(new SRVRecord(new Name("_sip._" + ListeningPoint.TCP.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 2, 0, 5081, name)); - mockedSRVTCPRecords.add(new SRVRecord(new Name("_sip._" + ListeningPoint.TCP.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 1, 0, 5082, name)); - when(dnsLookupPerformer.performSRVLookup("_sip._" + ListeningPoint.TCP.toLowerCase() + "." + host)).thenReturn(mockedSRVTCPRecords); - } - - private void mockDNSLookup4Records(String host) throws TextParseException { - DNSLookupPerformer dnsLookupPerformer = mock(DefaultDNSLookupPerformer.class); - //mocking the DNS Lookups to match our test cases - tomcat.getSipService().getSipApplicationDispatcher().getDNSServerLocator().setDnsLookupPerformer(dnsLookupPerformer); - - Set supportedTransports = new HashSet(); - supportedTransports.add(TRANSPORT.toUpperCase()); - supportedTransports.add(ListeningPoint.TCP.toUpperCase()); - supportedTransports.add(ListeningPoint.TLS.toUpperCase()); - - Queue hops = new ConcurrentLinkedQueue(); - hops = new ConcurrentLinkedQueue(); - //dont use "localhost" or DNS will not work (wouldnt be external) - hops.add(new HopImpl("127.0.0.1", 5080, TRANSPORT.toLowerCase())); - when(dnsLookupPerformer.locateHopsForNonNumericAddressWithPort("localhost", 5080, TRANSPORT.toLowerCase())).thenReturn(hops); - hops = new ConcurrentLinkedQueue(); - //dont use "localhost" or DNS will not work (wouldnt be external) - hops.add(new HopImpl("127.0.0.1", 5081, TRANSPORT.toLowerCase())); - when(dnsLookupPerformer.locateHopsForNonNumericAddressWithPort("localhost", 5081, TRANSPORT.toLowerCase())).thenReturn(hops); - hops = new ConcurrentLinkedQueue(); - //dont use "localhost" or DNS will not work (wouldnt be external) - hops.add(new HopImpl("127.0.0.1", 5082, TRANSPORT.toLowerCase())); - when(dnsLookupPerformer.locateHopsForNonNumericAddressWithPort("localhost", 5082, TRANSPORT.toLowerCase())).thenReturn(hops); - hops = new ConcurrentLinkedQueue(); - //dont use "localhost" or DNS will not work (wouldnt be external) - hops.add(new HopImpl("127.0.0.1", 5083, TRANSPORT.toLowerCase())); - when(dnsLookupPerformer.locateHopsForNonNumericAddressWithPort("localhost", 5083, TRANSPORT.toLowerCase())).thenReturn(hops); - - List mockedNAPTRRecords = new LinkedList(); - // mocking the name because localhost is not absolute and localhost. cannot be resolved - Name name = mock(Name.class); - when(name.isAbsolute()).thenReturn(true); - when(name.toString()).thenReturn("localhost"); - mockedNAPTRRecords.add(new NAPTRRecord(new Name(host + "."), DClass.IN, 1000, 0, 0, "s", "SIP+D2U", "", new Name("_sip._" + TRANSPORT.toLowerCase() + "." + host + "."))); - when(dnsLookupPerformer.performNAPTRLookup(host, false, supportedTransports)).thenReturn(mockedNAPTRRecords); - List mockedSRVRecords = new LinkedList(); - mockedSRVRecords.add(new SRVRecord(new Name("_sip._" + TRANSPORT.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 3, 0, 5080, name)); - mockedSRVRecords.add(new SRVRecord(new Name("_sip._" + TRANSPORT.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 0, 0, 5081, name)); - mockedSRVRecords.add(new SRVRecord(new Name("_sip._" + TRANSPORT.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 1, 0, 5082, name)); - mockedSRVRecords.add(new SRVRecord(new Name("_sip._" + TRANSPORT.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 2, 0, 5083, name)); - when(dnsLookupPerformer.performSRVLookup("_sip._" + TRANSPORT.toLowerCase() + "." + host)).thenReturn(mockedSRVRecords); - List mockedSRVTCPRecords = new LinkedList(); - mockedSRVTCPRecords.add(new SRVRecord(new Name("_sips._" + ListeningPoint.TCP.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 1, 0, 5081, name)); -// mockedSRVTLSRecords.add(new SRVRecord(new Name("_sips._" + ListeningPoint.TLS.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 1, 0, 5081, name)); - when(dnsLookupPerformer.performSRVLookup("_sips._" + ListeningPoint.TCP.toLowerCase() + "." + host)).thenReturn(mockedSRVTCPRecords); - - List mockedSRVTLSRecords = new LinkedList(); - mockedSRVTLSRecords.add(new SRVRecord(new Name("_sips._" + ListeningPoint.TCP.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 1, 0, 5081, name)); -// mockedSRVTLSRecords.add(new SRVRecord(new Name("_sips._" + ListeningPoint.TLS.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 1, 0, 5081, name)); - when(dnsLookupPerformer.performSRVLookup("_sips._" + ListeningPoint.TLS.toLowerCase() + "." + host)).thenReturn(mockedSRVTLSRecords); - } - - /* - * Making sure the procedures of retrying the next hop of RFC 3263 are working - * and that the same hop is used for CANCEL - */ - public void testShootistCancel() throws Exception { -// receiver.sendInvite(); - receiverProtocolObjects = new ProtocolObjects( - "receiver", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - receiver.setWaitForCancel(true); - SipProvider receiverProvider = receiver.createProvider(); - receiverProvider.addSipListener(receiver); - - badReceiverProtocolObjects = new ProtocolObjects( - "bad-receiver", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - badReceiver = new TestSipListener(5081, 5070, badReceiverProtocolObjects, false); - SipProvider badReceiverProvider = badReceiver.createProvider(); - badReceiverProvider.addSipListener(badReceiver); - badReceiverProtocolObjects.start(); - badReceiver.setDropRequest(true); - - String host = "mobicents.org"; - - mockDNSLookup(host, "udp"); - - receiverProtocolObjects.start(); - tomcat.startTomcat(); - Map params = new HashMap(); - params.put("host", host); - params.put("cancelOn1xx", "true"); - deployApplication(params); - - Thread.sleep(DIALOG_TIMEOUT + TIMEOUT); - assertFalse(badReceiver.getByeReceived()); - assertFalse(badReceiver.isCancelReceived()); - RouteHeader routeHeader = (RouteHeader) receiver.getInviteRequest().getHeader(RouteHeader.NAME); - assertNull(routeHeader); - assertTrue(receiver.isCancelReceived()); - List allMessagesContent = receiver.getAllMessagesContent(); - assertTrue(allMessagesContent.size() >= 2); - assertTrue("sipSessionReadyToInvalidate", allMessagesContent.contains("sipSessionReadyToInvalidate")); - assertTrue("sipAppSessionReadyToInvalidate", allMessagesContent.contains("sipAppSessionReadyToInvalidate")); - } - - /* - * Making sure the procedures of retrying the next hop of RFC 3263 are working - * and that the ACK to an error response uses the same hop - * - * Updated for https://code.google.com/p/sipservlets/issues/detail?id=249 - */ - public void testShootistErrorResponse() throws Exception { - Map additionalProps = new HashMap(); - additionalProps.put(SipStandardService.PASS_INVITE_NON_2XX_ACK_TO_LISTENER, "true"); - - receiverProtocolObjects = new ProtocolObjects( - "receiver", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null, additionalProps); - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - receiver.setProvisionalResponsesToSend(new ArrayList()); - receiver.setFinalResponseToSend(Response.SERVER_INTERNAL_ERROR); - SipProvider receiverProvider = receiver.createProvider(); - receiverProvider.addSipListener(receiver); - receiverProtocolObjects.start(); - - badReceiverProtocolObjects = new ProtocolObjects( - "bad-receiver", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null, additionalProps); - badReceiver = new TestSipListener(5081, 5070, badReceiverProtocolObjects, false); - SipProvider badReceiverProvider = badReceiver.createProvider(); - badReceiverProvider.addSipListener(badReceiver); - badReceiverProtocolObjects.start(); - badReceiver.setDropRequest(true); - - badReceiver2ProtocolObjects = new ProtocolObjects( - "bad-receiver2", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - badReceiver2 = new TestSipListener(5082, 5070, badReceiver2ProtocolObjects, false); - SipProvider badReceiver2Provider = badReceiver2.createProvider(); - badReceiver2Provider.addSipListener(badReceiver2); - badReceiver2ProtocolObjects.start(); - badReceiver2.setDropRequest(true); - - badReceiver3ProtocolObjects = new ProtocolObjects( - "bad-receiver3", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - badReceiver3 = new TestSipListener(5083, 5070, badReceiver3ProtocolObjects, false); - SipProvider badReceiver3Provider = badReceiver3.createProvider(); - badReceiver3Provider.addSipListener(badReceiver3); - badReceiver3ProtocolObjects.start(); - badReceiver3.setDropRequest(true); - - String host = "mobicents.org"; - - tomcat.startTomcat(); - - mockDNSLookup4Records(host); - - Map params = new HashMap(); - params.put("host", host); - params.put("testErrorResponse", "true"); - deployApplication(params); - - Thread.sleep(DIALOG_TIMEOUT * 3 + TIMEOUT); - assertTrue(badReceiver.isInviteReceived()); - assertTrue(badReceiver2.isInviteReceived()); - //assertTrue(badReceiver3.isInviteReceived()); - assertFalse(badReceiver.isAckReceived()); - assertFalse(badReceiver2.isAckReceived()); - //assertFalse(badReceiver3.isAckReceived()); - //assertTrue(receiver.isAckReceived()); - RouteHeader routeHeader = (RouteHeader) receiver.getInviteRequest().getHeader(RouteHeader.NAME); - assertNull(routeHeader); - List allMessagesContent = receiver.getAllMessagesContent(); - assertEquals(2, allMessagesContent.size()); - assertTrue("sipSessionReadyToInvalidate", allMessagesContent.contains("sipSessionReadyToInvalidate")); - assertTrue("sipAppSessionReadyToInvalidate", allMessagesContent.contains("sipAppSessionReadyToInvalidate")); - } - - @Override - protected void tearDown() throws Exception { - receiverProtocolObjects.destroy(); - if (badReceiverProtocolObjects != null) { - badReceiverProtocolObjects.destroy(); - } - if (badReceiver2ProtocolObjects != null) { - badReceiver2ProtocolObjects.destroy(); - } - if (badReceiver3ProtocolObjects != null) { - badReceiver3ProtocolObjects.destroy(); - } - logger.info("Test completed"); - super.tearDown(); - } -} +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2014, Telestax Inc and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + */ +package org.mobicents.servlet.sip.testsuite.simple.rfc3263; + +import gov.nist.javax.sip.stack.HopImpl; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.Queue; +import java.util.Set; +import java.util.concurrent.ConcurrentLinkedQueue; + +import javax.sip.ListeningPoint; +import javax.sip.SipProvider; +import javax.sip.address.Hop; +import javax.sip.header.ContactHeader; +import javax.sip.header.RouteHeader; +import javax.sip.message.Response; + +import org.apache.log4j.Logger; +import org.mobicents.ext.javax.sip.dns.DNSLookupPerformer; +import org.mobicents.ext.javax.sip.dns.DefaultDNSLookupPerformer; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.catalina.SipStandardService; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; +import org.mobicents.servlet.sip.testsuite.simple.ShootistSipServletTest; +import org.xbill.DNS.DClass; +import org.xbill.DNS.NAPTRRecord; +import org.xbill.DNS.Name; +import org.xbill.DNS.Record; +import org.xbill.DNS.SRVRecord; +import org.xbill.DNS.TextParseException; + +public class ShootistSipServletRFC3263Test extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ShootistSipServletRFC3263Test.class); + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 80000; + private static final int DIALOG_TIMEOUT = 40000; + + + + public ShootistSipServletRFC3263Test(String name) { + super(name); + startTomcatOnStartup = false; + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + assertTrue(tomcat.deployContext( + projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp", + "sip-test-context", "sip-test")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/simple/shootist-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + System.setProperty("javax.net.ssl.keyStore", ShootistSipServletTest.class.getResource("testkeys").getPath()); + System.setProperty("javax.net.ssl.trustStore", ShootistSipServletTest.class.getResource("testkeys").getPath()); + System.setProperty("javax.net.ssl.keyStorePassword", "passphrase"); + System.setProperty("javax.net.ssl.keyStoreType", "jks"); + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + } + + /* + * Making sure the procedures of retrying the next hop of RFC 3263 are working + */ + public void testShootist() throws Exception { + ProtocolObjects receiverProtocolObjects = new ProtocolObjects( + "receiver", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + testResources.add(receiverProtocolObjects); + + + int myPort = NetworkPortAssigner.retrieveNextPort(); + TestSipListener receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + + ProtocolObjects badReceiverProtocolObjects = new ProtocolObjects( + "bad-receiver", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + testResources.add(badReceiverProtocolObjects); + int badReceiverPort = NetworkPortAssigner.retrieveNextPort(); + TestSipListener badReceiver = new TestSipListener(badReceiverPort, containerPort, badReceiverProtocolObjects, false); + SipProvider badReceiverProvider = badReceiver.createProvider(); + badReceiverProvider.addSipListener(badReceiver); + badReceiverProtocolObjects.start(); + badReceiver.setDropRequest(true); + + tomcat.startTomcat(); + + + + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + String host = "mobicents.org"; + ctxAtts.put("host", host); + mockDNSLookup(host, "udp", myPort); + deployShootist(ctxAtts, null); + Thread.sleep(TIMEOUT); + assertNotNull(receiver.getInviteRequest()); + RouteHeader routeHeader = (RouteHeader) receiver.getInviteRequest().getHeader(RouteHeader.NAME); + assertNull(routeHeader); + assertFalse(badReceiver.getByeReceived()); + assertTrue(receiver.getByeReceived()); + } + + /* + * Non Regression test for Issue http://code.google.com/p/mobicents/issues/detail?id=3140 + */ + public void testShootistTLSwithTLSConnector() throws Exception { + ProtocolObjects receiverProtocolObjects = new ProtocolObjects( + "receiver", "gov.nist", ListeningPoint.TLS, AUTODIALOG, null, null, null); + testResources.add(receiverProtocolObjects); + int myPort = NetworkPortAssigner.retrieveNextPort(); + TestSipListener receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + + ProtocolObjects badReceiverProtocolObjects = new ProtocolObjects( + "bad-receiver", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + testResources.add(badReceiverProtocolObjects); + int badReceiverPort = NetworkPortAssigner.retrieveNextPort(); + TestSipListener badReceiver = new TestSipListener(badReceiverPort, containerPort, badReceiverProtocolObjects, false); + SipProvider badReceiverProvider = badReceiver.createProvider(); + badReceiverProvider.addSipListener(badReceiver); + badReceiverProtocolObjects.start(); + badReceiver.setDropRequest(true); + String host = "mobicents.org"; + + tomcat.startTomcat(); + tomcat.removeConnector(sipConnector); + tomcat.addSipConnector(serverName, sipIpAddress, 5071, ListeningPoint.TLS); + + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("host", host); + ctxAtts.put("method", "REGISTER"); + ctxAtts.put("secureRURI", "true"); + mockDNSLookup(host, "tls", myPort); + deployShootist(ctxAtts, null); + + Thread.sleep(TIMEOUT); + assertNotNull(receiver.getRegisterReceived()); + RouteHeader routeHeader = (RouteHeader) receiver.getRegisterReceived().getHeader(RouteHeader.NAME); + assertNull(routeHeader); + assertNull(receiver.getRegisterReceived().getHeader(ContactHeader.NAME)); + } + + /* + * Non Regression test for Issue http://code.google.com/p/mobicents/issues/detail?id=3140 + */ + public void testShootistTLSwithTCPConnector() throws Exception { + ProtocolObjects receiverProtocolObjects = new ProtocolObjects( + "receiver", "gov.nist", ListeningPoint.TCP, AUTODIALOG, null, null, null); + testResources.add(receiverProtocolObjects); + int myPort = NetworkPortAssigner.retrieveNextPort(); + TestSipListener receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + + ProtocolObjects badReceiverProtocolObjects = new ProtocolObjects( + "bad-receiver", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + testResources.add(badReceiverProtocolObjects); + int badReceiverPort = NetworkPortAssigner.retrieveNextPort(); + TestSipListener badReceiver = new TestSipListener(badReceiverPort, containerPort, badReceiverProtocolObjects, false); + SipProvider badReceiverProvider = badReceiver.createProvider(); + badReceiverProvider.addSipListener(badReceiver); + badReceiverProtocolObjects.start(); + badReceiver.setDropRequest(true); + String host = "mobicents.org"; + + tomcat.startTomcat(); + tomcat.removeConnector(sipConnector); + tomcat.addSipConnector(serverName, sipIpAddress, containerPort, ListeningPoint.TCP); + + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("host", host); + ctxAtts.put("method", "REGISTER"); + ctxAtts.put("secureRURI", "true"); + mockDNSLookup(host, "tcp", myPort); + deployShootist(ctxAtts, null); + + Thread.sleep(TIMEOUT); + RouteHeader routeHeader = (RouteHeader) receiver.getRegisterReceived().getHeader(RouteHeader.NAME); + assertNull(routeHeader); + assertNull(receiver.getRegisterReceived().getHeader(ContactHeader.NAME)); + } + + /* + * Non Regression test for Issue https://code.google.com/p/sipservlets/issues/detail?id=250 + */ + public void testShootistTCP() throws Exception { + ProtocolObjects receiverProtocolObjects = new ProtocolObjects( + "receiver", "gov.nist", ListeningPoint.TCP, AUTODIALOG, null, null, null); + testResources.add(receiverProtocolObjects); + int myPort = NetworkPortAssigner.retrieveNextPort(); + TestSipListener receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + + ProtocolObjects badReceiverProtocolObjects = new ProtocolObjects( + "bad-receiver", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + testResources.add(badReceiverProtocolObjects); + int badReceiverPort = NetworkPortAssigner.retrieveNextPort(); + TestSipListener badReceiver = new TestSipListener(badReceiverPort, containerPort, badReceiverProtocolObjects, false); + SipProvider badReceiverProvider = badReceiver.createProvider(); + badReceiverProvider.addSipListener(badReceiver); + badReceiverProtocolObjects.start(); + badReceiver.setDropRequest(true); + String host = "mobicents.org"; + + tomcat.startTomcat(); + tomcat.removeConnector(sipConnector); + tomcat.addSipConnector(serverName, sipIpAddress, containerPort, ListeningPoint.TCP); + + + + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("host", host); + ctxAtts.put("method", "REGISTER"); + ctxAtts.put("route", "sip:mobicents.org;transport=tcp"); + mockDNSLookupTCP(host, myPort, new int[]{badReceiverPort,badReceiverPort}); + deployShootist(ctxAtts, null); + + Thread.sleep(TIMEOUT); + assertNotNull(receiver.getRegisterReceived()); + RouteHeader routeHeader = (RouteHeader) receiver.getRegisterReceived().getHeader(RouteHeader.NAME); + assertNull(routeHeader); + assertNull(receiver.getRegisterReceived().getHeader(ContactHeader.NAME)); + } + + /* + * Non Regression test for Issue http://code.google.com/p/mobicents/issues/detail?id=2346 + */ + public void testShootistRouteCheck() throws Exception { + ProtocolObjects receiverProtocolObjects = new ProtocolObjects( + "receiver", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + testResources.add(receiverProtocolObjects); + int myPort = NetworkPortAssigner.retrieveNextPort(); + TestSipListener receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + + String host = "mobicents.org"; + + tomcat.startTomcat(); + + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("host", host); + ctxAtts.put("route", "sip:" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" +myPort+ ";lr"); + deployShootist(ctxAtts, null); + + Thread.sleep(TIMEOUT / 4); + assertTrue(receiver.isInviteReceived()); + ListIterator routeHeaders = receiver.getInviteRequest().getHeaders(RouteHeader.NAME); + assertNotNull(routeHeaders); + RouteHeader routeHeader = routeHeaders.next(); + assertFalse(routeHeaders.hasNext()); + assertEquals("sip:" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" +myPort+ ";lr", routeHeader.getAddress().getURI().toString()); + assertTrue(receiver.getByeReceived()); + } + + private void mockDNSLookup(String host, String transport, int hopsPort) throws TextParseException { + DNSLookupPerformer dnsLookupPerformer = mock(DefaultDNSLookupPerformer.class); + //mocking the DNS Lookups to match our test cases + tomcat.getSipService().getSipApplicationDispatcher().getDNSServerLocator().setDnsLookupPerformer(dnsLookupPerformer); + + Set supportedTransports = new HashSet(); + supportedTransports.add(TRANSPORT.toUpperCase()); + supportedTransports.add(ListeningPoint.TCP.toUpperCase()); + supportedTransports.add(ListeningPoint.TLS.toUpperCase()); + + Queue hops = new ConcurrentLinkedQueue(); + hops = new ConcurrentLinkedQueue(); + //dont use "localhost" or DNS will not work (wouldnt be external) + hops.add(new HopImpl("127.0.0.1", hopsPort, transport)); + when(dnsLookupPerformer.locateHopsForNonNumericAddressWithPort("localhost", hopsPort, transport)).thenReturn(hops); + when(dnsLookupPerformer.locateHopsForNonNumericAddressWithPort("localhost", 5082, transport)).thenReturn(null); + when(dnsLookupPerformer.locateHopsForNonNumericAddressWithPort("localhost", 5081, transport)).thenReturn(null); + + List mockedNAPTRRecords = new LinkedList(); + // mocking the name because localhost is not absolute and localhost. cannot be resolved + Name name = mock(Name.class); + when(name.isAbsolute()).thenReturn(true); + when(name.toString()).thenReturn("localhost"); + mockedNAPTRRecords.add(new NAPTRRecord(new Name(host + "."), DClass.IN, 1000, 0, 0, "s", "SIP+D2U", "", new Name("_sip._" + TRANSPORT.toLowerCase() + "." + host + "."))); + when(dnsLookupPerformer.performNAPTRLookup(host, false, supportedTransports)).thenReturn(mockedNAPTRRecords); + List mockedSRVRecords = new LinkedList(); + mockedSRVRecords.add(new SRVRecord(new Name("_sip._" + TRANSPORT.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 1, 0, hopsPort, name)); + mockedSRVRecords.add(new SRVRecord(new Name("_sip._" + TRANSPORT.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 0, 0, 5081, name)); + when(dnsLookupPerformer.performSRVLookup("_sip._" + TRANSPORT.toLowerCase() + "." + host)).thenReturn(mockedSRVRecords); + List mockedSRVTCPRecords = new LinkedList(); + mockedSRVTCPRecords.add(new SRVRecord(new Name("_sips._" + ListeningPoint.TCP.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 1, 0, hopsPort, name)); + mockedSRVTCPRecords.add(new SRVRecord(new Name("_sips._" + ListeningPoint.TCP.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 0, 0, 5081, name)); +// mockedSRVTLSRecords.add(new SRVRecord(new Name("_sips._" + ListeningPoint.TLS.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 1, 0, 5081, name)); + when(dnsLookupPerformer.performSRVLookup("_sips._" + ListeningPoint.TCP.toLowerCase() + "." + host)).thenReturn(mockedSRVTCPRecords); + + List mockedSRVTLSRecords = new LinkedList(); + mockedSRVTLSRecords.add(new SRVRecord(new Name("_sips._" + ListeningPoint.TCP.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 1, 0, hopsPort, name)); + mockedSRVTLSRecords.add(new SRVRecord(new Name("_sips._" + ListeningPoint.TCP.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 0, 0, 5081, name)); +// mockedSRVTLSRecords.add(new SRVRecord(new Name("_sips._" + ListeningPoint.TLS.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 1, 0, 5081, name)); + when(dnsLookupPerformer.performSRVLookup("_sips._" + ListeningPoint.TLS.toLowerCase() + "." + host)).thenReturn(mockedSRVTLSRecords); + } + + private void mockDNSLookupTCP(String host, int receiverPort, int[] badReceiverPort) throws TextParseException { + DNSLookupPerformer dnsLookupPerformer = mock(DefaultDNSLookupPerformer.class); + //mocking the DNS Lookups to match our test cases + tomcat.getSipService().getSipApplicationDispatcher().getDNSServerLocator().setDnsLookupPerformer(dnsLookupPerformer); + + Set supportedTransports = new HashSet(); + supportedTransports.add(TRANSPORT.toUpperCase()); + supportedTransports.add(ListeningPoint.TCP.toUpperCase()); + + List mockedNAPTRRecords = new LinkedList(); + // mocking the name because localhost is not absolute and localhost. cannot be resolved + Name name = mock(Name.class); + when(name.isAbsolute()).thenReturn(true); + when(name.toString()).thenReturn("localhost"); + mockedNAPTRRecords.add(new NAPTRRecord(new Name(host + "."), DClass.IN, 1000, 0, 0, "s", "SIP+D2T", "", new Name("_sip._" + ListeningPoint.TCP.toLowerCase() + "." + host + "."))); + when(dnsLookupPerformer.performNAPTRLookup(host, false, supportedTransports)).thenReturn(mockedNAPTRRecords); + + Queue hops = new ConcurrentLinkedQueue(); + hops = new ConcurrentLinkedQueue(); + //dont use "localhost" or DNS will not work (wouldnt be external) + hops.add(new HopImpl("127.0.0.1", receiverPort, "tcp")); + when(dnsLookupPerformer.locateHopsForNonNumericAddressWithPort("localhost", badReceiverPort[0], "tcp")).thenReturn(null); + when(dnsLookupPerformer.locateHopsForNonNumericAddressWithPort("localhost", badReceiverPort[1], "tcp")).thenReturn(null); + when(dnsLookupPerformer.locateHopsForNonNumericAddressWithPort("localhost", receiverPort, "tcp")).thenReturn(hops); + + List mockedSRVTCPRecords = new LinkedList(); + mockedSRVTCPRecords.add(new SRVRecord(new Name("_sip._" + ListeningPoint.TCP.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 0, 0, badReceiverPort[0], name)); + mockedSRVTCPRecords.add(new SRVRecord(new Name("_sip._" + ListeningPoint.TCP.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 2, 0, receiverPort, name)); + mockedSRVTCPRecords.add(new SRVRecord(new Name("_sip._" + ListeningPoint.TCP.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 1, 0, badReceiverPort[1], name)); + when(dnsLookupPerformer.performSRVLookup("_sip._" + ListeningPoint.TCP.toLowerCase() + "." + host)).thenReturn(mockedSRVTCPRecords); + } + + private void mockDNSLookup4Records(String host, int receiverPort, int[] badReceiverPorts) throws TextParseException { + DNSLookupPerformer dnsLookupPerformer = mock(DefaultDNSLookupPerformer.class); + //mocking the DNS Lookups to match our test cases + tomcat.getSipService().getSipApplicationDispatcher().getDNSServerLocator().setDnsLookupPerformer(dnsLookupPerformer); + + Set supportedTransports = new HashSet(); + supportedTransports.add(TRANSPORT.toUpperCase()); + supportedTransports.add(ListeningPoint.TCP.toUpperCase()); + supportedTransports.add(ListeningPoint.TLS.toUpperCase()); + + Queue hops = new ConcurrentLinkedQueue(); + hops = new ConcurrentLinkedQueue(); + //dont use "localhost" or DNS will not work (wouldnt be external) + hops.add(new HopImpl("127.0.0.1", receiverPort, TRANSPORT.toLowerCase())); + when(dnsLookupPerformer.locateHopsForNonNumericAddressWithPort("localhost", receiverPort, TRANSPORT.toLowerCase())).thenReturn(hops); + hops = new ConcurrentLinkedQueue(); + //dont use "localhost" or DNS will not work (wouldnt be external) + hops.add(new HopImpl("127.0.0.1", badReceiverPorts[0], TRANSPORT.toLowerCase())); + when(dnsLookupPerformer.locateHopsForNonNumericAddressWithPort("localhost", badReceiverPorts[0], TRANSPORT.toLowerCase())).thenReturn(hops); + hops = new ConcurrentLinkedQueue(); + //dont use "localhost" or DNS will not work (wouldnt be external) + hops.add(new HopImpl("127.0.0.1", badReceiverPorts[1], TRANSPORT.toLowerCase())); + when(dnsLookupPerformer.locateHopsForNonNumericAddressWithPort("localhost", badReceiverPorts[1], TRANSPORT.toLowerCase())).thenReturn(hops); + hops = new ConcurrentLinkedQueue(); + //dont use "localhost" or DNS will not work (wouldnt be external) + hops.add(new HopImpl("127.0.0.1", badReceiverPorts[2], TRANSPORT.toLowerCase())); + when(dnsLookupPerformer.locateHopsForNonNumericAddressWithPort("localhost", badReceiverPorts[2], TRANSPORT.toLowerCase())).thenReturn(hops); + + List mockedNAPTRRecords = new LinkedList(); + // mocking the name because localhost is not absolute and localhost. cannot be resolved + Name name = mock(Name.class); + when(name.isAbsolute()).thenReturn(true); + when(name.toString()).thenReturn("localhost"); + mockedNAPTRRecords.add(new NAPTRRecord(new Name(host + "."), DClass.IN, 1000, 0, 0, "s", "SIP+D2U", "", new Name("_sip._" + TRANSPORT.toLowerCase() + "." + host + "."))); + when(dnsLookupPerformer.performNAPTRLookup(host, false, supportedTransports)).thenReturn(mockedNAPTRRecords); + List mockedSRVRecords = new LinkedList(); + mockedSRVRecords.add(new SRVRecord(new Name("_sip._" + TRANSPORT.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 3, 0, receiverPort, name)); + mockedSRVRecords.add(new SRVRecord(new Name("_sip._" + TRANSPORT.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 0, 0, badReceiverPorts[0], name)); + mockedSRVRecords.add(new SRVRecord(new Name("_sip._" + TRANSPORT.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 1, 0, badReceiverPorts[1], name)); + mockedSRVRecords.add(new SRVRecord(new Name("_sip._" + TRANSPORT.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 2, 0, badReceiverPorts[2], name)); + when(dnsLookupPerformer.performSRVLookup("_sip._" + TRANSPORT.toLowerCase() + "." + host)).thenReturn(mockedSRVRecords); + List mockedSRVTCPRecords = new LinkedList(); + mockedSRVTCPRecords.add(new SRVRecord(new Name("_sips._" + ListeningPoint.TCP.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 1, 0, badReceiverPorts[0], name)); + when(dnsLookupPerformer.performSRVLookup("_sips._" + ListeningPoint.TCP.toLowerCase() + "." + host)).thenReturn(mockedSRVTCPRecords); + + List mockedSRVTLSRecords = new LinkedList(); + mockedSRVTLSRecords.add(new SRVRecord(new Name("_sips._" + ListeningPoint.TCP.toLowerCase() + "." + host + "."), DClass.IN, 1000L, 1, 0, badReceiverPorts[0], name)); + when(dnsLookupPerformer.performSRVLookup("_sips._" + ListeningPoint.TLS.toLowerCase() + "." + host)).thenReturn(mockedSRVTLSRecords); + } + + /* + * Making sure the procedures of retrying the next hop of RFC 3263 are working + * and that the same hop is used for CANCEL + */ + public void testShootistCancel() throws Exception { + ProtocolObjects receiverProtocolObjects = new ProtocolObjects( + "receiver", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + testResources.add(receiverProtocolObjects); + int myPort = NetworkPortAssigner.retrieveNextPort(); + TestSipListener receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + receiver.setWaitForCancel(true); + SipProvider receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + + ProtocolObjects badReceiverProtocolObjects = new ProtocolObjects( + "bad-receiver", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + testResources.add(badReceiverProtocolObjects); + int badReceiverPort = NetworkPortAssigner.retrieveNextPort(); + TestSipListener badReceiver = new TestSipListener(badReceiverPort, containerPort, badReceiverProtocolObjects, false); + SipProvider badReceiverProvider = badReceiver.createProvider(); + badReceiverProvider.addSipListener(badReceiver); + badReceiverProtocolObjects.start(); + badReceiver.setDropRequest(true); + + String host = "mobicents.org"; + + + receiverProtocolObjects.start(); + tomcat.startTomcat(); + + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("host", host); + ctxAtts.put("cancelOn1xx", "true"); + mockDNSLookup(host, "udp", myPort); + deployShootist(ctxAtts, null); + + Thread.sleep(DIALOG_TIMEOUT + TIMEOUT); + assertFalse(badReceiver.getByeReceived()); + assertFalse(badReceiver.isCancelReceived()); + RouteHeader routeHeader = (RouteHeader) receiver.getInviteRequest().getHeader(RouteHeader.NAME); + assertNull(routeHeader); + assertTrue(receiver.isCancelReceived()); + List allMessagesContent = receiver.getAllMessagesContent(); + assertTrue(allMessagesContent.size() >= 2); + assertTrue("sipSessionReadyToInvalidate", allMessagesContent.contains("sipSessionReadyToInvalidate")); + assertTrue("sipAppSessionReadyToInvalidate", allMessagesContent.contains("sipAppSessionReadyToInvalidate")); + } + + /* + * Making sure the procedures of retrying the next hop of RFC 3263 are working + * and that the ACK to an error response uses the same hop + * + * Updated for https://code.google.com/p/sipservlets/issues/detail?id=249 + */ + public void testShootistErrorResponse() throws Exception { + Map additionalProps = new HashMap(); + additionalProps.put(SipStandardService.PASS_INVITE_NON_2XX_ACK_TO_LISTENER, "true"); + + ProtocolObjects receiverProtocolObjects = new ProtocolObjects( + "receiver", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null, additionalProps); + testResources.add(receiverProtocolObjects); + int myPort = NetworkPortAssigner.retrieveNextPort(); + TestSipListener receiver = new TestSipListener(myPort, containerPort, receiverProtocolObjects, false); + receiver.setProvisionalResponsesToSend(new ArrayList()); + receiver.setFinalResponseToSend(Response.SERVER_INTERNAL_ERROR); + SipProvider receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + + ProtocolObjects badReceiverProtocolObjects = new ProtocolObjects( + "bad-receiver", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null, additionalProps); + testResources.add(badReceiverProtocolObjects); + int badReceiverPort = NetworkPortAssigner.retrieveNextPort(); + TestSipListener badReceiver = new TestSipListener(badReceiverPort, containerPort, badReceiverProtocolObjects, false); + SipProvider badReceiverProvider = badReceiver.createProvider(); + badReceiverProvider.addSipListener(badReceiver); + badReceiverProtocolObjects.start(); + badReceiver.setDropRequest(true); + + ProtocolObjects badReceiver2ProtocolObjects = new ProtocolObjects( + "bad-receiver2", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + testResources.add(badReceiver2ProtocolObjects); + int badReceiverPort2 = NetworkPortAssigner.retrieveNextPort(); + TestSipListener badReceiver2 = new TestSipListener(badReceiverPort2, containerPort, badReceiver2ProtocolObjects, false); + SipProvider badReceiver2Provider = badReceiver2.createProvider(); + badReceiver2Provider.addSipListener(badReceiver2); + badReceiver2ProtocolObjects.start(); + badReceiver2.setDropRequest(true); + + ProtocolObjects badReceiver3ProtocolObjects = new ProtocolObjects( + "bad-receiver3", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + testResources.add(badReceiver3ProtocolObjects); + int badReceiverPort3 = NetworkPortAssigner.retrieveNextPort(); + TestSipListener badReceiver3 = new TestSipListener(badReceiverPort3, containerPort, badReceiver3ProtocolObjects, false); + SipProvider badReceiver3Provider = badReceiver3.createProvider(); + badReceiver3Provider.addSipListener(badReceiver3); + badReceiver3ProtocolObjects.start(); + badReceiver3.setDropRequest(true); + + String host = "mobicents.org"; + + tomcat.startTomcat(); + + + + Map ctxAtts = new HashMap(); + ctxAtts.put("testPort", String.valueOf(myPort)); + ctxAtts.put("servletContainerPort", String.valueOf(containerPort)); + ctxAtts.put("host", host); + ctxAtts.put("testErrorResponse", "true"); + mockDNSLookup4Records(host, myPort, new int[]{badReceiverPort,badReceiverPort2,badReceiverPort3}); + deployShootist(ctxAtts, null); + + Thread.sleep(DIALOG_TIMEOUT * 3 + TIMEOUT); + assertTrue(badReceiver.isInviteReceived()); + assertTrue(badReceiver2.isInviteReceived()); + //assertTrue(badReceiver3.isInviteReceived()); + assertFalse(badReceiver.isAckReceived()); + assertFalse(badReceiver2.isAckReceived()); + //assertFalse(badReceiver3.isAckReceived()); + //assertTrue(receiver.isAckReceived()); + assertTrue(receiver.isInviteReceived()); + RouteHeader routeHeader = (RouteHeader) receiver.getInviteRequest().getHeader(RouteHeader.NAME); + assertNull(routeHeader); + List allMessagesContent = receiver.getAllMessagesContent(); + assertEquals(2, allMessagesContent.size()); + assertTrue("sipSessionReadyToInvalidate", allMessagesContent.contains("sipSessionReadyToInvalidate")); + assertTrue("sipAppSessionReadyToInvalidate", allMessagesContent.contains("sipAppSessionReadyToInvalidate")); + } + + @Override + protected void tearDown() throws Exception { + logger.info("Test completed"); + super.tearDown(); + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/rfc5626/CallForwardingB2BUAReInviteRFC5626JunitTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/rfc5626/CallForwardingB2BUAReInviteRFC5626JunitTest.java index 640d3ebee4..f83ce337cf 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/rfc5626/CallForwardingB2BUAReInviteRFC5626JunitTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/rfc5626/CallForwardingB2BUAReInviteRFC5626JunitTest.java @@ -1,146 +1,162 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.simple.rfc5626; - -import javax.sip.SipProvider; -import javax.sip.address.SipURI; -import javax.sip.header.MaxForwardsHeader; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.RFC5626UseCase; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -/* - * - * Added for Issue 2254 http://code.google.com/p/mobicents/issues/detail?id=2254 - * Testing B2BUA Use case not covered by the spec where the UA connects directly to a B2BUA instead of edge proxy - */ -public class CallForwardingB2BUAReInviteRFC5626JunitTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(CallForwardingB2BUAReInviteRFC5626JunitTest.class); - - private static final String TRANSPORT = "tcp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 20000; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender; - TestSipListener receiver; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - - public CallForwardingB2BUAReInviteRFC5626JunitTest(String name) { - super(name); - listeningPointTransport = TRANSPORT; - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", - "sip-test-context", - "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/callcontroller/call-forwarding-b2bua-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects = new ProtocolObjects("forward-sender", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - receiverProtocolObjects = new ProtocolObjects("receiver", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - } - - /** - * UAC sends INVITE with wrong Via and Contact IP address to make sure that when the subsequent request from the other end is received back - * it can be routed back to UAC on the correct IP through the ob parameter support - * @throws Exception - */ - public void testCallForwardingCallerSendBye() throws Exception { - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5090, 5070, receiverProtocolObjects, false); - receiver.setSendReinvite(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - - String fromName = "forward-tcp-sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setRFC5626UseCase(RFC5626UseCase.B2BUA); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isInviteReceived()); - assertTrue(sender.isAckReceived()); - assertNotNull(sender.getInviteRequest().getHeader("ReInvite")); - MaxForwardsHeader maxForwardsHeader = (MaxForwardsHeader) receiver.getInviteRequest().getHeader(MaxForwardsHeader.NAME); - assertNotNull(maxForwardsHeader); - // Non Regression test for http://code.google.com/p/mobicents/issues/detail?id=1490 - // B2buaHelper.createRequest does not decrement Max-forwards - assertEquals(69, maxForwardsHeader.getMaxForwards()); - sender.sendInDialogSipRequest("BYE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - assertTrue(sender.getOkToByeReceived()); - assertEquals(1,sender.bindings); //http://code.google.com/p/mobicents/issues/detail?id=2100 - maxForwardsHeader = (MaxForwardsHeader) receiver.getByeRequestReceived().getHeader(MaxForwardsHeader.NAME); - assertNotNull(maxForwardsHeader); - // Non Regression test for http://code.google.com/p/mobicents/issues/detail?id=1490 - // B2buaHelper.createRequest does not decrement Max-forwards - assertEquals(69, maxForwardsHeader.getMaxForwards()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite.simple.rfc5626; + +import java.util.HashMap; +import java.util.Map; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import javax.sip.header.MaxForwardsHeader; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.RFC5626UseCase; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +/* + * + * Added for Issue 2254 http://code.google.com/p/mobicents/issues/detail?id=2254 + * Testing B2BUA Use case not covered by the spec where the UA connects directly to a B2BUA instead of edge proxy + */ +public class CallForwardingB2BUAReInviteRFC5626JunitTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(CallForwardingB2BUAReInviteRFC5626JunitTest.class); + + private static final String TRANSPORT = "tcp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 20000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + TestSipListener receiver; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + + public CallForwardingB2BUAReInviteRFC5626JunitTest(String name) { + super(name); + listeningPointTransport = TRANSPORT; + autoDeployOnStartup = false; + } + + + @Override + public void deployApplication() { + ctx = tomcat.deployAppContext( + projectHome + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + "sip-test-context", "sip-test"); + assertTrue(ctx.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/callcontroller/call-forwarding-b2bua-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects("forward-sender", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects("receiver", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + } + + /** + * UAC sends INVITE with wrong Via and Contact IP address to make sure that when the subsequent request from the other end is received back + * it can be routed back to UAC on the correct IP through the ob parameter support + * @throws Exception + */ + public void testCallForwardingCallerSendBye() throws Exception { + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setSendReinvite(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("testPort", String.valueOf(receiverPort)); + params.put("servletContainerPort", String.valueOf(containerPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/call-forwarding-b2bua-servlet/src/main/sipapp", + params, null); + + String fromName = "forward-tcp-sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setRFC5626UseCase(RFC5626UseCase.B2BUA); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isInviteReceived()); + assertTrue(sender.isAckReceived()); + assertNotNull(sender.getInviteRequest().getHeader("ReInvite")); + MaxForwardsHeader maxForwardsHeader = (MaxForwardsHeader) receiver.getInviteRequest().getHeader(MaxForwardsHeader.NAME); + assertNotNull(maxForwardsHeader); + // Non Regression test for http://code.google.com/p/mobicents/issues/detail?id=1490 + // B2buaHelper.createRequest does not decrement Max-forwards + assertEquals(69, maxForwardsHeader.getMaxForwards()); + sender.sendInDialogSipRequest("BYE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + assertTrue(sender.getOkToByeReceived()); + assertEquals(1,sender.bindings); //http://code.google.com/p/mobicents/issues/detail?id=2100 + maxForwardsHeader = (MaxForwardsHeader) receiver.getByeRequestReceived().getHeader(MaxForwardsHeader.NAME); + assertNotNull(maxForwardsHeader); + // Non Regression test for http://code.google.com/p/mobicents/issues/detail?id=1490 + // B2buaHelper.createRequest does not decrement Max-forwards + assertEquals(69, maxForwardsHeader.getMaxForwards()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/rfc5626/ProxyEdgeRecordRouteTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/rfc5626/ProxyEdgeRecordRouteTest.java index 2c1702daf4..5ca3a86024 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/rfc5626/ProxyEdgeRecordRouteTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/rfc5626/ProxyEdgeRecordRouteTest.java @@ -1,239 +1,254 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.simple.rfc5626; - -import gov.nist.javax.sip.header.ims.PathHeader; - -import javax.sip.ListeningPoint; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.RFC5626UseCase; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class ProxyEdgeRecordRouteTest extends SipServletTestCase { - private static transient Logger logger = Logger.getLogger(ProxyEdgeRecordRouteTest.class); - private static final boolean AUTODIALOG = true; - private static final String TRANSPORT = "tcp"; - private static final int TIMEOUT = 20000; - - TestSipListener sender; - TestSipListener receiver; - ProtocolObjects senderProtocolObjects; - ProtocolObjects receiverProtocolObjects; - - public ProxyEdgeRecordRouteTest(String name) { - super(name); - listeningPointTransport = TRANSPORT; - } - - @Override - public void setUp() throws Exception { - super.setUp(); - senderProtocolObjects = new ProtocolObjects("proxy-sender", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - receiverProtocolObjects = new ProtocolObjects("proxy-receiver", - "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - sender.setRecordRoutingProxyTesting(true); - SipProvider senderProvider = sender.createProvider(); - - receiver = new TestSipListener(5057, 5070, receiverProtocolObjects, false); - receiver.setRecordRoutingProxyTesting(true); - SipProvider receiverProvider = receiver.createProvider(); - - receiverProvider.addSipListener(receiver); - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - receiverProtocolObjects.start(); - } - - public void testProxyProcessOutgoingInitialRequests() throws Exception { - String fromName = "register-outbound"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "proxy-receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setRFC5626UseCase(RFC5626UseCase.Proxy); - sender.sendSipRequest("REGISTER", fromAddress, toAddress, null, null, false, new String[]{"Supported"}, new String[]{"outbound"}, true); - Thread.sleep(TIMEOUT); - assertEquals(200, sender.getFinalResponseStatus()); - PathHeader pathHeader = (PathHeader) sender.getFinalResponse().getHeader(PathHeader.NAME); - assertNotNull(pathHeader); - String flow = ((SipURI)pathHeader.getAddress().getURI()).getUser(); - assertNotNull(flow); - assertNotNull(((SipURI)pathHeader.getAddress().getURI()).getParameter("ob")); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null,(SipURI) pathHeader.getAddress().getURI(), false, null, null, true); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(receiver.isAckReceived()); - receiver.setAckReceived(false); - receiver.setAckSent(false); - sender.setAckSent(false); - sender.setAckReceived(false); - sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(receiver.isAckReceived()); - sender.sendBye(); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - assertTrue(sender.getOkToByeReceived()); - } - - public void testProxyProcessOutgoingInitialRequests403() throws Exception { - String fromName = "register-outbound"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "proxy-receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setRFC5626UseCase(RFC5626UseCase.Proxy); - sender.sendSipRequest("REGISTER", fromAddress, toAddress, null, null, false, new String[]{"Supported"}, new String[]{"outbound"}, true); - Thread.sleep(TIMEOUT); - assertEquals(200, sender.getFinalResponseStatus()); - PathHeader pathHeader = (PathHeader) sender.getFinalResponse().getHeader(PathHeader.NAME); - assertNotNull(pathHeader); - String flow = ((SipURI)pathHeader.getAddress().getURI()).getUser(); - assertNotNull(flow); - assertNotNull(((SipURI)pathHeader.getAddress().getURI()).getParameter("ob")); - ((SipURI)pathHeader.getAddress().getURI()).setUser("77+977+977+977+9AXvvv71C77+9Qu+/vTlt3ITvv70677+977+9Zi9UQ1BfMTI3LjAuMC4xXzUwNzBfMTI3LjAuMC4xXzQ2MTYy"); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null,(SipURI) pathHeader.getAddress().getURI(), false, null, null, true); - Thread.sleep(TIMEOUT); - assertEquals(403,sender.getFinalResponseStatus()); - } - - public void testProxyProcessIncomingInitialRequests() throws Exception { - String fromName = "invite-inbound"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "proxy-receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setRFC5626UseCase(RFC5626UseCase.Proxy); - sender.sendSipRequest("REGISTER", fromAddress, toAddress, null, null, false, new String[]{"Supported"}, new String[]{"outbound"}, true); - Thread.sleep(TIMEOUT); - assertEquals(200, sender.getFinalResponseStatus()); - PathHeader pathHeader = (PathHeader) sender.getFinalResponse().getHeader(PathHeader.NAME); - assertNotNull(pathHeader); - String flow = ((SipURI)pathHeader.getAddress().getURI()).getUser(); - assertNotNull(flow); - assertNotNull(((SipURI)pathHeader.getAddress().getURI()).getParameter("ob")); - receiver.sendSipRequest("INVITE", fromAddress, toAddress, null,(SipURI) pathHeader.getAddress().getURI(), false, null, null, true); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isAckSent()); - assertTrue(sender.isAckReceived()); - receiver.setAckReceived(false); - receiver.setAckSent(false); - sender.setAckSent(false); - sender.setAckReceived(false); - receiver.sendInDialogSipRequest("INVITE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isAckSent()); - assertTrue(sender.isAckReceived()); - receiver.sendBye(); - Thread.sleep(TIMEOUT); - assertTrue(sender.getByeReceived()); - assertTrue(receiver.getOkToByeReceived()); - } - - public void testProxyProcessOutgoingAndIncomingInitialRequests() throws Exception { - String fromName = "register-outbound"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toSipAddress = "sip-servlets.com"; - String toUser = "proxy-receiver"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setRFC5626UseCase(RFC5626UseCase.Proxy); - sender.sendSipRequest("REGISTER", fromAddress, toAddress, null, null, false, new String[]{"Supported"}, new String[]{"outbound"}, true); - Thread.sleep(TIMEOUT); - assertEquals(200, sender.getFinalResponseStatus()); - PathHeader pathHeader = (PathHeader) sender.getFinalResponse().getHeader(PathHeader.NAME); - assertNotNull(pathHeader); - String flow = ((SipURI)pathHeader.getAddress().getURI()).getUser(); - assertNotNull(flow); - assertNotNull(((SipURI)pathHeader.getAddress().getURI()).getParameter("ob")); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null,(SipURI) pathHeader.getAddress().getURI(), false, null, null, true); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(receiver.isAckReceived()); - receiver.setAckReceived(false); - receiver.setAckSent(false); - sender.setAckSent(false); - sender.setAckReceived(false); - receiver.sendInDialogSipRequest("INVITE", null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertTrue(receiver.isAckSent()); - assertTrue(sender.isAckReceived()); - sender.sendBye(); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getByeReceived()); - assertTrue(sender.getOkToByeReceived()); - } - - @Override - public void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - @Override - public void deployApplication() { - assertTrue(tomcat - .deployContext( - projectHome - + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" - + projectHome - + "/sip-servlets-test-suite/testsuite/src/test/resources/" - + "org/mobicents/servlet/sip/testsuite/proxy/simple-sip-servlet-dar.properties"; - } -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.mobicents.servlet.sip.testsuite.simple.rfc5626; + +import gov.nist.javax.sip.header.ims.PathHeader; + +import java.util.HashMap; +import java.util.Map; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.RFC5626UseCase; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class ProxyEdgeRecordRouteTest extends SipServletTestCase { + private static transient Logger logger = Logger.getLogger(ProxyEdgeRecordRouteTest.class); + private static final boolean AUTODIALOG = true; + private static final String TRANSPORT = "tcp"; + private static final int TIMEOUT = 20000; + + TestSipListener sender; + TestSipListener receiver; + ProtocolObjects senderProtocolObjects; + ProtocolObjects receiverProtocolObjects; + + public ProxyEdgeRecordRouteTest(String name) { + super(name); + listeningPointTransport = TRANSPORT; + autoDeployOnStartup = false; + } + + @Override + public void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + + senderProtocolObjects = new ProtocolObjects("proxy-sender", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + receiverProtocolObjects = new ProtocolObjects("proxy-receiver", + "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + sender.setRecordRoutingProxyTesting(true); + SipProvider senderProvider = sender.createProvider(); + + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + receiver.setRecordRoutingProxyTesting(true); + SipProvider receiverProvider = receiver.createProvider(); + + receiverProvider.addSipListener(receiver); + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put( "containerPort", String.valueOf(containerPort)); + params.put( "testPort", String.valueOf(senderPort)); + params.put( "receiverPort", String.valueOf(receiverPort)); + deployApplication(projectHome + + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + params, null); + } + + public void testProxyProcessOutgoingInitialRequests() throws Exception { + String fromName = "register-outbound"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "proxy-receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setRFC5626UseCase(RFC5626UseCase.Proxy); + sender.sendSipRequest("REGISTER", fromAddress, toAddress, null, null, false, new String[]{"Supported"}, new String[]{"outbound"}, true); + Thread.sleep(TIMEOUT); + assertEquals(200, sender.getFinalResponseStatus()); + PathHeader pathHeader = (PathHeader) sender.getFinalResponse().getHeader(PathHeader.NAME); + assertNotNull(pathHeader); + String flow = ((SipURI)pathHeader.getAddress().getURI()).getUser(); + assertNotNull(flow); + assertNotNull(((SipURI)pathHeader.getAddress().getURI()).getParameter("ob")); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null,(SipURI) pathHeader.getAddress().getURI(), false, null, null, true); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(receiver.isAckReceived()); + receiver.setAckReceived(false); + receiver.setAckSent(false); + sender.setAckSent(false); + sender.setAckReceived(false); + sender.sendInDialogSipRequest("INVITE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(receiver.isAckReceived()); + sender.sendBye(); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + assertTrue(sender.getOkToByeReceived()); + } + + public void testProxyProcessOutgoingInitialRequests403() throws Exception { + String fromName = "register-outbound"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "proxy-receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setRFC5626UseCase(RFC5626UseCase.Proxy); + sender.sendSipRequest("REGISTER", fromAddress, toAddress, null, null, false, new String[]{"Supported"}, new String[]{"outbound"}, true); + Thread.sleep(TIMEOUT); + assertEquals(200, sender.getFinalResponseStatus()); + PathHeader pathHeader = (PathHeader) sender.getFinalResponse().getHeader(PathHeader.NAME); + assertNotNull(pathHeader); + String flow = ((SipURI)pathHeader.getAddress().getURI()).getUser(); + assertNotNull(flow); + assertNotNull(((SipURI)pathHeader.getAddress().getURI()).getParameter("ob")); + ((SipURI)pathHeader.getAddress().getURI()).setUser("77+977+977+977+9AXvvv71C77+9Qu+/vTlt3ITvv70677+977+9Zi9UQ1BfMTI3LjAuMC4xXzUwNzBfMTI3LjAuMC4xXzQ2MTYy"); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null,(SipURI) pathHeader.getAddress().getURI(), false, null, null, true); + Thread.sleep(TIMEOUT); + assertEquals(403,sender.getFinalResponseStatus()); + } + + public void testProxyProcessIncomingInitialRequests() throws Exception { + String fromName = "invite-inbound"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "proxy-receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setRFC5626UseCase(RFC5626UseCase.Proxy); + sender.sendSipRequest("REGISTER", fromAddress, toAddress, null, null, false, new String[]{"Supported"}, new String[]{"outbound"}, true); + Thread.sleep(TIMEOUT); + assertEquals(200, sender.getFinalResponseStatus()); + PathHeader pathHeader = (PathHeader) sender.getFinalResponse().getHeader(PathHeader.NAME); + assertNotNull(pathHeader); + String flow = ((SipURI)pathHeader.getAddress().getURI()).getUser(); + assertNotNull(flow); + assertNotNull(((SipURI)pathHeader.getAddress().getURI()).getParameter("ob")); + receiver.sendSipRequest("INVITE", fromAddress, toAddress, null,(SipURI) pathHeader.getAddress().getURI(), false, null, null, true); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isAckSent()); + assertTrue(sender.isAckReceived()); + receiver.setAckReceived(false); + receiver.setAckSent(false); + sender.setAckSent(false); + sender.setAckReceived(false); + receiver.sendInDialogSipRequest("INVITE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isAckSent()); + assertTrue(sender.isAckReceived()); + receiver.sendBye(); + Thread.sleep(TIMEOUT); + assertTrue(sender.getByeReceived()); + assertTrue(receiver.getOkToByeReceived()); + } + + public void testProxyProcessOutgoingAndIncomingInitialRequests() throws Exception { + String fromName = "register-outbound"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toSipAddress = "sip-servlets.com"; + String toUser = "proxy-receiver"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setRFC5626UseCase(RFC5626UseCase.Proxy); + sender.sendSipRequest("REGISTER", fromAddress, toAddress, null, null, false, new String[]{"Supported"}, new String[]{"outbound"}, true); + Thread.sleep(TIMEOUT); + assertEquals(200, sender.getFinalResponseStatus()); + PathHeader pathHeader = (PathHeader) sender.getFinalResponse().getHeader(PathHeader.NAME); + assertNotNull(pathHeader); + String flow = ((SipURI)pathHeader.getAddress().getURI()).getUser(); + assertNotNull(flow); + assertNotNull(((SipURI)pathHeader.getAddress().getURI()).getParameter("ob")); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null,(SipURI) pathHeader.getAddress().getURI(), false, null, null, true); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(receiver.isAckReceived()); + receiver.setAckReceived(false); + receiver.setAckSent(false); + sender.setAckSent(false); + sender.setAckReceived(false); + receiver.sendInDialogSipRequest("INVITE", null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertTrue(receiver.isAckSent()); + assertTrue(sender.isAckReceived()); + sender.sendBye(); + Thread.sleep(TIMEOUT); + assertTrue(receiver.getByeReceived()); + assertTrue(sender.getOkToByeReceived()); + } + + @Override + public void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + + @Override + public void deployApplication() { + ctx = tomcat.deployAppContext( + projectHome + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + "sip-test-context", "sip-test"); + assertTrue(ctx.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + + projectHome + + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/proxy/simple-sip-servlet-dar.properties"; + } +} \ No newline at end of file diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/rfc5626/RFC5626KeepAliveSipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/rfc5626/RFC5626KeepAliveSipServletTest.java index 82336f6f2f..9070feef61 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/rfc5626/RFC5626KeepAliveSipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/simple/rfc5626/RFC5626KeepAliveSipServletTest.java @@ -1,347 +1,354 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.simple.rfc5626; - -import gov.nist.javax.sip.SipStackImpl; -import gov.nist.javax.sip.stack.NioMessageProcessorFactory; -import gov.nist.javax.sip.stack.SIPTransactionStack; - -import java.io.File; -import java.text.ParseException; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Properties; - -import javax.sip.InvalidArgumentException; -import javax.sip.ListeningPoint; -import javax.sip.SipException; -import javax.sip.SipProvider; - -import org.apache.catalina.connector.Connector; -import org.apache.catalina.deploy.ApplicationParameter; -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipEmbedded; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.catalina.SipStandardService; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -/** - * Added for Issue 2254 http://code.google.com/p/mobicents/issues/detail?id=2254 - * Testing keepalive section 4.4.1 - * - * @author jean.deruelle@gmail.com - * - */ -public class RFC5626KeepAliveSipServletTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(RFC5626KeepAliveSipServletTest.class); - - private static final String TRANSPORT = "tcp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 30000; -// private static final int TIMEOUT = 100000000; - - SipEmbedded tomcatShootist; - - TestSipListener receiver; - SipProvider receiverProvider = null; - ProtocolObjects receiverProtocolObjects; - - private Connector shootistConnector; - -// TestSipListener registerReciever; -// ProtocolObjects registerRecieverProtocolObjects; - - public RFC5626KeepAliveSipServletTest(String name) { - super(name); - listeningPointTransport = ListeningPoint.TCP; - } - - @Override - public void deployApplication() { - - } - - - public SipStandardContext deployShootme(Map params) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp"); - context.setName("shootme-context"); - context.setPath("shootme-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setConcurrencyControlMode(ConcurrencyControlMode.SipApplicationSession); - context.setManager(new SipStandardManager()); - for (Entry param : params.entrySet()) { - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(param.getKey()); - applicationParameter.setValue(param.getValue()); - context.addApplicationParameter(applicationParameter); - } - assertTrue(tomcat.deployContext(context)); - return context; - } - - - public SipStandardContext deployShootist(Map params) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp"); - context.setName("shootist-context"); - context.setPath("shootist-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setConcurrencyControlMode(ConcurrencyControlMode.SipApplicationSession); - context.setManager(new SipStandardManager()); - for (Entry param : params.entrySet()) { - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(param.getKey()); - applicationParameter.setValue(param.getValue()); - context.addApplicationParameter(applicationParameter); - } - assertTrue(tomcatShootist.deployContext(context)); - return context; - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/simple/simple-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - tomcatShootist = new SipEmbedded("tomcatShootist", serviceFullClassName); - tomcatShootist.setLoggingFilePath( - projectHome + File.separatorChar + "sip-servlets-test-suite" + - File.separatorChar + "testsuite" + - File.separatorChar + "src" + - File.separatorChar + "test" + - File.separatorChar + "resources" + File.separatorChar); - logger.info("Log4j path is : " + tomcatShootist.getLoggingFilePath()); - String darConfigurationFile = getDarConfigurationFile(); - tomcatShootist.setDarConfigurationFilePath(darConfigurationFile); - tomcatShootist.initTomcat(darConfigurationFile, getSipStackProperties("mss-Shootist")); - tomcatShootist.startTomcat(); - shootistConnector = tomcatShootist.addSipConnector("tomcatShootist", System.getProperty("org.mobicents.testsuite.testhostaddr"), 5090, listeningPointTransport); - - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, "4", "true"); - receiver = new TestSipListener(5081, 5070, receiverProtocolObjects, true); - receiverProvider = receiver.createProvider(); - receiverProvider.addSipListener(receiver); - receiverProtocolObjects.start(); - } - - public void testNoTimeout() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - ((SIPTransactionStack)tomcat.getSipService().getSipStack()).setReliableConnectionKeepAliveTimeout(2200); - ((SIPTransactionStack)tomcatShootist.getSipService().getSipStack()).setReliableConnectionKeepAliveTimeout(2200); - - Map params = new HashMap(); - deployShootme(params); - params = new HashMap(); - params.put("host", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + sipConnector.getPort()+";transport=tcp;"); - params.put("noBye", "true"); - params.put("testKeepAlive", "100"); - deployShootist(params); - Thread.sleep(TIMEOUT); - Iterator allMessagesIterator = receiver.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertEquals(0, receiver.getAllMessagesContent().size()); - } - - public void testShootmeTimeout() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - ((SIPTransactionStack)tomcat.getSipService().getSipStack()).setReliableConnectionKeepAliveTimeout(2200); - ((SIPTransactionStack)tomcatShootist.getSipService().getSipStack()).setReliableConnectionKeepAliveTimeout(2200); - - Map params = new HashMap(); - deployShootme(params); - params = new HashMap(); - params.put("host", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + sipConnector.getPort()+";transport=tcp;"); - params.put("noBye", "true"); - params.put("testKeepAlive", "1"); - deployShootist(params); - Thread.sleep(TIMEOUT); - Iterator allMessagesIterator = receiver.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertTrue("shootme onKeepAliveTimeout", receiver.getAllMessagesContent().contains("shootme onKeepAliveTimeout")); - assertEquals(1, receiver.getAllMessagesContent().size()); - } - - public void testShootistTimeout() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - ((SIPTransactionStack)tomcat.getSipService().getSipStack()).setReliableConnectionKeepAliveTimeout(2200); - ((SIPTransactionStack)tomcatShootist.getSipService().getSipStack()).setReliableConnectionKeepAliveTimeout(2200); - - Map params = new HashMap(); - deployShootme(params); - params = new HashMap(); - params.put("host", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + sipConnector.getPort()+";transport=tcp;"); - params.put("noBye", "true"); - params.put("testKeepAlive", "100"); - deployShootist(params); - Thread.sleep(TIMEOUT); - tomcat.stopTomcat(); - Thread.sleep(TIMEOUT/2); - Iterator allMessagesIterator = receiver.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertTrue("shootist onKeepAliveTimeout", receiver.getAllMessagesContent().contains("shootist onKeepAliveTimeout")); - assertEquals(1, receiver.getAllMessagesContent().size()); - } - - // making sure that we don't receive one timeout per Connection Based Transport Connector - public void testShootistTimeoutMultipleListeningPoints() throws Exception { - ((SIPTransactionStack)tomcat.getSipService().getSipStack()).setReliableConnectionKeepAliveTimeout(2200); - ((SIPTransactionStack)tomcatShootist.getSipService().getSipStack()).setReliableConnectionKeepAliveTimeout(2200); - - tomcat.addSipConnector(serverName, "" + System.getProperty("org.mobicents.testsuite.testhostaddr"), 5070, ListeningPoint.TLS); - tomcatShootist.addSipConnector(serverName, "" + System.getProperty("org.mobicents.testsuite.testhostaddr"), 5090, ListeningPoint.TLS); - Map params = new HashMap(); - deployShootme(params); - params = new HashMap(); - params.put("host", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + sipConnector.getPort()+";transport=tcp;"); - params.put("noBye", "true"); - params.put("testKeepAlive", "100"); - deployShootist(params); - Thread.sleep(TIMEOUT); - tomcat.stopTomcat(); - Thread.sleep(TIMEOUT/2); - Iterator allMessagesIterator = receiver.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertTrue("shootist onKeepAliveTimeout", receiver.getAllMessagesContent().contains("shootist onKeepAliveTimeout")); - assertEquals(1, receiver.getAllMessagesContent().size()); - } - - public void testShootistModifyKeepAliveTimeout() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - ((SIPTransactionStack)tomcat.getSipService().getSipStack()).setReliableConnectionKeepAliveTimeout(2200); - ((SIPTransactionStack)tomcatShootist.getSipService().getSipStack()).setReliableConnectionKeepAliveTimeout(2200); - - Map params = new HashMap(); - params.put("changeKeepAliveTimeout", "1000"); - params.put("timeout", "" + TIMEOUT); - deployShootme(params); - params = new HashMap(); - params.put("host", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + sipConnector.getPort()+";transport=tcp;"); - params.put("noBye", "true"); - params.put("testKeepAlive", "100"); - deployShootist(params); - Thread.sleep(TIMEOUT); - assertEquals(0, receiver.getAllMessagesContent().size()); - Thread.sleep(TIMEOUT); - Iterator allMessagesIterator = receiver.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertTrue("shootme onKeepAliveTimeout", receiver.getAllMessagesContent().contains("shootme onKeepAliveTimeout")); - assertTrue("shootist onKeepAliveTimeout", receiver.getAllMessagesContent().contains("shootme onKeepAliveTimeout")); - assertTrue(receiver.getAllMessagesContent().size()>0); - } - - public void testShootistCloseReliableChannel() throws Exception { - ((SIPTransactionStack)tomcat.getSipService().getSipStack()).setReliableConnectionKeepAliveTimeout(2200); - ((SIPTransactionStack)tomcatShootist.getSipService().getSipStack()).setReliableConnectionKeepAliveTimeout(2200); - - Map params = new HashMap(); - deployShootme(params); - params = new HashMap(); - params.put("host", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + sipConnector.getPort()+";transport=tcp;"); - params.put("noBye", "true"); - params.put("testKeepAlive", "100"); - if(!((SipStackImpl)tomcatShootist.getSipService().getSipStack()).getMessageProcessorFactory().getClass().getName().equals(NioMessageProcessorFactory.class.getName())) { - params.put("closeReliableChannel", "true"); - params.put("timeout", "" + TIMEOUT); - } else { - logger.debug("Nio setup we will kill the connection through removal of connector to avoid the retry mechanism false positivie"); - } - deployShootist(params); - Thread.sleep(TIMEOUT); - if(((SipStackImpl)tomcatShootist.getSipService().getSipStack()).getMessageProcessorFactory().getClass().getName().equals(NioMessageProcessorFactory.class.getName())) { - logger.debug("killing the connection through removal of connector to avoid the retry mechanism false positivie"); - tomcatShootist.removeConnector(shootistConnector); - } - assertEquals(0, receiver.getAllMessagesContent().size()); - Thread.sleep(TIMEOUT); - Iterator allMessagesIterator = receiver.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertTrue("shootme onKeepAliveTimeout", receiver.getAllMessagesContent().contains("shootme onKeepAliveTimeout")); - assertEquals(1, receiver.getAllMessagesContent().size()); - } - - @Override - protected Properties getSipStackProperties() { - return getSipStackProperties(getName()); - } - - protected Properties getSipStackProperties(String name) { - Properties sipStackProperties = new Properties(); - sipStackProperties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", - "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", - "32"); - sipStackProperties.setProperty(SipStandardService.DEBUG_LOG_STACK_PROP, - tomcatBasePath + "/" + "mss-jsip-" + getName() +"-debug.txt"); - sipStackProperties.setProperty(SipStandardService.SERVER_LOG_STACK_PROP, - tomcatBasePath + "/" + "mss-jsip-" + getName() +"-messages.xml"); - sipStackProperties.setProperty("javax.sip.STACK_NAME", "mss-" + name); - sipStackProperties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", "off"); - sipStackProperties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.THREAD_POOL_SIZE", "64"); - sipStackProperties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", "true"); - sipStackProperties.setProperty("gov.nist.javax.sip.MAX_FORK_TIME_SECONDS", "1"); - sipStackProperties.setProperty(SipStandardService.LOOSE_DIALOG_VALIDATION, "true"); - sipStackProperties.setProperty(SipStandardService.PASS_INVITE_NON_2XX_ACK_TO_LISTENER, "true"); - return sipStackProperties; - } - - @Override - protected void tearDown() throws Exception { - receiverProtocolObjects.destroy(); -// registerRecieverProtocolObjects.destroy(); - tomcatShootist.stopTomcat(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.simple.rfc5626; + +import gov.nist.javax.sip.SipStackImpl; +import gov.nist.javax.sip.stack.NioMessageProcessorFactory; +import gov.nist.javax.sip.stack.SIPTransactionStack; + +import java.io.File; +import java.text.ParseException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Properties; + +import javax.sip.InvalidArgumentException; +import javax.sip.ListeningPoint; +import javax.sip.SipException; +import javax.sip.SipProvider; +import static junit.framework.Assert.assertTrue; + +import org.apache.catalina.connector.Connector; +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipEmbedded; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; +import org.mobicents.servlet.sip.catalina.SipStandardService; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +/** + * Added for Issue 2254 http://code.google.com/p/mobicents/issues/detail?id=2254 + * Testing keepalive section 4.4.1 + * + * @author jean.deruelle@gmail.com + * + */ +public class RFC5626KeepAliveSipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(RFC5626KeepAliveSipServletTest.class); + + private static final String TRANSPORT = "tcp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 30000; +// private static final int TIMEOUT = 100000000; + + SipEmbedded tomcatShootist; + + TestSipListener receiver; + SipProvider receiverProvider = null; + ProtocolObjects receiverProtocolObjects; + int receiverPort; + int shootistContainerPort; + + private Connector shootistConnector; + + public RFC5626KeepAliveSipServletTest(String name) { + super(name); + listeningPointTransport = ListeningPoint.TCP; + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + + } + + public void deployShootme(Map params) { + SipStandardContext context = deployApplication(projectHome + + "/sip-servlets-test-suite/applications/simple-sip-servlet/src/main/sipapp", + "sip-test", + params, + ConcurrencyControlMode.SipApplicationSession); + assertTrue(context.getAvailable()); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/simple/simple-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + tomcatShootist = new SipEmbedded("tomcatShootist", serviceFullClassName); + tomcatShootist.setLoggingFilePath( + projectHome + File.separatorChar + "sip-servlets-test-suite" + + File.separatorChar + "testsuite" + + File.separatorChar + "src" + + File.separatorChar + "test" + + File.separatorChar + "resources" + File.separatorChar); + logger.info("Log4j path is : " + tomcatShootist.getLoggingFilePath()); + String darConfigurationFile = getDarConfigurationFile(); + tomcatShootist.setDarConfigurationFilePath(darConfigurationFile); + tomcatShootist.initTomcat(darConfigurationFile, getSipStackProperties("mss-Shootist")); + tomcatShootist.startTomcat(); + shootistContainerPort = NetworkPortAssigner.retrieveNextPort(); + shootistConnector = tomcatShootist.addSipConnector("tomcatShootist", System.getProperty("org.mobicents.testsuite.testhostaddr"), shootistContainerPort, listeningPointTransport); + + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, "4", "true"); + receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, true); + receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + } + + public void testNoTimeout() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + ((SIPTransactionStack) tomcat.getSipService().getSipStack()).setReliableConnectionKeepAliveTimeout(2200); + ((SIPTransactionStack) tomcatShootist.getSipService().getSipStack()).setReliableConnectionKeepAliveTimeout(2200); + + Map params = new HashMap(); + params.put("testPort", String.valueOf(receiverPort)); + params.put("servletContainerPort", String.valueOf(containerPort)); + deployShootme(params); + + params = new HashMap(); + params.put("testPort", String.valueOf(receiverPort)); + params.put("servletContainerPort", String.valueOf(shootistContainerPort)); + params.put("host", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + sipConnector.getPort() + ";transport=tcp;"); + params.put("noBye", "true"); + params.put("testKeepAlive", "100"); + deployShootist(params, null); + + Thread.sleep(TIMEOUT); + Iterator allMessagesIterator = receiver.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertEquals(0, receiver.getAllMessagesContent().size()); + } + + public void testShootmeTimeout() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + ((SIPTransactionStack) tomcat.getSipService().getSipStack()).setReliableConnectionKeepAliveTimeout(2200); + ((SIPTransactionStack) tomcatShootist.getSipService().getSipStack()).setReliableConnectionKeepAliveTimeout(2200); + + Map params = new HashMap(); + params.put("testPort", String.valueOf(receiverPort)); + params.put("servletContainerPort", String.valueOf(containerPort)); + deployShootme(params); + + params = new HashMap(); + params.put("testPort", String.valueOf(receiverPort)); + params.put("servletContainerPort", String.valueOf(shootistContainerPort)); + params.put("host", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + sipConnector.getPort() + ";transport=tcp;"); + params.put("noBye", "true"); + params.put("testKeepAlive", "1"); + deployShootist(params, null); + + Thread.sleep(TIMEOUT); + Iterator allMessagesIterator = receiver.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertTrue("shootme onKeepAliveTimeout", receiver.getAllMessagesContent().contains("shootme onKeepAliveTimeout")); + assertEquals(1, receiver.getAllMessagesContent().size()); + } + + public void testShootistTimeout() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + ((SIPTransactionStack) tomcat.getSipService().getSipStack()).setReliableConnectionKeepAliveTimeout(2200); + ((SIPTransactionStack) tomcatShootist.getSipService().getSipStack()).setReliableConnectionKeepAliveTimeout(2200); + + Map params = new HashMap(); + params.put("testPort", String.valueOf(5081));//dont let shootme send MESSAGE + params.put("servletContainerPort", String.valueOf(containerPort)); + deployShootme(params); + + params = new HashMap(); + params.put("testPort", String.valueOf(receiverPort)); + params.put("servletContainerPort", String.valueOf(shootistContainerPort)); + params.put("host", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + sipConnector.getPort() + ";transport=tcp;"); + params.put("noBye", "true"); + params.put("testKeepAlive", "100"); + deployShootist(params, null); + + Thread.sleep(TIMEOUT); + tomcat.stopTomcat(); + Thread.sleep(TIMEOUT / 2); + Iterator allMessagesIterator = receiver.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertTrue("shootist onKeepAliveTimeout", receiver.getAllMessagesContent().contains("shootist onKeepAliveTimeout")); + assertEquals(1, receiver.getAllMessagesContent().size()); + } + + // making sure that we don't receive one timeout per Connection Based Transport Connector + public void testShootistTimeoutMultipleListeningPoints() throws Exception { + ((SIPTransactionStack) tomcat.getSipService().getSipStack()).setReliableConnectionKeepAliveTimeout(2200); + ((SIPTransactionStack) tomcatShootist.getSipService().getSipStack()).setReliableConnectionKeepAliveTimeout(2200); + + tomcat.addSipConnector(serverName, "" + System.getProperty("org.mobicents.testsuite.testhostaddr"), containerPort, ListeningPoint.TLS); + tomcatShootist.addSipConnector(serverName, "" + System.getProperty("org.mobicents.testsuite.testhostaddr"), shootistContainerPort, ListeningPoint.TLS); + + Map params = new HashMap(); + params.put("testPort", String.valueOf(5081));//dont let shootme send MESSAGE + params.put("servletContainerPort", String.valueOf(containerPort)); + deployShootme(params); + + params = new HashMap(); + params.put("testPort", String.valueOf(receiverPort)); + params.put("servletContainerPort", String.valueOf(shootistContainerPort)); + params.put("host", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + sipConnector.getPort() + ";transport=tcp;"); + params.put("noBye", "true"); + params.put("testKeepAlive", "100"); + deployShootist(params, null); + + Thread.sleep(TIMEOUT); + tomcat.stopTomcat(); + Thread.sleep(TIMEOUT / 2); + Iterator allMessagesIterator = receiver.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertTrue("shootist onKeepAliveTimeout", receiver.getAllMessagesContent().contains("shootist onKeepAliveTimeout")); + assertEquals(1, receiver.getAllMessagesContent().size()); + } + + public void testShootistModifyKeepAliveTimeout() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + ((SIPTransactionStack) tomcat.getSipService().getSipStack()).setReliableConnectionKeepAliveTimeout(2200); + ((SIPTransactionStack) tomcatShootist.getSipService().getSipStack()).setReliableConnectionKeepAliveTimeout(2200); + + Map params = new HashMap(); + params.put("changeKeepAliveTimeout", "1000"); + params.put("timeout", "" + TIMEOUT); + params.put("testPort", String.valueOf(receiverPort)); + params.put("servletContainerPort", String.valueOf(containerPort)); + deployShootme(params); + + params = new HashMap(); + params.put("testPort", String.valueOf(receiverPort)); + params.put("servletContainerPort", String.valueOf(shootistContainerPort)); + params.put("host", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + sipConnector.getPort() + ";transport=tcp;"); + params.put("noBye", "true"); + params.put("testKeepAlive", "100"); + deployShootist(params, null); + + Thread.sleep(TIMEOUT); + assertEquals(0, receiver.getAllMessagesContent().size()); + Thread.sleep(TIMEOUT); + Iterator allMessagesIterator = receiver.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertTrue("shootme onKeepAliveTimeout", receiver.getAllMessagesContent().contains("shootme onKeepAliveTimeout")); + assertTrue("shootist onKeepAliveTimeout", receiver.getAllMessagesContent().contains("shootme onKeepAliveTimeout")); + assertTrue(receiver.getAllMessagesContent().size() > 0); + } + + public void testShootistCloseReliableChannel() throws Exception { + ((SIPTransactionStack) tomcat.getSipService().getSipStack()).setReliableConnectionKeepAliveTimeout(2200); + ((SIPTransactionStack) tomcatShootist.getSipService().getSipStack()).setReliableConnectionKeepAliveTimeout(2200); + + Map params = new HashMap(); + params.put("testPort", String.valueOf(receiverPort)); + params.put("servletContainerPort", String.valueOf(containerPort)); + deployShootme(params); + + params = new HashMap(); + params.put("testPort", String.valueOf(receiverPort)); + params.put("servletContainerPort", String.valueOf(shootistContainerPort)); + params.put("host", "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + sipConnector.getPort() + ";transport=tcp;"); + params.put("noBye", "true"); + params.put("testKeepAlive", "100"); + if (!((SipStackImpl) tomcatShootist.getSipService().getSipStack()).getMessageProcessorFactory().getClass().getName().equals(NioMessageProcessorFactory.class.getName())) { + params.put("closeReliableChannel", "true"); + params.put("timeout", "" + TIMEOUT); + } else { + logger.debug("Nio setup we will kill the connection through removal of connector to avoid the retry mechanism false positivie"); + } + deployShootist(params, null); + + Thread.sleep(TIMEOUT); + if (((SipStackImpl) tomcatShootist.getSipService().getSipStack()).getMessageProcessorFactory().getClass().getName().equals(NioMessageProcessorFactory.class.getName())) { + logger.debug("killing the connection through removal of connector to avoid the retry mechanism false positivie"); + tomcatShootist.removeConnector(shootistConnector); + } + assertEquals(0, receiver.getAllMessagesContent().size()); + Thread.sleep(TIMEOUT); + Iterator allMessagesIterator = receiver.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertTrue("shootme onKeepAliveTimeout", receiver.getAllMessagesContent().contains("shootme onKeepAliveTimeout")); + assertEquals(1, receiver.getAllMessagesContent().size()); + } + + @Override + protected Properties getSipStackProperties() { + return getSipStackProperties(getName()); + } + + protected Properties getSipStackProperties(String name) { + Properties sipStackProperties = new Properties(); + sipStackProperties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", + "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", + "32"); + sipStackProperties.setProperty(SipStandardService.DEBUG_LOG_STACK_PROP, + tomcatBasePath + "/" + "mss-jsip-" + getName() + "-debug.txt"); + sipStackProperties.setProperty(SipStandardService.SERVER_LOG_STACK_PROP, + tomcatBasePath + "/" + "mss-jsip-" + getName() + "-messages.xml"); + sipStackProperties.setProperty("javax.sip.STACK_NAME", "mss-" + name); + sipStackProperties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", "off"); + sipStackProperties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.THREAD_POOL_SIZE", "64"); + sipStackProperties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", "true"); + sipStackProperties.setProperty("gov.nist.javax.sip.MAX_FORK_TIME_SECONDS", "1"); + sipStackProperties.setProperty(SipStandardService.LOOSE_DIALOG_VALIDATION, "true"); + sipStackProperties.setProperty(SipStandardService.PASS_INVITE_NON_2XX_ACK_TO_LISTENER, "true"); + return sipStackProperties; + } + + @Override + protected void tearDown() throws Exception { + receiverProtocolObjects.destroy(); +// registerRecieverProtocolObjects.destroy(); + tomcatShootist.stopTomcat(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/subsnotify/InDialogNotifierSipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/subsnotify/InDialogNotifierSipServletTest.java index 49acf79186..eb103d2bda 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/subsnotify/InDialogNotifierSipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/subsnotify/InDialogNotifierSipServletTest.java @@ -1,184 +1,198 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.subsnotify; - -import gov.nist.javax.sip.header.SubscriptionState; - -import java.text.ParseException; - -import javax.sip.InvalidArgumentException; -import javax.sip.SipException; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; -import javax.sip.message.Request; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class InDialogNotifierSipServletTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(InDialogNotifierSipServletTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 5000; -// private static final int TIMEOUT = 100000000; - - private static final String[] SUBSCRIPTION_STATES = new String[]{ - SubscriptionState.PENDING.toLowerCase(), SubscriptionState.ACTIVE.toLowerCase(), SubscriptionState.TERMINATED.toLowerCase() - }; - - private static final String SESSION_INVALIDATED = new String("sipSessionReadyToBeInvalidated"); - - TestSipListener sender; - - ProtocolObjects senderProtocolObjects; - - - public InDialogNotifierSipServletTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/notifier-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/subsnotify/indialog-notifier-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() { - try { - super.setUp(); - - senderProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - } catch (Exception ex) { - ex.printStackTrace(); - fail("unexpected exception "); - } - } - - /* - * Test the fact that a sip servlet receive SUBSCRIBE and sends NOTIFYs in response in an existing dialog (INVITE call). - * Check that everything works correctly included the Sip Session Termination. - * Session Termination should occur only when the last NOTIFY comes in is since the NOTIFY - * containing Subscription State of Terminated is sent after the BYE - */ - public void testInDialogSubscriptionByeSentBeforeTerminatingNotify() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest(Request.INVITE, fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - - sender.setSendByeBeforeTerminatingNotify(true); - sender.sendInDialogSipRequest(Request.SUBSCRIBE, null, null, null, null, null); - Thread.sleep(TIMEOUT*2); - assertTrue(sender.getOkToByeReceived()); - for (String subscriptionState : sender.getAllSubscriptionState()) { - logger.info("Subscription state :" + subscriptionState); - } - assertEquals(3, sender.getAllSubscriptionState().size()); - for (String subscriptionState : SUBSCRIPTION_STATES) { - assertTrue(subscriptionState + " not present",sender.getAllSubscriptionState().contains(subscriptionState)); - } - Thread.sleep(TIMEOUT); - for (String message : sender.getAllMessagesContent()) { - logger.info("Message :" + message); - } - assertTrue(sender.getAllMessagesContent().size() >= 1); - assertTrue("session not invalidated after receiving Terminated Subscription State", sender.getAllMessagesContent().contains(SESSION_INVALIDATED)); - - } - - /* - * Test the fact that a sip servlet receive SUBSCRIBE and sends NOTIFYs in response in an existing dialog (INVITE call). - * Check that everything works correctly included the Sip Session Termination. - * Session Termination should occur only when the BYE is sent since the NOTIFY - * containing Subscription State of Terminated is sent before the BYE - */ - public void testInDialogSubscriptionByeSentAfterTerminatingNotify() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest(Request.INVITE, fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - - sender.setSendByeAfterTerminatingNotify(true); - sender.sendInDialogSipRequest(Request.SUBSCRIBE, null, null, null, null, null); - Thread.sleep(TIMEOUT*2); - assertTrue(sender.getOkToByeReceived()); - for (String subscriptionState : sender.getAllSubscriptionState()) { - logger.info("Subscription state :" + subscriptionState); - } - assertEquals(3, sender.getAllSubscriptionState().size()); - for (String subscriptionState : SUBSCRIPTION_STATES) { - assertTrue(subscriptionState + " not present",sender.getAllSubscriptionState().contains(subscriptionState)); - } - Thread.sleep(TIMEOUT); - assertTrue(sender.getAllMessagesContent().size() >= 1); - assertTrue("session not invalidated after receiving Terminated Subscription State", sender.getAllMessagesContent().contains(SESSION_INVALIDATED)); - - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.subsnotify; + +import gov.nist.javax.sip.header.SubscriptionState; + +import java.text.ParseException; +import java.util.HashMap; +import java.util.Map; + +import javax.sip.InvalidArgumentException; +import javax.sip.SipException; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import javax.sip.message.Request; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class InDialogNotifierSipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(InDialogNotifierSipServletTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 5000; +// private static final int TIMEOUT = 100000000; + + private static final String[] SUBSCRIPTION_STATES = new String[]{ + SubscriptionState.PENDING.toLowerCase(), SubscriptionState.ACTIVE.toLowerCase(), SubscriptionState.TERMINATED.toLowerCase() + }; + + private static final String SESSION_INVALIDATED = new String("sipSessionReadyToBeInvalidated"); + + TestSipListener sender; + + ProtocolObjects senderProtocolObjects; + + public InDialogNotifierSipServletTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + public SipStandardContext deployApplication(Map params) { + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/notifier-servlet/src/main/sipapp", + "sip-test", + params, + null); + assertTrue(ctx.getAvailable()); + return ctx; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/subsnotify/indialog-notifier-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() { + try { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + deployApplication(params); + } catch (Exception ex) { + ex.printStackTrace(); + fail("unexpected exception "); + } + } + + /* + * Test the fact that a sip servlet receive SUBSCRIBE and sends NOTIFYs in response in an existing dialog (INVITE call). + * Check that everything works correctly included the Sip Session Termination. + * Session Termination should occur only when the last NOTIFY comes in is since the NOTIFY + * containing Subscription State of Terminated is sent after the BYE + */ + public void testInDialogSubscriptionByeSentBeforeTerminatingNotify() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest(Request.INVITE, fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + + sender.setSendByeBeforeTerminatingNotify(true); + sender.sendInDialogSipRequest(Request.SUBSCRIBE, null, null, null, null, null); + Thread.sleep(TIMEOUT * 2); + assertTrue(sender.getOkToByeReceived()); + for (String subscriptionState : sender.getAllSubscriptionState()) { + logger.info("Subscription state :" + subscriptionState); + } + assertEquals(3, sender.getAllSubscriptionState().size()); + for (String subscriptionState : SUBSCRIPTION_STATES) { + assertTrue(subscriptionState + " not present", sender.getAllSubscriptionState().contains(subscriptionState)); + } + Thread.sleep(TIMEOUT); + for (String message : sender.getAllMessagesContent()) { + logger.info("Message :" + message); + } + assertTrue(sender.getAllMessagesContent().size() >= 1); + assertTrue("session not invalidated after receiving Terminated Subscription State", sender.getAllMessagesContent().contains(SESSION_INVALIDATED)); + + } + + /* + * Test the fact that a sip servlet receive SUBSCRIBE and sends NOTIFYs in response in an existing dialog (INVITE call). + * Check that everything works correctly included the Sip Session Termination. + * Session Termination should occur only when the BYE is sent since the NOTIFY + * containing Subscription State of Terminated is sent before the BYE + */ + public void testInDialogSubscriptionByeSentAfterTerminatingNotify() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest(Request.INVITE, fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + + sender.setSendByeAfterTerminatingNotify(true); + sender.sendInDialogSipRequest(Request.SUBSCRIBE, null, null, null, null, null); + Thread.sleep(TIMEOUT * 2); + assertTrue(sender.getOkToByeReceived()); + for (String subscriptionState : sender.getAllSubscriptionState()) { + logger.info("Subscription state :" + subscriptionState); + } + assertEquals(3, sender.getAllSubscriptionState().size()); + for (String subscriptionState : SUBSCRIPTION_STATES) { + assertTrue(subscriptionState + " not present", sender.getAllSubscriptionState().contains(subscriptionState)); + } + Thread.sleep(TIMEOUT); + assertTrue(sender.getAllMessagesContent().size() >= 1); + assertTrue("session not invalidated after receiving Terminated Subscription State", sender.getAllMessagesContent().contains(SESSION_INVALIDATED)); + + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/subsnotify/InDialogSubscriberSipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/subsnotify/InDialogSubscriberSipServletTest.java index 213d96927c..96979658d8 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/subsnotify/InDialogSubscriberSipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/subsnotify/InDialogSubscriberSipServletTest.java @@ -1,164 +1,178 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.subsnotify; - -import gov.nist.javax.sip.header.SubscriptionState; - -import java.text.ParseException; - -import javax.sip.InvalidArgumentException; -import javax.sip.SipException; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; -import javax.sip.message.Request; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class InDialogSubscriberSipServletTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(InDialogSubscriberSipServletTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; -// private static final int TIMEOUT = 100000000; - - private static final String[] SUBSCRIPTION_STATES = new String[]{ - SubscriptionState.PENDING.toLowerCase(), SubscriptionState.ACTIVE.toLowerCase(), SubscriptionState.TERMINATED.toLowerCase() - }; - - private static final String SESSION_INVALIDATED = new String("sipSessionReadyToBeInvalidated"); - - TestSipListener sender; - - ProtocolObjects senderProtocolObjects; - - - public InDialogSubscriberSipServletTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/subscriber-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/subsnotify/indialog-subscriber-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - senderProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - } - - /* - * Test the fact that a sip servlet send SUBSCRIBEs and receives NOTIFYs in response in an existing dialog (INVITE call). - * Check that everything works correctly included the Sip Session Termination. - * Session Termination should occur only when the last NOTIFY goes out since the NOTIFY - * containing Subscription State of Terminated is sent after the BYE - */ - public void testInDialogSubscriptionByeSentBeforeTerminatingNotify() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setSendByeBeforeTerminatingNotify(true); - sender.sendSipRequest(Request.INVITE, fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - - Thread.sleep(TIMEOUT*2); - assertTrue(sender.getOkToByeReceived()); - assertEquals(SUBSCRIPTION_STATES.length, sender.getAllSubscriptionState().size()); - for (String subscriptionState : SUBSCRIPTION_STATES) { - assertTrue(subscriptionState + " not present", sender.getAllSubscriptionState().contains(subscriptionState)); - } - assertTrue("session not invalidated after receiving Terminated Subscription State", sender.getAllMessagesContent().contains(SESSION_INVALIDATED)); - } - - /* - * Test the fact that a sip servlet send SUBSCRIBEs and receives NOTIFYs in response in an existing dialog (INVITE call). - * Check that everything works correctly included the Sip Session Termination. - * Session Termination should occur only when the BYE is sent since the NOTIFY - * containing Subscription State of Terminated is sent before the BYE - */ - public void testInDialogSubscriptionByeSentAfterTerminatingNotify() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setSendByeAfterTerminatingNotify(true); - sender.sendSipRequest(Request.INVITE, fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - - Thread.sleep(TIMEOUT); - assertEquals(SUBSCRIPTION_STATES.length, sender.getAllSubscriptionState().size()); - for (String subscriptionState : SUBSCRIPTION_STATES) { - assertTrue(subscriptionState + " not present", sender.getAllSubscriptionState().contains(subscriptionState)); - } - sender.sendBye(); - Thread.sleep(TIMEOUT); - assertTrue(sender.getOkToByeReceived()); - assertTrue("session not invalidated after receiving Terminated Subscription State", sender.getAllMessagesContent().contains(SESSION_INVALIDATED)); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.subsnotify; + +import gov.nist.javax.sip.header.SubscriptionState; + +import java.text.ParseException; +import java.util.HashMap; +import java.util.Map; + +import javax.sip.InvalidArgumentException; +import javax.sip.SipException; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import javax.sip.message.Request; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class InDialogSubscriberSipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(InDialogSubscriberSipServletTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; +// private static final int TIMEOUT = 100000000; + + private static final String[] SUBSCRIPTION_STATES = new String[]{ + SubscriptionState.PENDING.toLowerCase(), SubscriptionState.ACTIVE.toLowerCase(), SubscriptionState.TERMINATED.toLowerCase() + }; + + private static final String SESSION_INVALIDATED = new String("sipSessionReadyToBeInvalidated"); + + TestSipListener sender; + + ProtocolObjects senderProtocolObjects; + + public InDialogSubscriberSipServletTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + public SipStandardContext deployApplication(Map params) { + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/subscriber-servlet/src/main/sipapp", + "sip-test", + params, + null); + assertTrue(ctx.getAvailable()); + return ctx; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/subsnotify/indialog-subscriber-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + deployApplication(params); + } + + /* + * Test the fact that a sip servlet send SUBSCRIBEs and receives NOTIFYs in response in an existing dialog (INVITE call). + * Check that everything works correctly included the Sip Session Termination. + * Session Termination should occur only when the last NOTIFY goes out since the NOTIFY + * containing Subscription State of Terminated is sent after the BYE + */ + public void testInDialogSubscriptionByeSentBeforeTerminatingNotify() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setSendByeBeforeTerminatingNotify(true); + sender.sendSipRequest(Request.INVITE, fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + + Thread.sleep(TIMEOUT * 2); + assertTrue(sender.getOkToByeReceived()); + assertEquals(SUBSCRIPTION_STATES.length, sender.getAllSubscriptionState().size()); + for (String subscriptionState : SUBSCRIPTION_STATES) { + assertTrue(subscriptionState + " not present", sender.getAllSubscriptionState().contains(subscriptionState)); + } + assertTrue("session not invalidated after receiving Terminated Subscription State", sender.getAllMessagesContent().contains(SESSION_INVALIDATED)); + } + + /* + * Test the fact that a sip servlet send SUBSCRIBEs and receives NOTIFYs in response in an existing dialog (INVITE call). + * Check that everything works correctly included the Sip Session Termination. + * Session Termination should occur only when the BYE is sent since the NOTIFY + * containing Subscription State of Terminated is sent before the BYE + */ + public void testInDialogSubscriptionByeSentAfterTerminatingNotify() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setSendByeAfterTerminatingNotify(true); + sender.sendSipRequest(Request.INVITE, fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + + Thread.sleep(TIMEOUT); + assertEquals(SUBSCRIPTION_STATES.length, sender.getAllSubscriptionState().size()); + for (String subscriptionState : SUBSCRIPTION_STATES) { + assertTrue(subscriptionState + " not present", sender.getAllSubscriptionState().contains(subscriptionState)); + } + sender.sendBye(); + Thread.sleep(TIMEOUT); + assertTrue(sender.getOkToByeReceived()); + assertTrue("session not invalidated after receiving Terminated Subscription State", sender.getAllMessagesContent().contains(SESSION_INVALIDATED)); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/subsnotify/NotifierSipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/subsnotify/NotifierSipServletTest.java index 33c865a7b5..49027c320d 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/subsnotify/NotifierSipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/subsnotify/NotifierSipServletTest.java @@ -1,206 +1,201 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.subsnotify; - -import gov.nist.javax.sip.header.SubscriptionState; - -import java.util.HashMap; -import java.util.Map; - -import javax.sip.SipProvider; -import javax.sip.address.SipURI; -import javax.sip.message.Request; - -import org.apache.catalina.deploy.ApplicationParameter; -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class NotifierSipServletTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(NotifierSipServletTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; -// private static final int TIMEOUT = 100000000; - - private static final String[] SUBSCRIPTION_STATES = new String[]{ - SubscriptionState.PENDING.toLowerCase(), SubscriptionState.ACTIVE.toLowerCase(), SubscriptionState.TERMINATED.toLowerCase() - }; - - private static final String SESSION_INVALIDATED = new String("sipSessionReadyToBeInvalidated"); - - TestSipListener sender; - - ProtocolObjects senderProtocolObjects; - - - public NotifierSipServletTest(String name) { - super(name); - autoDeployOnStartup = false; - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/notifier-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - public SipStandardContext deployApplication(String name, String value) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/notifier-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(name); - applicationParameter.setValue(value); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - return context; - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/subsnotify/notifier-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - } - - /* - * Test the fact that a sip servlet receive SUBSCRIBEs and sends NOTIFYs in response. - * Check that everything works correctly included the Sip Session Termination upon sending a NOTIFY - * containing Subscription State of Terminated. - */ - public void testNotify() throws Exception { - senderProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - - deployApplication(); - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest(Request.SUBSCRIBE, fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertEquals(3, sender.getAllSubscriptionState().size()); - for (String subscriptionState : SUBSCRIPTION_STATES) { - assertTrue(subscriptionState + " not present",sender.getAllSubscriptionState().contains(subscriptionState)); - } - Thread.sleep(TIMEOUT); - assertTrue(sender.getAllMessagesContent().size() >= 1); - assertTrue("session not invalidated after receiving Terminated Subscription State", sender.getAllMessagesContent().contains(SESSION_INVALIDATED)); - } - -// /* -// * Test the fact that a sip servlet receive SUBSCRIBEs and sends NOTIFYs in response. -// * Check that everything works correctly included the Sip Session Termination upon sending a NOTIFY -// * containing Subscription State of Terminated. -// */ -// public void testNotify408() throws Exception { -// senderProtocolObjects =new ProtocolObjects( -// "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); -// -// sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); -// SipProvider senderProvider = sender.createProvider(); -// sender.setFinalResponseToSend(408); -// senderProvider.addSipListener(sender); -// -// senderProtocolObjects.start(); -// -// deployApplication(); -// String fromName = "sender"; -// String fromSipAddress = "sip-servlets.com"; -// SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( -// fromName, fromSipAddress); -// -// String toUser = "receiver"; -// String toSipAddress = "sip-servlets.com"; -// SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( -// toUser, toSipAddress); -// -// sender.sendSipRequest(Request.SUBSCRIBE, fromAddress, toAddress, null, null, false); -// Thread.sleep(TIMEOUT); -// for (String subscriptionState : SUBSCRIPTION_STATES) { -// assertTrue(subscriptionState + " not present",sender.getAllSubscriptionState().contains(subscriptionState)); -// } -// assertEquals(3, sender.getAllSubscriptionState().size()); -// Thread.sleep(TIMEOUT); -// assertTrue(sender.getAllMessagesContent().size() >= 1); -// assertTrue("session not invalidated after receiving Terminated Subscription State", sender.getAllMessagesContent().contains(SESSION_INVALIDATED)); -// } - - /* - * Test the fact that a sip servlet send an unsollicited NOTIFY - */ - public void testSendUnsollicitedNotify() throws Exception { - Map properties = new HashMap(); - properties.put("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); - senderProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null, properties); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - - deployApplication("sendUnsollictedNotify", "true"); - Thread.sleep(TIMEOUT); - assertTrue(sender.allRequests.size() >= 1); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.subsnotify; + +import gov.nist.javax.sip.header.SubscriptionState; + +import java.util.HashMap; +import java.util.Map; + +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import javax.sip.message.Request; + +import org.apache.catalina.deploy.ApplicationParameter; +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.catalina.SipStandardManager; +import org.mobicents.servlet.sip.startup.SipContextConfig; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class NotifierSipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(NotifierSipServletTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; +// private static final int TIMEOUT = 100000000; + + private static final String[] SUBSCRIPTION_STATES = new String[]{ + SubscriptionState.PENDING.toLowerCase(), SubscriptionState.ACTIVE.toLowerCase(), SubscriptionState.TERMINATED.toLowerCase() + }; + + private static final String SESSION_INVALIDATED = new String("sipSessionReadyToBeInvalidated"); + + TestSipListener sender; + + ProtocolObjects senderProtocolObjects; + + public NotifierSipServletTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + public SipStandardContext deployApplication(Map params) { + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/notifier-servlet/src/main/sipapp", + "sip-test", + params, + null); + assertTrue(ctx.getAvailable()); + return ctx; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/subsnotify/notifier-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + } + + /* + * Test the fact that a sip servlet receive SUBSCRIBEs and sends NOTIFYs in response. + * Check that everything works correctly included the Sip Session Termination upon sending a NOTIFY + * containing Subscription State of Terminated. + */ + public void testNotify() throws Exception { + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + deployApplication(params); + + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest(Request.SUBSCRIBE, fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertEquals(3, sender.getAllSubscriptionState().size()); + for (String subscriptionState : SUBSCRIPTION_STATES) { + assertTrue(subscriptionState + " not present", sender.getAllSubscriptionState().contains(subscriptionState)); + } + Thread.sleep(TIMEOUT); + assertTrue(sender.getAllMessagesContent().size() >= 1); + assertTrue("session not invalidated after receiving Terminated Subscription State", sender.getAllMessagesContent().contains(SESSION_INVALIDATED)); + } + +// /* +// * Test the fact that a sip servlet receive SUBSCRIBEs and sends NOTIFYs in response. +// * Check that everything works correctly included the Sip Session Termination upon sending a NOTIFY +// * containing Subscription State of Terminated. +// */ +// public void testNotify408() throws Exception { +// senderProtocolObjects =new ProtocolObjects( +// "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); +// +// sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); +// SipProvider senderProvider = sender.createProvider(); +// sender.setFinalResponseToSend(408); +// senderProvider.addSipListener(sender); +// +// senderProtocolObjects.start(); +// +// deployApplication(); +// String fromName = "sender"; +// String fromSipAddress = "sip-servlets.com"; +// SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( +// fromName, fromSipAddress); +// +// String toUser = "receiver"; +// String toSipAddress = "sip-servlets.com"; +// SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( +// toUser, toSipAddress); +// +// sender.sendSipRequest(Request.SUBSCRIBE, fromAddress, toAddress, null, null, false); +// Thread.sleep(TIMEOUT); +// for (String subscriptionState : SUBSCRIPTION_STATES) { +// assertTrue(subscriptionState + " not present",sender.getAllSubscriptionState().contains(subscriptionState)); +// } +// assertEquals(3, sender.getAllSubscriptionState().size()); +// Thread.sleep(TIMEOUT); +// assertTrue(sender.getAllMessagesContent().size() >= 1); +// assertTrue("session not invalidated after receiving Terminated Subscription State", sender.getAllMessagesContent().contains(SESSION_INVALIDATED)); +// } + /* + * Test the fact that a sip servlet send an unsollicited NOTIFY + */ + public void testSendUnsollicitedNotify() throws Exception { + Map properties = new HashMap(); + properties.put("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); + + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null, properties); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + params.put("sendUnsollictedNotify", "true"); + deployApplication(params); + Thread.sleep(TIMEOUT); + assertTrue(sender.allRequests.size() >= 1); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/subsnotify/ProxyNotifierSipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/subsnotify/ProxyNotifierSipServletTest.java index 49ebf5ef38..aff699c3b1 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/subsnotify/ProxyNotifierSipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/subsnotify/ProxyNotifierSipServletTest.java @@ -1,186 +1,206 @@ -/* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2014, Telestax Inc and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - * - * This file incorporates work covered by the following copyright contributed under the GNU LGPL : Copyright 2007-2011 Red Hat. - */ - -package org.mobicents.servlet.sip.testsuite.subsnotify; - -import java.text.ParseException; - -import javax.sip.InvalidArgumentException; -import javax.sip.SipException; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; -import javax.sip.header.RecordRouteHeader; -import javax.sip.header.ViaHeader; -import javax.sip.message.Request; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -/** - * http://code.google.com/p/mobicents/issues/detail?id=1481 - * NPE during 200 OK to SUBSCRIBE in proxy mode - * @author jean.deruelle@gmail.com - */ -public class ProxyNotifierSipServletTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(ProxyNotifierSipServletTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; - - TestSipListener sender; - ProtocolObjects senderProtocolObjects; - - TestSipListener receiver; - ProtocolObjects receiverProtocolObjects; - - - public ProxyNotifierSipServletTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/subsnotify/proxy-notifier-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() { - try { - super.setUp(); - - senderProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - senderProvider.addSipListener(sender); - senderProtocolObjects.start(); - - receiverProtocolObjects =new ProtocolObjects( - "receiver", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - receiver = new TestSipListener(5057, 5070, receiverProtocolObjects, false); - SipProvider receiverProvider = receiver.createProvider(); - receiverProvider.addSipListener(receiver); - receiverProtocolObjects.start(); - } catch (Exception ex) { - ex.printStackTrace(); - fail("unexpected exception "); - } - } - - /* - * Test the fact that a sip servlet proxies a SUBSCRIBE not in dialog - */ - public void testNotify() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "recordRoute"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - receiver.setSendNotify(false); - sender.sendSipRequest(Request.SUBSCRIBE, fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertEquals(202, sender.getFinalResponseStatus()); - - } - - /* - * https://code.google.com/p/sipservlets/issues/detail?id=275 - */ - public void testNotifyWithLateAnswerToSubscribe() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "recordRouting"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setRecordRoutingProxyTesting(true); - receiver.setSendNotify(true); - receiver.setSendNotifyBeforeResponseToSubscribe(true); - receiver.setWaitBeforeFinalResponse(receiver.getTimeToWaitBetweenSubsNotify()+1000); - sender.sendSipRequest(Request.SUBSCRIBE, fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT*2); - assertEquals(202, sender.getFinalResponseStatus()); - assertEquals(3, sender.notifyCount); - // https://github.com/RestComm/sip-servlets/issues/121 - for(Request request:sender.allRequests) { - if(request.getMethod().equals("NOTIFY")) { - assertNotNull(request.getHeader(RecordRouteHeader.NAME)); - } - } - } - - /* - * Test the fact that a sip servlet proxies a SUBSCRIBE in a dialog (INVITE Sent) - */ - public void testNotifyInDialog() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "recordRoute"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - receiver.setSendNotify(false); - sender.setRecordRoutingProxyTesting(true); - sender.setSendByeBeforeTerminatingNotify(true); - - sender.sendSipRequest(Request.INVITE, fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - sender.sendInDialogSipRequest(Request.SUBSCRIBE, null, null, null, null, null); - Thread.sleep(TIMEOUT); - assertEquals(202, sender.getFinalResponseStatus()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2014, Telestax Inc and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * + * This file incorporates work covered by the following copyright contributed under the GNU LGPL : Copyright 2007-2011 Red Hat. + */ +package org.mobicents.servlet.sip.testsuite.subsnotify; + +import java.text.ParseException; +import java.util.HashMap; +import java.util.Map; + +import javax.sip.InvalidArgumentException; +import javax.sip.SipException; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import javax.sip.header.RecordRouteHeader; +import javax.sip.header.ViaHeader; +import javax.sip.message.Request; +import static junit.framework.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +/** + * http://code.google.com/p/mobicents/issues/detail?id=1481 NPE during 200 OK to + * SUBSCRIBE in proxy mode + * + * @author jean.deruelle@gmail.com + */ +public class ProxyNotifierSipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(ProxyNotifierSipServletTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; + + TestSipListener sender; + ProtocolObjects senderProtocolObjects; + + TestSipListener receiver; + ProtocolObjects receiverProtocolObjects; + + public ProxyNotifierSipServletTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + public SipStandardContext deployApplication(Map params) { + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/proxy-sip-servlet/src/main/sipapp", + "sip-test", + params, + null); + assertTrue(ctx.getAvailable()); + return ctx; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/subsnotify/proxy-notifier-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() { + try { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + receiverProtocolObjects = new ProtocolObjects( + "receiver", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider receiverProvider = receiver.createProvider(); + receiverProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + params.put("receiverPort", String.valueOf(receiverPort)); + deployApplication(params); + } catch (Exception ex) { + ex.printStackTrace(); + fail("unexpected exception "); + } + } + + /* + * Test the fact that a sip servlet proxies a SUBSCRIBE not in dialog + */ + public void testNotify() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "recordRoute"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + receiver.setSendNotify(false); + sender.sendSipRequest(Request.SUBSCRIBE, fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertEquals(202, sender.getFinalResponseStatus()); + + } + + /* + * https://code.google.com/p/sipservlets/issues/detail?id=275 + */ + public void testNotifyWithLateAnswerToSubscribe() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "recordRouting"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setRecordRoutingProxyTesting(true); + receiver.setSendNotify(true); + receiver.setSendNotifyBeforeResponseToSubscribe(true); + receiver.setWaitBeforeFinalResponse(receiver.getTimeToWaitBetweenSubsNotify() + 1000); + sender.sendSipRequest(Request.SUBSCRIBE, fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT * 2); + assertEquals(202, sender.getFinalResponseStatus()); + assertEquals(3, sender.notifyCount); + // https://github.com/RestComm/sip-servlets/issues/121 + for (Request request : sender.allRequests) { + if (request.getMethod().equals("NOTIFY")) { + assertNotNull(request.getHeader(RecordRouteHeader.NAME)); + } + } + } + + /* + * Test the fact that a sip servlet proxies a SUBSCRIBE in a dialog (INVITE Sent) + */ + public void testNotifyInDialog() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "recordRoute"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + receiver.setSendNotify(false); + sender.setRecordRoutingProxyTesting(true); + sender.setSendByeBeforeTerminatingNotify(true); + + sender.sendSipRequest(Request.INVITE, fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + sender.sendInDialogSipRequest(Request.SUBSCRIBE, null, null, null, null, null); + Thread.sleep(TIMEOUT); + assertEquals(202, sender.getFinalResponseStatus()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/subsnotify/SubscriberSipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/subsnotify/SubscriberSipServletTest.java index 7332f8621b..09d2b3303c 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/subsnotify/SubscriberSipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/subsnotify/SubscriberSipServletTest.java @@ -1,221 +1,254 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.subsnotify; -import gov.nist.javax.sip.header.SubscriptionState; - -import javax.sip.SipProvider; -import javax.sip.address.SipURI; -import javax.sip.header.ContentTypeHeader; -import javax.sip.header.EventHeader; -import javax.sip.header.SubscriptionStateHeader; -import javax.sip.message.Request; - -import org.apache.catalina.deploy.ApplicationParameter; -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -public class SubscriberSipServletTest extends SipServletTestCase { - private static transient Logger logger = Logger.getLogger(SubscriberSipServletTest.class); - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 5000; -// private static final int TIMEOUT = 100000000; - - private static final String[] SUBSCRIPTION_STATES = new String[]{ - SubscriptionState.PENDING.toLowerCase(), SubscriptionState.ACTIVE.toLowerCase(), SubscriptionState.TERMINATED.toLowerCase() - }; - - private static final String SESSION_INVALIDATED = new String("sipSessionReadyToBeInvalidated"); - - TestSipListener receiver; - - ProtocolObjects receiverProtocolObjects; - - public SubscriberSipServletTest(String name) { - super(name); - autoDeployOnStartup = false; - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/subscriber-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - public SipStandardContext deployApplication(String name, String value) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/subscriber-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(name); - applicationParameter.setValue(value); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - return context; - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/subsnotify/subscriber-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - - } - - /* - * Test the fact that a sip servlet send a SUBSCRIBE (here 2 subscribes for different event ie subscriptions) - * and receive NOTIFYs. - * Check that everything works correctly included the Sip Session Termination upon receiving a NOTIFY - * containing Subscription State of Terminated. - */ - public void testSipServletSendsSubscribe() throws InterruptedException { - deployApplication(); -// receiver.sendInvite(); - Thread.sleep(TIMEOUT*2); - assertEquals(6, receiver.getAllSubscriptionState().size()); - for (String subscriptionState : SUBSCRIPTION_STATES) { - assertTrue(subscriptionState + " not present", receiver.getAllSubscriptionState().contains(subscriptionState)); - } - Thread.sleep(TIMEOUT); - assertEquals(1, receiver.getAllMessagesContent().size()); - assertTrue("session not invalidated after receiving Terminated Subscription State", receiver.getAllMessagesContent().contains(SESSION_INVALIDATED)); - - } - - /* - * Issue 1123 : http://code.google.com/p/mobicents/issues/detail?id=1123 - * Multipart type is not supported - */ - public void testSipServletsReceiveNotifyMultipart() throws Exception { - deployApplication("testMultipart", "testMultipart"); - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = receiverProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = receiverProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - String content = "--50UBfW7LSCVLtggUPe5z\r\nContent-Transfer-Encoding: binary\r\nContent-ID: \r\nContent-Type: application/rlmi+xml;charset=\"UTF-8\"\r\n\n\nBuddy List at COM\nListe der Freunde an COM\n\nBob Smith\n\n\n\nDave Jones\n\n\n\nEd at NET\n\n\nMy Friends at ORG\nMeine Freunde an ORG\n\n\n\n--50UBfW7LSCVLtggUPe5z\r\nContent-Transfer-Encoding: binary\r\nContent-ID: \r\nContent-Type: application/pidf+xml;charset=\"UTF-8\"\r\n\n\n\n\nopen\n\nsip:bob@vancouver.example.com\n\n\n\n--50UBfW7LSCVLtggUPe5z\r\nContent-Transfer-Encoding: binary\r\nContent-ID: \r\nContent-Type: application/pidf+xml;charset=\"UTF-8\"\r\n\n\n\n\nclosed\n\n\n\n\n--50UBfW7LSCVLtggUPe5z--"; - - receiver.sendSipRequest(Request.NOTIFY, fromAddress, toAddress, content, null, false, new String[] {ContentTypeHeader.NAME, SubscriptionStateHeader.NAME, EventHeader.NAME}, new String[]{"multipart/related;type=\"application/rlmi+xml\";start=\"\";boundary=\"50UBfW7LSCVLtggUPe5z\"", "pending", "presence"}, true); - Thread.sleep(TIMEOUT); - assertEquals(200, receiver.getFinalResponseStatus()); - assertTrue(receiver.getAllMessagesContent().size() > 0); - assertTrue(receiver.getAllMessagesContent().contains("3")); - } - - /* - * Issue 1123 : http://code.google.com/p/mobicents/issues/detail?id=1123 - * Multipart type is not supported - */ - public void testSipServletsReceiveSendNotifyMultipart() throws Exception { - deployApplication("testSendMultipart", "testSendMultipart"); - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = receiverProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = receiverProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - String content = "--50UBfW7LSCVLtggUPe5z\r\nContent-Transfer-Encoding: binary\r\nContent-ID: \r\nContent-Type: application/rlmi+xml;charset=\"UTF-8\"\r\n\n\nBuddy List at COM\nListe der Freunde an COM\n\nBob Smith\n\n\n\nDave Jones\n\n\n\nEd at NET\n\n\nMy Friends at ORG\nMeine Freunde an ORG\n\n\n\n--50UBfW7LSCVLtggUPe5z\r\nContent-Transfer-Encoding: binary\r\nContent-ID: \r\nContent-Type: application/pidf+xml;charset=\"UTF-8\"\r\n\n\n\n\nopen\n\nsip:bob@vancouver.example.com\n\n\n\n--50UBfW7LSCVLtggUPe5z\r\nContent-Transfer-Encoding: binary\r\nContent-ID: \r\nContent-Type: application/pidf+xml;charset=\"UTF-8\"\r\n\n\n\n\nclosed\n\n\n\n\n--50UBfW7LSCVLtggUPe5z--"; - - receiver.sendSipRequest(Request.NOTIFY, fromAddress, toAddress, content, null, false, new String[] {ContentTypeHeader.NAME, SubscriptionStateHeader.NAME, EventHeader.NAME}, new String[]{"multipart/related;type=\"application/rlmi+xml\";start=\"\";boundary=\"50UBfW7LSCVLtggUPe5z\"", "pending", "presence"}, true); - Thread.sleep(TIMEOUT); - assertEquals(200, receiver.getFinalResponseStatus()); - assertTrue(receiver.getAllMessagesContent().size() > 0); - assertTrue(receiver.getAllMessagesContent().contains("3")); - } - - // http://code.google.com/p/mobicents/issues/detail?id=2182 - public void testSipServletsReceiveNotifyMimeMultipartWhitespace() throws Exception { - deployApplication("testMimeMultipartWhitespaces", "testMimeMultipartWhitespaces"); - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = receiverProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = receiverProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - String content = "--1A713B7EE42ABF467A11E416\r\n" + "Content-Type: application/pidf+xml\r\n" - + "Content-ID: <317A166E4BEB17EA1A24F417@telecomsys.com>\r\n" + "\r\n" - + "\r\n" - + "\r\n" + "\r\n" + "\r\n" + "\r\n" - + "\r\n" - + "30.8686739957541 -97.0195399766783\r\n" + "\r\n" - + "\r\n" + "\r\n" - + "yes\r\n" + "\r\n" - + "Derived\r\n" + "www.telecomsys.com\r\n" - + "\r\n" + "\r\n" + "2010-05-17T17:20:55Z\r\n" - + "\r\n" + "\r\n" + "--1A713B7EE42ABF467A11E416\r\n" - + "Content-Type: application/sdp\r\n" + "\r\n" + "v=0\r\n" - + "o=user1 53655765 2353687637 IN IP4 10.15.90.101\r\n" + "s=-\r\n" + "c=IN IP4 10.15.90.101\r\n" - + "t=0 0\r\n" + "m=audio 6001 RTP/AVP 0\r\n" + "a=rtpmap:0 PCMU/8000\r\n"; - receiver.sendSipRequest(Request.NOTIFY, fromAddress, toAddress, content, null, false, new String[] {ContentTypeHeader.NAME, SubscriptionStateHeader.NAME, EventHeader.NAME}, new String[]{"multipart/related;type=\"application/rlmi+xml\";boundary=\"1A713B7EE42ABF467A11E416\"", "pending", "presence"}, true); - Thread.sleep(TIMEOUT); - assertEquals(200, receiver.getFinalResponseStatus()); - assertTrue(receiver.getAllMessagesContent().size() > 0); - assertTrue(receiver.getAllMessagesContent().contains("2")); - } - - @Override - protected void tearDown() throws Exception { - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } -} \ No newline at end of file +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.subsnotify; + +import gov.nist.javax.sip.header.SubscriptionState; +import java.util.HashMap; +import java.util.Map; + +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import javax.sip.header.ContentTypeHeader; +import javax.sip.header.EventHeader; +import javax.sip.header.SubscriptionStateHeader; +import javax.sip.message.Request; +import static junit.framework.Assert.assertTrue; + +import org.apache.catalina.deploy.ApplicationParameter; +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.catalina.SipStandardManager; +import org.mobicents.servlet.sip.startup.SipContextConfig; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +public class SubscriberSipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(SubscriberSipServletTest.class); + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 5000; +// private static final int TIMEOUT = 100000000; + + private static final String[] SUBSCRIPTION_STATES = new String[]{ + SubscriptionState.PENDING.toLowerCase(), SubscriptionState.ACTIVE.toLowerCase(), SubscriptionState.TERMINATED.toLowerCase() + }; + + private static final String SESSION_INVALIDATED = new String("sipSessionReadyToBeInvalidated"); + + TestSipListener receiver; + + ProtocolObjects receiverProtocolObjects; + + public SubscriberSipServletTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + } + + public SipStandardContext deployApplication(Map params) { + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/subscriber-servlet/src/main/sipapp", + "sip-test", + params, + null); + assertTrue(ctx.getAvailable()); + return ctx; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/subsnotify/subscriber-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + } + + /* + * Test the fact that a sip servlet send a SUBSCRIBE (here 2 subscribes for different event ie subscriptions) + * and receive NOTIFYs. + * Check that everything works correctly included the Sip Session Termination upon receiving a NOTIFY + * containing Subscription State of Terminated. + */ + public void testSipServletSendsSubscribe() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + senderProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + deployApplication(params); +// receiver.sendInvite(); + Thread.sleep(TIMEOUT * 2); + assertEquals(6, receiver.getAllSubscriptionState().size()); + for (String subscriptionState : SUBSCRIPTION_STATES) { + assertTrue(subscriptionState + " not present", receiver.getAllSubscriptionState().contains(subscriptionState)); + } + Thread.sleep(TIMEOUT); + assertEquals(1, receiver.getAllMessagesContent().size()); + assertTrue("session not invalidated after receiving Terminated Subscription State", receiver.getAllMessagesContent().contains(SESSION_INVALIDATED)); + + } + + /* + * Issue 1123 : http://code.google.com/p/mobicents/issues/detail?id=1123 + * Multipart type is not supported + */ + public void testSipServletsReceiveNotifyMultipart() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + senderProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("testMultipart", "testMultipart"); + deployApplication(params); + + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = receiverProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = receiverProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + String content = "--50UBfW7LSCVLtggUPe5z\r\nContent-Transfer-Encoding: binary\r\nContent-ID: \r\nContent-Type: application/rlmi+xml;charset=\"UTF-8\"\r\n\n\nBuddy List at COM\nListe der Freunde an COM\n\nBob Smith\n\n\n\nDave Jones\n\n\n\nEd at NET\n\n\nMy Friends at ORG\nMeine Freunde an ORG\n\n\n\n--50UBfW7LSCVLtggUPe5z\r\nContent-Transfer-Encoding: binary\r\nContent-ID: \r\nContent-Type: application/pidf+xml;charset=\"UTF-8\"\r\n\n\n\n\nopen\n\nsip:bob@vancouver.example.com\n\n\n\n--50UBfW7LSCVLtggUPe5z\r\nContent-Transfer-Encoding: binary\r\nContent-ID: \r\nContent-Type: application/pidf+xml;charset=\"UTF-8\"\r\n\n\n\n\nclosed\n\n\n\n\n--50UBfW7LSCVLtggUPe5z--"; + + receiver.sendSipRequest(Request.NOTIFY, fromAddress, toAddress, content, null, false, new String[]{ContentTypeHeader.NAME, SubscriptionStateHeader.NAME, EventHeader.NAME}, new String[]{"multipart/related;type=\"application/rlmi+xml\";start=\"\";boundary=\"50UBfW7LSCVLtggUPe5z\"", "pending", "presence"}, true); + Thread.sleep(TIMEOUT); + assertEquals(200, receiver.getFinalResponseStatus()); + assertTrue(receiver.getAllMessagesContent().size() > 0); + assertTrue(receiver.getAllMessagesContent().contains("3")); + } + + /* + * Issue 1123 : http://code.google.com/p/mobicents/issues/detail?id=1123 + * Multipart type is not supported + */ + public void testSipServletsReceiveSendNotifyMultipart() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + senderProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("testSendMultipart", "testSendMultipart"); + deployApplication(params); + + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = receiverProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = receiverProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + String content = "--50UBfW7LSCVLtggUPe5z\r\nContent-Transfer-Encoding: binary\r\nContent-ID: \r\nContent-Type: application/rlmi+xml;charset=\"UTF-8\"\r\n\n\nBuddy List at COM\nListe der Freunde an COM\n\nBob Smith\n\n\n\nDave Jones\n\n\n\nEd at NET\n\n\nMy Friends at ORG\nMeine Freunde an ORG\n\n\n\n--50UBfW7LSCVLtggUPe5z\r\nContent-Transfer-Encoding: binary\r\nContent-ID: \r\nContent-Type: application/pidf+xml;charset=\"UTF-8\"\r\n\n\n\n\nopen\n\nsip:bob@vancouver.example.com\n\n\n\n--50UBfW7LSCVLtggUPe5z\r\nContent-Transfer-Encoding: binary\r\nContent-ID: \r\nContent-Type: application/pidf+xml;charset=\"UTF-8\"\r\n\n\n\n\nclosed\n\n\n\n\n--50UBfW7LSCVLtggUPe5z--"; + + receiver.sendSipRequest(Request.NOTIFY, fromAddress, toAddress, content, null, false, new String[]{ContentTypeHeader.NAME, SubscriptionStateHeader.NAME, EventHeader.NAME}, new String[]{"multipart/related;type=\"application/rlmi+xml\";start=\"\";boundary=\"50UBfW7LSCVLtggUPe5z\"", "pending", "presence"}, true); + Thread.sleep(TIMEOUT); + assertEquals(200, receiver.getFinalResponseStatus()); + assertTrue(receiver.getAllMessagesContent().size() > 0); + assertTrue(receiver.getAllMessagesContent().contains("3")); + } + + // http://code.google.com/p/mobicents/issues/detail?id=2182 + public void testSipServletsReceiveNotifyMimeMultipartWhitespace() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + senderProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("testMimeMultipartWhitespaces", "testMimeMultipartWhitespaces"); + deployApplication(params); + + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = receiverProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = receiverProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + String content = "--1A713B7EE42ABF467A11E416\r\n" + "Content-Type: application/pidf+xml\r\n" + + "Content-ID: <317A166E4BEB17EA1A24F417@telecomsys.com>\r\n" + "\r\n" + + "\r\n" + + "\r\n" + "\r\n" + "\r\n" + "\r\n" + + "\r\n" + + "30.8686739957541 -97.0195399766783\r\n" + "\r\n" + + "\r\n" + "\r\n" + + "yes\r\n" + "\r\n" + + "Derived\r\n" + "www.telecomsys.com\r\n" + + "\r\n" + "\r\n" + "2010-05-17T17:20:55Z\r\n" + + "\r\n" + "\r\n" + "--1A713B7EE42ABF467A11E416\r\n" + + "Content-Type: application/sdp\r\n" + "\r\n" + "v=0\r\n" + + "o=user1 53655765 2353687637 IN IP4 10.15.90.101\r\n" + "s=-\r\n" + "c=IN IP4 10.15.90.101\r\n" + + "t=0 0\r\n" + "m=audio 6001 RTP/AVP 0\r\n" + "a=rtpmap:0 PCMU/8000\r\n"; + receiver.sendSipRequest(Request.NOTIFY, fromAddress, toAddress, content, null, false, new String[]{ContentTypeHeader.NAME, SubscriptionStateHeader.NAME, EventHeader.NAME}, new String[]{"multipart/related;type=\"application/rlmi+xml\";boundary=\"1A713B7EE42ABF467A11E416\"", "pending", "presence"}, true); + Thread.sleep(TIMEOUT); + assertEquals(200, receiver.getFinalResponseStatus()); + assertTrue(receiver.getAllMessagesContent().size() > 0); + assertTrue(receiver.getAllMessagesContent().contains("2")); + } + + @Override + protected void tearDown() throws Exception { + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/targeting/AppKeySipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/targeting/AppKeySipServletTest.java index 1fbbe72dcb..e5e1d12e94 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/targeting/AppKeySipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/targeting/AppKeySipServletTest.java @@ -1,154 +1,193 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.targeting; -import javax.sip.SipProvider; - -import org.apache.catalina.deploy.ApplicationParameter; -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -/** - * This test is aimed to test the @SipApplicationKey annotation and check that this is compliant with JSR 289 - * - * @author Jean Deruelle - * - */ -public class AppKeySipServletTest extends SipServletTestCase { - private static transient Logger logger = Logger.getLogger(AppKeySipServletTest.class); - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; -// private static final int TIMEOUT = 100000000; - - TestSipListener receiver; - - ProtocolObjects receiverProtocolObjects; - - public AppKeySipServletTest(String name) { - super(name); - startTomcatOnStartup = false; - autoDeployOnStartup = false; - initTomcatOnStartup = false; - addSipConnectorOnStartup = false; - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/appkey-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - public SipStandardContext deployApplication(String name, String value) { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/appkey-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - context.setConcurrencyControlMode(ConcurrencyControlMode.SipApplicationSession); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName(name); - applicationParameter.setValue(value); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - return context; - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/targeting/appkey-sip-servlet-dar.properties"; - } - - protected String getWilcardDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/targeting/wilcard-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, true); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - } - - /** - * This test gets a REGISTER and later an INVITE that are created by the same app session through - * sipSessionsUtil.getApplicationSessionByKey("appkeytest", true); - * It tests that the 2 requests have different Call Id. - * @throws Exception - */ - public void testSessionUtilsGetApplicationSessionByAppKey() throws Exception { - tomcat.initTomcat(tomcatBasePath, null); - tomcat.addSipConnector(serverName, sipIpAddress, 5070, listeningPointTransport); - tomcat.startTomcat(); - deployApplication(); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getOkToByeReceived()); - } - - public void testSipFactoryCreateApplicationSessionByAppKey() throws Exception { - tomcat.initTomcat(tomcatBasePath, null); - tomcat.addSipConnector(serverName, sipIpAddress, 5070, listeningPointTransport); - tomcat.startTomcat(); - deployApplication("createApplicationSessionByKey", "true"); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getOkToByeReceived()); - } - - /** - * This test tests the wildcard feature of the AR - * @throws Exception - */ - public void testWildcard() throws Exception { - tomcat.setDarConfigurationFilePath(getWilcardDarConfigurationFile()); - tomcat.initTomcat(tomcatBasePath, null); - tomcat.addSipConnector(serverName, sipIpAddress, 5070, listeningPointTransport); - tomcat.startTomcat(); - deployApplication(); - Thread.sleep(TIMEOUT); - assertTrue(receiver.getOkToByeReceived()); - } - - @Override - protected void tearDown() throws Exception { - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } -} \ No newline at end of file +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.targeting; + +import java.util.HashMap; +import java.util.Map; +import javax.sip.SipProvider; +import static junit.framework.Assert.assertTrue; + +import org.apache.catalina.deploy.ApplicationParameter; +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.annotation.ConcurrencyControlMode; +import org.mobicents.servlet.sip.catalina.SipStandardManager; +import org.mobicents.servlet.sip.startup.SipContextConfig; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +/** + * This test is aimed to test the @SipApplicationKey annotation and check that + * this is compliant with JSR 289 + * + * @author Jean Deruelle + * + */ +public class AppKeySipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(AppKeySipServletTest.class); + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; +// private static final int TIMEOUT = 100000000; + + TestSipListener receiver; + + ProtocolObjects receiverProtocolObjects; + + public AppKeySipServletTest(String name) { + super(name); + startTomcatOnStartup = false; + autoDeployOnStartup = false; + initTomcatOnStartup = false; + addSipConnectorOnStartup = false; + } + + @Override + public void deployApplication() { + assertTrue(tomcat.deployContext( + projectHome + "/sip-servlets-test-suite/applications/appkey-sip-servlet/src/main/sipapp", + "sip-test-context", "sip-test")); + } + + public SipStandardContext deployApplication(Map params) { + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/appkey-sip-servlet/src/main/sipapp", + "sip-test", + params, + null); + assertTrue(ctx.getAvailable()); + return ctx; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/targeting/appkey-sip-servlet-dar.properties"; + } + + protected String getWilcardDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/targeting/wilcard-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + + + + } + + /** + * This test gets a REGISTER and later an INVITE that are created by the + * same app session through + * sipSessionsUtil.getApplicationSessionByKey("appkeytest", true); It tests + * that the 2 requests have different Call Id. + * + * @throws Exception + */ + public void testSessionUtilsGetApplicationSessionByAppKey() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, true); + SipProvider senderProvider = receiver.createProvider(); + senderProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + + tomcat.initTomcat(tomcatBasePath, null); + tomcat.addSipConnector(serverName, sipIpAddress, containerPort, listeningPointTransport); + tomcat.startTomcat(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + deployApplication(params); + + Thread.sleep(TIMEOUT); + assertTrue(receiver.getOkToByeReceived()); + } + + public void testSipFactoryCreateApplicationSessionByAppKey() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, true); + SipProvider senderProvider = receiver.createProvider(); + senderProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + + tomcat.initTomcat(tomcatBasePath, null); + tomcat.addSipConnector(serverName, sipIpAddress, containerPort, listeningPointTransport); + tomcat.startTomcat(); + + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("createApplicationSessionByKey", "true"); + deployApplication(params); + + Thread.sleep(TIMEOUT); + assertTrue(receiver.getOkToByeReceived()); + } + + /** + * This test tests the wildcard feature of the AR + * + * @throws Exception + */ + public void testWildcard() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, true); + SipProvider senderProvider = receiver.createProvider(); + senderProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + + tomcat.setDarConfigurationFilePath(getWilcardDarConfigurationFile()); + tomcat.initTomcat(tomcatBasePath, null); + tomcat.addSipConnector(serverName, sipIpAddress, containerPort, listeningPointTransport); + tomcat.startTomcat(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + deployApplication(params); + + Thread.sleep(TIMEOUT); + assertTrue(receiver.getOkToByeReceived()); + } + + @Override + protected void tearDown() throws Exception { + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/targeting/EncodeURISipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/targeting/EncodeURISipServletTest.java index 0c8a6b5950..27e8ddc1ce 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/targeting/EncodeURISipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/targeting/EncodeURISipServletTest.java @@ -1,135 +1,147 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.targeting; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; -import javax.sip.message.Request; - -import org.apache.catalina.deploy.ApplicationParameter; -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -/** - * This test is aimed to test the Chapter "15.11.3 The Encode URI Mechanism" compliancy of JSR 289 - * - * @author Jean Deruelle - * - */ -public class EncodeURISipServletTest extends SipServletTestCase { - private static transient Logger logger = Logger.getLogger(EncodeURISipServletTest.class); - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; -// private static final int TIMEOUT = 100000000; - - TestSipListener receiver; - - ProtocolObjects receiverProtocolObjects; - - public EncodeURISipServletTest(String name) { - super(name); - startTomcatOnStartup = false; - autoDeployOnStartup = false; - initTomcatOnStartup = false; - addSipConnectorOnStartup = false; - } - - @Override - public void deployApplication() { - SipStandardContext context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - ApplicationParameter applicationParameter = new ApplicationParameter(); - applicationParameter.setName("encodeRequestURI"); - applicationParameter.setValue("true"); - context.addApplicationParameter(applicationParameter); - assertTrue(tomcat.deployContext(context)); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/targeting/encode-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - receiverProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - receiver = new TestSipListener(5080, 5070, receiverProtocolObjects, false); - SipProvider senderProvider = receiver.createProvider(); - - senderProvider.addSipListener(receiver); - - receiverProtocolObjects.start(); - } - - /** - * This test gets an INVITE with an encoded URI, it extracts it and send it back in a new INVITE not related to the same dialog - * to make sure the same application session is used - * @throws Exception - */ - public void testEncodeURI() throws Exception { - tomcat.initTomcat(tomcatBasePath, null); - tomcat.addSipConnector(serverName, sipIpAddress, 5070, listeningPointTransport); - tomcat.startTomcat(); - deployApplication(); - Thread.sleep(TIMEOUT); - Request invite = receiver.getInviteRequest(); - - String fromName = "encodedUri"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = receiverProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "mss"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = receiverProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - SipURI requestURI = (SipURI) toAddress.clone(); - requestURI.setParameter("org.mobicents.servlet.sip.ApplicationSessionKey", ((SipURI)invite.getRequestURI()).getParameter("org.mobicents.servlet.sip.ApplicationSessionKey")); - - receiver.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, null, null, requestURI); - Thread.sleep(TIMEOUT); - assertEquals(200, receiver.getFinalResponseStatus()); - } - - @Override - protected void tearDown() throws Exception { - receiverProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } -} \ No newline at end of file +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.targeting; + +import java.util.HashMap; +import java.util.Map; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; +import javax.sip.message.Request; +import static junit.framework.Assert.assertTrue; + +import org.apache.catalina.deploy.ApplicationParameter; +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.catalina.SipStandardManager; +import org.mobicents.servlet.sip.startup.SipContextConfig; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +/** + * This test is aimed to test the Chapter "15.11.3 The Encode URI Mechanism" + * compliancy of JSR 289 + * + * @author Jean Deruelle + * + */ +public class EncodeURISipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(EncodeURISipServletTest.class); + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; +// private static final int TIMEOUT = 100000000; + + TestSipListener receiver; + + ProtocolObjects receiverProtocolObjects; + + public EncodeURISipServletTest(String name) { + super(name); + startTomcatOnStartup = false; + autoDeployOnStartup = false; + initTomcatOnStartup = false; + addSipConnectorOnStartup = false; + } + + @Override + public void deployApplication() { + } + + public SipStandardContext deployApplication(Map params) { + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/shootist-sip-servlet/src/main/sipapp", + "sip-test", + params, + null); + assertTrue(ctx.getAvailable()); + return ctx; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/targeting/encode-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + } + + /** + * This test gets an INVITE with an encoded URI, it extracts it and send it + * back in a new INVITE not related to the same dialog to make sure the same + * application session is used + * + * @throws Exception + */ + public void testEncodeURI() throws Exception { + receiverProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int receiverPort = NetworkPortAssigner.retrieveNextPort(); + receiver = new TestSipListener(receiverPort, containerPort, receiverProtocolObjects, false); + SipProvider senderProvider = receiver.createProvider(); + senderProvider.addSipListener(receiver); + receiverProtocolObjects.start(); + + tomcat.initTomcat(tomcatBasePath, null); + tomcat.addSipConnector(serverName, sipIpAddress, containerPort, listeningPointTransport); + tomcat.startTomcat(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(receiverPort)); + params.put("encodeRequestURI", "true"); + deployApplication(params); + + Thread.sleep(TIMEOUT); + Request invite = receiver.getInviteRequest(); + + String fromName = "encodedUri"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = receiverProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "mss"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = receiverProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + SipURI requestURI = (SipURI) toAddress.clone(); + requestURI.setParameter("org.mobicents.servlet.sip.ApplicationSessionKey", ((SipURI) invite.getRequestURI()).getParameter("org.mobicents.servlet.sip.ApplicationSessionKey")); + + receiver.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false, null, null, requestURI); + Thread.sleep(TIMEOUT); + assertEquals(200, receiver.getFinalResponseStatus()); + } + + @Override + protected void tearDown() throws Exception { + receiverProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/targeting/SessionKeyTargetingSipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/targeting/SessionKeyTargetingSipServletTest.java index 0d7ef72d79..17085c539f 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/targeting/SessionKeyTargetingSipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/targeting/SessionKeyTargetingSipServletTest.java @@ -1,292 +1,297 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.targeting; - -import java.text.ParseException; -import java.util.Iterator; - -import javax.sip.InvalidArgumentException; -import javax.sip.SipException; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -/** - * This test is aimed to test the @SipApplicationKey annotation and check that this is compliant with JSR 289 - * - * @author Jean Deruelle - * - */ -public class SessionKeyTargetingSipServletTest extends SipServletTestCase { - - - private static transient Logger logger = Logger.getLogger(SessionKeyTargetingSipServletTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 10000; - private static final int TIMEOUT_TIMER = 6000; - private static final int CONTAINER_PORT = 5070; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender1Chat1; - TestSipListener sender2Chat1; - TestSipListener sender3Chat1; - TestSipListener sender1Chat2; - - - ProtocolObjects sender1Chat1ProtocolObjects; - ProtocolObjects sender2Chat1ProtocolObjects; - ProtocolObjects sender3Chat1ProtocolObjects; - ProtocolObjects sender1Chat2ProtocolObjects; - - - public SessionKeyTargetingSipServletTest(String name) { - super(name); -// startTomcatOnStartup = false; -// autoDeployOnStartup = false; -// initTomcatOnStartup = false; - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/chatroom-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/targeting/chatroom-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - sender1Chat1ProtocolObjects =new ProtocolObjects( - "sender1Chat1", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - sender2Chat1ProtocolObjects =new ProtocolObjects( - "sender2Chat1", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - sender3Chat1ProtocolObjects =new ProtocolObjects( - "sender3Chat1", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - sender1Chat2ProtocolObjects =new ProtocolObjects( - "sender1Chat2", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - sender1Chat1 = new TestSipListener(5071, CONTAINER_PORT, sender1Chat1ProtocolObjects, false); - SipProvider senderProvider = sender1Chat1.createProvider(); - senderProvider.addSipListener(sender1Chat1); - sender1Chat1ProtocolObjects.start(); - - sender2Chat1 = new TestSipListener(5072, CONTAINER_PORT, sender2Chat1ProtocolObjects, false); - SipProvider sender2Provider = sender2Chat1.createProvider(); - sender2Provider.addSipListener(sender2Chat1); - sender2Chat1ProtocolObjects.start(); - - sender3Chat1 = new TestSipListener(5073, CONTAINER_PORT, sender3Chat1ProtocolObjects, false); - SipProvider sender3Provider = sender3Chat1.createProvider(); - sender3Provider.addSipListener(sender3Chat1); - sender3Chat1ProtocolObjects.start(); - - sender1Chat2 = new TestSipListener(5074, CONTAINER_PORT, sender1Chat2ProtocolObjects, false); - SipProvider sender4Provider = sender1Chat2.createProvider(); - sender4Provider.addSipListener(sender1Chat2); - sender1Chat2ProtocolObjects.start(); - } - - /** - * This test check to see if all requests with the same request URI - * "sip:mychatroom1@example.com" will be handled by the same application - * session. (The sip servlet will return the same key for the same request - * URI) - * - * So it starts 4 sip clients. 3 of them will connect to the same request - * Uri and the last one to another request uri. The sip servlet application - * will send back a MESSAGE containing the number of clients connected to - * the same application session upon ACK reception. - * - * The 3 first clients should receive respectively 1, 2 and 3. And the 4th - * client should receive 1. - * - * @throws InterruptedException - * @throws SipException - * @throws ParseException - * @throws InvalidArgumentException - */ - public void testSipApplicationSessionTargeting() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "sender1Chat1"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = sender1Chat1ProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "chatroom1"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = sender1Chat1ProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender1Chat1.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender1Chat1.isAckSent()); - fromName = "sender2Chat1"; - fromAddress = sender2Chat1ProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - sender2Chat1.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender2Chat1.isAckSent()); - fromName = "sender3Chat1"; - fromAddress = sender3Chat1ProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - sender3Chat1.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender3Chat1.isAckSent()); - - toUser = "chatroom2"; - toAddress = sender1Chat2ProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - fromName = "sender1Chat2"; - fromAddress = sender1Chat2ProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - sender1Chat2.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender1Chat2.isAckSent()); - - Thread.sleep(TIMEOUT); - sender1Chat1.sendBye(); - sender2Chat1.sendBye(); - sender3Chat1.sendBye(); - sender1Chat2.sendBye(); - Thread.sleep(TIMEOUT); - assertTrue(sender1Chat1.getOkToByeReceived()); - assertTrue(sender2Chat1.getOkToByeReceived()); - assertTrue(sender3Chat1.getOkToByeReceived()); - assertTrue(sender1Chat2.getOkToByeReceived()); - Thread.sleep(TIMEOUT_TIMER); - Iterator allMessagesIterator = sender1Chat1.getAllMessagesContent().iterator(); - logger.info("all messages received from sender1Chat1 : "); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertEquals(1, sender1Chat1.getAllMessagesContent().size()); - assertTrue(sender1Chat1.getAllMessagesContent().contains("1")); - - allMessagesIterator = sender2Chat1.getAllMessagesContent().iterator(); - logger.info("all messages received from sender2Chat1 : "); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertEquals(1, sender1Chat1.getAllMessagesContent().size()); - assertTrue(sender2Chat1.getAllMessagesContent().contains("2")); - - allMessagesIterator = sender3Chat1.getAllMessagesContent().iterator(); - logger.info("all messages received from sender3Chat1 : "); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertEquals(1, sender1Chat1.getAllMessagesContent().size()); - assertTrue(sender3Chat1.getAllMessagesContent().contains("3")); - - allMessagesIterator = sender1Chat2.getAllMessagesContent().iterator(); - logger.info("all messages received from sender1Chat2 : "); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertEquals(1, sender1Chat1.getAllMessagesContent().size()); - assertTrue(sender1Chat2.getAllMessagesContent().contains("1")); - } - - /** - * This test check that this is not possible to modify the request in the @SipApplicationKey annotated method - * @throws InterruptedException - * @throws SipException - * @throws ParseException - * @throws InvalidArgumentException - */ - public void testSipApplicationKeyStaticField() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "staticField"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = sender1Chat1ProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "chatroom"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = sender1Chat1ProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender1Chat1.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - sender1Chat1.sendBye(); - Thread.sleep(TIMEOUT); - assertTrue(sender1Chat1.getOkToByeReceived()); - } - - /** - * This test check that this is not possible to modify the request in the @SipApplicationKey annotated method - * @throws InterruptedException - * @throws SipException - * @throws ParseException - * @throws InvalidArgumentException - */ - public void testSipApplicationKeyModifyingSipServletRequest() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "modifyRequest"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = sender1Chat1ProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "chatroom"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = sender1Chat1ProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender1Chat1.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender1Chat1.isFinalResponseReceived()); - assertTrue(!sender1Chat1.isAckSent()); - } - - @Override - protected void tearDown() throws Exception { - sender1Chat1ProtocolObjects.destroy(); - if(sender2Chat1ProtocolObjects != null){ - sender2Chat1ProtocolObjects.destroy(); - } - if(sender3Chat1ProtocolObjects != null){ - sender3Chat1ProtocolObjects.destroy(); - } - if(sender1Chat2ProtocolObjects != null){ - sender1Chat2ProtocolObjects.destroy(); - } - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.targeting; + +import java.text.ParseException; +import java.util.Iterator; + +import javax.sip.InvalidArgumentException; +import javax.sip.SipException; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +/** + * This test is aimed to test the @SipApplicationKey annotation and check that + * this is compliant with JSR 289 + * + * @author Jean Deruelle + * + */ +public class SessionKeyTargetingSipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(SessionKeyTargetingSipServletTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 10000; + private static final int TIMEOUT_TIMER = 6000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender1Chat1; + TestSipListener sender2Chat1; + TestSipListener sender3Chat1; + TestSipListener sender1Chat2; + + ProtocolObjects sender1Chat1ProtocolObjects; + ProtocolObjects sender2Chat1ProtocolObjects; + ProtocolObjects sender3Chat1ProtocolObjects; + ProtocolObjects sender1Chat2ProtocolObjects; + + public SessionKeyTargetingSipServletTest(String name) { + super(name); +// startTomcatOnStartup = false; +// autoDeployOnStartup = false; +// initTomcatOnStartup = false; + } + + @Override + public void deployApplication() { + assertTrue(tomcat.deployContext( + projectHome + "/sip-servlets-test-suite/applications/chatroom-sip-servlet/src/main/sipapp", + "sip-test-context", "sip-test")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/targeting/chatroom-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() throws Exception { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + sender1Chat1ProtocolObjects = new ProtocolObjects( + "sender1Chat1", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + sender2Chat1ProtocolObjects = new ProtocolObjects( + "sender2Chat1", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + sender3Chat1ProtocolObjects = new ProtocolObjects( + "sender3Chat1", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + sender1Chat2ProtocolObjects = new ProtocolObjects( + "sender1Chat2", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + + int sender1Chat1Port = NetworkPortAssigner.retrieveNextPort(); + sender1Chat1 = new TestSipListener(sender1Chat1Port, containerPort, sender1Chat1ProtocolObjects, false); + SipProvider senderProvider = sender1Chat1.createProvider(); + senderProvider.addSipListener(sender1Chat1); + sender1Chat1ProtocolObjects.start(); + + int sender2Chat1Port = NetworkPortAssigner.retrieveNextPort(); + sender2Chat1 = new TestSipListener(sender2Chat1Port, containerPort, sender2Chat1ProtocolObjects, false); + SipProvider sender2Provider = sender2Chat1.createProvider(); + sender2Provider.addSipListener(sender2Chat1); + sender2Chat1ProtocolObjects.start(); + + int sender3Chat1Port = NetworkPortAssigner.retrieveNextPort(); + sender3Chat1 = new TestSipListener(sender3Chat1Port, containerPort, sender3Chat1ProtocolObjects, false); + SipProvider sender3Provider = sender3Chat1.createProvider(); + sender3Provider.addSipListener(sender3Chat1); + sender3Chat1ProtocolObjects.start(); + + int sender1Chat2Port = NetworkPortAssigner.retrieveNextPort(); + sender1Chat2 = new TestSipListener(sender1Chat2Port, containerPort, sender1Chat2ProtocolObjects, false); + SipProvider sender4Provider = sender1Chat2.createProvider(); + sender4Provider.addSipListener(sender1Chat2); + sender1Chat2ProtocolObjects.start(); + } + + /** + * This test check to see if all requests with the same request URI + * "sip:mychatroom1@example.com" will be handled by the same application + * session. (The sip servlet will return the same key for the same request + * URI) + * + * So it starts 4 sip clients. 3 of them will connect to the same request + * Uri and the last one to another request uri. The sip servlet application + * will send back a MESSAGE containing the number of clients connected to + * the same application session upon ACK reception. + * + * The 3 first clients should receive respectively 1, 2 and 3. And the 4th + * client should receive 1. + * + * @throws InterruptedException + * @throws SipException + * @throws ParseException + * @throws InvalidArgumentException + */ + public void testSipApplicationSessionTargeting() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "sender1Chat1"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = sender1Chat1ProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "chatroom1"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = sender1Chat1ProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender1Chat1.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender1Chat1.isAckSent()); + fromName = "sender2Chat1"; + fromAddress = sender2Chat1ProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + sender2Chat1.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender2Chat1.isAckSent()); + fromName = "sender3Chat1"; + fromAddress = sender3Chat1ProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + sender3Chat1.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender3Chat1.isAckSent()); + + toUser = "chatroom2"; + toAddress = sender1Chat2ProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + fromName = "sender1Chat2"; + fromAddress = sender1Chat2ProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + sender1Chat2.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender1Chat2.isAckSent()); + + Thread.sleep(TIMEOUT); + sender1Chat1.sendBye(); + sender2Chat1.sendBye(); + sender3Chat1.sendBye(); + sender1Chat2.sendBye(); + Thread.sleep(TIMEOUT); + assertTrue(sender1Chat1.getOkToByeReceived()); + assertTrue(sender2Chat1.getOkToByeReceived()); + assertTrue(sender3Chat1.getOkToByeReceived()); + assertTrue(sender1Chat2.getOkToByeReceived()); + Thread.sleep(TIMEOUT_TIMER); + Iterator allMessagesIterator = sender1Chat1.getAllMessagesContent().iterator(); + logger.info("all messages received from sender1Chat1 : "); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertEquals(1, sender1Chat1.getAllMessagesContent().size()); + assertTrue(sender1Chat1.getAllMessagesContent().contains("1")); + + allMessagesIterator = sender2Chat1.getAllMessagesContent().iterator(); + logger.info("all messages received from sender2Chat1 : "); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertEquals(1, sender1Chat1.getAllMessagesContent().size()); + assertTrue(sender2Chat1.getAllMessagesContent().contains("2")); + + allMessagesIterator = sender3Chat1.getAllMessagesContent().iterator(); + logger.info("all messages received from sender3Chat1 : "); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertEquals(1, sender1Chat1.getAllMessagesContent().size()); + assertTrue(sender3Chat1.getAllMessagesContent().contains("3")); + + allMessagesIterator = sender1Chat2.getAllMessagesContent().iterator(); + logger.info("all messages received from sender1Chat2 : "); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertEquals(1, sender1Chat1.getAllMessagesContent().size()); + assertTrue(sender1Chat2.getAllMessagesContent().contains("1")); + } + + /** + * This test check that this is not possible to modify the request in the + * @SipApplicationKey annotated method + * + * @throws InterruptedException + * @throws SipException + * @throws ParseException + * @throws InvalidArgumentException + */ + public void testSipApplicationKeyStaticField() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "staticField"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = sender1Chat1ProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "chatroom"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = sender1Chat1ProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender1Chat1.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + sender1Chat1.sendBye(); + Thread.sleep(TIMEOUT); + assertTrue(sender1Chat1.getOkToByeReceived()); + } + + /** + * This test check that this is not possible to modify the request in the + * @SipApplicationKey annotated method + * + * @throws InterruptedException + * @throws SipException + * @throws ParseException + * @throws InvalidArgumentException + */ + public void testSipApplicationKeyModifyingSipServletRequest() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "modifyRequest"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = sender1Chat1ProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "chatroom"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = sender1Chat1ProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender1Chat1.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender1Chat1.isFinalResponseReceived()); + assertTrue(!sender1Chat1.isAckSent()); + } + + @Override + protected void tearDown() throws Exception { + sender1Chat1ProtocolObjects.destroy(); + if (sender2Chat1ProtocolObjects != null) { + sender2Chat1ProtocolObjects.destroy(); + } + if (sender3Chat1ProtocolObjects != null) { + sender3Chat1ProtocolObjects.destroy(); + } + if (sender1Chat2ProtocolObjects != null) { + sender1Chat2ProtocolObjects.destroy(); + } + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/timers/TimersSipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/timers/TimersSipServletTest.java index 3c779be774..024656325d 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/timers/TimersSipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/timers/TimersSipServletTest.java @@ -1,224 +1,233 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.timers; - -import java.text.ParseException; -import java.util.Iterator; - -import javax.sip.InvalidArgumentException; -import javax.sip.SipException; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.catalina.LifecycleException; -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.catalina.SipStandardManager; -import org.mobicents.servlet.sip.startup.SipContextConfig; -import org.mobicents.servlet.sip.startup.SipStandardContext; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; - -/** - * Checks that applicaiton session expiration is working - * - * @author Jean Deruelle - * - */ -public class TimersSipServletTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(TimersSipServletTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - //1 sec - private static final int TIMEOUT = 5000; - //1 minute and 10 sec - private static final int APP_SESSION_TIMEOUT = 80000; -// private static final int TIMEOUT = 100000000; - - // the order is important here - private static final String[] TIMERS_TO_TEST = new String[]{ - "recurringTimerExpired", - "timerExpired", - "sipAppSessionExpired", - "sipAppSessionReadyToBeInvalidated" - }; - - TestSipListener sender; - - ProtocolObjects senderProtocolObjects; - - SipStandardContext context = null; - - public TimersSipServletTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - context = new SipStandardContext(); - context.setDocBase(projectHome + "/sip-servlets-test-suite/applications/timers-sip-servlet/src/main/sipapp"); - context.setName("sip-test-context"); - context.setPath("sip-test"); - //setting the sip application timeout to 1 minutes instead of the regular 3 minutes - context.setSipApplicationSessionTimeout(1); - context.addLifecycleListener(new SipContextConfig()); - context.setManager(new SipStandardManager()); - assertTrue(tomcat.deployContext(context)); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/timers/timers-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() { - try { - super.setUp(); - - senderProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, false); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - } catch (Exception ex) { - fail("unexpected exception "); - } - } - -// public void testTimers() throws InterruptedException, SipException, ParseException, InvalidArgumentException { -// String fromName = "sender"; -// String fromSipAddress = "sip-servlets.com"; -// SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( -// fromName, fromSipAddress); -// -// String toUser = "receiver"; -// String toSipAddress = "sip-servlets.com"; -// SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( -// toUser, toSipAddress); -// -// sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); -// Thread.sleep(TIMEOUT); -// assertTrue(sender.isAckSent()); -// Thread.sleep(APP_SESSION_TIMEOUT); -// sender.sendBye(); -// Thread.sleep(TIMEOUT); -// assertTrue(sender.getOkToByeReceived()); -// Thread.sleep(APP_SESSION_TIMEOUT); -// Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); -// while (allMessagesIterator.hasNext()) { -// String message = (String) allMessagesIterator.next(); -// logger.info(message); -// } -// for (int i = 0; i < TIMERS_TO_TEST.length; i++) { -// assertTrue(sender.getAllMessagesContent().contains(TIMERS_TO_TEST[i])); -// } -// } - - // Test Issue 1698 : http://code.google.com/p/mobicents/issues/detail?id=1698 - // SipApplicationSession Expiration Timer is not reset and so does not fire if - // an indialog request is sent from within sessionExpired callback - // - // Issue 1773 : http://code.google.com/p/mobicents/issues/detail?id=1773 - // This has been commented out because of JSR 289, Section 6.1.2 SipApplicationSession Lifetime : - // "Servlets can register for application session timeout notifications using the SipApplicationSessionListener interface. - // In the sessionExpired() callback method, the application may request an extension of the application session lifetime - // by invoking setExpires() on the timed out SipApplicationSession giving as an argument the number of minutes until the session expires again" - // Even sending a message out will not start the expiration timer anew indirectly otherwise it makes some TCK tests fail - public void testTimerExpirationExtensionByInDialogRequest() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "expExtInDialog"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - Thread.sleep(APP_SESSION_TIMEOUT); - assertTrue(sender.isInviteReceived()); - assertFalse(sender.getAllMessagesContent().contains("sipAppSessionExpired")); - Thread.sleep(APP_SESSION_TIMEOUT); - Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); - while (allMessagesIterator.hasNext()) { - String message = (String) allMessagesIterator.next(); - logger.info(message); - } - assertTrue(sender.getAllMessagesContent().isEmpty()); - } - - // Issue 1478 : http://code.google.com/p/mobicents/issues/detail?id=1478 - // Attempting to use the TimerService after reloading a servlet throws a RejectedExecutionException - public void testTimerReloading() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "checkReload"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(sender.getAllMessagesContent().contains("timerExpired")); - -// tomcat.undeployContext(context); -// tomcat.deployContext(context); - try { - context.stop(); - context.start(); - } catch (LifecycleException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - sender.getAllMessagesContent().clear(); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(sender.getAllMessagesContent().contains("timerExpired")); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.timers; + +import java.text.ParseException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import javax.sip.InvalidArgumentException; +import javax.sip.SipException; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; + +import org.apache.catalina.LifecycleException; +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.catalina.SipStandardManager; +import org.mobicents.servlet.sip.startup.SipContextConfig; +import org.mobicents.servlet.sip.startup.SipStandardContext; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +/** + * Checks that applicaiton session expiration is working + * + * @author Jean Deruelle + * + */ +public class TimersSipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(TimersSipServletTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + //1 sec + private static final int TIMEOUT = 5000; + //1 minute and 10 sec + private static final int APP_SESSION_TIMEOUT = 80000; +// private static final int TIMEOUT = 100000000; + + // the order is important here + private static final String[] TIMERS_TO_TEST = new String[]{ + "recurringTimerExpired", + "timerExpired", + "sipAppSessionExpired", + "sipAppSessionReadyToBeInvalidated" + }; + + TestSipListener sender; + + ProtocolObjects senderProtocolObjects; + + SipStandardContext context = null; + + public TimersSipServletTest(String name) { + super(name); + autoDeployOnStartup = false; + } + + @Override + public void deployApplication() { + + } + + public SipStandardContext deployApplication(Map params) { + SipStandardContext ctx = deployApplication( + projectHome + "/sip-servlets-test-suite/applications/timers-sip-servlet/src/main/sipapp", + "sip-test", + params, + null, + Integer.valueOf(1), + null);//setting the sip application timeout to 1 minutes instead of the regular 3 minutes + assertTrue(ctx.getAvailable()); + return ctx; + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/timers/timers-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() { + try { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, null, null, null); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, false); + SipProvider senderProvider = sender.createProvider(); + senderProvider.addSipListener(sender); + senderProtocolObjects.start(); + + Map params = new HashMap(); + params.put("servletContainerPort", String.valueOf(containerPort)); + params.put("testPort", String.valueOf(senderPort)); + context = deployApplication(params); + } catch (Exception ex) { + fail("unexpected exception "); + } + } + +// public void testTimers() throws InterruptedException, SipException, ParseException, InvalidArgumentException { +// String fromName = "sender"; +// String fromSipAddress = "sip-servlets.com"; +// SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( +// fromName, fromSipAddress); +// +// String toUser = "receiver"; +// String toSipAddress = "sip-servlets.com"; +// SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( +// toUser, toSipAddress); +// +// sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); +// Thread.sleep(TIMEOUT); +// assertTrue(sender.isAckSent()); +// Thread.sleep(APP_SESSION_TIMEOUT); +// sender.sendBye(); +// Thread.sleep(TIMEOUT); +// assertTrue(sender.getOkToByeReceived()); +// Thread.sleep(APP_SESSION_TIMEOUT); +// Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); +// while (allMessagesIterator.hasNext()) { +// String message = (String) allMessagesIterator.next(); +// logger.info(message); +// } +// for (int i = 0; i < TIMERS_TO_TEST.length; i++) { +// assertTrue(sender.getAllMessagesContent().contains(TIMERS_TO_TEST[i])); +// } +// } + // Test Issue 1698 : http://code.google.com/p/mobicents/issues/detail?id=1698 + // SipApplicationSession Expiration Timer is not reset and so does not fire if + // an indialog request is sent from within sessionExpired callback + // + // Issue 1773 : http://code.google.com/p/mobicents/issues/detail?id=1773 + // This has been commented out because of JSR 289, Section 6.1.2 SipApplicationSession Lifetime : + // "Servlets can register for application session timeout notifications using the SipApplicationSessionListener interface. + // In the sessionExpired() callback method, the application may request an extension of the application session lifetime + // by invoking setExpires() on the timed out SipApplicationSession giving as an argument the number of minutes until the session expires again" + // Even sending a message out will not start the expiration timer anew indirectly otherwise it makes some TCK tests fail + public void testTimerExpirationExtensionByInDialogRequest() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "expExtInDialog"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + Thread.sleep(APP_SESSION_TIMEOUT); + assertTrue(sender.isInviteReceived()); + assertFalse(sender.getAllMessagesContent().contains("sipAppSessionExpired")); + Thread.sleep(APP_SESSION_TIMEOUT); + Iterator allMessagesIterator = sender.getAllMessagesContent().iterator(); + while (allMessagesIterator.hasNext()) { + String message = (String) allMessagesIterator.next(); + logger.info(message); + } + assertTrue(sender.getAllMessagesContent().isEmpty()); + } + + // Issue 1478 : http://code.google.com/p/mobicents/issues/detail?id=1478 + // Attempting to use the TimerService after reloading a servlet throws a RejectedExecutionException + public void testTimerReloading() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "checkReload"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(sender.getAllMessagesContent().contains("timerExpired")); + +// tomcat.undeployContext(context); +// tomcat.deployContext(context); + try { + context.stop(); + context.start(); + } catch (LifecycleException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + sender.getAllMessagesContent().clear(); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(sender.getAllMessagesContent().contains("timerExpired")); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/update/UpdateSipServletTest.java b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/update/UpdateSipServletTest.java index bbc8423ec5..bde2022582 100644 --- a/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/update/UpdateSipServletTest.java +++ b/sip-servlets-test-suite/testsuite/src/test/java/org/mobicents/servlet/sip/testsuite/update/UpdateSipServletTest.java @@ -1,122 +1,122 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -package org.mobicents.servlet.sip.testsuite.update; - -import java.text.ParseException; - -import javax.sip.InvalidArgumentException; -import javax.sip.SipException; -import javax.sip.SipProvider; -import javax.sip.address.SipURI; - -import org.apache.log4j.Logger; -import org.mobicents.servlet.sip.SipServletTestCase; -import org.mobicents.servlet.sip.testsuite.ProtocolObjects; -import org.mobicents.servlet.sip.testsuite.TestSipListener; -/** - * This tests the UPDATE SIP extension see RFC 3311 - * - * @author Jean Deruelle - * - */ -public class UpdateSipServletTest extends SipServletTestCase { - - private static transient Logger logger = Logger.getLogger(UpdateSipServletTest.class); - - private static final String TRANSPORT = "udp"; - private static final boolean AUTODIALOG = true; - private static final int TIMEOUT = 20000; -// private static final int TIMEOUT = 100000000; - - TestSipListener sender; - - ProtocolObjects senderProtocolObjects; - - - public UpdateSipServletTest(String name) { - super(name); - } - - @Override - public void deployApplication() { - assertTrue(tomcat.deployContext( - projectHome + "/sip-servlets-test-suite/applications/update-sip-servlet/src/main/sipapp", - "sip-test-context", "sip-test")); - } - - @Override - protected String getDarConfigurationFile() { - return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + - "org/mobicents/servlet/sip/testsuite/update/update-sip-servlet-dar.properties"; - } - - @Override - protected void setUp() { - try { - super.setUp(); - - senderProtocolObjects =new ProtocolObjects( - "sender", "gov.nist", TRANSPORT, AUTODIALOG, "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":5070", null, null); - - sender = new TestSipListener(5080, 5070, senderProtocolObjects, true); - SipProvider senderProvider = sender.createProvider(); - - senderProvider.addSipListener(sender); - - senderProtocolObjects.start(); - } catch (Exception ex) { - ex.printStackTrace(); - fail("unexpected exception "); - } - } - - /** - * Call flow tested : See RFC 3311 Page 9 - */ - public void testUpdate() throws InterruptedException, SipException, ParseException, InvalidArgumentException { - String fromName = "sender"; - String fromSipAddress = "sip-servlets.com"; - SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( - fromName, fromSipAddress); - - String toUser = "receiver"; - String toSipAddress = "sip-servlets.com"; - SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( - toUser, toSipAddress); - - sender.setSendUpdateOn180(true); - sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); - Thread.sleep(TIMEOUT); - assertTrue(sender.isAckSent()); - assertTrue(sender.getOkToByeReceived()); - } - - @Override - protected void tearDown() throws Exception { - senderProtocolObjects.destroy(); - logger.info("Test completed"); - super.tearDown(); - } - - -} +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.mobicents.servlet.sip.testsuite.update; + +import java.text.ParseException; + +import javax.sip.InvalidArgumentException; +import javax.sip.SipException; +import javax.sip.SipProvider; +import javax.sip.address.SipURI; + +import org.apache.log4j.Logger; +import org.mobicents.servlet.sip.NetworkPortAssigner; +import org.mobicents.servlet.sip.SipServletTestCase; +import org.mobicents.servlet.sip.testsuite.ProtocolObjects; +import org.mobicents.servlet.sip.testsuite.TestSipListener; + +/** + * This tests the UPDATE SIP extension see RFC 3311 + * + * @author Jean Deruelle + * + */ +public class UpdateSipServletTest extends SipServletTestCase { + + private static transient Logger logger = Logger.getLogger(UpdateSipServletTest.class); + + private static final String TRANSPORT = "udp"; + private static final boolean AUTODIALOG = true; + private static final int TIMEOUT = 20000; +// private static final int TIMEOUT = 100000000; + + TestSipListener sender; + + ProtocolObjects senderProtocolObjects; + + public UpdateSipServletTest(String name) { + super(name); + } + + @Override + public void deployApplication() { + assertTrue(tomcat.deployContext( + projectHome + "/sip-servlets-test-suite/applications/update-sip-servlet/src/main/sipapp", + "sip-test-context", "sip-test")); + } + + @Override + protected String getDarConfigurationFile() { + return "file:///" + projectHome + "/sip-servlets-test-suite/testsuite/src/test/resources/" + + "org/mobicents/servlet/sip/testsuite/update/update-sip-servlet-dar.properties"; + } + + @Override + protected void setUp() { + try { + containerPort = NetworkPortAssigner.retrieveNextPort(); + super.setUp(); + + senderProtocolObjects = new ProtocolObjects( + "sender", "gov.nist", TRANSPORT, AUTODIALOG, "" + System.getProperty("org.mobicents.testsuite.testhostaddr") + ":" + containerPort, null, null); + int senderPort = NetworkPortAssigner.retrieveNextPort(); + sender = new TestSipListener(senderPort, containerPort, senderProtocolObjects, true); + SipProvider senderProvider = sender.createProvider(); + + senderProvider.addSipListener(sender); + + senderProtocolObjects.start(); + } catch (Exception ex) { + ex.printStackTrace(); + fail("unexpected exception "); + } + } + + /** + * Call flow tested : See RFC 3311 Page 9 + */ + public void testUpdate() throws InterruptedException, SipException, ParseException, InvalidArgumentException { + String fromName = "sender"; + String fromSipAddress = "sip-servlets.com"; + SipURI fromAddress = senderProtocolObjects.addressFactory.createSipURI( + fromName, fromSipAddress); + + String toUser = "receiver"; + String toSipAddress = "sip-servlets.com"; + SipURI toAddress = senderProtocolObjects.addressFactory.createSipURI( + toUser, toSipAddress); + + sender.setSendUpdateOn180(true); + sender.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false); + Thread.sleep(TIMEOUT); + assertTrue(sender.isAckSent()); + assertTrue(sender.getOkToByeReceived()); + } + + @Override + protected void tearDown() throws Exception { + senderProtocolObjects.destroy(); + logger.info("Test completed"); + super.tearDown(); + } + +} diff --git a/sip-servlets-test-suite/testsuite/src/test/resources/log4j.xml b/sip-servlets-test-suite/testsuite/src/test/resources/log4j.xml index 694ec8d0c4..b72efc44d7 100644 --- a/sip-servlets-test-suite/testsuite/src/test/resources/log4j.xml +++ b/sip-servlets-test-suite/testsuite/src/test/resources/log4j.xml @@ -1,34 +1,34 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sip-servlets-test-suite/testsuite/src/test/resources/mss-sip-stack.properties b/sip-servlets-test-suite/testsuite/src/test/resources/mss-sip-stack.properties index 7f9f3ca482..6aaaaa67bc 100644 --- a/sip-servlets-test-suite/testsuite/src/test/resources/mss-sip-stack.properties +++ b/sip-servlets-test-suite/testsuite/src/test/resources/mss-sip-stack.properties @@ -1,7 +1,7 @@ gov.nist.javax.sip.LOG_MESSAGE_CONTENT=true gov.nist.javax.sip.TRACE_LEVEL=32 -gov.nist.javax.sip.DEBUG_LOG=logs/mss-jsip-debuglog.txt -gov.nist.javax.sip.SERVER_LOG=logs/mss-jsip-messages.xml +gov.nist.javax.sip.DEBUG_LOG=target/logs/mss-jsip-debuglog.txt +gov.nist.javax.sip.SERVER_LOG=target/logs/mss-jsip-messages.xml javax.sip.STACK_NAME=Mobicents-SIP-Servlets javax.sip.AUTOMATIC_DIALOG_SUPPORT=off gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY=true diff --git a/sip-servlets-test-suite/testsuite/src/test/resources/org/mobicents/servlet/sip/testsuite/routing/closest/log4j.xml b/sip-servlets-test-suite/testsuite/src/test/resources/org/mobicents/servlet/sip/testsuite/routing/closest/log4j.xml new file mode 100644 index 0000000000..8eb45e573a --- /dev/null +++ b/sip-servlets-test-suite/testsuite/src/test/resources/org/mobicents/servlet/sip/testsuite/routing/closest/log4j.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sip-servlets-test-suite/testsuite/src/test/resources/org/mobicents/servlet/sip/testsuite/routing/closest/logging.properties b/sip-servlets-test-suite/testsuite/src/test/resources/org/mobicents/servlet/sip/testsuite/routing/closest/logging.properties new file mode 100644 index 0000000000..cd8ad79d1a --- /dev/null +++ b/sip-servlets-test-suite/testsuite/src/test/resources/org/mobicents/servlet/sip/testsuite/routing/closest/logging.properties @@ -0,0 +1,41 @@ +#FILE for JULI - tomcat implementation of loggin facitlity + +handlers = org.apache.juli.FileHandler, java.util.logging.ConsoleHandler +#handlers = org.apache.juli.FileHandler + +############################################################ +# Handler specific properties. +# Describes specific configuration info for Handlers. +############################################################ + +org.apache.juli.FileHandler.level = INFO +org.apache.juli.FileHandler.prefix = testsuite. +java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter + +java.util.logging.ConsoleHandler.level = INFO +java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter + +# ROOT LOGGER LEVEL +#.level = FINE +# Specific for org.mobicents +# FINE = DEBUG + +#LEVELS +# * SEVERE (highest value) +# * WARNING +# * INFO +# * CONFIG +# * FINE +# * FINER +# * FINEST (lowest value) +# * OFF + +#Default levels for our packages +org.mobicents.tools = FINEST +org.mobicents.servlet.sip.level = FINE +org.mobicents.servlet.sip.dd.level = WARNING +org.mobicents.servlet.sip.startup.level = INFO +#for certain classes +org.mobicents.servlet.sip.AddressImpl.level = FINE +org.mobicents.servlet.sip.ApplicationDispatcher.level = FINE + diff --git a/sip-servlets-test-suite/testsuite/src/test/resources/org/mobicents/servlet/sip/testsuite/routing/closest/mss-sip-stack.properties b/sip-servlets-test-suite/testsuite/src/test/resources/org/mobicents/servlet/sip/testsuite/routing/closest/mss-sip-stack.properties new file mode 100644 index 0000000000..6aaaaa67bc --- /dev/null +++ b/sip-servlets-test-suite/testsuite/src/test/resources/org/mobicents/servlet/sip/testsuite/routing/closest/mss-sip-stack.properties @@ -0,0 +1,13 @@ +gov.nist.javax.sip.LOG_MESSAGE_CONTENT=true +gov.nist.javax.sip.TRACE_LEVEL=32 +gov.nist.javax.sip.DEBUG_LOG=target/logs/mss-jsip-debuglog.txt +gov.nist.javax.sip.SERVER_LOG=target/logs/mss-jsip-messages.xml +javax.sip.STACK_NAME=Mobicents-SIP-Servlets +javax.sip.AUTOMATIC_DIALOG_SUPPORT=off +gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY=true +gov.nist.javax.sip.THREAD_POOL_SIZE=64 +gov.nist.javax.sip.REENTRANT_LISTENER=true +gov.nist.javax.sip.AGGRESSIVE_CLEANUP=true +gov.nist.javax.sip.MAX_FORK_TIME_SECONDS=0 +gov.nist.javax.sip.AUTOMATIC_DIALOG_ERROR_HANDLING=false +gov.nist.javax.sip.MESSAGE_PROCESSOR_FACTORY=gov.nist.javax.sip.stack.NioMessageProcessorFactory \ No newline at end of file diff --git a/sip-servlets-test-suite/testsuite/src/test/resources/org/mobicents/servlet/sip/testsuite/testsuite.properties b/sip-servlets-test-suite/testsuite/src/test/resources/org/mobicents/servlet/sip/testsuite/testsuite.properties index d09302b630..d3164d138f 100644 --- a/sip-servlets-test-suite/testsuite/src/test/resources/org/mobicents/servlet/sip/testsuite/testsuite.properties +++ b/sip-servlets-test-suite/testsuite/src/test/resources/org/mobicents/servlet/sip/testsuite/testsuite.properties @@ -8,5 +8,5 @@ #tomcat.home=/home/jean/servers/MSS/mss-1.8.0-SNAPSHOT-apache-tomcat-7.0.27 tomcat.home=/home/jean/servers/MSS/mss-3.0.0-SNAPSHOT-apache-tomcat-7.0.50 tomcat.backup.home=/home/jean/servers/MSS/mss-3.0.0-SNAPSHOT-apache-tomcat-7.0.50-backup -project.home=/home/jean/workspaces/sipservlets +project.home=/Users/gvagenas/data/devWorkspace/telWorkspace/sip-servlets