Adempier ERP to WebSphere

Reviews
PartnerWorld University of Technology, Sydney uses the IBM Innovation Centre to port ADempiere ERP to WebSphere and System i The University of Technology, Sydney (UTS) Faculty of Information Technology and Engineering is Australia's leading provider of industry-based undergraduate and postgraduate programs in Information Technology and Engineering. ADempiere Enterprise Resource Planning (ERP) is employed in teaching & learning to promote a widespread understanding of ERP's benefits and use. ADempiere ERP was selected because it is already deployed globally in many companies and also because it is an open source community development to which the Faculty's research programs can materially contribute. UTS used the IBM® Innovation Centre for Business Partners in 2008 to port the ADempiere open source ERP application suite to WebSphere® Application Server and System i. Stuart Nettleton, Senior Lecturer in the Faculty of Information Technology & Engineering and active member of the IBM Academic Initiative says that the work performed at the Innovation Centre was “a perfect example of an industry based partnership that the University is seeking.” The Innovation Centre staff helped UTS by providing the initial test equipment that included a System i model 520 running IBM i and SuSe Linux partitions. Further to the engagement at the Innovation Centre, UTS also received a System i server model 525 on loan to enable further testing and porting activities on site. ADempiere was first ported to WebSphere® Application Server 6.1 on a SUSE Linux Partition on a System i server. After a few weeks of rigorous testing, ADempiere was also ported to run on WebSphere® Application Server 6.1 running the IBM i operating system. The success of the engagement was due to the efforts and technical support provided by the staff at the IBM Innovation Centre. Grant Quick, UTS capstone student leading the project said “as issues arose, we were referred to experts in the centre whose experience proved invaluable in overcoming many of the obstacles inherent in the project. Without the support of the IIC success of the project would not have been possible.” Grant adds “our achievement in this project will definitely help the ADempiere community to choose System i and WebSphere Application Server 6.1 for their future implementations”. For further information: University of Technology Sydney http://www.uts.edu.au IBM Innovation Center ibm.com/partnerworld/iic ® Copyright IBM Corporation 2008 Printed in the United States of America. All Rights Reserved. IBM, the IBM logo, System i, WebSphere and IBM i are trademarks or registered trademarks of International Business Machines Corporation in the United States, other countries, or both. Other company, product, and service names may be trademarks or service marks of others. ibm.com/partnerworld University of Technology, Sydney Faculty of Engineering EMPIRICAL INVESTIGATION INTO ADEMPIERE OPEN SOURCE BUSINESS MODEL By Grant Andrew Quick Student Number: 10047595 Project Number: A08-121 Major: Software Engineering Supervisor: Mr Stuart Nettleton Industry Co-supervisors: Mr John Schilt (IBM), Mr Alan McNamara (Badja Consulting) A 12 Credit Point Project submitted in partial fulfilment of the requirement for the Degree of Bachelor of Engineering November 2008 i Statement of Originality I declare that I am the sole author of this document. No fragments of text from external sources have been included without proper acknowledgement and all theories, results and designs of others have been correctly referenced. All sources of assistance have been acknowledged. Grant Quick November 2008 ii Abstract As the complexity of organisations around the globe increases, the need to effectively manage business processes has never been more important. In order to remain viable in such an environment, organisations increasingly need to rely on technology to automate their processes. ADempiere provides world's best practice in an open source ERP environment that allows businesses to streamline and customise their operations. This project materially enhances the competitiveness of many organisations by expanding ADempiere's capability from Intel processors to Power processors as used, for example, in IBM's highly regarded range of Power System servers. In addition, the application was ported to WebSphere Application Server, which is required for its industrial strength and compatibility with other service architectures in organisations. To supplement these world first achievements, further research was carried out in database independence, performance testing and various other areas that will help the ADempiere community to continue developments in a direction of increased system independence. Whilst the contributions of an individual are invaluable, the efforts of one person alone are not enough in a major business solution such as ADempiere. This research will help other individuals to undertake system independence projects for ADempiere in the future, which will ensure that the application remains relevant as new technologies emerge. Publishing this work widely in the IBM Innovation network and in the ADempiere developer and support community has significantly added to reputation of the ADempiere community, IBM and above all to the prestige of the University in carrying out research in areas relevant to industry. iii Acknowledgements As with any non-trivial task, this capstone would not have been possible without the help and assistance of others. I am indebted to Stuart Nettleton for supervising the project and for organising IBM’s involvement. Stuart’s patience and constructive feedback helped keep the project on track and brought it to a higher level of quality. I would like to thank the IBM Innovation Centre for Business Partners for their extensive help throughout the project. The Innovation Centre provided the hardware and much of the software used in the project as well as access to consultants to help with diagnosing technical problems. In particular I would like to thank John Schilt for his organisation of resources and for taking the time to discuss new project directions in his role as industry co-supervisor. I would also like to thank Norman Bels for his mentoring role in IBM system administration. I am also grateful to my other industry co-supervisor, Alan McNamara, whose insights into systems architecture and emerging technologies proved very useful. Finally I must express my sincerest gratitude to my parents for their support throughout the project and throughout my entire undergraduate course. Grant Quick November 2008 iv Table of Contents Abstract ................................................................................................................................ iii Acknowledgements ............................................................................................................... iv List of Figures ........................................................................................................................ x List of Tables ......................................................................................................................... xi Acronyms and Abbreviations ...............................................................................................xii Units of Measure ................................................................................................................ xiii 1. Introduction ...................................................................................................................... 1 1.1 1.2 1.3 Project Background ..................................................................................................... 1 Project Purpose............................................................................................................ 2 Project Scope ............................................................................................................... 2 WebSphere Application Server Migration........................................................... 2 Database Independence Investigation .................................................................. 3 IBM i Port ............................................................................................................ 3 Performance Testing of Application Servers on IBM i ....................................... 3 1.3.1 1.3.2 1.3.3 1.3.4 1.4 2. Document Layout ........................................................................................................ 3 Product Outline................................................................................................................. 5 2.1 2.2 Overview ..................................................................................................................... 5 Enterprise Resource Planning ..................................................................................... 6 ERP History ......................................................................................................... 7 Motivations for ERP Implementation .................................................................. 8 Approaches to ERP Implementation .................................................................... 8 Advantages ........................................................................................................... 9 Disadvantages .................................................................................................... 10 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3 Open-Source ERP ..................................................................................................... 10 v 2.4 2.5 History of ADempiere ............................................................................................... 11 Additional ADempiere Features................................................................................ 12 Data Dictionary .................................................................................................. 12 Workflow Engine ............................................................................................... 12 Web Front End ................................................................................................... 13 2.5.1 2.5.2 2.5.3 2.6 2.7 3. Structure of the ADempiere Community .................................................................. 13 Direction of ADempiere and the Community ........................................................... 14 WebSphere Application Server Migration................................................................... 16 3.1 3.2 3.3 3.4 Overview ................................................................................................................... 16 Methodology and Migration Strategy ....................................................................... 17 J2EE and Application Servers ................................................................................... 18 WebSphere Application Server Distributions ........................................................... 20 Community Edition ............................................................................................ 20 Express Edition .................................................................................................. 21 Base Edition ....................................................................................................... 21 Network Deployment Edition ............................................................................ 21 Editions to be Supported .................................................................................... 21 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.5 EJB Roles .................................................................................................................. 22 Enterprise Bean Provider ................................................................................... 22 EJB Server Provider ........................................................................................... 22 EJB Container Provider ..................................................................................... 23 Application Assembler....................................................................................... 23 Deployer ............................................................................................................. 23 Systems Administrator ....................................................................................... 23 3.5.1 3.5.2 3.5.3 3.5.4 3.5.5 3.5.6 3.6 3.7 Structure of the ADempiere Deployment.................................................................. 24 Problems Resolved Throughout WAS Deployment ................................................. 24 vi 3.7.1 3.7.2 3.7.3 3.7.4 3.7.5 3.7.6 3.7.7 3.7.8 3.7.9 3.8 3.9 3.10 4. Configuration of adempiereApps.war ................................................................ 25 Configuration of admpiereRoot.war .................................................................. 25 Configuration of adempiereWebCM.war .......................................................... 25 Configuration of adempiereWebStore.war ........................................................ 25 Removal of JBoss Deployment Descriptor ........................................................ 26 Removal of Posterita .......................................................................................... 26 Overall Application Configuration .................................................................... 26 Deplosion of Enterprise Archive ....................................................................... 27 Hot deployment vs Configured Deployment ..................................................... 27 Lessons for Future Migrations .................................................................................. 27 Production of Installation Guide ............................................................................... 28 Impact of WAS Migration......................................................................................... 28 Database Independence Investigation .......................................................................... 30 4.1 4.2 4.3 4.4 4.5 4.6 4.7 Overview ................................................................................................................... 30 Current Database Implementation ............................................................................. 31 Layered Approach ..................................................................................................... 32 Object-Relational Mapping Middleware Approach .................................................. 33 EJB 3.0 Container Managed Persistence Approach .................................................. 35 Alternate Framework Approach ................................................................................ 37 Recommended Solution ............................................................................................ 37 5. IBM i Port........................................................................................................................ 39 5.1 5.2 5.3 Overview ................................................................................................................... 39 Methodology ............................................................................................................. 39 Platform Overview .................................................................................................... 40 History................................................................................................................ 41 Object-based Storage ......................................................................................... 41 vii 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.3.6 5.4 Integrated Database ............................................................................................ 42 Logical Partitioning (LPAR).............................................................................. 42 Single-level Storage ........................................................................................... 42 Technology Independent Machine Interface ..................................................... 42 Problems encountered in Linux for Power Systems Installation .............................. 43 PL/Java incompatibility with PostgreSQL......................................................... 43 Key Generation .................................................................................................. 43 Non-GUI installation ......................................................................................... 44 5.4.1 5.4.2 5.4.3 5.5 Problems Encountered in IBM i Installation ............................................................. 44 Use of different command environment ............................................................ 45 Lack of Editing Utilities..................................................................................... 45 Use of Different Character Encoding Schemes ................................................. 45 Different Java Options ....................................................................................... 45 Flushing the Configuration Directory in WAS .................................................. 46 Adding Access Privileges to PostgreSQL.......................................................... 46 5.5.1 5.5.2 5.5.3 5.5.4 5.5.5 5.5.6 5.6 6. Impact of Installation ................................................................................................ 46 Performance Testing of Application Servers on IBM i ............................................... 48 6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8 6.9 Overview ................................................................................................................... 48 Methodology ............................................................................................................. 48 Identification of Test Environment ........................................................................... 49 Identification of Performance Acceptance Criteria ................................................... 51 Plan and Design Tests ............................................................................................... 51 Configuration of Test Environment .......................................................................... 52 Implementation of Test Design ................................................................................. 53 Execution of Tests ..................................................................................................... 53 Analysis of Results .................................................................................................... 53 viii 6.9.1 6.9.2 6.9.3 6.9.4 6.10 7. Reliability........................................................................................................... 53 Response Time ................................................................................................... 54 Throughput ......................................................................................................... 56 Hits per Second .................................................................................................. 57 Conclusion................................................................................................................. 59 Future Directions ............................................................................................................ 60 7.1 7.2 7.3 7.4 7.5 7.6 Improving Robustness of the Ports in this Project .................................................... 60 Support for Additional Application Servers.............................................................. 61 Support for Additional Modules ............................................................................... 61 Database Independence ............................................................................................. 62 Service-Oriented Architecture................................................................................... 63 Modelling Approach to Development ....................................................................... 64 8. 9. Conclusion ....................................................................................................................... 66 References........................................................................................................................ 68 10. Appendix A: ADempiere on WebSphere Installation Guide...................................... 73 11. Appendix B: ADempiere on IBM i Installation Guide................................................ 80 12. Appendix C: WebLoad Test Scripts ............................................................................. 94 12.1 12.2 12.3 Login (simple) ........................................................................................................... 94 View Product Data (read operations) ........................................................................ 95 Place Sales Order (read/write operations) ............................................................... 103 13. Appendix D: Test Results............................................................................................. 113 13.1 13.2 JBoss........................................................................................................................ 113 WebSphere Application Server ............................................................................... 115 14. Appendix E: Document Version History .................................................................... 117 ix List of Figures Figure 1 - The core technologies from which ERP has evolved................................................ 7 Figure 2 - Methodology for Application Server Migration ..................................................... 18 Figure 3 - The Structure of a J2EE Application ...................................................................... 19 Figure 4 - Structure of a Typical EAR File.............................................................................. 20 Figure 5 - Current Data Access Code Structure....................................................................... 31 Figure 6 – Extending DBMS Support with the Layered Approach ......................................... 32 Figure 7 - Persistence implementation using Hibernate .......................................................... 34 Figure 8 - Data persistence implemented using EJB 3.0 Container Managed Persistence...... 36 Figure 9 - Methodology for IBM i Port ................................................................................... 40 Figure 10: Test Methodology................................................................................................... 49 Figure 11: Test Environment ................................................................................................... 50 Figure 12: Response time for WAS ......................................................................................... 55 Figure 13: Response time for JBoss......................................................................................... 55 Figure 14: Throughput for WAS.............................................................................................. 56 Figure 15: Throughput for JBoss ............................................................................................. 57 Figure 16: Hits per second for WAS........................................................................................ 58 Figure 17: Hits per second for JBoss ....................................................................................... 58 Figure 18 - First Run of Testing on JBoss ............................................................................. 113 Figure 19 - Second Run of Testing on JBoss ......................................................................... 114 Figure 20 - Third Run of Testing on JBoss............................................................................ 114 Figure 21 - First Run of Testing on WebSphere Application Server .................................... 115 Figure 22 - Second Run of Testing on WebSphere Application Server ................................ 115 Figure 23 - Third Run of Testing on WebSphere Application Server ................................... 116 x List of Tables Table 1 - Specifications of the test server ................................................................................ 49 Table 2 - Specifications of the Test Load Machine ................................................................. 50 xi Acronyms and Abbreviations AIX AJAX BMP BPM CE CMP CPU CPW DBMS EAR EJB ERP FTP HTML HQL IBM IO IP IT J2EE JAR JDBC JSP LPAR MDA MRP MRP-II ORM OS RAD Advanced Interactive Executable Asynchronous JavaScript and XML Bean-Managed Persistence Business Process Modelling Community Edition Container-Managed Persistence Central Processing Unit Commercial Processing Workload Database Management System Enterprise Archive Enterprise Java Beans Enterprise Resource Planning File Transfer Protocol Hypertext Markup Language Hibernate Query Language International Business Machines Input/Output Internet Protocol Information Technology Java 2 Enterprise Edition Java Archive Java Database Connectivity Java Server Page Logical Partitioning Model-Driven Architecture Material Requirements Planning Manufacturing Resource Planning Object-Relational Mapping Operating System Rational Application Developer xii SLES SOA SQL TAR TIMI WAR WAS XE XML Suse Linux Enterprise Server Service Oriented Architecture Structured Query Language Tape Archive Technology Independent Machine Interface Web Archive WebSphere Application Server Express Edition Extended Mark-up Language Units of Measure GB GHz MB TB s Gigabytes Gigahertz Megabytes Terabytes Seconds xiii 1. Introduction 1.1 Project Background As competition between businesses increases around the globe, the need to effectively manage business processes has never been more important. As organisations expand, their processes become increasingly complex and harder to manage, making it difficult for organisations to expand their operations. Over the past 30 years large amounts of money have been invested in software that can help to manage business processes. Of these software products perhaps the most important are the Enterprise Resource Planning (ERP) systems. ERP systems are used to manage the supply chain, finance and various other areas of an organisation. They have traditionally been very costly to install, partly because of software licensing and implementation costs. Many organisations have been slow to adopt the systems because of this expense, although the benefits of an implementation can be significant. This is beginning to change, however, with the emergence of open source ERP. The benefits of open source ERP products such as ADempiere are not limited to mature businesses. ADempiere is used all around the world, including in third world countries and non-profit organisations. By increasing the efficiency of operations and providing world’s best practice processes, ERP systems have the potential to make the running of organisations in undeveloped nations more efficient and increase the standard of living in such countries. Open source ERP systems are gaining acceptance very quickly in the industry, but still lack support for a number of environments. For them to continue their strong growth in the market, they need to increase their support for the hardware and infrastructure that is most commonly found in businesses today. In particular, these open source products need to support proprietary infrastructure products and midrange servers that are well established in the market. One open source ERP system that needs to do this is ADempiere. 1 1.2 Project Purpose The ultimate goal of this project is to help the ADempiere community move in the direction of greater system independence and increase the system’s long-term prospects of success by attacting a new dynamic in the community. With a system as large as ADempiere this cannot be achieved through the work of one individual alone, it must be pursued collaboratively. The effect of one individual that can inspire others is much greater than the one who works alone. As such, this project has set out to research what can be done to increase system independence for ADempiere and to undertake work that will inspire others to continue improving system independence. Because some of this work requires no programming experience, it is hoped that it will attract new members to the community with specialities outside of development. Amongst the work carried out is an application server migration, a database independence investigation, an operating system port and performance testing. Whilst this work stands up alone as a major achievement to the ADempiere community, its potential to inspire has much greater implications. 1.3 Project Scope The project includes a number of areas, such as application server migration, hardware porting and performance testing, which combine to achieve the goal of increased system independence for ADempiere. The scope of each of these areas is discussed in this section. 1.3.1 WebSphere Application Server Migration The first major task forming a part of this capstone project was the porting of ADempiere from JBoss to WAS. For reasons discussed in section 3, the migration was only performed for the commercial versions of WAS. Migrating to Community Edition was beyond the scope 2 of the project. The scope was also limited to the core functionality of ADempiere, add on modules were not included in the scope. 1.3.2 Database Independence Investigation The second major part of addressing system independence in ADempiere was an investigation into data independence. This section of the project was restricted to looking at options that could potentially be taken – experimenting with these options was considered but ultimately did not fall within the project scope. 1.3.3 IBM i Port Supporting one of the native OSs for Power Systems architecture formed the third major task of the project. As with the application server migration, this component was only concerned with the core functionality of ADempiere and not with add-on modules. Both JBoss and WAS were included in the scope of the port. 1.3.4 Performance Testing of Application Servers on IBM i The performance testing section of the project was limited to JBoss and WAS on IBM i. It also did not consider the performance of applications in general, only ADempiere. It was restricted to ten minute periods of operation. 1.4 Document Layout This thesis has been presented in the following sections: • Introduction – this section, which presents an overview of the project, its purpose and its scope • Product overview – a basic description of ADempiere, its features, its history and the advantages that it provides to businesses that choose to use it 3 • WebSphere Application Server Migration – describes the process used to port ADempiere from JBoss onto WebSphere Application Server • Database Independence Investigation – researches the current implementation of data persistence in ADempiere and which approaches can be used to extend database support in the product • • IBM i Port – details the work involved in porting ADempiere onto the IBM i platform Performance Testing of Application Servers on IBM i – summarises the results of performance testing of JBoss and WebSphere Application Server using ADempiere on IBM i • Future Directions – investigates further initiatives that could be taken in the near future to help better address system independence in ADempiere • Conclusion – summarises the achievements of the project and the discoveries made throughout it 4 2. Product Outline 2.1 Overview ADempiere is a full-featured open source ERP system that includes funtionalities such as supply chain management, human resources, customer relationship management and financial reporting. In a time when open source ERP systems are gaining popularity (Gruman 2007), ADempiere is emerging as one of the most rapidly advancing open source solutions to support the operations of businesses. ERP systems have been around for over a decade now and have proven their value to countless organisations. Their longevity shows that they are not simply another software fad (Robinson 2008), but rather a serious business solution capable of fulfilling the changing needs of organisations. Whilst ERP systems have shown strong returns on investment for many large organisations, they are often unattractive to start-up businesses because of the costs involved in installing and maintaining them. Open source ERP eliminates the licensing fees associated with the adoption and operation of an ERP system, significantly reducing the costs for many organisations. Furthermore, open source ERP does not involve risks associated with vendor lock-in and can be customised by anyone. ADempiere is in an exciting position at the time of writing. Despite being around for only little over two years, ADempiere is amongst the leading open source ERP distributions at a time when open source ERP is gaining much attention in industry. Whilst part of its success is owed to its Compiere code base, which has been on the market since 1999, the dynamic community that surrounds ADempiere has helped it to emerge as one of the premier open source ERP systems. 5 2.2 Enterprise Resource Planning The ERP market is currently one of the fastest growing in the IT industry (Sumner 2004). Despite involving large investments of time and money, many businesses are finding it necessary to install an ERP system just to stay competitive. The improvements obtained from them can be significant and despite often exceeding budget in installation, one study found that 92% of businesses who had implemented ERP systems were at least somewhat satisfied with their investment (McNurlin 2001, cited by Sumner 2004). An ERP system is essentially a collection of integrated software tools that manage the core business processes of a company (Stair 2006). Its ultimate goal is to integrate all departments and operations of an organisation into a single consistent system (Wailgum 2007). Although the ERP system can be built to support an organisation’s current processes, successful implementations are more likely to involve the re-engineering of the company’s business processes to meet the best-practice solutions provided in the ERP system. Many businesses have found that when linking the people, processes and technology of their organisation through an ERP system, reshaping their processes can result in significant improvement (Soliman 2006). Each of the software tools contained within an ERP system support a number of business processes and connect to a common database that stores all of their organisation’s operational data. By storing all data in the one location, inconsistencies between departments are removed and advanced data mining techniques can be used to extract more useful information, which can be used in turn to make more reliable forecasts and improve planning. Before ERP, most organisational departments used their own software modules. In addition to the data ambiguity problems this raised, the non-compliance of interfaces between two modules often resulted in inefficiencies within the organisation, requiring additional human interaction, resulting in slower and less reliable processes. ERP systems allow for seamless integration of modules and have been used in practice to help organisations increase their revenue and reduce expenses. 6 2.2.1 ERP History The origins of ERP date back to the 1960’s, when customer inventory control systems were first implemented. Because of technology limitations at the time, these systems were very expensive and had very restricted functionalities. Although rudimentary, these systems were able to forecast demand from past data. In the 1970’s Material Requirements Planning (MRP) Systems emerged as an evolution of the earlier inventory control systems. MRP could be used to control the production of goods to meet demand and reduce inventory. Over time, closed-loop MRP systems emerged with additional tools such as sales planning and customer service (Somers and Nelson 2003, cited by Sumner 2004). With the explosive growth of MRP systems in the 1980’s, the term MRP-II was coined to denote new systems with accounting and materials management functionalities. Whilst MRPII systems covered a large share of an organisation’s operations, they were limited in scope and could only be used by manufacturing companies. Figure 1 - The core technologies from which ERP has evolved In the mid 1990’s ERP extended on MRP with the addition of features such as human resources and supply chain management, which allowed some businesses to run entirely from the one system. The list of functionalities continues to grow, allowing an ever-increasing 7 number of organisations to integrate their processes and improve the efficiency of their operations. 2.2.2 Motivations for ERP Implementation There are a number of reasons as to why an organisation may elect to implement an ERP system. Typical reasons include: • • • • • • • • The need for a system that links geographically dispersed departments More efficient communications between departments The ability to store data in a single location for data warehousing The need to replace an unsupported legacy system To avoid risking loss of competitive advantage to competitors with ERP systems To attempt gaining a competitive advantage Better interaction with supply chains Standardisation of systems to simplify training and system upgrades 2.2.3 Approaches to ERP Implementation Norris et al (2004) suggests five possible options for businesses to support their business processes in relation to ERP. These are: • • • • • Green field Non-Integrated ERP Implemented by Function ERP Implemented by Business Unit Fully Integrated ERP The simplest approach to business process management, known as green field, is an ad-hoc approach that involves no structured management of business processes. This is often the approach taken by new start-up businesses, though few businesses remain with it for long. As 8 green field businesses mature they can afford to be flexible and setup their business processes to be consistent with an ERP system or in any other way that suits their needs. The second option describes businesses that choose to have their business processes supported by a number of separate systems that do not communicate with each other. These businesses tend to be inflexible and are slow to respond to change. The process of upgrading to an ERP system is most expensive for such businesses. Non-integrated support for business processes should be avoided wherever possible. ERP implemented by function is an approach whereby a business supports some, but not all of its business processes in an ERP system. This is often an interim solution for businesses that do not want to undertake the risks involved with a fully integrated ERP system. Over time the business may choose to incorporate more of the ERP system’s functionality. The fourth option refers to organisations that implement ERP systems only in certain departments of sections and not across the entire organisation. In some instances this is ideal, for example a parent company may have several sub-companies that are run independently and maintain their own ERP systems. In other cases it is a less than ideal scenario as it may involve duplicate data and less than optimal communication across departments. The final option is for an organisation to implement a fully-integrated ERP system. Organisations that take this approach can generally be run at optimal efficiency and encourage greater productivity. On the downside, organisations that opt for a fully-integrated ERP system must be prepared for greater expense and higher risk in the short term. 2.2.4 Advantages There are a large number of benefits to implementing an ERP system. These include: • Reduced cycle times • Faster and more efficient reporting • Inventory reduction 9 • Elimination of unnecessary expenses • Greater employee productivity • Better co-ordination across departments • Adoption of flexible best-practice business processes • Less effort spent on integrating systems • Ability to perform data warehousing on a single database • Reduction of the need for paperwork • Ability to produce more accurate quotes in less time 2.2.5 Disadvantages Whilst ERP has been taken advantage of to the benefit of many organisations, it is not without disadvantages. For many organisations the advantages involved in adopting an ERP system outweigh the disadvantages. Nevertheless all disadvantages should be considered before any ERP implementation is undertaken. Shortcomings include: • • • • Traditionally high software licensing fees Significant implementation cost The majority of implementations exceed budgeted time and cost (Sumner 2004) A successful implementation may take several years to produce a return on investment (Wailgum 2007) • • • • Organisation culture may need to change in order to accommodate the ERP system Privacy concerns regarding the storage of data in a single location Extensive training is required for all users Vendor lock-in 2.3 Open-Source ERP At the moment the business models of large ERP vendors are not well suited to start-up businesses and growing organisations. In addition to expensive licensing fees they charge, commercial ERP vendors are generally more interested in pursuing large contracts and are 10 not able to focus on the needs of any but the largest organisations (Gruman 2007). There is a need for consultants who are able to supply the support needed by all types of organisations without being distracted by larger contracts. Open source ERP provides a model that is able to accommodate such needs. A number of small consulting firms have emerged to help organisations of all sizes implement ERP systems and customise them to suit their needs. These consultants are able to operate because they do not have to outlay the financial overheads involved with supporting a proprietary ERP system. Furthermore such consultants are able to access the source code of the ERP system and implement changes for their clients if necessary. It is also common for the end-users of an open source ERP system to be involved in the community. Some might be developers themselves, whilst others provide feedback and support in other areas. This allows developers to become more aware of the needs of the end user, which leads development in a more user-conscious direction (Chen 2005, cited in Moore 2005). Another benefit, which applies to companies of all sizes, is freedom from vendor lock-in (Lemos 2008).Organisations that implement open source ERP solutions have total control over what they do with their installation and, should the creator of their ERP system cease to support their system, they are in a position to maintain their investment. 2.4 History of ADempiere ADempiere has its origin in a competing product named Compiere, an ERP system that was designed by Jorg Janke. Janke founded the Compiere company along with version 1.0 of the product in 1999. Although he maintained control of the code base, others were able to download and modify the source and submit the changes back to Compiere to be considered for inclusion in the next release. 11 Compiere enjoyed strong growth, but was sometimes criticised by the open source community for being commercially driven. A situation arose in 2006 when Compiere gained the backing of a venture capitalist and decided on a new strategy whereby parts of the code would be developed proprietarily and not made available to the open source community. In retaliation to this the ADempiere Bazaar was founded by a number of key contributors. The Bazaar soon released a rebranded version of Compiere known as ADempiere. Over the past two years it has moved further away from Compiere and has become a fully fledged product in its own right. 2.5 Additional ADempiere Features In addition to the features that are common amongst most modern ERP systems, ADempiere contains a number of features that differentiate it from competitors. 2.5.1 Data Dictionary The data dictionary in ADempiere was inherited from the Compiere project. It allows for database changes to be made dynamically without having to make any programming changes. This means that columns can be added and removed from the database tables without needing to bring the ERP system down. 2.5.2 Workflow Engine Another feature inherited from the Compiere project, the workflow engine allows for entire business flows to be constructed without making programming changes. It is common for business processes to evolve over the life of an ERP system and with this feature it is possible to accommodate such change without system downtime. Furthermore, workflow editing is performed at a high level in the interface, meaning that business analysts are able to implement the changes without involving technical support. 12 2.5.3 Web Front End Traditionally, Compiere users had to rely on a rich Java client, which had to be installed on the machine that they were working on. ADempiere has a full AJAX web user interface that allows the core system functionality to be accessed from any machine connected to the same network that has an Internet browser. The installation of additional files is not required. 2.6 Structure of the ADempiere Community The ADempiere community is structured in a similar fashion to many other open source projects, in what is known as a Bazaar. This term was first coined by Eric Raymond in his seminal work The Cathedral and the Bazaar (1999). The idea behind the Bazaar is that all contributors are equal. Although there is generally a leadership panel to control project direction, as is the case with ADempiere, the product belongs to the greater community and is not directly tied to commercial interests. The value of the work produced by all members of the community is considered priceless. The members of the ADempiere Bazaar come from a variety of backgrounds. Whilst the majority are involved in development or customisation, others are able to contribute in testing, documentation, publicity and a variety of other areas. There are a number of members in the community that have set out to make a living from the product. These are generally consultants, who install and maintain the product for their clients. Because of the way the Bazaar is structured, such consultants are in no way financially liable to the community. However, it is hoped that any development from customisations performed will be fed back into the community, so that everyone can benefit from the changes. A number of clients are also involved directly in the community. They are able to provide feedback, suggest new features and report bugs based on the work performed in their production environments. Some clients are also more technically involved and release changes made to their own systems to the greater community. 13 Whilst the structure of the ADempiere community is very loose, there is a small committee that oversees the overall direction of the product. These individuals decide on which contributions are included in the core release of ADempiere and work together to implement certain features to coincide with new release versions. This helps to maintain project cohesion and reduce branching of the project into various spin-offs. 2.7 Direction of ADempiere and the Community Whilst the ADempiere Bazaar does have an eclectic range of talents within it, the focus of skills is currently centred around technical aspects such as programming and customisation. Many of the technicians involved in the community are multi-skilled and have some business experience, but ultimately the community has a large proportion of freelance consultants who do not specialise in business strategy. Whilst technical consultants are and will always be a vital part of the community, their proliference tends to focus the product around short-term goals. Development efforts are rarely focused on large features not scheduled in the current milestone, they are generally concentrated on small enhancements and bug fixes. If ADempiere is to grow and become more competitive in the ERP market, it needs to attract long-term strategic thinkers into its community. Many other open source communities, such as those focused around various distributions of Linux, benefit from the support of large corporations (Seltzer 2002). This support helps not only the other developers to work toward long-term goals without fear of cash-flow problems, it provides the community with new members who specialise in business operations and enable the community to better align their product with emerging industry trends. Having more strategic specialists in the ADempiere community would allow the community to grow more rapidly and attract more developers. Furthermore, current developers would be able to focus more on what they are best at, rather than spending time in the areas where they do not specialise. As a result, the quality of ADempiere would improve and all members 14 would see benefits, whether they are involved in the corporate world, voluntary orgnisations or in businesses operating in developing nations. By focusing on increasing the platform support of ADempiere to systems that are commonly used by corporate organisations, the product will be exposed to more business-oriented individuals with the skills that the community needs to develop. If these individuals become members of the community, they will help bring a new direction to the advancement of ADempiere over the coming years. 15 3. WebSphere Application Server Migration 3.1 Overview Prior to this project ADempiere was only supported by one application server: JBoss, which is open source and distributed freely with ADempiere. If an organisation wished to perform a full install of ADempiere, they were forced to install JBoss, even if they already had a different application server installed. Although JBoss is a mature application, it began as a small project amongst a group of a few people (Richards and Griffith 2005). It was not designed from the outset to be a full J2EE server and has never received the same financial commitment as commercial competitors such as BEA WebLogic, Oracle Application Server or IBM WebSphere Application Server. For this reason, as well as the fact it is rarely used in large scale projects and can be difficult to secure, JBoss is not as trusted in a business environment. As such it is very desirable to support at least one of the big commercial vendors. Many organisations have an IT policy in which only certain infrastructure software components are permitted. Typically these components are proprietary products with long standing reputations. Such organisations do not necessarily have an aversion to open source applications, but have difficulty finding open source applications that support the restricted infrastructure mandated by their policies. Additionally, the performance of a web-based product is often determined by the skill of the administrator in configuring the application server (Roehm et al 2005). If an administrator is skilled in only one application server, it does not make sense to install a product that requires a completely different application server, particularly if the product, like JBoss, is rarely run on certain hardware configurations. The goal in this project was to support IBM WebSphere Application Server (WAS). WAS is a very widely used product and highly regarded in the industry, according to Black et al 16 (2005) it is the fastest growing and most widely used product in the middleware market. It supports a number of different platforms, including Linux, Windows, IBM i, AIX, HP-UX and z/OS, and is included in the price tag of many of IBM’s midrange servers. WAS has a very different deployment process to JBoss. By supporting WAS many of the problems that are generally encountered when performing an application server migration were resolved. This will make it easier for other members of the ADempiere community to port to other application servers in the future. It will also provide a path that new developers can use as a way of getting involved in the community. Should support for JBoss ever cease, it also provides a way through which ADempiere can continue to prosper without lock-in to a legacy vendor. 3.2 Methodology and Migration Strategy Migration of an application between different vendors’ products is generally not a straight forward task. It often requires the involvement of a variety of people from different backgrounds carrying different skill sets (Black et al 2005). Cunico et al (2005) suggests three different approaches that can be taken for migration: • Modulisation – The system is broken down into smaller components, which are deployed one at a time. • Deploy, test and solve – The system is deployed onto the new application server straight away. Any problems encountered are traced back and solved. • Vertical slice – The system is migrated one use-case at a time. This approach is generally taken for very large projects involving lengthy periods of time. In this project the “deploy, test and solve” method was primarily relied upon. Where problems were difficult to isolate, packages were removed from the core and added back one at a time, as per the “modulisation” method, until a working system was obtained. All modifications were made in Rational Application Developer. The complete methodology is summarised in the following diagram: 17 Figure 2 - Methodology for Application Server Migration 3.3 J2EE and Application Servers The application server is perhaps the most important infrastructure component of any J2EE application. In essence, it provides most of the core functionality that is common to all enterprise applications and allows developers to focus on the product at hand, rather than implementing the repetitive functionality that is better left to specialists. J2EE is an open standard that specifies how the services supplied by an application server can be used. Anyone can write an implementation of a J2EE application server and there are many vendors who have – there are 17 application servers with officially accredited implementations of J2EE 1.4 at the time of writing (Sun 2008) The J2EE standard specifies a number of services, such as connectivity, directory services, security, transactions, messaging and email (Bond et al 2004). These services support the Enterprise Java Bean (EJB) and web containers that host the applications running on the server. The EJB container is the most important part of the application server. It provides a component architecture that reduces the complexity of developing enterprise-level distributed 18 applications (Roman 1999). Essentially, developers simply need to break their problem space up into smaller components that can be implemented as enterprise beans. The EJB container provides an extensive range of no cost middleware features that glues the application together with the extra features that are provided by the application server. A basic overview of the structure of a J2EE application, indicating the various tiers of the architecture, is shown in the following diagram: Figure 3 - The Structure of a J2EE Application Full J2EE applications are generally distributed as EAR files. An EAR file is simply a compressed archive that contains the various EJB modules, web modules and application client modules used in the application (Black et al 2005), as well as utility classes that support these modules. The EAR file and each of its modules contain deployment descriptors that provide the application server with information that is needed in order to run the application. This structure is represented in the following figure: 19 Figure 4 - Structure of a Typical EAR File Theoretically an application that is written in J2EE should work with any J2EE compliant application server. However, in practice this is not the case. Because the J2EE standard was designed to be flexible, every vendor adds their own additional functionality to allow for better tuning of applications. Additionally many vendors do not enforce applications to strictly conform to the J2EE standard, so what might work on one vendor’s product will fail on another product. 3.4 WebSphere Application Server Distributions There are several different distributions of WAS that support varying features. These are: 3.4.1 Community Edition WAS CE is the most unique of all the WAS distributions. Whereas all of the other distributions share the same code base, WAS CE is based upon Apache Geronimo, an open source J2EE application server. WAS CE maintains the file structure and deployment descriptors that are used by Geronimo as opposed to those used by the commercial 20 distributions of WAS. This makes a port to CE unique from the other editions of WAS and from a development perspective it must be treated as a separate product. 3.4.2 Express Edition Express Edition is the entry level commercial version of WAS. It contains all the necessary functionality of a J2EE application server, including EJB 3.0 support (IBM 2008a). It is limited to running on a maximum of two processors. 3.4.3 Base Edition Base is virtually the same as Express Edition, but is packaged differently (Cunico 2005). It comes with development tools and different licensing. It also supports additional features such as load balancing and can be run on unlimited processors (IBM 2008a). From a development perspective it can be treated exactly the same as Express Edition. 3.4.4 Network Deployment Edition The Network Deployment Edition supports clustering - the distribution of an application over multiple servers (Cunico 2005). This can be of benefit to applications in high demand as requests from different clients can potentially be handled by different servers. As Network Deployment Edition is an extension of Base Edition, any program that can be deployed and run on Express and Base Editions will also work in Network Deployment Edition. 3.4.5 Editions to be Supported As one of the main reasons for porting ADempiere to WAS is to add support for a commercial application server, development efforts in this project will not be concerned with CE. Instead efforts within this project will be focused on Express, Base and Network Deployment Editions. 21 3.5 EJB Roles The Sun EJB specification (Matena and Hapner 1998) describes six roles with associated responsibilities which need to be undertaken during the lifecycle of a system involving Enterprise JavaBeans. The roles can entail a degree of overlap and it is often desirable for a single individual or group to undertake multiple roles. A better understanding of these roles can lead to a shorter development lifecycle (Black et al 2005) and help to compartmentalise problems, making them easier to solve. 3.5.1 Enterprise Bean Provider This party is responsible for creating EJB components, which are essentially the building blocks of enterprise Java applications. In large systems there will usually be a number of such providers, some in-house and some third-party developers. With the exception of legacy code remaining from Compiere development, all Enterprise Bean development in ADempiere is performed by the Bazaar. As the project being undertaken is concerned with greater system independence as opposed to increased functionality, development of further beans will not be a concern. It should be noted that in full J2EE applications the data model is encapsulated within persistence beans. With ADempiere however, this is not the case. Research conducted during this project found that the data model was maintained separate to the development of beans and accessed directly using a layered JDBC approach. This is explained in further detail in section 4. 3.5.2 EJB Server Provider The EJB Server Provider produces an application server that can contain EJB containers. Before this project JBoss was the only application server supported by ADempiere. The goal of this section of the project is to support IBM as an alternative EJB server provider. 22 3.5.3 EJB Container Provider The EJB Container Provider develops the low level environment in which an EJB component operates. The container sits inside the application server and provides a number of required services, such as transaction management, security and persistence (Roman 1999). Traditionally ADempiere has relied on Apache as its EJB Container provider, which produces the popular Tomcat container. As the commercial versions of WAS contain their own proprietary container, IBM can be seen as another EJB Container Provider for this project. 3.5.4 Application Assembler The application assembler takes the EJB components from the various Enterprise Bean Providers and integrates them into a functioning application. In the case of ADempiere the integration of the components is the responsibility of the community. This project touched on this role where it was necessary to remove components in order to obtain a working deployment. 3.5.5 Deployer The deployer role involves installing EJB components in the EJB container of an application server. This is primarily what this section of the project was concerned with. The deployer does not need to work with the application code, but rather the configuration of the application, which needs to be modified when the deployment environment is changed. 3.5.6 Systems Administrator This party is responsible for maintaining an implementation of the system once it has been deployed and is live. This role was not dealt with in this section, but was undertaken in 23 sections 5 and 6 of the project when ADempiere was installed on IBM i hardware and underwent testing in a live environment. 3.6 Structure of the ADempiere Deployment Once ADempiere was installed and its operation verified on JBoss, it was migrated directly into WAS. Initially the application deployment failed, so the EAR file that contained the application was imported into Rational Application Developer for analysis. The file contained the following components: • • • • • • • • • Posterita.war – The point of sales web interface WebStore.war – The online store web interface AdempiereCM.war – The main menu web interface AdempiereRoot.war – The administrator web interface AdempiereApps.war – The core ADempiere operator web interface. AdempiereRoot.jar – Contains the ADempiere Status and Server session beans. AdempiereApps.jar – Utility archive containing the application libraries. AdempiereSLib.jar – Utility archive containing server libraries Adempiere.jar – Utility archive containing general libraries It was found that ADempiere was not a well-structured three-tier J2EE application, but more closely resembled a client-server architecture. The business logic was intertwined with data and the services provided by J2EE were used minimally. Whilst this would not affect the application server migration, it impacted on the other parts of system independence addressed in this project, particularly in relation to database independence. 3.7 Problems Resolved Throughout WAS Deployment Numerous problems were encountered throughout the deploy, test and solve cycle. These included non-adherance to doctype definitions, syntax errors in deployment descriptors and 24 deployment strategies. Each one of these issues was addressed individually until a working deployment was obtained. 3.7.1 Configuration of adempiereApps.war A document type descriptor reference was not included in the adempiereApps.war deployment descriptor. A reference to the Sun Web Application 2.3 descriptor was added and a number of parameters were removed from the tag to enforce compliance with the document type descriptor. 3.7.2 Configuration of admpiereRoot.war The deployment descriptor for adempiereRoot.war did not contain a reference to a document type descriptor. Once again the Sun Web Application 2.3 descriptor was referenced and a number of parameters were removed from the tag to conform with the document type descriptor. 3.7.3 Configuration of adempiereWebCM.war The deployment descriptor for adempiereWebCM.war did not contain a document type descriptor reference. A reference to the Sun Web Application 2.3 descriptor was added. To conform with the document type descriptor a number of parameters were removed from the tag. The order of the and tags also had to be changed. 3.7.4 Configuration of adempiereWebStore.war The deployment descriptor for adempiereWebStore.war needed to contain a reference to a document type descriptor. The Sun Web Application 2.3 descriptor was referenced. 25 To make the deployment descriptor compliant with the document type descriptor a number of parameters were removed from the tag and the ordering of the and tags was changed. 3.7.5 Removal of JBoss Deployment Descriptor This step was not in fact needed to get ADempiere running on WAS, but was performed for tidiness. As the JBoss specific deployment descriptors were no longer needed, they were removed from the project entirely. There were two JBoss deployment descriptors – jboss.xml and jaws.xml. Both of these descriptors were contained in the adempiereRoot.jar session bean. The files were deleted and their references were removed from the manifest file of adempiereRoot.jar. 3.7.6 Removal of Posterita For reasons unknown ADempiere could not be run in WAS when it contained Posterita, the point of sales module. The package would properly deploy, but hang when started. As Posteritia was not required for the core ADempiere functionality, it was removed from the package entirely. This included the JAR file for Posterita as well as the references to it in the application deployment descriptor and the EAR manifest file. 3.7.7 Overall Application Configuration There were several problems stemming from the application deployment descriptor. Firstly, the file did not include a document type descriptor. The Sun Application 1.2 descriptor was included, standardising the descriptor. Secondly, the three utility files used by ADempiere – Adempiere.jar, adempiereSLib.jar and adempiereApps.jar, were included as session beans in the application deployment descriptor. This is incorrect and prevented the WAS from deploying the application. They simply needed 26 to be removed from the deployment descriptor, as utility JAR files do not need to be referenced in the descriptor. 3.7.8 Deplosion of Enterprise Archive Unlike JBoss, WAS does not support deployment of exploded archives. As such, a proper enterprise archive needed to be produced using the following command: jar cvfM adempiere.ear * 3.7.9 Hot deployment vs Configured Deployment WAS does not support hot deployment like JBoss. Whilst this can make the deployment process harder to automate, it has the advantage of automatically generating vendor-specific deployment descriptors, rather than requiring the deployer to learn the format of the descriptors and write them manually. The ability to automatically generate these descriptors helped to reduce the effort required in the migration. 3.8 Lessons for Future Migrations Each future application server migration will contain its own issues that will need to be resolved independently. However, there were a number of lessons learnt from this migration that can be used for simplifying future migrations. It is important that applications standardise their configurations in order to be easily migrated across application servers. At the time of writing, the ADempiere core uses non-standardised deployment descriptors that will cause errors on all application servers other than JBoss. It is highly recommended that the community adopt doctype definitions for all descriptors so that they can be universally understood by all application servers. 27 The ADempiere core is continually being added with functionality that is not of any use to many organisations. The core now contains three separate interfaces – a legacy rich Java client and two functionally identical web interfaces, which all serve the same purpose. Ideally the community should be focusing their efforts on one interface and including only that interface in the core distribution. The community should also consider removing or allowing users to disable add-on packages such as the Posterita point of sale component. Posterita is only of use to retail-based organisations and can potentially cause installation problems for other organisations that don’t need it. The final lesson that should be taken into account when performing future migrations is to consider the deployment process for the target application server and to prepare the EAR file in a format it will accept. This may seem obvious, but there are a lot of intracacies in EAR files, some of which may cause problems on certain application servers. 3.9 Production of Installation Guide Once all of the aforementioned issues were addressed, the deployment of ADempiere was successful in WAS. A number of tests were run to make sure that the key functionality in ADempiere was operational. To assist the community in repeating the WAS migration and developing migration strategies for other application servers, a comprehensive installation guide was written and published in the community’s wiki. This guide has been included as Appendix A. 3.10 Impact of WAS Migration The migration to WAS is the first time that ADempiere has ever been run on an application server other than JBoss. This is a landmark for the ADempiere community and represents a big step in terms of system independence. Whilst additional work must be performed to run ADempiere on other application servers, the work in this project has pioneered the way for further developments. As many of the issues 28 overcome would have caused failures in other migrations, it will no longer be necessary for developers to address such issues again. Most importantly, this project has shown that the selected methodology can be successfully used to perform application server migrations. By adapting this methodology to a particular platform, migrations can be performed for any application server. This provides a number of potential new projects for members new to the community to undertake, which will allow the community to grow and achieve more in the future. The increase of supported application servers, particularly of commercial vendors, will also make ADempiere more attractive to a number of businesses and attract new members from a corporate domain. Such members will add a new element to the community and allow development to better align with industry trends. The migration has been well received within the community and a similar migration was performed for the Glassfish application server soon after the successful outcome of this project was announced. With these two achievements, the community should now be confident in migrating to any desired application server and further increasing system independence. 29 4. Database Independence Investigation 4.1 Overview One of the most important system independence issues that must be addressed in ADempiere is database independence. At the moment ADempiere supports only two different database vendors: Oracle and PostgreSQL. The choice of database is amongst the most important for many businesses that may have sensitive data that they need to secure. Often businesses will build up trust in a particular database vendor and will not select a product to support its business processes unless it will work with their chosen database. Alternatively a business may simply make a good deal with a particular database vendor and decide to adopt their solution. Individuals within organisations may not be concerned at all about the choice of database vendor, but may be restricted in choice because of IT policies mandated throughout the organisation. If the vendors supported by ADempiere do not conform with these policies, the product cannot be installed no matter how attractive it may otherwise seem. Some businesses may be less concerned about a using a particular vendor, but do not trust an open source Database Management System (DBMS) or require the support that comes with a proprietary product. For these organisations, improved database independence can provide more negotiating power when obtaining licensing agreements from database vendors. Finally, support is an important issue that needs to be considered when considering the useful life of the system. Throughout the past twenty years a number of highly regarded database vendors have gone out of business (Symonds 2003) and it is never a good idea to be locked into one vendor. Easy migration strategies should be available. The ways in which database independence can be improved in ADempiere were investigated and the viable alternatives evaluated. Undertaking one of the alternatives as a part of this project was also considered, but it was decided that the amount of effort required would have 30 been too great given the resources available. As such, it is hoped that this section will facilitate further discussion within the community and inspire others to undertake database independence work in the future. 4.2 Current Database Implementation When ADempiere was originally branched away from Compiere in 2006 it supported only Oracle. There was a high coupling between the application logic and data, stemming from the product’s architecture. When the community carried out the PostgreSQL port they faced a difficult task. Rather than separate the data away from the business logic, an abstract “convert” class was created. Database support is carried out by converting Oracle SQL statements through this class, which is inherited by any classes written to carry out database conversions. Figure 5 - Current Data Access Code Structure 31 There is currently an implementation of convert for PostgreSQL and Oracle. The Oracle implementation does not in fact perform any conversion and simply logs all database calls. The PostgreSQL conversion class interprets the syntax from Oracle SQL statements and converts them into the equivalent statements in its own SQL dialect. 4.3 Layered Approach The simplest means of improving database independence would be to extend the current structure one class at a time to satisfy each additional supported DBMS. Figure 6 – Extending DBMS Support with the Layered Approach In terms of source code changes the amount of effort required for each new DBMS would vary, but would amount to approximately 1000 lines of code for an SQL 92 compliant implementation. 32 In addition to the implementation of the relevant class, a number of stored procedures would need to be rewritten for the DBMS. Currently some of the stored procedures are written in Java and can be reused by other DBMSs that support Java procedures. Also a migration of the initial database configuration would need to be performed. The new procedures and the database configuration would need to be stored in a dump file that can be loaded onto the database during installation. The advantages of using the layered approach include: • • • • It is the quickest way of supporting a new DBMS It has been done before – expertise is available in the community There are no major performance issues Because the current structure is not being changed there would be a minimal impact on the rest of the project The disadvantages of using the layered approach are: • It isn’t scalable – each new implementation will require a roughly equal amount of work and add significantly to the code base • It’s difficult to maintain – each new implementation would have to be maintained by somebody in the community • It requires an excellent understanding of Oracle SQL and the SQL dialect of the vendor being supported 4.4 Object-Relational Mapping Middleware Approach Object-Relational Mapping (ORM) middleware products allow a programmer to specify their data model in the application independently of the relational tables in the database. This not only allows for a clean fully object-oriented solution, it abstracts the data storage details to a point where the underlying database can be changed with very little effort. Hibernate, one of the most popular ORM middleware products for Java, currently supports more than twenty different DBMSs, including Oracle, DB2, MySQL, PostgreSQL, Microsoft SQL Server and Caché (Hibernate 2008b). Because changing DBMS can be a simple matter 33 of configuration, it is possible to support a large number of DBMSs without the extra maintenance required with the layered approach. Using an ORM middleware solution would involve extensive changes to the code base. In the case of Hibernate, all database queries would need to be replaced by HQL statements, the language that Hibernate uses to manipulate data. The data model would also need to be encapsulated in a series of classes setup to be mapped by the ORM product. Figure 7 - Persistence implementation using Hibernate Whilst an ORM middleware solution would be ideal in terms scalability and maintainability, it comes with a performance penalty. To overcome this it may be necessary to use stored procedures. Unfortunately this requires additional maintenance for each DBMS that is supported. Furthermore, not all ORM middleware products support stored procedures, so this should be a consideration when selecting an ORM middleware vendor. Hibernate 3.0 is one example that does support stored procedures. (Hibernate 2008a) The advantages of using the ORM Approach include: • Maintainability does not increase significantly as additional DBMSs are supported 34 • • It is easier to scale system to support a greater range of DBMSs All supported DBMSs can be updated at once by simply updating to a newer version of the middleware The disadvantages of using the ORM Approach are: • The performance penalty can be significant • Performance may be restricted if stored procedures are not supported by the chosen middleware • It requires a significant amount of effort to implement • It relies on the continued support of the chosen ORM vendor to remain viable • It can be more difficult to debug than native SQL 4.5 EJB 3.0 Container Managed Persistence Approach The EJB 3.0 framework supports ORM implicitly, meaning that an abstraction of the data model from the database can be made without relying on middleware or custom code. As EJB 3.0 is a specification, there is no vendor lock-in as there is when using an ORM middleware (Ramaswamy 2008). For example, JBoss has based their implementation upon Hibernate, whilst Oracle has based theirs upon Toplink (Coffin 2006). This is good for developers who now have an industry standard to follow as well as for businesses that no longer need to risk the future of their system on the support of a particular ORM vendor. In addition to ORM, EJB 3.0 provides a variety of other services, such as transaction management, instance pooling, security and concurrency control (Yuan 2005). By adopting the standard, developers within the ADempiere community would no longer need to concern themselves with such tasks and could concentrate their efforts on improving product functionality. Unfortunately, as ADempiere does not currently use entity beans, the amount of effort required to upgrade to EJB 3.0 is very significant. Using EJBs requires the data model to be broken up into manageable components know as entity beans. 35 Figure 8 - Data persistence implemented using EJB 3.0 Container Managed Persistence As with ORM middleware, performance could potentially be an issue with EJB 3.0 Container Managed Persitence (CMP). There are however, mechanisms for improving performance, such as using native queries. Alternatively, if performance becomes a major issue using EJB 3.0 CMP, it is possible to use Bean-Managed Persistence (BMP) on bottleneck components. Whilst BMP is not a part of the EJB 3.0 standard, it is defined in the EJB 2.1 standard and must therefore be implemented in all EJB 3.0 distributions. When using BMP the programmer specifies exactly how a beans data is mapped into the database. The advantages of using the EJB 3.0 Approach include: • • It provides the cleanest result of the proposed solutions It theoretically provides all of the advantages of the ORM middleware approach, but without the same performance penalties. • Because EJB 3.0 uses annotations by default instead of XML for configuration, the configuration can be included in the code and is easier for developers to maintain • EJB 3.0 skills are highly sought after in industry, which would encourage members of the community to get involved in its use. 36 The disadvantages of using the EJB 3.0 approach are: • Significant amount of work required, will probably need to be undertaken by a small dedicated team • Requires support from the community as it will involve major changes to the direction of future development • • Does not provide the same performance potential as the layered approach If annotations are used they cannot be reconfigured without recompiling the source code 4.6 Alternate Framework Approach In addition to the approaches described already, it would also be possible to adopt an entirely new framework to manage persistence. At the time of writing Spring is probably the most popular Java framework for performing such tasks. In comparison to EJB 3.0, Spring is more flexible and performs arguably better, but it is also more complicated to configure and provides poor support for stateful components (Coffin 2006). Furthermore, Spring is not an open standard like EJB 3.0 and only one implementation of it is available. Each individual framework would need to be evaluated individually for its suitability to the ADempiere project. As there are many such frameworks and new ones emerge frequently, reviewing each one is beyond the scope of this investigation. It should be noted though, that many of these frameworks involve vendor lock-in and are not as widely accepted as EJB 3.0, meaning that they carry higher levels of risk. 4.7 Recommended Solution The decision as to which approach should be taken for database independence needs to involve the ADempiere community. Because of the nature of the Bazaar, it is important that developers are happy with the choice of technologies in order to ensure maintenance 37 continues when key individuals join and leave the community. Ultimately, the support of the community is more important that the technical advantages of the chosen approach. At the time of writing EJB 3.0 is probably the most appealing solution. Like ORM middleware it abstracts the data used in the business logic from the underlying database, but with the added benefits of being an open standard that is widely recognised in the industry. Although it would require significant effort to implement, over the long-term it would save time by improving maintenance, scalability and testability. Nevertheless, ORM technologies have improved rapidly over the past several years and there is no reason why they cannot continue to improve. When the community is ready to commit to improving data independence, the choice of technologies used in the approach should be re-evaluated. The earlier this is done the better, as such developments could attract new members to the community that could also help in other areas. 38 5. IBM i Port 5.1 Overview As ADempiere is targeted towards businesses, it is important that it supports the hardware designed for such organisations, known as midrange servers. IBM recently outscored its rivals in customer satisfaction with midrange servers (DeMarzo 2008) and continues to hold one of the greatest market shares in the server market today (IDC 2008). As such, it is crucial that ADempiere supports IBM’s most current midrange server series, the IBM Power Systems. IBM’s midrange servers have played an important role in the history of ERP systems, with JD Edwards focusing its support on the System/38 platform throughout the 1980s and the AS/400 throughout the 1990s (ERP and More 2008). Subsequently, there are many legacy ERP systems that are hosted by IBM midrange servers. By porting ADempiere to the IBM Power System, a step is being made that puts ADempiere is a unique position ahead of other open source ERP vendors. By providing businesses with a solution that they can run on trusted hardware, the product’s reputation in industry will increase and inspire ports to other popular midrange servers in the market. As more ports are performed and more platforms are supported, ADempiere will become a more viable option in many corporate environments. As these environments adopt ADempiere, the community will be rewarded with a greater and more diverse culture. 5.2 Methodology IBM i is a radically different platform to the environments that ADempiere is usually installed on. Not only is the hardware on which it runs structured according to different architectural principles, the operation of the system is completely different to all of its market 39 competitors. As such, a methodology was required that would allow for a phased approach, rather than a “big bang” method that would require all problems to be solved at once. In order to break the up the complexity of the port, an installation on a Linux partition of the Power Systems server was first performed. By doing this the hardware compatibility problems surrounding the port could be resolved independently of the compatibility problems stemming from the operating system. Once ADempiere was completely operational on the Linux partition, the application was moved onto the native IBM i partition. The database was installed on the Linux partition because it provided a better utilisation of system resources and because Oracle and PostgreSQL are not supported in IBM i. Furthermore, it simulated having the database installed on a separate server to the application, which is a common practice with business software installations. This methodology is represented in the following diagram: Figure 9 - Methodology for IBM i Port 5.3 Platform Overview The IBM Power System is built upon arguably the most unique architecture in the market today. It is important to understand these differences and the reasons behind them before undertaking a port to such a system. 40 5.3.1 History The IBM Power System is a completely in-house developed system that has its roots in the research of Dr Frank Soltis. Soltis published his doctoral thesis in 1970, which described a revolutionary new approach to systems architecture (Edwards 2004). This research was further developed through the secretive IBM Future Systems project, which set out to develop a system that would render all existing computers obsolete. Although the Future Systems project was disbanded in 1975, the research was used for developing the System/38, which was released in 1980 (IBM 2008b). In 1988 the System/38 was made compatible with the popular System/36, had capability-based addressing removed (Soltis 2001) and was renamed the AS/400. The basic architecture of the Power Systems today is virtually identical to that of the AS/400. The AS/400 was renamed the eServer iSeries in 2000 and underwent a number of name changes throughout subsequent years. Whilst this was happening the architecture of the IBM midrange pSeries servers, designed to run IBM AIX Unix, incorporated many of the features of the AS/400. In 2008 IBM decided to merge the two platforms in order have a single midrange product line that supports AIX, IBM i, Suse Linux Enterprise Server and Redhat Enterprise Linux. This new product line is known as the IBM Power Systems. 5.3.2 Object-based Storage In contrast to most operating systems where data is represented by files, IBM i stores everything in the system as objects. This includes files, programs, commands, libraries, user profiles and job queues. Because everything has a known object type, the operating system is able to regulate file operations much more effectively. For example, a program object cannot be modified by other programs, making it virtually impossible for viruses to spread throughout the system. 41 5.3.3 Integrated Database IBM i does not require the installation of a DBMS – it has a purpose built version of DB2 Universal Database built into its core. The high-level of integration between the Operating System and the Database improves performance and removes the costs involved in setting up a DBMS. 5.3.4 Logical Partitioning (LPAR) The architecture of the IBM Power Systems is set out in a way that multiple Operating Systems can be run simultaneously. This was recently extended to dynamic logical partitioning, which allows for multiple partitions to more effectively share system resources according to demand (NASI 2008). This can radically reduce hardware costs when more than one operating system is required. 5.3.5 Single-level Storage Programmers of IBM i do not need to concern themselves with memory management so much as they would in other environments. This is because physical memory and disk space are treated as a single entity known as an auxiliary storage pool. Programmers do not need to worry about whether or not data needed is in memory or on disk, if an object is needed the system will make sure it is available to the program that needs it. The only thing programmers need to concern themselves with is whether an object is temporary or permanent, which must be specified when the object is created. 5.3.6 Technology Independent Machine Interface One of the most powerful concepts in IBM i is the Technology Independent Machine Interface (TIMI). TIMI provides a layer of abstraction from the hardware that means changes to the underlying hardware will not affect any programs that run on earlier versions of Power Systems hardware. Over the years many significant changes have been made, such as the 42 migration from 48 to 64-bit CPUs in the mid 90s, and programs developed years before have continued to function. In this way TIMI works like a virtual machine, but as it is built into the system’s architecture, there is no performance penalty. 5.4 Problems encountered in Linux for Power Systems Installation The installation of ADempiere on Linux for Power Systems has been previously performed by another capstone student (Pinto 2007). Whilst this helped greatly with many of the aspects surrounding the installation, a number of problems were encountered that were not documented in the installation guide produced by the student. For every problem encountered, the installation guide was updated to help members of the ADempiere community who choose to perform similar installations in the future. 5.4.1 PL/Java incompatibility with PostgreSQL Because PostgreSQL does not natively support stored procedures written in Java, a plug-in is required to add this functionality to the DBMS. The most popular plug-in for this purpose in PostgreSQL is PL/Java. It is not well documented that certain versions of PL/Java are not compatible with particular versions of PostgreSQL. As it turned out, the latest version of PL/Java at the time of installation was not compatible with the recommended version of PostgreSQL for ADempiere. After some experimentation it was found that PL/Java1.3 could be used without issues and the installation guide was updated to reflect this. 5.4.2 Key Generation When ADempiere is installed, the JAR files that constitute the program are signed with a digital key before being packaged together. This is a security measure to prevent unauthorised users from replacing a JAR file with malicious code, which could potentially be used to collect sensitive business data. The problem with this was that the ADempiere 43 installation program uses functions to generate this key that are only found in the Sun distribution of Java. To solve this problem the source code was analysed to see if there was any way that the installation could be run without using the code that generated the key. It was found that a conditional statement was used to avoid the code if a key file already existed. Therefore in order to overcome the problem a key file would need to be generated prior to installation. Further research revealed that a program called “keygen” is included with all standard distributions of Java. Once its usage had been discovered, the documentation was updated to describe the procedure needed to generate a key file using the program. 5.4.3 Non-GUI installation Although this was not an issue on the installation of Linux used in this project, it was desirable to find a way that the installation process could be run without having to use the rich graphical installer. It was known that this would be an issue on IBM i and it made sense to solve the problem early with an installation that had a better chance of succeeding. Additionally, it is a procedure that would be needed for others performing the installation on Linux over a remote connection who may not be able to obtain display access. A script called RUN_silentsetup was found, which was designed for upgrading ADempiere and could be used for installing the program from the command line. In order to do this, a configuration file needed to be created from a template to provide the script with the variables that are usually acquired via the graphical installation. 5.5 Problems Encountered in IBM i Installation Once ADempiere had been successfully installed on the Linux partition, it was known that all of the issues relating to compatibility with the underlying hardware architecture had been 44 resolved. The only step left was to get ADempiere running on the native IBM i partition, which involved overcoming several additional problems. 5.5.1 Use of different command environment Operating in the IBM i environment is very different to UNIX and Windows. Whilst there is a UNIX-like shell called q-shell that allows the use of UNIX style commands, the command list is limited and most important system administration tasks need to be performed external to this. Tasks such as monitoring processes and configuring hardware are performed external to the shell and the need to carry out such tasks involved a significant amount of learning. 5.5.2 Lack of Editing Utilities The IBM i environment does not contain any text editors by default, so it is impossible to modify files from within the system. To overcome this, FTP was used to extract and replace files on the server. By using this approach any text editor in either Linux or Windows could be used. 5.5.3 Use of Different Character Encoding Schemes The character encoding scheme used by IBM i is different to that of Linux and Windows. Because of this, there were problems extracting the TAR file that ADempiere is distributed as. Research uncovered a program in IBM i known as pax, which was designed to overcome such problems. Pax allows for the extraction of archives from any standard character encoding scheme. 5.5.4 Different Java Options Most of the problems relating to IBM Java were solved during the Linux for Power Systems installation. In addition to these problems, it was found that the Java distribution included in 45 IBM i did not support the “–server” parameter. This parameter was used when starting JBoss. In order to run JBoss the “–server” parameter had to be removed from the start-up scripts. 5.5.5 Flushing the Configuration Directory in WAS The version of WAS that came bundled with the distribution of IBM i was not recent enough to support ADempiere. It was upgraded using IBM fix central, a website that is designed to download files directly onto a server via a proxy. After the upgrade was complete, ADempiere would still not run on the server. After further investigation it was discovered that the configuration had not been updated to work with the updated application server. Deleting the files in the configuration directory caused them to be regenerated, which then allowed for ADempiere to be successfully deployed. 5.5.6 Adding Access Privileges to PostgreSQL As there were no examples of ADempiere installations provided by the ADempiere community’s installation guides that used separate partitions or servers for the database and application server, security access needed to be resolved. In PostgreSQL this is a simple case of adding the application server’s IP address to a security configuration file. The only complication with this stemmed from the virtual IO setup required to run dual partitions on Power Systems. This meant that the IP address used for the application server had to be a virtual address rather than its actual address. 5.6 Impact of Installation After all of the aforementioned problems were addressed, ADempiere was able to run in IBM i using either JBoss or WAS as the application server. This was the first time that such an installation had been attempted and its success has placed ADempiere in a unique competitive position. 46 ADempiere can now be run on a system that is specifically designed for running business applications. By running on the hardware that is actually used by real-world organisations, ADempiere can be more easily accepted as a serious business application that businesses can rely upon to manage their operations. As there are many businesses that already have IBM Power Systems, ADempiere will become a much more attractive option for many businesses. This in turn will generate more interest in the ADempiere community and additional support. As the community starts to attract more members from a business domain, a new area of expertise will emerge that will help the community to focus future developments in a direction that will take advantage of emerging trends in industry. 47 6. Performance Testing of Application Servers on IBM i 6.1 Overview When it comes to selecting an application server to host an application, there is rarely a product that is outright superior to all others. An application server might be chosen for a number of reasons, including ease of installation, quality of documentation, reliability, cost and performance (Merrill 2004). Whilst many of these factors can be easily measured, performance and reliability can vary greatly depending on the application and hardware. Since ADempiere had never been run on IBM i before, no data existed about the performance and reliability of application servers in that environment prior to this project. A methodology was designed that would allow the two application servers to be compared as directly as possible. Tests were then carried out in accordance with this methodology and the data analysed to draw meaningful inferences. 6.2 Methodology The methodology used for testing was based upon the approach used by Meier et al (2007). The steps in this modified approach are: 1. Identify test environment 2. Identify performance acceptance criteria 3. Plan and design tests 4. Configure test environment 5. Implement test design 6. Execute tests 7. Analyse, report and retest 48 Figure 10: Test Methodology 6.3 Identification of Test Environment To perform testing, an IBM System i 525 server was supplied by IBM Australia. WAS Base Edition version 6.1.0.17 was tested against the version of JBoss distributed with version 3.4.0 of ADempiere. The application servers were run in an IBM i partition, whilst the database was run on a separate Suse Linux Enterprise Server partition. The specifications of the server are outlined in the following table: Table 1 - Specifications of the test server Processing Processor CPW Memory Operating System Storage Capacity 2x 1.9GHz Power5+ Processors (64-bit) 3800/7800 32Gb i5/OS + SLES 1TB (8 disks) 49 To load the server a more modest machine was used. The specifications of this machine are contained in the following table: Table 2 - Specifications of the Test Load Machine Processing Memory Operating System Storage Capacity Pentium 4 2.8Ghz (32-bit) 512MB Windows XP 40GB The test load machine was installed with WebLoad 8.0, an open source load testing tool from RadView. WebLoad was chosen because it is freely available and captures a large array of performance metrics. It is capable of simulating a large number of concurrent users and conveniently reporting performance related data. Using WebLoad entails the recording of user events as scripts, which are known as agendas. When testing is being carried out these agendas are played back in the WebLoad console to simulate concurrent users logging into and operating ADempiere. This is represented in the figure below. Figure 11: Test Environment 50 6.4 Identification of Performance Acceptance Criteria Specific values for performance acceptance were not specified for these tests. This was primarily for two reasons: 1. Performance requirements will vary for different customers 2. The goal of the tests is to provide a direct comparison of two application servers with regards to certain properties for which acceptance criteria are not necessary. The results of these tests should be used as a guide for selecting the application server that better suits an organisation’s requirements. The exact values of performance metrics are dependent on many factors including the hardware configuration, network traffic and the extent of tuning of the application server. As such further testing to determine whether the selected environment is able to sufficiently cope with an organisation’s needs should be conducted before an ADempiere installation is put into full use. 6.5 Plan and Design Tests To construct a fair test environment the random factors that could affect performance outside of the application server had to be minimised. This meant performing the tests as close in time to each other as possible and performing them in an environment where network conditions would vary the least – in the same lab as the server. In order to do this, extensive planning was necessary. WebLoad works by playing back pre-recorded scripts that are stored in JavaScript code. By providing a mix of scripts, a realistic environment can be effectively simulated (Subraya 2006). Three different scripts were designed to represent three common user events – login, read product data and place sales order. 51 Each application server was tested three times in an effort to reduce random error. In each test the load was increased from one user to 500 concurrent users over a period of ten minutes. The application servers were tested in alternate order to further reduce random error. Four metrics from the tests were analysed. Firstly reliability was evaluated from the application server’s ability to continually operate throughout the stresses placed on it through testing. Additionally, hits per second, throughput and response time were recorded by WebLoad and analysed. The original intent was to analyse data across the full spectrum of 1 to 500 users. However, because of reliability issues with JBoss, insufficient data was available for loads in excess of 300 concurrent users and analysis was generally restricted to loads of up to 300 users. 6.6 Configuration of Test Environment The default configuration for both application servers was used for testing. This was because: 1. It would not be a fair comparison to tune one application server and not the other. The tuning of each application server would depend on the tester’s capabilities with that particular product (Roehm et al 2005) and test results would be skewed in favour of the best-tuned server. 2. Since not all ADempiere administrators can be expected to be expert application server administrators it is fair to assume that some may use the default configuration and thus, it can be viewed as a potentially realistic configuration in practice. Fresh deployments of the ADempiere were made just prior to the commencement of testing to ensure a clean environment. 52 6.7 Implementation of Test Design As scripts recorded by WebLoad are stored in JavaScript, they can be easily modified by anyone with coding experience. Because of this tests can be captured for one application server and made to work on another with slight modifications. This way it is easy to ensure that the tests being run are exactly the same for both application servers. The test scripts were captured using with Internet Explorer 7 as the client, connecting to WAS. Once all of the scripts were captured copies were created that had their port numbers changed to be compatible with JBoss. They were then tested to verify that they worked on JBoss with no problems. The WAS scripts can be viewed in Appendix C: WebLoad Test Scripts. 6.8 Execution of Tests Testing was carried out in the server lab in which the test server was stored. The results recorded by WebLoad during these tests can be seen in Appendix D: Test Results. 6.9 Analysis of Results A comparison of results from the two applications in terms of reliability, response time, throughput and hits per second is presented in this section. 6.9.1 Reliability Reliability is difficult to measure in simulation and it can be difficult to draw meaningful conclusions from test data (Bennett et al 2003). In the testing carried out, reliability was determined by the systems ability to continue operating during the tests. 53 Throughout the tests WAS functioned flawlessly. Even under heavy loads it continued to service requests and operate correctly. JBoss on the other hand failed on two of the three test runs performed on it. On both of these occasions the application server failed to respond to requests from the test environment in an appropriate time frame, which caused the testing to abort prematurely. This happened at around 473 users on the first test and 275 users on the first and second test runs respectively. Given that the total duration of testing was 30 minutes for each application server, the failure of JBoss on two occasions suggests that it lacks the reliability needed for most non-trivial installations. WAS on the other hand experienced no such problems. Although more testing would need to be performed to draw better more certain conclusions, it would appear that WAS is a more stable choice than JBoss in IBM i from this result. 6.9.2 Response Time Response Time was similar for both JBoss and WAS. According to Subraya (2006), most users generally lose focus on a website when response times pass one second. Both servers consistently responded to requests in less than this threshold until reaching a load of 200 users. At the 200 users mark delays became noticeably slower for both application servers. WAS had an average response time of 0.489 seconds throughout testing up to the 300 user mark and a standard deviation of 0.904 seconds. On light loads it performed very well with its fastest response time at 13 milliseconds. 54 Figure 12: Response time for WAS JBoss performed better than WAS on average under light loads with an average response time of 0.173 seconds throughout all tests up to 300 users and a standard deviation of 0.365 seconds. Its fastest response was 4 milliseconds. The only drawback for JBoss was it failing to respond under heavy loads above the 300 user mark. Figure 13: Response time for JBoss JBoss proved to be more responsive than WAS, which is not surprising given it is a lighterweight product. As such, when response time is the most important factor, JBoss may be better suited to small installations where the number of concurrent users is likely to be low. 55 6.9.3 Throughput Throughput, measured as the number of bytes transferred between the application server and the client, was similar for both WAS and JBoss. Both application servers stabilised their throughput at about the 100 concurrent users mark and transferred a similar amount of data. To compare the performance of the two application servers, focus was placed on data in the range of 100 to 300 concurrent users. In the selected range WAS delivered an average of 676,044 bytes per second. This was with a standard deviation of 274,910 bytes per second. Its minimum throughput for this range was 154,691 bytes per second whilst its maximum throughput was 1,284,060 bytes per second. Figure 14: Throughput for WAS JBoss demonstrated a marginally lesser average throughput than WAS with 674,841 bytes per second, with a standard deviation of 308,274 bytes per second. The minimum value for the selected range was 145,514 bytes per second whilst the maximum was 1,556,688 bytes per second. 56 Figure 15: Throughput for JBoss In the comparison range WAS provided a higher average throughput than JBoss. Furthermore, the standard deviation shows that the rate at which WAS transferred data was more consistent than JBoss. Results from these tests indicate that WAS appears to be a better choice than JBoss for installations where high throughput is the most important factor. 6.9.4 Hits per Second The most noticeable difference between the two application servers came when analysing the hits per second. Similar results were obtained for loads of up to 50 concurrent users, from which the results for both servers began to stabilise. From here however there was a magnitude of difference between the two products. For the range between 50 and 300 concurrent users WAS averaged 222.2 hits per second with a standard deviation of 135.8 hits per second. Its worst result for this range was 29.5 hits per second, whilst its best was 536.9 hits per second 57 Figure 16: Hits per second for WAS Over the same range JBoss provided a mean of 145.24 hits per second with a standard deviation of 62.76 hits per second. Its lowest result was marginally higher than WAS at 33.9 hits per second, but its best result was barely half as good as WAS at just 286.76 hits per second. Figure 17: Hits per second for JBoss WAS performed significantly better than JBoss in terms of hits per second. Whilst its results came with a much higher standard deviation, WAS averaged more than 50% more hits per second than JBoss once the number of concurrent users exceeded 50. In installations that require a high rate of page hits, the test results indicated that WAS is clearly preferable on IBM i. 58 6.10 Conclusion The results of the performance tests have shown that there is no outright answer as to which of the two tested application servers is superior on power systems hardware. JBoss provides better response times under smaller loads, but has questionable reliability when the number of concurrent users approaches 300. WAS is capable of handling a slightly higher throughput at a more consistent rate for over 100 concurrent users and is able to continue servicing requests when loads exceed 300 users with degraded performance. Furthermore, WAS is far more capable at supporting a high number of hits per second once the number of concurrent users exceeds 50. For many businesses the questionable stability of JBoss on IBM i will be an issue. Many organisations outsource their application hosting to third parties and have limited access to the hardware that they are using. In such an environment, any risk of the application server failing is not acceptable and such failure could be disasterous for the business. Whilst this testing has provided an insight into the differences between JBoss and WAS on IBM i, it has been limited in scope. Further testing is encouraged so that more powerful inferences can be drawn in the future. Organisations struggling to decide on a particular application server are encouraged to perform their own testing and contribute the results to the greater ADempiere community. Development experience is not a requirement for performance testing, which makes it a suitable area for non-developer members of the community to get involved. The methodology used here can be adapted to other environments. Ultimately, as ADempiere is further tested, a greater understanding of the system will be obtained by the community, which will help the product to grow and to support organisational processes more effectively. 59 7. Future Directions 7.1 Improving Robustness of the Ports in this Project Despite the usefulness of the ports performed throughout this project to the community and other ADempiere consumers, further testing and strengthening needs to be performed before the benefits can be completely realised. Until this is done, some organisations may elect to avoid using ADempiere on IBM i because of the potential risks. Although some testing has been carried out, which has produced performance comparisons of WAS compared with JBoss, these tests were limited to a single machine and were performed over short time periods. Useful ERP systems can have life-spans of more than 10 years and downtime can be expensive to businesses. Testing needs to be carried out in a wider variety of machines and over longer periods of time before more conclusive results can be obtained. Furthermore, tests were only carried out in Base Edition of WAS. Although all applications that run in Base Edition theoretically run in Express Edition and Network Deployment Edition as well, these editions should be specifically tested to confirm proper functionality. As an extra step, it may be desirable to set up ADempiere using clusters in Network Deployment Edition. ADempiere has never been run in a clustered environment and it would be a significant achievement for the community. For work to continue in this area, it is important that interest in running ADempiere on WAS is maintained in the community. For this reason it is critical that support for midrange servers increases, which in turn will further drive the need for commercial application servers such as WAS. The organisations using these servers are the target market of ADempiere and addressing their needs is of vital importance to the growth of the community. 60 7.2 Support for Additional Application Servers The port to WAS performed during this project has not only resolved the majority of issues that would be encountered in ports to other application servers, it has also defined a methodology that can be used as a template for future migrations. As it now stands ADempiere can be run on three different application servers: JBoss, Glassfish and WAS. This means that users are still restricted to two freely distributed application servers and one proprietary product. At the time of writing Apache Geronimo is becoming the open source application server of choice for many users. Furthermore, it is the basis of WAS CE, so for essentially the same effort required for one application server migration, two additional application servers could be supported. On the other end of the spectrum, commercial products such as BEA WebLogic and Oracle Application Server are still commonly mandated by IT policies and need to be supported. Because the difficult work in application server migration has been performed, future migrations should be a much easier task and may be completed as small part of another capstone project or by interested members of the ADempiere community. 7.3 Support for Additional Modules The scope of this project was limited to the core functionality of ADempiere. In practice there are many add-on modules that are commonly used, such as the point of sales component, Posterita, which is currently bundled with the core distribution. Further research into supporting such modules would help to make WAS installations more attractive to organisations that require these modules. Until this has been done, organisations may prefer to integrate their legacy modules, which could be problematic, or avoid using ADempiere on WAS altogether. As such, future developments in this area should be treated as a high priority. 61 7.4 Database Independence The investigation of database independence in this project has revealed the current structure of persistence in ADempiere and the approaches that can be taken to support additional database vendors. If the layered approach is decided upon, an additional DBMS can be supported with the work of one individual or a small team, probably in a matter of several person-months. This approach is not strongly encouraged because it requires continued maintenance as ADempiere evolves. Nevertheless, if the support of an additional DBMS is required, this approach will provide the fastest solution and have minimal impact on the rest of the ADempiere project. If a longer term approach is taken the task is one that requires the support of the whole community. The ideal scenario would probably be for one person to take responsibility and delegate work to other developers within the community around the world. In a community of volunteers this may not be an easy task and the enthusiasm of developers must be weighed up before commencing. Of the longer term approaches investigated within this project EJB 3.0 container-managed persistence appeared to be the most attractive option, but the approach taken should be decided by the community as a whole and based upon the best technologies available at the time of the decision. It should be noted that support for commercial DBMSs should be a priority in the community so as to encourage the involvement of more commercial interest in the Bazaar. It is not only a short-term priority in terms of supporting more organisations, it’s successful implementation has long reaching effects in terms of establishing a more dynamic and diverse community. 62 7.5 Service-Oriented Architecture In some organisations, the range of functionalities provided by ERP systems may not be sufficient for their needs. Large-scale ERP vendors have started to acknowledge this as a problem and are attempting to solve it by restructuring their products to use Service-Oriented Architecture (Frye 2005). SOA is essentially a way of breaking up an application into a collection of reusable standards-based components that can be linked together to provide useful functionality (Demarzo et al 2008). Whilst writing reusable components has always been good programming practice, SOA differentiates itself in the way that components can be integrated together. Because modules are built around common services, they can be easily joined together to carry out business processes. As standard communications mechanisms are used it is much easier to integrate new modules or legacy modules that are SOA-enabled (Robinson 2008). The ADempiere community has commenced using the OSGi framework to improve modularity in the system. Whilst these developments are yet to be accepted into the core product, they have gained the support of many leading contributors within the community. The implementation of component framework such as OSGi will help to move development in an SOA direction. However, if the OSGi changes are eventually accepted into the core distribution this should not be mistaken for SOA. Although component frameworks are an SOA enabler, the components themselves must be designed to provide useful services to constitute an SOA. The current changes are seeing every major class being set up as an internal service within ADempiere. These do not correlate to useful services at a business level and cannot be interchanged with services provided by other ERP vendors or standalone applications. Whilst the current OSGi developments will make it significantly easier to integrate new plugins with the core product, it will still leave a lot of work to be completed if the decision is made to create an SOA. The entire application suite would need to be restructured so that useful services could be externally exposed to other applications and swapped out for 63 components supplied by other vendors. This would be a large undertaking and require the support of the whole community. Although OSGi may be used for the backbone of an SOA implementation, it may prove beneficial to use a more extensive and flexible framework such as J2EE. Since an architectural overhaul is scheduled for version 4.1 of ADempiere, discussion on adopting an SOA needs to begin in the community soon. 7.6 Modelling Approach to Development Dugerdil and Gaillard (2006) argues that ERP systems have reached a point of complexity where they cannot be changed quick enough to respond to demands of a business using conventional programming. Model-based development is the only realistic way of being able to keep up with change at high levels of complexity. To manage this model a Business Process Modelling (BPM) tool could be used, which automates many of the steps involved in the software life-cycle. ADempiere currently has a Model-Driven Architecture (MDA), allowing for dynamic changes to data structures and workflows without needing to bring the system down. This has been very successful and one of the reasons many businesses have chosen to use ADempiere over other open source ERP vendors. However, the MDA only allows for customisation of a deployed system – it does not assist in development changes or allow for additional modules to be easily integrated. BPM tools allow for the same principles behind the MDA to be employed at a development level. The exact parts of the system to be deployed and the way they are arranged together can be customised using the BPM tool without having to change code by hand. This means that it is possible for business analysts with no programming experience to easily customise an ERP system. Because manual coding is not required the speed at which these changes can be made is significantly less. BPM is most powerful when combined with SOA. One of the arguments against introducing SOA into ERP systems is that it makes them inherently less integrated whilst integration is one of the primary reasons for implementing an ERP system in the first place. BPM tools 64 provide a mechanism to integrate dispersed SOA components and thus eliminate this problem. Services from a variety of vendors can be adopted and integrated together using a BPM tool. Some BPM tools, such as IBM WebSphere Business Modeler, can be further used to define web services. This allows for ERP implementations to be taken a step further by providing them with a means of using services that do not even exist. Such tools can be coupled with code generators to build required services with minimal coding required. Because advanced BPM tools are able to automate large parts of the software lifecycle, development times would be reduced and members of the ADempiere community without programming experience would be able to get more involved in contributing to the community. Such members may have extensive domain knowledge and their inputs would help to improve the quality of ADempiere’s usability and usefulness. Ultimately, the adoption of a BPM tool would allow for the ADempiere community to operate more efficiently and produce a product with greater flexibility and of greater quality. 65 8. Conclusion This project has been multifaceted and helped ADempiere to achieve greater system independence in a variety of ways. By advancing ADempiere, the project has helped an open source ERP product develop that will save many organisations significant licensing and implementation fees. It also has the potential to bring ERP to more non-profit organisations and businesses in third-world countries that cannot afford the products offered by commercial ERP vendors. The first major undertaking was the successful migration of ADempiere from JBoss to WebSphere Application Server, which had never been attempted before. By supporting the commercial infrastructure that is commonly mandated by IT policies in industry, ADempiere will grow in popularity and attract a new element of membership to the community. Further to this, ADempiere is no longer dependent on JBoss and future support of the application server is no longer a risk to ADempiere. The database independence review was performed and revealed a number of alternatives to improve database independence. The EJB 3.0 approach was considered the best option at the time of writing, but because of continual advancements in this area the approach adopted by the community will need to be re-evaluated once they are committed to addressing the issue. The database is considered the most important infrastructure component of many organisations and the more ADempiere can be tailored to these organisations, rather than forcing change upon them, the better the chance of such organisations adopting ADempiere. The installation of ADempiere in IBM i was successful and marks another milestone for the community. Now that ADempiere can be run in an environment that is designed for businesses, it will gain recognition from the very market it is trying to serve. This will bolster the community with members from a business domain, which will help it to focus on longterm strategies. The performance testing undertaken revealed that in general WAS performed better than JBoss under heavy loads. This is to be expected from a commercial application server and 66 reflects the importance of the migration to the community. Now that ADempiere is supported by this infrastructure, open source ERP can be better scaled to meet the needs of expanding organisations. A number of future directions have been discussed, which can be undertaken to further the system independence of ADempiere. These included strengthening of the application server migration, additional migrations, supporting add-on modules on WAS, database independence, developing a service-oriented architecture and adopting a model-driven software development approach. Some of these developments do not require extensive knowledge of programming and, given that an effective methodology has been established for some of these tasks through this project, they could be used as a path for less technical people to get more involved in the ADempiere community. Through this research the groundwork has been laid for future ADempiere developers to get involved with the community. With the successful outcomes of this project it is hoped that others will be inspired to contribute more to system independence and help ADempiere emerge as the premier ERP system of the future. 67 9. References Bennett, T. et al. 2003, ‘Testing the Untestable: Reliability in the 21st Century’, IEEE Transactions on Reliability, vol. 52, no. 1, pp. 118-124. Black, A. et al. 2005, IBM WebSphere Application Server for Distributed Platforms and z/OS, Pearson Education, Upper Saddle River, New Jersey. Burrus, C. And Parkin, S. 2005, Developing Web Services for Web Applications: A Guided Tour for Rational Application Developer and WebSphere Application Server, MC Press Online, Lewisville, Texas. Bond, M. et al. 2004, Teach yourself J2EE in 21 Days, 2nd edn, Sams Publishing, Indianapolis, Indiana. Coffin, R. 2006, Make the Right Decision with Our Side-by-Side Comparison of Spring and EJB 3.0, DevX, viewed 11th September, . Cunico, H. et al. 2005, Migrating Applications from WebLogic, JBoss and Tomcat to WebSphere V6, IBM Redbooks, viewed 21 November 2007, . DeMarzo, R. 2008, ‘Big Winners, Surprises In Channel Champs’, CRN, iss. 1261, p. 44. Dugerdil, P. and Gaillard, G. 2006, Model-Driven ERP Implementation, viewed 16th September 2008, . Edwards, P. 2004, You’ve come a long way, baby, viewed 16th June 2008, . 68 Erl, T. 2008, SOA: Principles of Service Design, Pearson Education, Upper Saddle River, New Jersey. ERP and More. 2008, ERP History, viewed 16th June 2008, . ERP Wire. 2008, Advantages and Disadvantages of ERP, viewed 13th Septmeber2008, . ExForSys. 2008, The Advantages and Disadvantages of ERP, viewed 13th September 2008, . Frye, C. 2005, SOA promises more freedom for ERP customers, viewed 18th September 2008, . Gruman, G. 2007, More midmarket firms choose open-source ERP, CIO, viewed 13th September 2008, . Hibernate. 2008a, Native SQL, viewed 17th September 2008, . Hibernate. 2008b, Supported Databases, viewed 2nd September 2008, . Hamilton, S. 2002, Maximizing your ERP system: a practical guide for managers, McGrawHill, NewYork. IBM. 2008a, WebSphere Application Server: Compare Editions, viewed 10th September 2008, . 69 IBM. 2008b, IBM System/38, viewed 16th June 2008, . IDC. 2008, Worldwide Server Market Shows Resiliency with Solid First Quarter Results, viewed 16th June 2008, . Lemos, R. 2008, Open-source ERP Grows Up, CIO, viewed 16th September 2008, . Matena, V. and Hapner, M. 1998, Enterprise JavaBeans, Sun Microsystems, Palo Alto. Meier, J. et al. 2007, Performance Testing Guidance for Web Applications, viewed 30th June 2008, . Merrill, C. 2004, Comparing the Performance of J2EE Servers, viewed 4th July 2008, . Moore, J. 2005, The Case for Open Source ERP, e Week, viewed 16th September 2008, . NASI. 2008, IBM LPAR Services, viewed 10th September 2008, . Norris, G. at al. 2000, E-Business and ERP: Transforming the Enterprise, John Wiley and Sons, New York. Pinto, L. 2007, Sizing Model for the ADempiere Application, Sydney. Ramaswamy, R. 2008, Hibernate Vs EJB 3.0, viewed 28 August 2008, . Raymond, E. 1999, The Cathedral and the Bazaar: Musings on Linux and Open Source by an Accidental Revolutionary, O’Reilly, Sebastopol, California. 70 Rayns, C. et al. 2005, WebSphere application server express V5.0.2 developer handbook, IBM Redbooks, . Richards, N. and Griffith, S. 2005, JBoss: A Developer’s Notebook, O’Reilly Media, Sebastopol, California. Robinson, S. 2008, A Developer’s Overview of ERP, viewed 13th September 2008, . Roehm, B. et al. 2005, WebSphere Application Server V6 Scalability and Performance Handbook, IBM Redbooks, viewed 11th September 2008, . Roman, E. 1999, Mastering Enterprise Java Beans, John Wiley and Sons, New York. Sadtler, C. et al. 2005, WebSphere application server V6 system management and configuration handbook, IBM Redbooks, . Seltzer, L. 2002, The Commercial Salvation of Linux, viewed 18th November 2008, . Soliman, F. 1999, Strategic Enterprise Resource Planning Systems, University of Technology Sydney Printing Services, Sydney. Stair, R. et al. 2006, Principles of Information Systems, 7th edn, Thomson, Boston., Massachusetts. Subraya, B. 2006, Integrated Approach to Web Performance Testing: A Practitioner’s Guide, IRM Press, Hershey, Pennsylvania. Sumner, M. 2004, Enterprise Resource Planning, Pearson, Upper Saddle River, New Jersey. 71 Sun. 2008, Java Enterprise Edition Platform – Compatibility, viewed 3rd September 2008, . Symonds, M. 2003, Softwar: An intimate Picture of Larry Ellison and Oracle, Simon and Schuster, New York. Williamson, L. et al. 2005, IBM WebSphere System Administration, Pearson Education, Upper Saddle River, New Jersey. Wailgum, T. 2007, ABC: An Introduction to ERP, viewed 17th September 2008, . Yuan, M. 2005, Pojo Application Frameworks: Spring Vs. EJB 3.0, viewed 27 August 2008, . Zadrozny, P. and Kodali, R. 2005, The Performance of EJB 3.0, viewed 24th August 2008, . 72 10. Appendix A: ADempiere on WebSphere Installation Guide Overview This guide should be used for installing ADempiere with WebSphere Application Server. It has been written generically, so that it can be tailored to suit the purposes of different Operating Systems. If you require more information about setting up ADempiere in your chosen environment, please refer to the other installation guides. Limitations • • Posterita not supported WebStore not supported Tested ADempiere Versions • • 3.4.0 3.3.1b Prerequisites • Java Development Kit (JDK) 1.5.0_14 (Do not install newer versions of Java or simply the JRE) • • WebSphere Application Server 6.1.0.17 Eclipse IDE for Java EE Developers ADempiere Installation 73 Set the following environment variables to their relevant directories: • • JAVA_HOME – the directory where java is installed ADEMPIERE_HOME – the directory where ADempiere is installed, usually C:\Adempiere or /Adempiere) Database Installation Install either PostgreSQL, Oracle 10g or Oracle 10g XE. You will need to know the administrator password for the database to continue with the ADempiere setup. If you choose to install PostgreSQL you will also need to download and install PL/Java. Note that certain versions of PL/Java have compatibility issues with certain versions of PostgreSQL. One combination that has been tested and works is PostgreSQL 8.1 and PL/Java 1.3. PL/Java is available from here. Run the ADempiere setup Download ADempiere from source forge and extract the archive to a known directory (the root directory is recommended). If you have GUI access use RUN_Setup.sh/RUN_Setup.bat to install ADempiere. You will be prompted to enter your configuration. Enter all necessary details and click test. Once all tests have passed click save to install ADempiere. If you do NOT have GUI access you will need to copy the contents of the file ADEMPIERE_HOME/AdempiereEnvTemplate.properties into a new file named ADEMPIERE_HOME/AdempiereEnv.properties. Modify the various properties in the new file to suit your installation, save it and run RUN_SilentSetup.sh. 74 Once the installation has been successfully completed you will need to setup the database tables for the application to use. This can be done by running the script ADEMPIERE_HOME/utils/RUN_ImportAdempiere.sh or in Windows ADEMPIERE_HOME\utils\RUN_ImportAdempiere.bat. ADempiere should now be setup to work for JBoss. Migrating to WebSphere Application Server In the command prompt change the working directory to: ADEMPIERE_HOME\jboss\server\adempiere\deploy\adempiere.ear Package the exploded ear into a compressed file using: jar cvfM adempiere.ear * Open eclipse and go to file -> import. Select J2EE -> ear file. Locate the compressed ear file and use all of the default settings. Do NOT select a target runtime. Click Finish. Open up the application deployment descriptor (adempiere -> earContent -> META-INF -> application.xml) and make the following modifications: • Add in a document type descriptor tag directly before the application tag: • • Remove all of the parameters from the application tag. Add the next two lines directly beneath the application tag if they are not already present ADempiere ADempiere Applications 75 • Remove the following lines completely from the file: AdempiereSLib.jar Adempiere.jar adempiereApps.jar • Remove the following completely from the file: posterita.war /posterita Open up the deployment descriptor for adempiereApps.war (adempiereApps ->WebContent > WEB-INF -> web.xml) and make the following modifications: • Add in a document type definition tag directly before the web-app tag: • Remove all of the parameters from the web-app tag Open up the manifest file for adempiereRoot.jar (adempierRoot_EJB -> ejbModule -> META-INF -> MANIFEST.MF and make the following modifications: • Delete the following section: 76 Name: META-INF/jaws.xml SHA1-Digest: vb2Dx67PF/Qhr9XGrx03Of8tjdw= • Delete the following section: Name: META-INF/jboss.xml SHA1-Digest: FF5ayoXZ7BfYVDld/IMvvHqpvEg= Delete the following files from the adempiereRoot_EJB -> ejbModule -> META-INF folder: • • jaws.xml jboss.xml Open up the deployment descriptor for adempiereRoot.war (adempiereRoot_WEB >WebContent -> WEB-INF -> web.xml) and make the following modifications: • Add in a document type definition tag directly before the web-app tag: • Remove all of the parameters from the web-app tag Open up the deployment descriptor for adempiereWebCM.war (adempiereWebCM >WebContent -> WEB-INF -> web.xml) and make the following modifications: • Add in a document type definition tag directly before the web-app tag: • • Remove all of the parameters from the web-app tag Swap the order of the and the tags 77 Open up the deployment descriptor for adempiereWebStore (adempiereWebStore >WebContent -> WEB-INF -> web.xml) and make the following modifications: Add in a document type definition tag directly before the web-app tag: • • • • • Remove all of the parameters from the web-app tag Move the mime-mapping tag to above the welcome-file-list tag Delete the Posterita project, including its contents, from the solution. Right Click on the Adempiere Project and select Export -> Ear File. Choose a directory and click finish. • • • • • Open up the WebSphere Administration Console. Go to Enterprise Applications -> Install New Application Browse for the ear file that was exported from Eclipse and click next Accept the installation options and click Next Select all of the modules to be mapped to the server by ticking all of the boxes and click next. • Provide the JNDI names as adempiere/Status and adempiere/Server respectively and click next. • Specify the target resource JNDIs as adempiere/Status, adempiere/StatusLocal, adempiere/Status and adempiere/ServerLocal and click next. • Accept the default configuration for Map virtual hosts for Web modules by clicking next. • A summary will be displayed, click finish. Troubleshooting Conflicting context-root 78 If you have other applications installed on your application server you may experience a conflict if one of them uses / as its context root. To overcome this, change the context-root of adempiereWebCM to /home. This can be done by modifying the application deployment descriptor (adempiere -> earContent -> META-INF -> application.xml) in Eclipse. Find the module for adempiereWebCM.war and change the context root to home, as shown below: adempiereWebCM.war /home Export the ear file once again and redeploy. The conflict should no longer occur. 79 11. Overview Appendix B: ADempiere on IBM i Installation Guide This installation guide has been written for setting up ADempiere on IBM i or i5/OS, the native operating systems of IBM Power Systems and System i. Either JBoss or WebSphere can be used as the application server, though performance testing has shown that WebSphere is faster and more reliable on installations that may require 50 or more concurrent users. Limitations Posterita not supported WebStore not supported • • Tested ADempiere versions 3.4.0 • Prerequisites IBM Power System, System i or iSeries IBM i or i5/OS WebSphere Application Server 6.1.0.17 (on native partition) Two partitions setup – IBM i for Application Server and Linux for Database (SLES 10.1 recommended) • • • • • Eclipse IDE for Java EE Developers (installed on Linux partition or separate machine with Linux or Windows) • You must be able to log in as the administrator in both partitions (root in Linux, qsecofr in IBM i) 80 Linux Partition Setup IBM Java installation Sun does not support Power5 and Power6 processors, IBM Java is required instead. IBMJAVA2-PPC64-SDK-5.0 can be downloaded from here. You will need to register with IBM if you have not already, which entitles you to free access to other software, white papers and red books. Once you have downloaded the file you will need to install it with the following command: rpm –Uvh ibm-java2-ppc64-sdk-5.0-5.1.ppc64.rpm Java should be installed in a directory similar to /opt/ibm/java2-ppc64-50. This can be checked with the following command: /opt/ibm/java2-ppc64-50/bin/java -version PostgreSQL Ensure that your setup has the following packages installed as they are required for compiling PL/Java. If you are using SLES 10 this can be done though Software Management in Yast 2 (Control Center -> Software -> Software Management): • • • • • • GCC-JAVA - gcc-java 4.1.0-28.4 (Must install) C compiler run time library - libgcc 64bit C compiler runtime library - libgcc-64bit Java Runtime Library for GCJ - libgcj 64bit Java Runtime Library for GCJ - libgcj-64bit GCC Preprocessor - cpp 81 In Software Management, verify that the following packages are installed for the PostgreSQL DBMS: • • • • • Postgresql-server Postgresql-dlevel Postgreslibs-64bit Postgresqllibs Postgresql-jdbc If you are using a Linux distribution other than SLES 10, you may need to download and install PostgreSQL manually. If you are using SLES 10.1 but cannot find the required packages, you will need to add the following repositories to Yast 2: http://download.opensuse.org/distribution/SL-10.1/inst-source/ http://download.opensuse.org/distribution/SL-10.1/non-oss-inst-source/ Once the files have been installed, start the PostgreSQL server with the following command: /etc/init.d/postgresql start If it does not already exist, create a new user called postgres: createuser – P postgres Change the password of postgres and switch to that user: passwd postgres su – postgres Create a database user called adempiere in PostgreSQL and create the adempiere database by entering the following on the command line: psql CREATE USER adempiere WITH PASSWORD 'adempiere'; ALTER USER adempiere WITH SUPERUSER; 82 ALTER USER adempiere WITH LOGIN; CREATE DATABASE adempiere WITH OWNER adempiere ENCODING 'UTF8'; \q You will now need to compile and install PL/Java. PL/Java Make sure you are logged in as root and set the JAVA_HOME environment variable to the directory where java was installed, for example: export JAVA_HOME=/opt/ibm/java2-ppc64-50 Download the PL/Java source code, which is available from here Save the archive to the /opt directory and then extract it: cd /opt tar zxfv pljava-1.3.0.tar.gz cd pljava-1.3.0 The following steps will compile pljava and build the required object files and jar files: make USE_GCJ=1 mkdir -p /usr/share/pljava install -m 644 build/pljava.jar /usr/share/pljava install -m 644 build/deploy.jar /usr/share/pljava install -m 755 build/objs/pljava.so /usr/share/pljava cat > /etc/ld.so.conf.d/postgresql.conf < /opt/ibm/java2-ppc6450/jre/bin/classic/libjvm.so. If the command returns nothing check the /etc/ld.so.conf.d/postgresql.conf file and verify that the directories are correct. Modify postgresql.conf in /var/lib/pgsql/data (remember to uncomment #the lines): add these lines: custom_variable_classes = 'pljava' pljava.classpath = '/usr/share/pljava/pljava.jar' Modify the following: listen_addresses = '*' # if you want to log in from the internet port = 5432 dynamic_library_path = '$libdir' to dynamic_library_path = '$libdir:/usr/share/pljava' then modify pg_hba.conf in /var/lib/pgsql/data. The result will look something like this: # TYPE DATABASE USER CIDR-ADDRESS METHOD # #local is for Unix domain socket connections only local all all trust # IPv4 local connections: host host host all all all all all all 127.0.0.1/32 127.0.0.2/32 appserver/32 trust trust trust # IPv6 local connections: host host all adempiere all adempiere ::1/128 0.0.0.0/0 trust trust 84 Restart the postgreSQL server by running the following command: /etc/init.d/postgresql restart (NOTE: You will need to restart the postgresql server every time you update the ph_hba.conf file for the changes to take effect) Then install pljava into Database by running: java -cp /usr/share/pljava/deploy.jar:/usr/share/pgsql/postgresql-8.1404.jdbc3.jar \ org.postgresql.pljava.deploy.Deployer -install -user adempiere -database adempiere \ -password adempiere Database Table Setup Download ADempiere and extract it to a temporary directory. Change to this directory and run the script: ./utils/RUN_ImportAdempiere.sh All of the tables required for ADempiere will be generated via this script, which may take several minutes to complete. The database should now be ready to communicate with the Application Server. IBM i partition setup Download ADempiere onto the Linux partition and decompress it using: gunzip Adempiere_340s.tar.gz 85 Transfer the archive to the native partition using ftp using binary mode: ftp cd / bin put Adempiere_340s.tar bye Extract the archive using pax. Do NOT use tar as IBM i uses a different character set and the binary files will be corrupted: pax –r –C 819 –f Adempiere.tar Export the JAVA_HOME and ADEMPIERE_HOME environment variables, make sure that JAVA_HOME points to version 1.5 of java: export ADEMPIERE_HOME=/Adempiere export JAVA_HOME=/QOpenSys/QIBM/ProdData/JavaVM/jdk50/32bit java –version (NOTE: It is strongly recommended that you use use /Adempiere as your adempiere installation directory. Using other directories may result in problems that are difficult to fix otherwise.) Copy the adempiere environment properties template into the adempiere environment properties file with the following command: cp AdempiereEnvTemplate.properties AdempiereEnv.properties Edit the AdempiereEnv.properties file and make the following changes. You may need to ftp the file to the Linux partition and back in order to edit it: ADEMPIERE_HOME=/Adempiere JAVA_HOME=/ QOpenSys/QIBM/ProdData/JavaVM/jdk50/32bit ADEMPIERE_DB_SYS=adempiere ADEMPIERE_KEYSTORE=/Adempiere/keystore/myKeystore 86 ADEMPIERE_KEYSTOREPASS=adempiere Make a directory for the key store and generate a key for ADempiere using the IBM Java keytool, as follows: Mkdir keystore $JAVA_HOME/bin/keytool –genkey –keyalg rsa –alias adempiere –dname “CN=localhost, OU=ADempiere Bazaar, O=AdempiereUser, L=Sydney, S=NSW, C=AU” –keypass adempiere –validity 999 –keystore /Adempiere/keystore/myKeystore –storepass adempiere Run the ADempiere setup with the following command: Chmod 744 RUN_silentsetup.sh RUN_silentsetup.sh Once the installation has completed successfully you have the option of fixing JBoss or migrating to WebSphere Application Server. Running JBoss In order to run JBoss in IBM i a few configuration changes are necessary. Edit the file (either natively or by transferring to another partition server with ftp) ADEMPIERE_HOME/jboss/server/adempiere/deploy/jbossweb-tomcat55.sar/server.xml. You will need to add the following argument to the tag below the comment : algorithm = IbmX509 Edit ADEMPIERE_HOME/utils/RUN_Server2.sh and remove the ‘-server’ options from JAVA_OPTS. 87 Migrating to WebSphere Change the working directory to: ADEMPIERE_HOME\jboss\server\adempiere\deploy\adempiere.ear Package the exploded ear into a compressed file using: jar cvfM adempiere.ear * Use ftp to transfer the packaged ear file to the machine where you have Eclipse installed. Open eclipse and go to file -> import. Select J2EE -> ear file. Locate the compressed ear file and use all of the default settings. Do NOT select a target runtime. Click Finish. Open up the application deployment descriptor (adempiere -> earContent -> META-INF -> application.xml) and make the following modifications: Add in a document type descriptor tag directly before the application tag: • • • Remove all of the parameters from the application tag. Add the next two lines directly beneath the application tag if they are not already present ADempiere ADempiere Applications • Remove the following lines completely from the file: 88 AdempiereSLib.jar Adempiere.jar adempiereApps.jar Find the module for adempiereWebCM.war and change the context root to home, as shown below: adempiereWebCM.war /home • Remove the following completely from the file: posterita.war /posterita Open up the deployment descriptor for adempiereApps.war (adempiereApps ->WebContent > WEB-INF -> web.xml) and make the following modifications: Add in a document type definition tag directly before the web-app tag: • • Remove all of the parameters from the web-app tag 89 Open up the manifest file for adempiereRoot.jar (adempierRoot_EJB -> ejbModule -> META-INF -> MANIFEST>MF and make the following modifications: • Delete the following section: Name: META-INF/jaws.xml SHA1-Digest: vb2Dx67PF/Qhr9XGrx03Of8tjdw= • Delete the following section: Name: META-INF/jboss.xml SHA1-Digest: FF5ayoXZ7BfYVDld/IMvvHqpvEg= Delete the following files from the adempiereRoot_EJB -> ejbModule -> META-INF folder: jaws.xml jboss.xml • • Open up the deployment descriptor for adempiereRoot.war (adempiereRoot_WEB >WebContent -> WEB-INF -> web.xml) and make the following modifications: Add in a document type definition tag directly before the web-app tag: • • Remove all of the parameters from the web-app tag Open up the deployment descriptor for adempiereWebCM.war (adempiereWebCM >WebContent -> WEB-INF -> web.xml) and make the following modifications: • Add in a document type definition tag directly before the web-app tag: 90 • • Remove all of the parameters from the web-app tag Swap the order of the and the tags Open up the deployment descriptor for adempiereWebStore (adempiereWebStore >WebContent -> WEB-INF -> web.xml) and make the following modifications: • Add in a document type definition tag directly before the web-app tag: • • • • Remove all of the parameters from the web-app tag Move the mime-mapping tag to above the welcome-file-list tag Delete the Posterita project, including its contents, from the solution. Right Click on the Adempiere Project and select Export -> Ear File. Choose a directory and click finish. Open up your web browser from the machine with new ear. Go to the WebSphere Administration Console and follow these steps to install the ear into the application server: Go to Enterprise Applications -> Install New Application Browse for the ear file that was exported from Eclipse and click next Accept the installation options and click Next Select all of the modules to be mapped to the server by ticking all of the boxes and click next. • • • • • Provide the JNDI names as adempiere/Status and adempiere/Server respectively and click next. • Specify the target resource JNDIs as adempiere/Status, adempiere/StatusLocal, adempiere/Status and adempiere/ServerLocal and click next. • Accept the default configuration for Map virtual hosts for Web modules by clicking next. 91 • A summary will be displayed, click finish. Troubleshooting Upgrading to WebSphere Application Server v6.1.0.17 If you have a slightly older version of WebSphere Application Server, it is highly recommended that you upgrade to v6.1.0.17 before attempting deployment. This is a straight forward process that can be performed by visiting IBM Fix Central. You will need to access the site from a browser that is on a machine that can access the server on which the installation is being performed as the file will be downloaded directly onto the server using the browser's machine as a proxy. At the site simply parameters for your installation, in this example the parameters were: Product family: System i Product: IBM i, i5/OS, and OS/400 Ordering Option: Groups, Hiper and Cumulative Fixes OS Level: V5R4 Next you will be prompted to login with an IBM ID (which can be obtained for free). Following this a list of fixes will be listed. Select SF99323 WebSphere App Server v6.1 Level 17 and add it to the download list, click continue. You will be prompted for the necessary details needed to access the server. Once the download has completed the fix needs to by entering into the /Base/bin directory in qsh and executing the fixpack as follows: ./installFixPack61017 EJB Deploy Error ADMA0086E If you upgraded your WebSphere Application Server version and you had previously attempted an ADempiere deploy on the prior version of the application server, there is a 92 strong chance you will receive this error. It occurs when the server is upgraded, but the configuration fails to update. To overcome this problem find the configuration directory using: ./ejbdeploy -log Now delete all files the configuration directory except config.ini if it exists. For more information about this problem visit http://www-1.ibm.com/support/ docview.wss?uid=swg21286215 93 12. Appendix C: WebLoad Test Scripts This appendix contains the test scripts used for performance testing of WAS. The scripts used for JBoss were identical, except that the port number was changed to 80, which was the default port that JBoss was configured to listen to. 12.1 Login (simple) /***** WLIDE - URL : http://hercules:10032/adempiere/WLogin - ID:2 *****/ wlGlobals.GetFrames = false wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/" wlHttp.Get("http://hercules:10032/adempiere/WLogin") /***** WLIDE - Sleep - ID:3 *****/ Sleep(9484 9484) 9484 /***** WLIDE - URL : http://hercules:10032/adempiere/WLogin - ID:4 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WLogin" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["User"] = "GardenAdmin" wlHttp.FormData["Password"] = "GardenAdmin" wlHttp.FormData["#AD_Language"] = "en_US" wlHttp.FormData["Submit"] = " OK" wlHttp.Post("http://hercules:10032/adempiere/WLogin") /***** WLIDE - URL : http://hercules:10032/adempiere/WFieldUpdate - ID:5 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WLogin" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["formName"] = "Login2" wlHttp.FormData["fieldName"] = "AD_Role_ID" wlHttp.FormData["fieldValue"] = "102" wlHttp.FormData["location"] = "top." wlHttp.Post("http://hercules:10032/adempiere/WFieldUpdate") /***** WLIDE - Sleep - ID:6 *****/ Sleep(10054 10054) 10054 /***** WLIDE - URL : http://hercules:10032/adempiere/WMenu - ID:7 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WLogin" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["AD_Role_ID"] = "102" wlHttp.FormData["AD_Client_ID"] = "11" wlHttp.FormData["AD_Org_ID"] = "0" wlHttp.FormData["Date"] = "07/14/2008" wlHttp.FormData["Submit"] = " OK" wlHttp.Post("http://hercules:10032/adempiere/WMenu") /***** WLIDE - Sleep - ID:8 *****/ Sleep(7090 7090) 7090 /***** WLIDE - URL : http://hercules:10032/adempiere/WMenu?Exit=true - ID:9 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WMenu" 94 wlHttp.FormData["Exit"] = "true" wlHttp.Get("http://hercules:10032/adempiere/WMenu") /***** WLIDE - URL : http://hercules:10032/adempiere/index.html - ID:10 *****/ wlHttp.Get("http://hercules:10032/adempiere/index.html") /***** WLIDE - Sleep - ID:11 *****/ Sleep(1682 1682) 1682 /***** WLIDE - URL : http://hercules:10032/adempiere/WLogin - ID:12 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/index.html" wlHttp.Get("http://hercules:10032/adempiere/WLogin") 12.2 View Product Data (read operations) /***** WLIDE - URL : http://hercules:10032/adempiere/WLogin - ID:2 *****/ wlGlobals.GetFrames = false wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WLogin" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["User"] = "GardenAdmin" wlHttp.FormData["Password"] = "GardenAdmin" wlHttp.FormData["#AD_Language"] = "en_US" wlHttp.FormData["Submit"] = " OK" wlHttp.Post("http://hercules:10032/adempiere/WLogin") /***** WLIDE - URL : http://hercules:10032/adempiere/WFieldUpdate - ID:3 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WLogin" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["formName"] = "Login2" wlHttp.FormData["fieldName"] = "AD_Role_ID" wlHttp.FormData["fieldValue"] = "102" wlHttp.FormData["location"] = "top." wlHttp.Post("http://hercules:10032/adempiere/WFieldUpdate") /***** WLIDE - Sleep - ID:4 *****/ Sleep(1943 1943) 1943 /***** WLIDE - URL : http://hercules:10032/adempiere/WMenu - ID:5 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WLogin" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["AD_Role_ID"] = "102" wlHttp.FormData["AD_Client_ID"] = "11" wlHttp.FormData["AD_Org_ID"] = "0" wlHttp.FormData["Date"] = "07/08/2008" wlHttp.FormData["Submit"] = " OK" wlHttp.Post("http://hercules:10032/adempiere/WMenu") /***** WLIDE - Sleep - ID:6 *****/ Sleep(23494 23494) 23494 /***** WLIDE - URL : http://hercules:10032/adempiere/WWindow?AD_Menu_ID=126 - ID:7 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WMenu" wlHttp.FormData["AD_Menu_ID"] = "126" wlHttp.Get("http://hercules:10032/adempiere/WWindow") /***** WLIDE - Sleep - ID:8 *****/ 95 Sleep(3325) 3325 3325 /***** WLIDE - URL : http://hercules:10032/adempiere/WWindow - ID:9 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WWindow?AD_Menu_ID=126" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["PCommand"] = "Next" wlHttp.FormData["PMRRowNo"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ChangedColumn"] = "$WL$EMPTY$STRING$" wlHttp.FormData["PTab"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Value"] = "AP" wlHttp.FormData["VersionNo"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Name"] = "Another Plant" wlHttp.FormData["Description"] = "Blue, brown leaves, gold flower" wlHttp.FormData["Help"] = "$WL$EMPTY$STRING$" wlHttp.FormData["DocumentNote"] = "$WL$EMPTY$STRING$" wlHttp.FormData["UPC"] = "$WL$EMPTY$STRING$" wlHttp.FormData["SKU"] = "$WL$EMPTY$STRING$" wlHttp.FormData["IsActive"] = "true" wlHttp.FormData["M_Product_Category_ID"] = "105" wlHttp.FormData["Classification"] = "$WL$EMPTY$STRING$" wlHttp.FormData["C_TaxCategory_ID"] = "107" wlHttp.FormData["C_RevenueRecognition_ID"] = "-1" wlHttp.FormData["C_UOM_ID"] = "100" wlHttp.FormData["SalesRep_ID"] = "101" wlHttp.FormData["ProductType"] = "I" wlHttp.FormData["R_MailText_ID"] = "-1" wlHttp.FormData["Weight"] = "0" wlHttp.FormData["Volume"] = "0" wlHttp.FormData["M_FreightCategory_ID"] = "-1" wlHttp.FormData["IsStocked"] = "true" wlHttp.FormData["M_Locator_ID"] = "101" wlHttp.FormData["ShelfWidth"] = "0" wlHttp.FormData["ShelfHeight"] = "0" wlHttp.FormData["ShelfDepth"] = "0" wlHttp.FormData["UnitsPerPallet"] = "0" wlHttp.FormData["IsPurchased"] = "true" wlHttp.FormData["IsSold"] = "true" wlHttp.FormData["C_SubscriptionType_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ImageURL"] = "$WL$EMPTY$STRING$" wlHttp.FormData["DescriptionURL"] = "$WL$EMPTY$STRING$" wlHttp.FormData["GuaranteeDays"] = "0" wlHttp.FormData["GuaranteeDaysMin"] = "0" wlHttp.FormData["M_AttributeSet_ID"] = "-1" wlHttp.FormData["M_AttributeSetInstance_ID"] = "0" wlHttp.FormData["M_AttributeSetInstance_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["IsSelfService"] = "true" wlHttp.FormData["Group1"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Group2"] = "$WL$EMPTY$STRING$" wlHttp.Post("http://hercules:10032/adempiere/WWindow") /***** WLIDE - Sleep - ID:10 *****/ Sleep(1532 1532) 1532 /***** WLIDE - URL : http://hercules:10032/adempiere/WWindow - ID:11 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WWindow" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["PCommand"] = "Next" wlHttp.FormData["PMRRowNo"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ChangedColumn"] = "$WL$EMPTY$STRING$" wlHttp.FormData["PTab"] = "$WL$EMPTY$STRING$" 96 wlHttp.FormData["Value"] = "Azalea Bush" wlHttp.FormData["VersionNo"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Name"] = "Azalea Bush" wlHttp.FormData["Description"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Help"] = "$WL$EMPTY$STRING$" wlHttp.FormData["DocumentNote"] = "$WL$EMPTY$STRING$" wlHttp.FormData["UPC"] = "81010123450901" wlHttp.FormData["SKU"] = "1234567890" wlHttp.FormData["IsActive"] = "true" wlHttp.FormData["M_Product_Category_ID"] = "107" wlHttp.FormData["Classification"] = "$WL$EMPTY$STRING$" wlHttp.FormData["C_TaxCategory_ID"] = "107" wlHttp.FormData["C_RevenueRecognition_ID"] = "-1" wlHttp.FormData["C_UOM_ID"] = "100" wlHttp.FormData["SalesRep_ID"] = "101" wlHttp.FormData["ProductType"] = "I" wlHttp.FormData["R_MailText_ID"] = "-1" wlHttp.FormData["Weight"] = "0" wlHttp.FormData["Volume"] = "0" wlHttp.FormData["M_FreightCategory_ID"] = "-1" wlHttp.FormData["IsStocked"] = "true" wlHttp.FormData["M_Locator_ID"] = "101" wlHttp.FormData["ShelfWidth"] = "0" wlHttp.FormData["ShelfHeight"] = "0" wlHttp.FormData["ShelfDepth"] = "0" wlHttp.FormData["UnitsPerPallet"] = "0" wlHttp.FormData["IsPurchased"] = "true" wlHttp.FormData["IsSold"] = "true" wlHttp.FormData["C_SubscriptionType_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ImageURL"] = "$WL$EMPTY$STRING$" wlHttp.FormData["DescriptionURL"] = "$WL$EMPTY$STRING$" wlHttp.FormData["GuaranteeDays"] = "0" wlHttp.FormData["GuaranteeDaysMin"] = "0" wlHttp.FormData["M_AttributeSet_ID"] = "-1" wlHttp.FormData["M_AttributeSetInstance_ID"] = "0" wlHttp.FormData["M_AttributeSetInstance_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["IsWebStoreFeatured"] = "true" wlHttp.FormData["IsSelfService"] = "true" wlHttp.FormData["Group1"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Group2"] = "$WL$EMPTY$STRING$" wlHttp.Post("http://hercules:10032/adempiere/WWindow") /***** WLIDE - Sleep - ID:12 *****/ Sleep(1733 1733) 1733 /***** WLIDE - URL : http://hercules:10032/adempiere/WWindow - ID:13 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WWindow" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["PCommand"] = "Next" wlHttp.FormData["PMRRowNo"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ChangedColumn"] = "$WL$EMPTY$STRING$" wlHttp.FormData["PTab"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Value"] = "Doc" wlHttp.FormData["VersionNo"] = "120" wlHttp.FormData["Name"] = "How To Plant" wlHttp.FormData["Description"] = "Information on how to best to plant your future." wlHttp.FormData["Help"] = "$WL$EMPTY$STRING$" wlHttp.FormData["DocumentNote"] = "$WL$EMPTY$STRING$" wlHttp.FormData["UPC"] = "$WL$EMPTY$STRING$" wlHttp.FormData["SKU"] = "$WL$EMPTY$STRING$" 97 wlHttp.FormData["IsActive"] = "true" wlHttp.FormData["M_Product_Category_ID"] = "111" wlHttp.FormData["Classification"] = "$WL$EMPTY$STRING$" wlHttp.FormData["C_TaxCategory_ID"] = "107" wlHttp.FormData["C_RevenueRecognition_ID"] = "-1" wlHttp.FormData["C_UOM_ID"] = "100" wlHttp.FormData["SalesRep_ID"] = "101" wlHttp.FormData["ProductType"] = "S" wlHttp.FormData["R_MailText_ID"] = "100" wlHttp.FormData["IsSold"] = "true" wlHttp.FormData["C_SubscriptionType_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ImageURL"] = "http://www.adempiere.org/product/icons/C32.gif" wlHttp.FormData["DescriptionURL"] = "http://www.adempiere.com/partner/index.html" wlHttp.FormData["GuaranteeDays"] = "30" wlHttp.FormData["GuaranteeDaysMin"] = "0" wlHttp.FormData["M_AttributeSet_ID"] = "-1" wlHttp.FormData["M_AttributeSetInstance_ID"] = "0" wlHttp.FormData["M_AttributeSetInstance_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["IsWebStoreFeatured"] = "true" wlHttp.FormData["IsSelfService"] = "true" wlHttp.FormData["Group1"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Group2"] = "$WL$EMPTY$STRING$" wlHttp.Post("http://hercules:10032/adempiere/WWindow") /***** WLIDE - Sleep - ID:14 *****/ Sleep(1371 1371) 1371 /***** WLIDE - URL : http://hercules:10032/adempiere/WWindow - ID:15 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WWindow" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["PCommand"] = "Next" wlHttp.FormData["PMRRowNo"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ChangedColumn"] = "$WL$EMPTY$STRING$" wlHttp.FormData["PTab"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Value"] = "Elm" wlHttp.FormData["VersionNo"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Name"] = "Elm Tree" wlHttp.FormData["Description"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Help"] = "$WL$EMPTY$STRING$" wlHttp.FormData["DocumentNote"] = "$WL$EMPTY$STRING$" wlHttp.FormData["UPC"] = "$WL$EMPTY$STRING$" wlHttp.FormData["SKU"] = "$WL$EMPTY$STRING$" wlHttp.FormData["IsActive"] = "true" wlHttp.FormData["M_Product_Category_ID"] = "106" wlHttp.FormData["Classification"] = "$WL$EMPTY$STRING$" wlHttp.FormData["C_TaxCategory_ID"] = "107" wlHttp.FormData["C_RevenueRecognition_ID"] = "-1" wlHttp.FormData["C_UOM_ID"] = "100" wlHttp.FormData["SalesRep_ID"] = "101" wlHttp.FormData["ProductType"] = "I" wlHttp.FormData["R_MailText_ID"] = "-1" wlHttp.FormData["Weight"] = "0" wlHttp.FormData["Volume"] = "0" wlHttp.FormData["M_FreightCategory_ID"] = "-1" wlHttp.FormData["IsStocked"] = "true" wlHttp.FormData["M_Locator_ID"] = "101" wlHttp.FormData["ShelfWidth"] = "0" wlHttp.FormData["ShelfHeight"] = "0" wlHttp.FormData["ShelfDepth"] = "0" wlHttp.FormData["UnitsPerPallet"] = "0" 98 wlHttp.FormData["IsPurchased"] = "true" wlHttp.FormData["IsSold"] = "true" wlHttp.FormData["C_SubscriptionType_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ImageURL"] = "$WL$EMPTY$STRING$" wlHttp.FormData["DescriptionURL"] = "$WL$EMPTY$STRING$" wlHttp.FormData["GuaranteeDays"] = "0" wlHttp.FormData["GuaranteeDaysMin"] = "0" wlHttp.FormData["M_AttributeSet_ID"] = "-1" wlHttp.FormData["M_AttributeSetInstance_ID"] = "0" wlHttp.FormData["M_AttributeSetInstance_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["IsSelfService"] = "true" wlHttp.FormData["Group1"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Group2"] = "$WL$EMPTY$STRING$" wlHttp.Post("http://hercules:10032/adempiere/WWindow") /***** WLIDE - Sleep - ID:16 *****/ Sleep(1282 1282) 1282 /***** WLIDE - URL : http://hercules:10032/adempiere/WWindow - ID:17 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WWindow" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["PCommand"] = "Next" wlHttp.FormData["PMRRowNo"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ChangedColumn"] = "$WL$EMPTY$STRING$" wlHttp.FormData["PTab"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Value"] = "Fertilizer" wlHttp.FormData["VersionNo"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Name"] = "Fertilizer #50" wlHttp.FormData["Description"] = "50 # Bag of Lawn Fertilizer" wlHttp.FormData["Help"] = "$WL$EMPTY$STRING$" wlHttp.FormData["DocumentNote"] = "$WL$EMPTY$STRING$" wlHttp.FormData["UPC"] = "$WL$EMPTY$STRING$" wlHttp.FormData["SKU"] = "$WL$EMPTY$STRING$" wlHttp.FormData["IsActive"] = "true" wlHttp.FormData["M_Product_Category_ID"] = "109" wlHttp.FormData["Classification"] = "$WL$EMPTY$STRING$" wlHttp.FormData["C_TaxCategory_ID"] = "107" wlHttp.FormData["C_RevenueRecognition_ID"] = "-1" wlHttp.FormData["C_UOM_ID"] = "100" wlHttp.FormData["SalesRep_ID"] = "101" wlHttp.FormData["ProductType"] = "I" wlHttp.FormData["R_MailText_ID"] = "-1" wlHttp.FormData["Weight"] = "0" wlHttp.FormData["Volume"] = "0" wlHttp.FormData["M_FreightCategory_ID"] = "-1" wlHttp.FormData["IsStocked"] = "true" wlHttp.FormData["M_Locator_ID"] = "101" wlHttp.FormData["ShelfWidth"] = "0" wlHttp.FormData["ShelfHeight"] = "0" wlHttp.FormData["ShelfDepth"] = "0" wlHttp.FormData["UnitsPerPallet"] = "0" wlHttp.FormData["IsPurchased"] = "true" wlHttp.FormData["IsSold"] = "true" wlHttp.FormData["C_SubscriptionType_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ImageURL"] = "$WL$EMPTY$STRING$" wlHttp.FormData["DescriptionURL"] = "$WL$EMPTY$STRING$" wlHttp.FormData["GuaranteeDays"] = "180" wlHttp.FormData["GuaranteeDaysMin"] = "30" wlHttp.FormData["M_AttributeSet_ID"] = "101" wlHttp.FormData["M_AttributeSetInstance_ID"] = "0" 99 wlHttp.FormData["M_AttributeSetInstance_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["IsSelfService"] = "true" wlHttp.FormData["Group1"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Group2"] = "$WL$EMPTY$STRING$" wlHttp.Post("http://hercules:10032/adempiere/WWindow") /***** WLIDE - Sleep - ID:18 *****/ Sleep(1292 1292) 1292 /***** WLIDE - URL : http://hercules:10032/adempiere/WWindow - ID:19 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WWindow" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["PCommand"] = "Next" wlHttp.FormData["PMRRowNo"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ChangedColumn"] = "$WL$EMPTY$STRING$" wlHttp.FormData["PTab"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Value"] = "Grass" wlHttp.FormData["VersionNo"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Name"] = "Grass Seed Container" wlHttp.FormData["Description"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Help"] = "$WL$EMPTY$STRING$" wlHttp.FormData["DocumentNote"] = "$WL$EMPTY$STRING$" wlHttp.FormData["UPC"] = "$WL$EMPTY$STRING$" wlHttp.FormData["SKU"] = "$WL$EMPTY$STRING$" wlHttp.FormData["IsActive"] = "true" wlHttp.FormData["M_Product_Category_ID"] = "105" wlHttp.FormData["Classification"] = "$WL$EMPTY$STRING$" wlHttp.FormData["C_TaxCategory_ID"] = "107" wlHttp.FormData["C_RevenueRecognition_ID"] = "-1" wlHttp.FormData["C_UOM_ID"] = "100" wlHttp.FormData["SalesRep_ID"] = "101" wlHttp.FormData["ProductType"] = "I" wlHttp.FormData["R_MailText_ID"] = "-1" wlHttp.FormData["Weight"] = "0" wlHttp.FormData["Volume"] = "0" wlHttp.FormData["M_FreightCategory_ID"] = "-1" wlHttp.FormData["IsStocked"] = "true" wlHttp.FormData["M_Locator_ID"] = "101" wlHttp.FormData["ShelfWidth"] = "0" wlHttp.FormData["ShelfHeight"] = "0" wlHttp.FormData["ShelfDepth"] = "0" wlHttp.FormData["UnitsPerPallet"] = "0" wlHttp.FormData["IsPurchased"] = "true" wlHttp.FormData["IsSold"] = "true" wlHttp.FormData["C_SubscriptionType_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ImageURL"] = "$WL$EMPTY$STRING$" wlHttp.FormData["DescriptionURL"] = "$WL$EMPTY$STRING$" wlHttp.FormData["GuaranteeDays"] = "0" wlHttp.FormData["GuaranteeDaysMin"] = "0" wlHttp.FormData["M_AttributeSet_ID"] = "-1" wlHttp.FormData["M_AttributeSetInstance_ID"] = "0" wlHttp.FormData["M_AttributeSetInstance_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["IsSelfService"] = "true" wlHttp.FormData["Group1"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Group2"] = "$WL$EMPTY$STRING$" wlHttp.Post("http://hercules:10032/adempiere/WWindow") /***** WLIDE - Sleep - ID:20 *****/ Sleep(1332 1332) 1332 100 /***** WLIDE - URL : http://hercules:10032/adempiere/WWindow - ID:21 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WWindow" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["PCommand"] = "Next" wlHttp.FormData["PMRRowNo"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ChangedColumn"] = "$WL$EMPTY$STRING$" wlHttp.FormData["PTab"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Value"] = "Gum Tree" wlHttp.FormData["VersionNo"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Name"] = "Gum Tree" wlHttp.FormData["Description"] = "Australian Native Tree" wlHttp.FormData["Help"] = "Big and heavy" wlHttp.FormData["DocumentNote"] = "$WL$EMPTY$STRING$" wlHttp.FormData["UPC"] = "$WL$EMPTY$STRING$" wlHttp.FormData["SKU"] = "$WL$EMPTY$STRING$" wlHttp.FormData["IsActive"] = "true" wlHttp.FormData["M_Product_Category_ID"] = "105" wlHttp.FormData["Classification"] = "$WL$EMPTY$STRING$" wlHttp.FormData["C_TaxCategory_ID"] = "107" wlHttp.FormData["C_RevenueRecognition_ID"] = "-1" wlHttp.FormData["C_UOM_ID"] = "100" wlHttp.FormData["SalesRep_ID"] = "101" wlHttp.FormData["ProductType"] = "I" wlHttp.FormData["R_MailText_ID"] = "-1" wlHttp.FormData["Weight"] = "0" wlHttp.FormData["Volume"] = "0" wlHttp.FormData["M_FreightCategory_ID"] = "-1" wlHttp.FormData["IsStocked"] = "true" wlHttp.FormData["M_Locator_ID"] = "101" wlHttp.FormData["ShelfWidth"] = "0" wlHttp.FormData["ShelfHeight"] = "0" wlHttp.FormData["ShelfDepth"] = "0" wlHttp.FormData["UnitsPerPallet"] = "0" wlHttp.FormData["IsPurchased"] = "true" wlHttp.FormData["IsSold"] = "true" wlHttp.FormData["C_SubscriptionType_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ImageURL"] = "$WL$EMPTY$STRING$" wlHttp.FormData["DescriptionURL"] = "$WL$EMPTY$STRING$" wlHttp.FormData["GuaranteeDays"] = "0" wlHttp.FormData["GuaranteeDaysMin"] = "0" wlHttp.FormData["M_AttributeSet_ID"] = "-1" wlHttp.FormData["M_AttributeSetInstance_ID"] = "0" wlHttp.FormData["M_AttributeSetInstance_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["IsSelfService"] = "true" wlHttp.FormData["Group1"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Group2"] = "$WL$EMPTY$STRING$" wlHttp.Post("http://hercules:10032/adempiere/WWindow") /***** WLIDE - Sleep - ID:22 *****/ Sleep(1312 1312) 1312 /***** WLIDE - URL : http://hercules:10032/adempiere/WWindow - ID:23 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WWindow" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["PCommand"] = "Next" wlHttp.FormData["PMRRowNo"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ChangedColumn"] = "$WL$EMPTY$STRING$" wlHttp.FormData["PTab"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Value"] = "Hoe" wlHttp.FormData["VersionNo"] = "$WL$EMPTY$STRING$" 101 wlHttp.FormData["Name"] = "Hoe 4 ft" wlHttp.FormData["Description"] = "4 Foot Metal Hoe" wlHttp.FormData["Help"] = "$WL$EMPTY$STRING$" wlHttp.FormData["DocumentNote"] = "$WL$EMPTY$STRING$" wlHttp.FormData["UPC"] = "$WL$EMPTY$STRING$" wlHttp.FormData["SKU"] = "$WL$EMPTY$STRING$" wlHttp.FormData["IsActive"] = "true" wlHttp.FormData["M_Product_Category_ID"] = "108" wlHttp.FormData["Classification"] = "$WL$EMPTY$STRING$" wlHttp.FormData["C_TaxCategory_ID"] = "107" wlHttp.FormData["C_RevenueRecognition_ID"] = "-1" wlHttp.FormData["C_UOM_ID"] = "100" wlHttp.FormData["SalesRep_ID"] = "101" wlHttp.FormData["ProductType"] = "I" wlHttp.FormData["R_MailText_ID"] = "-1" wlHttp.FormData["Weight"] = "0" wlHttp.FormData["Volume"] = "0" wlHttp.FormData["M_FreightCategory_ID"] = "-1" wlHttp.FormData["IsStocked"] = "true" wlHttp.FormData["M_Locator_ID"] = "101" wlHttp.FormData["ShelfWidth"] = "0" wlHttp.FormData["ShelfHeight"] = "0" wlHttp.FormData["ShelfDepth"] = "0" wlHttp.FormData["UnitsPerPallet"] = "0" wlHttp.FormData["IsPurchased"] = "true" wlHttp.FormData["IsSold"] = "true" wlHttp.FormData["C_SubscriptionType_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ImageURL"] = "$WL$EMPTY$STRING$" wlHttp.FormData["DescriptionURL"] = "$WL$EMPTY$STRING$" wlHttp.FormData["GuaranteeDays"] = "0" wlHttp.FormData["GuaranteeDaysMin"] = "0" wlHttp.FormData["M_AttributeSet_ID"] = "-1" wlHttp.FormData["M_AttributeSetInstance_ID"] = "0" wlHttp.FormData["M_AttributeSetInstance_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["IsSelfService"] = "true" wlHttp.FormData["Group1"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Group2"] = "$WL$EMPTY$STRING$" wlHttp.Post("http://hercules:10032/adempiere/WWindow") /***** WLIDE - Sleep - ID:24 *****/ Sleep(1702 1702) 1702 /***** WLIDE - URL : http://hercules:10032/adempiere/WWindow - ID:25 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WWindow" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["PCommand"] = "Next" wlHttp.FormData["PMRRowNo"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ChangedColumn"] = "$WL$EMPTY$STRING$" wlHttp.FormData["PTab"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Value"] = "Holly Bush" wlHttp.FormData["VersionNo"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Name"] = "Holly Bush" wlHttp.FormData["Description"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Help"] = "$WL$EMPTY$STRING$" wlHttp.FormData["DocumentNote"] = "$WL$EMPTY$STRING$" wlHttp.FormData["UPC"] = "$WL$EMPTY$STRING$" wlHttp.FormData["SKU"] = "$WL$EMPTY$STRING$" wlHttp.FormData["IsActive"] = "true" wlHttp.FormData["M_Product_Category_ID"] = "107" wlHttp.FormData["Classification"] = "$WL$EMPTY$STRING$" 102 wlHttp.FormData["C_TaxCategory_ID"] = "107" wlHttp.FormData["C_RevenueRecognition_ID"] = "-1" wlHttp.FormData["C_UOM_ID"] = "100" wlHttp.FormData["SalesRep_ID"] = "101" wlHttp.FormData["ProductType"] = "I" wlHttp.FormData["R_MailText_ID"] = "-1" wlHttp.FormData["Weight"] = "0" wlHttp.FormData["Volume"] = "0" wlHttp.FormData["M_FreightCategory_ID"] = "-1" wlHttp.FormData["IsStocked"] = "true" wlHttp.FormData["M_Locator_ID"] = "101" wlHttp.FormData["ShelfWidth"] = "0" wlHttp.FormData["ShelfHeight"] = "0" wlHttp.FormData["ShelfDepth"] = "0" wlHttp.FormData["UnitsPerPallet"] = "0" wlHttp.FormData["IsPurchased"] = "true" wlHttp.FormData["IsSold"] = "true" wlHttp.FormData["C_SubscriptionType_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ImageURL"] = "$WL$EMPTY$STRING$" wlHttp.FormData["DescriptionURL"] = "$WL$EMPTY$STRING$" wlHttp.FormData["GuaranteeDays"] = "0" wlHttp.FormData["GuaranteeDaysMin"] = "0" wlHttp.FormData["M_AttributeSet_ID"] = "-1" wlHttp.FormData["M_AttributeSetInstance_ID"] = "0" wlHttp.FormData["M_AttributeSetInstance_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["IsSelfService"] = "true" wlHttp.FormData["Group1"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Group2"] = "$WL$EMPTY$STRING$" wlHttp.Post("http://hercules:10032/adempiere/WWindow") /***** WLIDE - Sleep - ID:26 *****/ Sleep(6199 6199) 6199 /***** WLIDE - URL : http://hercules:10032/adempiere/WMenu?Exit=true - ID:27 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WMenu" wlHttp.FormData["Exit"] = "true" wlHttp.Get("http://hercules:10032/adempiere/WMenu") /***** WLIDE - URL : http://hercules:10032/adempiere/index.html - ID:28 *****/ wlHttp.Get("http://hercules:10032/adempiere/index.html") /***** WLIDE - URL : http://hercules:10032/adempiere/WLogin - ID:29 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/index.html" wlHttp.Get("http://hercules:10032/adempiere/WLogin") 12.3 Place Sales Order (read/write operations) /***** WLIDE - URL : http://hercules:10032/adempiere/index.html - ID:2 *****/ wlGlobals.GetFrames = false wlHttp.Get("http://hercules:10032/adempiere/index.html") /***** WLIDE - URL : http://hercules:10032/adempiere/WLogin - ID:3 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/index.html" wlHttp.Get("http://hercules:10032/adempiere/WLogin") 103 /***** WLIDE - Sleep - ID:4 *****/ Sleep(14691 14691) 14691 /***** WLIDE - URL : http://hercules:10032/adempiere/WLogin - ID:5 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WLogin" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["User"] = "GardenAdmin" wlHttp.FormData["Password"] = "GardenAdmin" wlHttp.FormData["#AD_Language"] = "en_US" wlHttp.FormData["Submit"] = " OK" wlHttp.Post("http://hercules:10032/adempiere/WLogin") /***** WLIDE - URL : http://hercules:10032/adempiere/WFieldUpdate - ID:6 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WLogin" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["formName"] = "Login2" wlHttp.FormData["fieldName"] = "AD_Role_ID" wlHttp.FormData["fieldValue"] = "102" wlHttp.FormData["location"] = "top." wlHttp.Post("http://hercules:10032/adempiere/WFieldUpdate") /***** WLIDE - Sleep - ID:7 *****/ Sleep(1432 1432) 1432 /***** WLIDE - URL : http://hercules:10032/adempiere/WMenu - ID:8 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WLogin" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["AD_Role_ID"] = "102" wlHttp.FormData["AD_Client_ID"] = "11" wlHttp.FormData["AD_Org_ID"] = "0" wlHttp.FormData["Date"] = "07/08/2008" wlHttp.FormData["Submit"] = " OK" wlHttp.Post("http://hercules:10032/adempiere/WMenu") /***** WLIDE - Sleep - ID:9 *****/ Sleep(30234 30234) 30234 /***** WLIDE - URL : http://hercules:10032/adempiere/WWindow?AD_Menu_ID=129 - ID:10 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WMenu" wlHttp.FormData["AD_Menu_ID"] = "129" wlHttp.Get("http://hercules:10032/adempiere/WWindow") /***** WLIDE - Sleep - ID:11 *****/ Sleep(6659 6659) 6659 /***** WLIDE - URL : http://hercules:10032/adempiere/WWindow - ID:12 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WWindow?AD_Menu_ID=129" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["PCommand"] = "New" wlHttp.FormData["PMRRowNo"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ChangedColumn"] = "$WL$EMPTY$STRING$" wlHttp.FormData["PTab"] = "$WL$EMPTY$STRING$" wlHttp.FormData["AD_Org_ID"] = "11" wlHttp.FormData["POReference"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Description"] = "direct sale" wlHttp.FormData["C_DocTypeTarget_ID"] = "135" wlHttp.FormData["DateOrderedD"] = "2008-07-08 00:00:00.0" wlHttp.FormData["DateOrdered"] = "07/08/2008" wlHttp.FormData["C_BPartner_ID"] = "120" wlHttp.FormData["C_BPartner_ID"] = "Seed Farm Inc." 104 wlHttp.FormData["Bill_BPartner_ID"] = "120" wlHttp.FormData["C_BPartner_Location_ID"] = "114" wlHttp.FormData["Bill_Location_ID"] = "114" wlHttp.FormData["AD_User_ID"] = "105" wlHttp.FormData["Bill_User_ID"] = "105" wlHttp.FormData["M_Warehouse_ID"] = "103" wlHttp.FormData["M_PriceList_ID"] = "101" wlHttp.FormData["SalesRep_ID"] = "101" wlHttp.FormData["IsDiscountPrinted"] = "true" wlHttp.FormData["C_PaymentTerm_ID"] = "106" wlHttp.FormData["C_Project_ID"] = "-1" wlHttp.FormData["C_Campaign_ID"] = "-1" wlHttp.FormData["OrderType"] = "$WL$EMPTY$STRING$" wlHttp.Post("http://hercules:10032/adempiere/WWindow") /***** WLIDE - Sleep - ID:13 *****/ Sleep(26979 26979) 26979 /***** WLIDE - URL : http://hercules:10032/adempiere/WLookup?ColumnName=C_BPartner_ID&AD_Process_ID=0&page =1 - ID:14 *****/ wlHttp.FormData["ColumnName"] = "C_BPartner_ID" wlHttp.FormData["AD_Process_ID"] = "0" wlHttp.FormData["page"] = "1" wlHttp.Get("http://hercules:10032/adempiere/WLookup") /***** WLIDE - Sleep - ID:15 *****/ Sleep(10125 10125) 10125 /***** WLIDE - URL : http://hercules:10032/adempiere/WWindow - ID:16 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WWindow" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["PCommand"] = "$WL$EMPTY$STRING$" wlHttp.FormData["PMRRowNo"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ChangedColumn"] = "C_BPartner_ID" wlHttp.FormData["PTab"] = "$WL$EMPTY$STRING$" wlHttp.FormData["AD_Client_ID"] = "11" wlHttp.FormData["AD_Org_ID"] = "11" wlHttp.FormData["DocumentNo"] = "<80004>" wlHttp.FormData["POReference"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Description"] = "Order for GardenAdmin" wlHttp.FormData["C_DocTypeTarget_ID"] = "135" wlHttp.FormData["DateOrderedD"] = "2008-07-08 00:00:00.0" wlHttp.FormData["DateOrdered"] = "07/08/2008" wlHttp.FormData["C_BPartner_ID"] = "113" wlHttp.FormData["C_BPartner_ID"] = "GardenAdmin BP" wlHttp.FormData["Bill_BPartner_ID"] = "-1" wlHttp.FormData["Bill_Location_ID"] = "-1" wlHttp.FormData["AD_User_ID"] = "-1" wlHttp.FormData["Bill_User_ID"] = "-1" wlHttp.FormData["M_PriceList_ID"] = "101" wlHttp.FormData["SalesRep_ID"] = "101" wlHttp.FormData["C_Project_ID"] = "-1" wlHttp.FormData["C_Campaign_ID"] = "-1" wlHttp.FormData["OrderType"] = "$WL$EMPTY$STRING$" wlHttp.Post("http://hercules:10032/adempiere/WWindow") /***** WLIDE - Sleep - ID:17 *****/ Sleep(22242 22242) 22242 105 /***** WLIDE - URL : http://hercules:10032/adempiere/WWindow - ID:18 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WWindow" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["PCommand"] = "$WL$EMPTY$STRING$" wlHttp.FormData["PMRRowNo"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ChangedColumn"] = "$WL$EMPTY$STRING$" wlHttp.FormData["PTab"] = "1" wlHttp.FormData["AD_Client_ID"] = "11" wlHttp.FormData["AD_Org_ID"] = "11" wlHttp.FormData["DocumentNo"] = "<80004>" wlHttp.FormData["POReference"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Description"] = "Order for GardenAdmin" wlHttp.FormData["C_DocTypeTarget_ID"] = "135" wlHttp.FormData["DateOrderedD"] = "2008-07-08 00:00:00.0" wlHttp.FormData["DateOrdered"] = "07/08/2008" wlHttp.FormData["C_BPartner_ID"] = "113" wlHttp.FormData["C_BPartner_ID"] = "GardenAdmin BP" wlHttp.FormData["Bill_BPartner_ID"] = "113" wlHttp.FormData["C_BPartner_Location_ID"] = "117" wlHttp.FormData["Bill_Location_ID"] = "117" wlHttp.FormData["AD_User_ID"] = "101" wlHttp.FormData["Bill_User_ID"] = "101" wlHttp.FormData["M_Warehouse_ID"] = "103" wlHttp.FormData["M_PriceList_ID"] = "101" wlHttp.FormData["SalesRep_ID"] = "101" wlHttp.FormData["IsDiscountPrinted"] = "true" wlHttp.FormData["C_PaymentTerm_ID"] = "105" wlHttp.FormData["C_Project_ID"] = "-1" wlHttp.FormData["C_Campaign_ID"] = "-1" wlHttp.FormData["OrderType"] = "$WL$EMPTY$STRING$" wlHttp.Post("http://hercules:10032/adempiere/WWindow") /***** WLIDE - Sleep - ID:19 *****/ Sleep(6339 6339) 6339 /***** WLIDE - URL : http://hercules:10032/adempiere/WWindow - ID:20 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WWindow" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["PCommand"] = "$WL$EMPTY$STRING$" wlHttp.FormData["PMRRowNo"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ChangedColumn"] = "$WL$EMPTY$STRING$" wlHttp.FormData["PTab"] = "0" wlHttp.FormData["C_Order_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["C_Order_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["M_Product_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["M_Product_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["M_AttributeSetInstance_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["M_AttributeSetInstance_ID"] = "$WL$EMPTY$STRING$" wlHttp.Post("http://hercules:10032/adempiere/WWindow") /***** WLIDE - Sleep - ID:21 *****/ Sleep(11246 11246) 11246 /***** WLIDE - URL : http://hercules:10032/adempiere/WWindow - ID:22 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WWindow" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["PCommand"] = "Save" wlHttp.FormData["PMRRowNo"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ChangedColumn"] = "$WL$EMPTY$STRING$" wlHttp.FormData["PTab"] = "$WL$EMPTY$STRING$" 106 wlHttp.FormData["AD_Client_ID"] = "11" wlHttp.FormData["AD_Org_ID"] = "11" wlHttp.FormData["DocumentNo"] = "<80004>" wlHttp.FormData["POReference"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Description"] = "Order for GardenAdmin" wlHttp.FormData["C_DocTypeTarget_ID"] = "135" wlHttp.FormData["DateOrderedD"] = "2008-07-08 00:00:00.0" wlHttp.FormData["DateOrdered"] = "07/08/2008" wlHttp.FormData["C_BPartner_ID"] = "113" wlHttp.FormData["C_BPartner_ID"] = "GardenAdmin BP" wlHttp.FormData["Bill_BPartner_ID"] = "113" wlHttp.FormData["C_BPartner_Location_ID"] = "117" wlHttp.FormData["Bill_Location_ID"] = "117" wlHttp.FormData["AD_User_ID"] = "101" wlHttp.FormData["Bill_User_ID"] = "101" wlHttp.FormData["M_Warehouse_ID"] = "103" wlHttp.FormData["M_PriceList_ID"] = "101" wlHttp.FormData["SalesRep_ID"] = "101" wlHttp.FormData["IsDiscountPrinted"] = "true" wlHttp.FormData["C_PaymentTerm_ID"] = "105" wlHttp.FormData["C_Project_ID"] = "-1" wlHttp.FormData["C_Campaign_ID"] = "-1" wlHttp.FormData["OrderType"] = "$WL$EMPTY$STRING$" wlHttp.Post("http://hercules:10032/adempiere/WWindow") /***** WLIDE - Sleep - ID:23 *****/ Sleep(10225 10225) 10225 /***** WLIDE - URL : http://hercules:10032/adempiere/WWindow - ID:24 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WWindow" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["PCommand"] = "$WL$EMPTY$STRING$" wlHttp.FormData["PMRRowNo"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ChangedColumn"] = "$WL$EMPTY$STRING$" wlHttp.FormData["PTab"] = "1" wlHttp.FormData["AD_Org_ID"] = "11" wlHttp.FormData["POReference"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Description"] = "Order for GardenAdmin" wlHttp.FormData["C_DocTypeTarget_ID"] = "135" wlHttp.FormData["DateOrderedD"] = "2008-07-08 00:00:00.0" wlHttp.FormData["DateOrdered"] = "07/08/2008" wlHttp.FormData["C_BPartner_ID"] = "113" wlHttp.FormData["C_BPartner_ID"] = "GardenAdmin BP" wlHttp.FormData["Bill_BPartner_ID"] = "113" wlHttp.FormData["C_BPartner_Location_ID"] = "117" wlHttp.FormData["Bill_Location_ID"] = "117" wlHttp.FormData["AD_User_ID"] = "101" wlHttp.FormData["Bill_User_ID"] = "101" wlHttp.FormData["M_Warehouse_ID"] = "103" wlHttp.FormData["M_PriceList_ID"] = "101" wlHttp.FormData["SalesRep_ID"] = "101" wlHttp.FormData["IsDiscountPrinted"] = "true" wlHttp.FormData["C_PaymentTerm_ID"] = "105" wlHttp.FormData["C_Project_ID"] = "-1" wlHttp.FormData["C_Campaign_ID"] = "-1" wlHttp.FormData["OrderType"] = "$WL$EMPTY$STRING$" wlHttp.Post("http://hercules:10032/adempiere/WWindow") /***** WLIDE - Sleep - ID:25 *****/ Sleep(5207 5207) 5207 107 /***** WLIDE - URL : http://hercules:10032/adempiere/WLookup?ColumnName=M_Product_ID&AD_Process_ID=0&page= 1 - ID:26 *****/ wlHttp.FormData["ColumnName"] = "M_Product_ID" wlHttp.FormData["AD_Process_ID"] = "0" wlHttp.FormData["page"] = "1" wlHttp.Get("http://hercules:10032/adempiere/WLookup") /***** WLIDE - Sleep - ID:27 *****/ Sleep(14361 14361) 14361 /***** WLIDE - URL : http://hercules:10032/adempiere/WWindow - ID:28 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WWindow" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["PCommand"] = "$WL$EMPTY$STRING$" wlHttp.FormData["PMRRowNo"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ChangedColumn"] = "M_Product_ID" wlHttp.FormData["PTab"] = "$WL$EMPTY$STRING$" wlHttp.FormData["AD_Org_ID"] = "11" wlHttp.FormData["C_Order_ID"] = "1000001" wlHttp.FormData["C_Order_ID"] = "80004_2008-07-08 00:00:00" wlHttp.FormData["Line"] = "10" wlHttp.FormData["M_Product_ID"] = "136" wlHttp.FormData["M_Product_ID"] = "Fertilizer #50" wlHttp.FormData["C_Charge_ID"] = "-1" wlHttp.FormData["M_AttributeSetInstance_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["M_AttributeSetInstance_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Description"] = "$WL$EMPTY$STRING$" wlHttp.FormData["QtyEntered"] = "1" wlHttp.FormData["C_UOM_ID"] = "100" wlHttp.FormData["PriceEntered"] = "0" wlHttp.FormData["PriceActual"] = "0" wlHttp.FormData["PriceList"] = "0" wlHttp.FormData["C_Tax_ID"] = "104" wlHttp.FormData["Discount"] = "0" wlHttp.FormData["C_Project_ID"] = "-1" wlHttp.FormData["C_Campaign_ID"] = "-1" wlHttp.Post("http://hercules:10032/adempiere/WWindow") /***** WLIDE - Sleep - ID:29 *****/ Sleep(13479 13479) 13479 /***** WLIDE - URL : http://hercules:10032/adempiere/WWindow - ID:30 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WWindow" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["PCommand"] = "$WL$EMPTY$STRING$" wlHttp.FormData["PMRRowNo"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ChangedColumn"] = "QtyEntered" wlHttp.FormData["PTab"] = "$WL$EMPTY$STRING$" wlHttp.FormData["AD_Org_ID"] = "11" wlHttp.FormData["C_Order_ID"] = "1000001" wlHttp.FormData["C_Order_ID"] = "80004_2008-07-08 00:00:00" wlHttp.FormData["Line"] = "10" wlHttp.FormData["M_Product_ID"] = "136" wlHttp.FormData["M_Product_ID"] = "Fertilizer #50" wlHttp.FormData["C_Charge_ID"] = "-1" wlHttp.FormData["M_AttributeSetInstance_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["M_AttributeSetInstance_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Description"] = "$WL$EMPTY$STRING$" 108 wlHttp.FormData["QtyEntered"] = "5" wlHttp.FormData["C_UOM_ID"] = "100" wlHttp.FormData["PriceEntered"] = "20" wlHttp.FormData["PriceActual"] = "20" wlHttp.FormData["PriceList"] = "20" wlHttp.FormData["C_Tax_ID"] = "104" wlHttp.FormData["Discount"] = "0" wlHttp.FormData["C_Project_ID"] = "-1" wlHttp.FormData["C_Campaign_ID"] = "-1" wlHttp.Post("http://hercules:10032/adempiere/WWindow") /***** WLIDE - Sleep - ID:31 *****/ Sleep(22583 22583) 22583 /***** WLIDE - URL : http://hercules:10032/adempiere/WWindow - ID:32 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WWindow" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["PCommand"] = "Save" wlHttp.FormData["PMRRowNo"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ChangedColumn"] = "$WL$EMPTY$STRING$" wlHttp.FormData["PTab"] = "$WL$EMPTY$STRING$" wlHttp.FormData["AD_Org_ID"] = "11" wlHttp.FormData["C_Order_ID"] = "1000001" wlHttp.FormData["C_Order_ID"] = "80004_2008-07-08 00:00:00" wlHttp.FormData["Line"] = "10" wlHttp.FormData["M_Product_ID"] = "136" wlHttp.FormData["M_Product_ID"] = "Fertilizer #50" wlHttp.FormData["C_Charge_ID"] = "-1" wlHttp.FormData["M_AttributeSetInstance_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["M_AttributeSetInstance_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Description"] = "$WL$EMPTY$STRING$" wlHttp.FormData["QtyEntered"] = "5" wlHttp.FormData["C_UOM_ID"] = "100" wlHttp.FormData["PriceEntered"] = "20" wlHttp.FormData["PriceActual"] = "20" wlHttp.FormData["PriceList"] = "20" wlHttp.FormData["C_Tax_ID"] = "104" wlHttp.FormData["Discount"] = "0" wlHttp.FormData["C_Project_ID"] = "-1" wlHttp.FormData["C_Campaign_ID"] = "-1" wlHttp.Post("http://hercules:10032/adempiere/WWindow") /***** WLIDE - Sleep - ID:33 *****/ Sleep(8762 8762) 8762 /***** WLIDE - URL : http://hercules:10032/adempiere/WWindow - ID:34 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WWindow" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["PCommand"] = "New" wlHttp.FormData["PMRRowNo"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ChangedColumn"] = "$WL$EMPTY$STRING$" wlHttp.FormData["PTab"] = "$WL$EMPTY$STRING$" wlHttp.FormData["AD_Org_ID"] = "11" wlHttp.FormData["C_Order_ID"] = "1000001" wlHttp.FormData["C_Order_ID"] = "80004_2008-07-08 00:00:00" wlHttp.FormData["Line"] = "10" wlHttp.FormData["M_Product_ID"] = "136" wlHttp.FormData["M_Product_ID"] = "Fertilizer #50" wlHttp.FormData["C_Charge_ID"] = "-1" wlHttp.FormData["M_AttributeSetInstance_ID"] = "0" 109 wlHttp.FormData["M_AttributeSetInstance_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Description"] = "$WL$EMPTY$STRING$" wlHttp.FormData["QtyEntered"] = "5" wlHttp.FormData["PriceEntered"] = "20" wlHttp.FormData["PriceList"] = "20" wlHttp.FormData["C_Tax_ID"] = "104" wlHttp.FormData["Discount"] = "0.00" wlHttp.FormData["C_Project_ID"] = "-1" wlHttp.FormData["C_Campaign_ID"] = "-1" wlHttp.Post("http://hercules:10032/adempiere/WWindow") /***** WLIDE - Sleep - ID:35 *****/ Sleep(3435 3435) 3435 /***** WLIDE - URL : http://hercules:10032/adempiere/WLookup?ColumnName=M_Product_ID&AD_Process_ID=0&page= 1 - ID:36 *****/ wlHttp.FormData["ColumnName"] = "M_Product_ID" wlHttp.FormData["AD_Process_ID"] = "0" wlHttp.FormData["page"] = "1" wlHttp.Get("http://hercules:10032/adempiere/WLookup") /***** WLIDE - Sleep - ID:37 *****/ Sleep(6880 6880) 6880 /***** WLIDE - URL : http://hercules:10032/adempiere/WWindow - ID:38 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WWindow" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["PCommand"] = "$WL$EMPTY$STRING$" wlHttp.FormData["PMRRowNo"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ChangedColumn"] = "M_Product_ID" wlHttp.FormData["PTab"] = "$WL$EMPTY$STRING$" wlHttp.FormData["AD_Org_ID"] = "11" wlHttp.FormData["C_Order_ID"] = "1000001" wlHttp.FormData["C_Order_ID"] = "80004_2008-07-08 00:00:00" wlHttp.FormData["Line"] = "20" wlHttp.FormData["M_Product_ID"] = "138" wlHttp.FormData["M_Product_ID"] = "Hoe 4 ft" wlHttp.FormData["C_Charge_ID"] = "-1" wlHttp.FormData["M_AttributeSetInstance_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["M_AttributeSetInstance_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Description"] = "$WL$EMPTY$STRING$" wlHttp.FormData["QtyEntered"] = "1" wlHttp.FormData["C_UOM_ID"] = "100" wlHttp.FormData["PriceEntered"] = "0" wlHttp.FormData["PriceActual"] = "0" wlHttp.FormData["PriceList"] = "0" wlHttp.FormData["C_Tax_ID"] = "104" wlHttp.FormData["Discount"] = "0" wlHttp.FormData["C_Project_ID"] = "-1" wlHttp.FormData["C_Campaign_ID"] = "-1" wlHttp.Post("http://hercules:10032/adempiere/WWindow") /***** WLIDE - Sleep - ID:39 *****/ Sleep(5979 5979) 5979 /***** WLIDE - URL : http://hercules:10032/adempiere/WWindow - ID:40 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WWindow" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["PCommand"] = "$WL$EMPTY$STRING$" 110 wlHttp.FormData["PMRRowNo"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ChangedColumn"] = "QtyEntered" wlHttp.FormData["PTab"] = "$WL$EMPTY$STRING$" wlHttp.FormData["AD_Org_ID"] = "11" wlHttp.FormData["C_Order_ID"] = "1000001" wlHttp.FormData["C_Order_ID"] = "80004_2008-07-08 00:00:00" wlHttp.FormData["Line"] = "20" wlHttp.FormData["M_Product_ID"] = "138" wlHttp.FormData["M_Product_ID"] = "Hoe 4 ft" wlHttp.FormData["C_Charge_ID"] = "-1" wlHttp.FormData["M_AttributeSetInstance_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["M_AttributeSetInstance_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Description"] = "$WL$EMPTY$STRING$" wlHttp.FormData["QtyEntered"] = "2" wlHttp.FormData["C_UOM_ID"] = "100" wlHttp.FormData["PriceEntered"] = "13.5" wlHttp.FormData["PriceActual"] = "13.5" wlHttp.FormData["PriceList"] = "15" wlHttp.FormData["C_Tax_ID"] = "104" wlHttp.FormData["Discount"] = "10" wlHttp.FormData["C_Project_ID"] = "-1" wlHttp.FormData["C_Campaign_ID"] = "-1" wlHttp.Post("http://hercules:10032/adempiere/WWindow") /***** WLIDE - Sleep - ID:41 *****/ Sleep(17134 17134) 17134 /***** WLIDE - URL : http://hercules:10032/adempiere/WWindow - ID:42 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WWindow" wlHttp.ContentType = "application/x-www-form-urlencoded" wlHttp.FormData["PCommand"] = "Save" wlHttp.FormData["PMRRowNo"] = "$WL$EMPTY$STRING$" wlHttp.FormData["ChangedColumn"] = "$WL$EMPTY$STRING$" wlHttp.FormData["PTab"] = "$WL$EMPTY$STRING$" wlHttp.FormData["AD_Org_ID"] = "11" wlHttp.FormData["C_Order_ID"] = "1000001" wlHttp.FormData["C_Order_ID"] = "80004_2008-07-08 00:00:00" wlHttp.FormData["Line"] = "20" wlHttp.FormData["M_Product_ID"] = "138" wlHttp.FormData["M_Product_ID"] = "Hoe 4 ft" wlHttp.FormData["C_Charge_ID"] = "-1" wlHttp.FormData["M_AttributeSetInstance_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["M_AttributeSetInstance_ID"] = "$WL$EMPTY$STRING$" wlHttp.FormData["Description"] = "$WL$EMPTY$STRING$" wlHttp.FormData["QtyEntered"] = "2" wlHttp.FormData["C_UOM_ID"] = "100" wlHttp.FormData["PriceEntered"] = "13.5" wlHttp.FormData["PriceActual"] = "13.5" wlHttp.FormData["PriceList"] = "15" wlHttp.FormData["C_Tax_ID"] = "104" wlHttp.FormData["Discount"] = "10" wlHttp.FormData["C_Project_ID"] = "-1" wlHttp.FormData["C_Campaign_ID"] = "-1" wlHttp.Post("http://hercules:10032/adempiere/WWindow") /***** WLIDE - Sleep - ID:43 *****/ Sleep(5228 5228) 5228 /***** WLIDE - URL : http://hercules:10032/adempiere/WMenu?Exit=true - ID:44 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WMenu" 111 wlHttp.FormData["Exit"] = "true" wlHttp.Get("http://hercules:10032/adempiere/WMenu") /***** WLIDE - URL : http://hercules:10032/adempiere/index.html - ID:45 *****/ wlHttp.Get("http://hercules:10032/adempiere/index.html") /***** WLIDE - URL : http://hercules:10032/adempiere/cmd.html - ID:46 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/index.html" wlHttp.Get("http://hercules:10032/adempiere/cmd.html") /***** WLIDE - URL : http://hercules:10032/adempiere/menu.html - ID:47 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/index.html" wlHttp.Get("http://hercules:10032/adempiere/menu.html") /***** WLIDE - URL : http://hercules:10032/adempiere/window.html - ID:48 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/index.html" wlHttp.Get("http://hercules:10032/adempiere/window.html") /***** WLIDE - URL : http://hercules:10032/adempiere/WLogin - ID:49 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/index.html" wlHttp.Get("http://hercules:10032/adempiere/WLogin") /***** WLIDE - URL : http://hercules:10032/adempiere/images/Ok16.gif - ID:50 *****/ wlHttp.Header["Referer"] = "http://hercules:10032/adempiere/WLogin" wlHttp.Get("http://hercules:10032/adempiere/images/Ok16.gif") 112 13. Appendix D: Test Results The test methodology required for load testing to be performed on each application server three times. Each test lasted for a duration of 10 minutes and ramped the number of concurrent users from1 to 500 over the entirety of the test. Test runs were alternated between application servers. Graphs of the results are contained in this section. 13.1 JBoss Figure 18 - First Run of Testing on JBoss 113 Figure 19 - Second Run of Testing on JBoss Figure 20 - Third Run of Testing on JBoss 114 13.2 WebSphere Application Server Figure 21 - First Run of Testing on WebSphere Application Server Figure 22 - Second Run of Testing on WebSphere Application Server 115 Figure 23 - Third Run of Testing on WebSphere Application Server 116 14. Appendix E: Document Version History Description Initial Draft Revision based on feedback from John Schilt Date 19.9.08 20.10.08 Version Author 0.1 0.2 0.3 1.0 Grant Quick Grant Quick Grant Quick Grant Quick Revision based on feedback from Alan McNamara 6.11.08 Release Version 21.11.08 117

Related docs
Manual for Adempier ERP Suite
Views: 750  |  Downloads: 59
Open Source ERP comparison
Views: 755  |  Downloads: 58
Adempiere Document Project
Views: 177  |  Downloads: 20
Open Source Applications Catalog
Views: 250  |  Downloads: 5
premium docs
Other docs by Tariq Rafique
Adempiere Document Project
Views: 177  |  Downloads: 20
Hamoodur Rahman Commission Report 1971
Views: 59  |  Downloads: 1
Open Source Applications Catalog
Views: 250  |  Downloads: 5
Dot to dot - airplane
Views: 103  |  Downloads: 17
directions2
Views: 54  |  Downloads: 7
directions1
Views: 45  |  Downloads: 9
dfPrintingModern
Views: 55  |  Downloads: 9
dfprinting
Views: 42  |  Downloads: 5
descriptionsmatchup
Views: 65  |  Downloads: 14
descriptions draw
Views: 49  |  Downloads: 7
descriptions2
Views: 22  |  Downloads: 4
defspellModern
Views: 48  |  Downloads: 9
defspell
Views: 38  |  Downloads: 6
defpicsModern
Views: 23  |  Downloads: 8
defpics
Views: 22  |  Downloads: 3