Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Events
Videos
Audiobooks
Packt Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials

7018 Articles
article-image-through-web-theming-using-python
Packt
26 Jul 2010
2 min read
Save for later

Through the Web Theming using Python

Packt
26 Jul 2010
2 min read
Download code from here (Read more interesting articles on Plone here.) Examining themes in the Zope Management Interface Now that we have seen in part how themes work, let us take a closer look at their representation in Zope Object Database (ZODB). Browse to http://localhost:8080/Plone. Click on Site Setup Zope Management Interface| and you should see: This is a Through the Web (TTW) representation of all the objects in the database at the Plone site level (the application root is one level above). The most frequently used theme-related objects here are: portal_css portal_javascripts portal_skins portal_view_customizations Of these, portal_css and portal_javascripts are most often used to enable their respective debug modes, wherein the CSS and JavaScript files are not compiled into a single file (not to be confused with Zope 2's debug mode which detects filesystem changes in real time when enabled). Take a look at your site with Firebug, in particular the style tab. You should see: Now enable debug mode in portal_javascripts and look again. You should see: When portal_css debug mode is enabled, we can see (or by viewing the HTML source) that the CSS files are loaded individually in Firebug. The same applies to portal_javascripts debug mode. This can be absolutely invaluable when trying to correlate various visual elements with their respective sources. In addition to debug mode, you can also add CSS/JavaScript files to their respective registries through the Web, which brings us to the next topic.
Read more
  • 0
  • 0
  • 6381

article-image-introduction-vtiger-crm
Packt
11 Jul 2011
6 min read
Save for later

Introduction to Vtiger CRM

Packt
11 Jul 2011
6 min read
Customer. Relationship. Management. These three words by themselves are enough to give us all nightmares, never mind all three of them together in the same sentence. But, vtiger CRM takes the pain away and provides us with a solution that will leave us whistling the 1812 Overture (Yeah, you can make the cannon noises if you want). vtiger CRM is an open source customer relationship management tool written in the PHP scripting language, and it uses MySQL as its database. This article introduces you to vtiger CRM and you'll learn a bit about its origin and history. The major technologies that make up vtiger CRM are outlined and the core feature set is explained. The history of Vtiger CRM As you may already know, vtiger CRM is a fork of another CRM package called SugarCRM. SugarCRM was originally released under the SPL or "SugarCRM Public License". It's a modified version of the Mozilla Public License 1.1. In 2004, Sridhar Vembu, CEO of AdventNet, created vtiger. SugarCRM was starting to "close" some of its source code for commercial gain. Vembu and the vtiger team created vtiger under the "honest open source" label based on SugarCRM's own SPL. SugarCRM was openly upset by this movement. They called vtiger CRM "a lie" and claimed they were not living up to "the spirit" of open source. However, the vtiger team claimed full compliance with the SPL and openly admitted that it was a fork. They also sent a letter to Eric Raymond, a well-renowned advocate of open source. You can read the whole thread from 2004 here. It's a very interesting read. vtiger CRM states that they will protect the CRM to stay free with no dual versioning. Until now, vtiger has remained 100 percent open source and free. With the current version of vtiger—version 5—vtiger has lost almost all SugarCRM code. The technical components of vtiger CRM vtiger CRM is built on Apache, PHP, and MySQL. We'll review briefly each of these components below. Apache Apache is another open source software project. Apache is a web server. A web server allows you to "host" a website. When you browse the Internet, Apache is what sends the content you're viewing to your screen. Of the roughly 255 million websites that existed in 2010, Apache hosted about 152 million of them. vtiger CRM uses the Apache web server by default, although it can be configured to work with other web servers. Make sure you have a working installation of Apache 2.0.40 or above. Litt le experience with Apache is necessary for the use of vtiger. PHP PHP is another open source soft ware project. It is a sophisticated scripting language that benefits from the contribution of developers all over the world. PHP allows you to process data among many other things. vtiger CRM is built on PHP. Over the last decade, PHP has become the scripting language of choice for many open-source and commercially hosted soft ware packages. With vtiger CRM 5.2, PHP 5.3.x is recommended. If you have significant experience in PHP, you will have more potential for automation and more power in customizing vtiger CRM for your organization's needs. MySQL MySQL is a free, open source database management engine. It allows you to store, process, and retrieve relational data. vtiger CRM uses MySQL to store all of its CRM data. To run vtiger well, MySQL 5.1.x is recommended. Like PHP, significant MySQL skill will unlock the true potential for customization that vtiger has. Smarty Smarty is a template engine designed for PHP. The result it that it separates the application logic (PHP) from the presentation or what you see on the screen. vtiger CRM uses Smarty to display its data, such as leads, accounts, and contacts. You don't have to worry about installing Smarty or its version, as it installs along with vtiger. Smarty is a PHP-based templating system that allows vtiger to create its various views and layouts and merge them with vtiger's data layer, MySQL. CSS CSS (Cascading Style Sheets) is the standard by which colors and background images are applied in vtiger. If you are proficient in CSS, you can significantly change the look and feel of vtiger CRM and even make important usability improvements specific to your organization. So, if you have experience with Apache, PHP, MySQL, and CSS, vtiger is a perfect fit for you and your organization. I'm sure you're eager to dig right in and start installing, but first let's take a look at vtiger's CRM feature set. Then you'll get a good picture of what you have to start with. vtiger's core feature set Lead Management, Sales Force Automation, Activity Management, and Customer Service are at the core of vtiger. However, there are plenty of other features that extend this core. There are also billing, inventory, email integration, and calendaring features that really start to build out the full-featured CRM that vtiger is. There won't be an extensive consideration of all of vtiger's features in this article, but we'll get an overview of the core features that have to do with sales force automation. Sales and marketing features First, here are some brief definitions of the terms that vtiger CRM uses. A Lead represents a company or a representative of a company that may have an interest in your products or services. A Potential is a lead that does have an interest in your products or services. An Account is either a customer or a prospect that has an attached Potential. A Contact is a person that is connected to an Account. Multi-channel lead and account management is an integral part of CRM and is firmly supported by vtiger. You can capture leads from your website, enter them after a conference, etc. and vtiger will help you work on those leads and track them until they become business opportunities and then paying accounts. Notice the default view of leads in the following screenshot. You can filter the lead view with custom filters so you can have visibility to specific segments of your lead pool, such as location, number of employees, revenue, sales stage, and so on: vtiger CRM also features an easy and secure web lead form that you can place on any website and it will insert new leads directly into your vtiger CRM system. The lead details screen tells you everything you need to know about the lead on one page: You can also incorporate a product-based selling process at the lead stage with integrated products. You can indicate any products that the lead is interested in. Once you have identified a lead as having potential for business, you can click on the Convert Lead link while viewing a lead to convert into a Potential and/or Account. We'll get into more detailed information about how to manage your sales process in vtiger CRM, but for now, you can see the power of vtiger CRM beginning to unfold and what it means for your sales process.
Read more
  • 0
  • 0
  • 6376

article-image-citrix-xenapp-performance-essentials
Packt
21 Aug 2013
18 min read
Save for later

Citrix XenApp Performance Essentials

Packt
21 Aug 2013
18 min read
(For more resources related to this topic, see here.) Optimizing Session Startup The most frequent complaint that system administrators receive from users about XenApp is definitely that the applications start slowly. They certainly do not consider that at least the first time you launch an application published by XenApp, an entire login process takes place. In this article you'll learn: Which steps form the login process and which systems are involved The most common causes of logon delays and how to mitigate them The use of some advanced XenApp features, like session pre-launch The logon process Let's briefly review the logon process that starts when a user launches an application through the Web Interface or through a link created by the Receiver. The following diagram explains the logon process: The logon process Resolution The user launches an application (A) and the Web Interface queries the Data Collector (B) that returns the least-loaded server for the requested application (C). The Web Interface generates an ICA file and passes it to the client (D). Connection The Citrix client running on the user's PC establishes a connection to the session-host server specified in the ICA file. In the handshake process, client and server agree on the security level and capabilities. Remote Desktop Services (RDS) license Windows Server validates that an RDS/Terminal Server (TS) license is available. AD authentication Windows Server authenticates the user against the Active Directory (AD). If the authentication is successful, the server queries account details from the AD, including Group Policies (GPOs) and roaming profiles. Citrix license XenApp validates that a Citrix license is available. Session startup If the user has a roaming profile, Windows downloads it from the specified location (usually a file server). Windows then applies any GPOs and XenApp applies any Citrix policies. Windows executes applications included in the Startup menu and finally launches the requested application. Some other steps may be necessary if other Citrix components (for example, the Citrix Access Gateway) are included in your infrastructure. Analysing the logon process Users perceive the overall duration of the process from the time when they click on the icon until the appearance of the application on their desktops. To troubleshoot slowness, a system administrator must know the duration of the individual steps. Citrix EdgeSight Citrix EdgeSight is a performance and availability management solution for XenApp and XenDesktop. If you own an Enterprise or Platinum XenApp license, you're entitled to install EdgeSight Basic (for Enterprise licensing) or Advanced (for Platinum licensing). You can also license it as a standalone product. If you deployed Citrix EdgeSight in your farm, you can run the Session Startup Duration Detail report, which includes information on both, the duration of server-side and client-side steps. This report is available only with EdgeSight Advanced. For each session, you can drill down the report to display information about server-side and client-side startup processes. An example is shown in the following screenshot: EdgeSight's Session Startup Duration Detail report The columns report the time (in milliseconds) spent by the startup process in the different steps. SSD is the total server-side time, while CSD the total client-side time. You can find a full description of the available reports and the meaning of the different acronyms in the EdgeSight Report List at http://community.citrix.com/display/edgesight/EdgeSight+5.4+Report+List. In the preceding example most of the time was spent in the Profile Load (PLSD) and Login Script Execution (LSESD) steps on the server and in the Session Creation (SCCD) step on the client. EdgeSight is a very valuable tool to analyze your farm. The available reports cover all the critical areas and gives detailed information about the "hidden" work of Citrix XenApp. With the Session Startup Duration Detail report you can identify which steps cause a slow session startup. If you want to understand why server-side steps, like the Profile Load step in the preceding example that lasted more than 15 seconds, take too much time, you need a different tool. Windows Performance Toolkit Windows Performance Toolkit (WPT) is a tool included in the Windows ADK, freely downloadable from the Microsoft website (http://www.microsoft.com/en-us/download/details.aspx?id=30652). You need an Internet connection to install Windows ADK. You can run the setup on a client with Internet access and configure it to download all the required components in a folder. Move the folder on your server and perform an offline installation. WPT has two components: Windows Performance Recorder, which is used to record all the performance data in an .etl file Windows Performance Analyzer, a graphical program to analyze the recorded data Run the following command from the WPT installed folder to capture slow logons: C:WPT>xperf -on base+latency+dispatcher+NetworkTrace+Registry+File IO -stackWalk CSwitch+ReadyThread+ThreadCreate+Profile -BufferSize 128 -start UserTrace -on "Microsoft-Windows-Shell-Core+Microsoft-Windows-Wininit+Microsoft-Windows-Folder Redirection+Microsoft-Windows-User Profiles Service+Microsoft-Windows-GroupPolicy+Microsoft-Windows-Winlogon+Microsoft-Windows-Security-Kerberos+Microsoft-Windows-User Profiles General+e5ba83f6-07d0-46b1-8bc7-7e669a1d31dc+63b530f8-29c9-4880-a5b4-b8179096e7b8+2f07e2ee-15db-40f1-90ef-9d7ba282188a" -BufferSize 1024 -MinBuffers 64 -MaxBuffers 128 -MaxFile 1024 After having recorded at least one slow logon, run the following command to stop recording and save the performance data to an .etl file: C:WPT>xperf -stop -stop UserTrace -d merged.etl This command creates a file called merged.etl in the WPT install folder. You can open this file with Windows Performance Analyzer. The Windows Performance Analyzer timeline is shown in the following screenshot: Windows Performance Analyzer timeline Windows Performance Analyzer shows a timeline with the duration of each step; for any point in time you can view the running processes, the usage of CPU and memory, the number of I/O operations, and the bytes sent or received through the network. WPT is a great tool to identify the reason for delays in Windows; it, however, has no visibility of Citrix processes. This is why EdgeSight is still necessary for complete troubleshooting. Common causes of logon delays After having analyzed many logon problems, I found that the slowness was usually caused by one or more of the following reasons: Authentication issues Profile issues GPO and logon script issues In the next paragraphs, you'll learn how to identify those issues and how to mitigate them. Even if you can't use the advanced tools (EdgeSight, WPT, and so on) described in the preceding sections, you can follow the guidelines in the next sections and best practices to solve or prevent most of the problems related to the logon process. Authentication issues During the logon process, authentication happens at multiple stages; at minimum when a user logs on to the Web Interface and when the session-host server creates a session for launching the requested application. Citrix XenApp integrates with Active Directory. The authentication is therefore performed by a Domain Controller (DC) server of your domain. Slowness in the Domain Controller response, caused by an overloaded server, can slow down the entire process. Worse, if the Domain Controller is unavailable, a domain member server may try to connect for 30 seconds before timing out and choosing a different DC. Domain member servers choose the Domain Controller for authenticating users based on their membership to Active Directory Sites. If sites are not correctly configured or don't reflect the real topology of your network, a domain member server may decide to use a remote Domain Controller, through a slow WAN link, instead of using a Domain Controller on the same LAN. Profile issues Each user has a profile that is a collection of personal files and settings. Windows offers different types of profiles, with advantages and disadvantages as shown in the following table: Type Description Local The profile folder is local to each server. Roaming The profile folder is saved on a central storage (usually a file server). Mandatory A read-only profile is assigned to users; changes are not saved across sessions. From the administrator's point of view, mandatory profiles are the best option because they are simple to maintain, allow fast logon, and users can't modify Windows or application settings. This option however is not often feasible. I could use mandatory profiles only in specific cases, for example; when users have to run only a single application without the need to customize it. Local profiles are almost never used in a XenApp environment because even if they offer the fastest logon time, they are not consistent across servers and sessions. Furthermore, you'll end up with all your session-host servers storing local profiles for all your users, and that is a waste of disk space. Finally, if you're provisioning your servers with Provisioning Server, this option, if not applicable as local profiles. would be saved in the local cache, which is deleted every time the server reboots. System administrators usually choose roaming profiles for their users. Roaming profiles indeed allow consistency across servers and sessions and preserve user. Roaming profiles are, however, the most significant cause of slow logons. Without a continuous control, they can rapidly grow to a large size. A small profile with a large number of files, for example, a profile with many cookies, can cause delays too. Roaming profiles also suffer of the last write wins problem. In a distributed environment like a XenApp farm, it is not unlikely that users are connected to different servers at the same time. Profiles are updated when users log off, so with different sessions on different servers, some settings could be overwritten, or worse, the profile could be corrupted. Folder redirection To reduce the size of roaming profiles, you can redirect most of the user folders to a different location. Instead of saving files in the user's profile, you can configure Windows to save them on a file sharing system. The advantages of using folder redirection are: The data in the redirected folders is not included in the synchronization job of the roaming profile, making the user logon and logoff processes faster Using disk quotas and redirecting folders to different disks, you can limit how much space is taken up by single folders instead of the whole profile Windows Offline Files technology allows users to access their files even when no network connection is available You can redirect some folders (for example, the Start Menu) to a read-only share, giving all your users the same content Folder redirection is configured through group policies as shown in the following screenshot: Configuring Folder Redirection For each folder, you can choose to redirect it to a fixed location (useful if you want to provide the same content to all your users), to a subfolder (named as the username) under a fixed root path to the user's home directory, or to the local user profile location. You may also apply different redirections based on group membership and define advanced settings for the Documents folder. In my experience, folder redirection plays a key role in speeding up the logon process. You should enable it at least for the Desktop and My Documents folder if you're using roaming profiles. Background upload With Windows 2008 R2, Microsoft added the ability to perform periodic upload of the user's profile registry file (NTUSER.DAT) on the file share. Even if this option wasn't added to address the last write wins problem, it may help to avoid profile corruption and Microsoft recommends enabling it through a GPO as shown in the following screenshot: Enabling Background upload Citrix Profile Management Citrix developed its own solution for managing profiles, Citrix Profile Management. You're entitled to use Citrix Profile Management if you have an active Subscription Advantage for the following products: XenApp Enterprise and Platinum edition XenDesktop Advanced, Enterprise, and Platinum edition You need to install the software on each computer whose user profiles you want to manage. In a XenApp farm install it on your session-host servers. Features Citrix Profile Management was designed specifically to solve some of the problems Windows roaming profiles introduced. Its main features are: Support for multiple sessions, without the last write wins problem Ability to manage large profiles, without the need to perform a full sync when the user logs on Support for v1 (Windows XP/2003) and v2 (Windows Vista/Seven/2008) profiles Ability to define inclusion/exclusion lists Extended synchronization can include files and folders external to the profile to support legacy applications Configuring Citrix Profile Management is configured using Windows Group Policy. In the Profile Management package, downloadable from the Citrix website, you can find the administrative template (.admx) and its language file (.adml). Copy the ADMX file in C:WindowsPolicyDefintions and the ADML file in C:WindowsPolicyDefintionslang (for example, on English operating systems the lang folder is en-US). A new Profile Management folder in Citrix is then available in your GPOs as shown in the following screenshot: Profile Management's settings in Windows GPOs Profile Management settings are in the Computer section, therefore, link the GPO to the Organizational Unit (OU) that contains your session-host servers. Profiles priority order If you deployed Citrix Profile Management, it takes precedence over any other profile assignment method. The priority order on a XenApp server is the following: Citrix Profile Management Remote Desktop Services profile assigned by a GPO Remote Desktop Services profile assigned by a user property Roaming profile assigned by a GPO Roaming profile assigned by a user property Troubleshooting Citrix Profile Management includes a logging functionality, you can enable via GPO as shown in the following screenshot: Enabling the logging functionality With the Log settings setting, you can also enable verbose logging for specific events or actions. Logs are usually saved in %SystemRoot%System32LogfilesUserProfileManager but you can change the path with the Path to log file property. Profile Management's logs are also useful to troubleshoot slow logons. Each step is logged with a timestamp so analyzing those logs you can find which steps last for a long time. GPO and logon script issues In a Windows environment, it's common to apply settings and customizations via Group Policy Objects (GPOs) or using logon scripts. Numerous GPOs and long-running scripts can significantly impact the speed of the logon process. It's sometimes hard to find which GPOs or scripts are causing delays. A suggestion is to move the XenApp server or a test user account in a new Organizational Unit, with no policies applied and blocked inheritance. Comparing the logon time in this scenario with the normal logon time can help you understand how GPOs and scripts affect the logon process. The following are some of the best practices when working with GPOs and logon scripts: Reduce the number of GPOs by merging them when possible. The time Windows takes to apply 10 GPOs is much more than the time to apply a single GPO including all their settings. Disable unused GPOs sections. It's common to have GPOs with only computer or user settings. Explicitly disabling the unused sections can speed up the time required to apply the GPOs. Use GPOs instead of logon scripts. Windows 2008 introduced Group Policy Preferences, which can be used to perform common tasks (map network drives, change registry keys, and so on) previously performed by logon scripts. The following screenshot displays configuring drive maps through GPOs. Configuring drive maps through GPO Session pre-launch, sharing, and lingering Setting up a session is the most time-consuming task Citrix and Windows have to perform when a user requests an application. In the latest version of XenApp, Citrix added some features to anticipate the session setup (pre-launch) and to improve the sharing of the same session between different applications (lingering). Session pre-launch Session pre-launch is a new feature of XenApp 6.5. Instead of waiting for the user to launch an application, you can configure XenApp to set up a session as soon as the user logs on to the farm. At the moment, session pre-launch works only if the user logs on using the Receiver, not through the Web Interface. This means that when the user requests an application, a session is already loaded and all the steps of the logon process you've learned have already taken place. The application can start without any delay. From my experience, this is a feature much appreciated by users and I use it in the production farms. Please note that if you enable session pre-launch, a license is consumed at the time the user logs on. Configuring A session pre-launch is based on a published application on your farm. A common mistake is thinking that when you configure a pre-launch application, Citrix effectively launches that application when the user logs on. The application is actually used as a template for the session. Citrix uses some of its settings, like users, servers/worker groups, color depth, and so on. To create a pre-launch session, right-click on the application and choose Other Tasks | Create pre-launch application as shown in the following screenshot: Creating pre-launch application To avoid confusion, I suggest renaming the configured pre-launch session removing the actual application name, for example, you can name it Pre-launch WGProd. A pre-launched session can be used to run applications that have the same settings of the application you chose when you created the session. For example, it can be used by applications that run on the same servers. If you published different groups of applications, usually assigned to different worker groups, you should create pre-launch sessions choosing one application for each group to be sure that all your users' benefit from this feature. Life cycle of a session If you configured a pre-launch session, when the Receiver passes the user credentials to the XenApp server a new session is created. The server that will host the session is chosen in the usual way by the Data Collector. In Citrix AppCenter, you can identify pre-launched sessions from the value in the Application State column as shown in the following screenshot: Pre-launched session Using Citrix policies, you can set the maximum time a pre-launch session is kept: Pre-launch Disconnect Timer Interval, is the time after which the pre-launch session is put in disconnected state Pre-launch Terminate Timer Interval, is the time after which the pre-launch session is terminated Session sharing Session sharing occurs when a user has an open session on a server and launches an application that is published on the same server. The launch time for the second application is quicker because Citrix doesn't need to set up a new session for it. Session sharing is enabled by default if you publish your applications in seamless window mode. In this mode, applications appear in their own windows without containing an ICA session window. They seem physically installed on the client. Session sharing fails if applications are published with different settings (for example, color depth, encryption, and so on). Make sure to publish your applications using the same settings if possible. Session sharing takes precedence over load balancing; the only exception is if the server reports full load. You can force XenApp to override the load check and to also use fully loaded servers for session sharing. Refer to CTX126839 for the requested registry changes. This is, however, not a recommended configuration; a fully loaded server can lead to poor performance. Session lingering If a user closes all the applications running in a session, the session is ended too. Sometimes it would be useful to keep the session open to speed up the start of new applications. With XenApp 6.5 you can configure a lingering time. XenApp waits before closing a session even if all the running applications are closed. Configuring With Citrix user policies, you can configure two timers for session lingering: Linger Disconnect Timer Interval, is the time after which a session without applications is put in disconnected state LingerTerminate Timer Interval, is the time after which a session without applications is terminated If you're running an older version of XenApp, you can keep a session open even if users close all the running applications with the KeepMeLoggedIn tool; refer to CTX128579. Summary The optimization of the logon process can greatly improve the user experience. With EdgeSight and Windows Performance Toolkit you can perform a deep analysis and detect any causes of delay. If you can't use those tools, you are still able to implement some guidelines and best practices that will surely make users' logon faster. Setting up a session is a time-consuming task. With XenApp 6.5, Citrix implemented some new features to improve session management. With session pre-launch and session lingering you can maximize the reuse of existing sessions when users request an application, speeding up its launch time. Resources for Article: Further resources on this subject: Managing Citrix Policies [Article] Getting Started with XenApp 6 [Article] Getting Started with the Citrix Access Gateway Product Family [Article]
Read more
  • 0
  • 0
  • 6369

article-image-auditing-and-e-discovery
Packt
01 Feb 2016
17 min read
Save for later

Auditing and E-discovery

Packt
01 Feb 2016
17 min read
In this article by Biswanath Banerjee, the author of the book Microsoft Exchange Server PowerShell Essentials, we are going to discuss about the new features in Exchange 2013 and 2016 release that will help organizations meet their compliance and E-discovery requirements. Let's learn about the Auditing and E-discovery features available in Exchange 2013 and online. (For more resources related to this topic, see here.) The following topics will be covered in this Article:- New features in Exchange 2016 The In-place hold Retrieving and exporting emails for Auditing Retrieving content using KQL queries Searching and removing emails from the server Enabling Auditing and understanding its usage Writing a basic script Now, let's review different features in Exchange 2013 and 2016 that can be used by organizations to meet their compliance requirements: The In-place hold: In Exchange 2010, when a mailbox is enabled for a feature called the Litigation hold, all mailbox data will be stored until the hold is removed. With Exchange 2013 and 2016 release, the In-place hold allows the Administrators granularity compared to the Litigation hold feature in Exchange 2010. Now, administrators can choose what to hold and for how long the hold to work. In Place E-Discovery: In Exchange 2010, when you run a discovery search, it will copy the items matching the searched criteria into a discovery mailbox from which you can export it to a PST file or provide access to a group of people. In Exchange, when you run the discovery search, you can see the results live from your search. You will also get an option to create a saved search to be used later with minor modifications if required. Audit logs: In Exchange 2013 and 2016, you can enable two types of audit logging: Administrator audit logs: Administrator audit logs will record any action performed by the administrator using tools such as Exchange Admin Center and Exchange management shell Mailbox Audit logs: Mailbox audit logs can be enabled for individual mailboxes and will store the log entries in their Recoverable items audits subfolder The In-Place hold The Exchange 2013 and 2016 release allows admins to create granular hold policies by allowing them to preserve items in the mailbox using the following scenarios: Indefinite hold: This feature is called Litigation hold in Exchange 2010, and it allows mailbox items to be stored indefinitely. The items in this case are never deleted. It can be used where a group of users are working on some highly sensitive content that might need a review later. The following example sets the mailbox for Amy Alberts on the Litigation hold (in Exchange 2010) for indefinite hold: Set-Mailbox -Identity amya -LitigationHoldEnabled $True In Exchange 2013 and 2016, you will need to use the New-MailboxSearch cmdlet without any parameters as shown next to get the same results: New-MailboxSearch "Amy mailbox hold" -SourceMailboxes "amya@contoso.com" -InPlaceHoldEnabled $True The same can be achieved using the In-place E-discovery and hold wizard in Exchange Admin Center as shown in the following screenshot:  The Query-based hold: Using this, you can specify keywords, date, message types, and recipient addresses, and only the one's specified in the query will be stored. This is useful if you don't want to enable all your mailboxes for indefinite hold. The Time-based hold: This will allow admins to hold items during a specific period. The duration is calculated from the date and time the item is received or created. The following example creates a Query-based and Time-based In-place hold for all the mailboxes that are part of the distribution group Group-Finance and hold every e-mail, meeting, or IM that contains the keywords Merger and Acquisition for 2 years: New-MailboxSearch "Acquisition-Merger" -SourceMailboxes Group-Finance -InPlaceHoldEnabled $True –ItemHoldPeriod 730 -SearchQuery '"Merger" and "Acquisition"' –MessageTypes Ema il,Meetings,IM The Recoverable items folder in each mailbox is used to store items using litigation and In-place hold. The subfolders used to store items are Deletions, Purges, Discovery holds, and versions. The versions folder is used to make a copy of the items before making changes using a process called as copy-on-write. This ensures that the original as well as modified copies of the items are stored in the versions folder. All these items are indexed by Exchange search and returned by the In-Place discovery search. The Recoverable items folder has its own storage quota, and it's different for Exchange 2013/2016 and Exchange online. For Exchange 2013 and 2016 deployments, the default value of RecoverableItemsWarningQuota and RecoverableItemsQuota are set to 20 GB and 30 GB respectively. These properties can be managed using the Set-MailboxDatabase and Set-Mailbox cmdlets. It is critical for administrators to monitor your quota messages logged in the Application event logs as users will not be able to permanently delete items, nor they will be able to empty the deleted items folder if the Recoverable Items Quota is reached. The copy-on-write feature will not work for obvious reasons. For the Exchange online, if a mailbox is placed on litigation hold, the size of the Recoverable items folder is set to 100 GB. If email forwarding is enabled for mailboxes, which are on hold and a message is forwarded without a copy to the original mailbox, Exchange 2013 will not capture that message. However, if the mailbox is on Exchange 2016 or Exchange online, and the message that is forwarded meets the hold criteria for the mailbox, a copy of the message will be saved in the Recoverable items folder and can be searched using the E-Discovery search later on. Retrieving and exporting Emails for Auditing using In-Place E-discovery Now, we have seen how to place mailboxes on hold. In this topic, you will learn how to search and retrieve mailbox items using the E-discovery search in Exchange 2013, 2016 and Exchange online. The In-place eDiscovery and hold wizard in Exchange Admin Center allows authorized users to search the content based on sender, recipient, keywords, start, and end dates. The administrators can then take the actions such as estimating, previewing, copying, and exporting search results. The following screenshot shows an example of a search result: Search starting Exchange 2013 uses Microsoft Search Foundation with better indexing and querying functionalities and performances. As the same search foundation is used with SharePoint and other office products, the e-discovery search can now be performed from both Exchange and SharePoint environments with the same results. The query language used by In-Place eDiscovery is Keyword Query Language (KQL), which you will learn in the next section. The following figure shows how to use the search query using KQL syntax and time range fields: You can also specify the message types to be returned in the search results as shown in the following screenshot: Once you have estimated the search items, you can then preview and export the items to a PST file or a discovery mailbox as shown in the following screenshot: Let's see how to use the same query in PowerShell using New-MailboxSearch cmdlet. Here, -SourceMailboxes will define mailboxes to be searched between 1st January 2014 to 31st December 2014 using the -StartDate and -EndDate parameters. The -SearchQuery parameter is used for KQL (Keyword Query Language) with words such as merger or acquisition. The results will be copied to the Legal-Mergers discovery mailbox specified using the -TargetMailbox parameter. Finally, status reports are sent to the group called legal@contoso.com when the search is completed and specified using the -StatusMailRecipient parameter: New-MailboxSearch "Acquisition-Merger" -SourceMailboxes bobk@contoso.com,susanb@contoso.com -SearchQuery '"Merger" OR "Acquisition"' -TargetMailbox Legal-Mergers -StartDate "01/01/2014" -EndDate "12/31/2014" -StatusMailRecipients legal@contoso.com Retrieving content using the KQL queries KQL consists of free text keywords including words, phrases, and property restrictions. The KQL queries are case-insensitive, but the operators are not and have to be specified in uppercase. A free text expression in a KQL query can be a word without any spaces or punctuation or a phrase enclosed in double quotation marks. The following examples will return the content that have the words Merger and Acquisition: merger acquisition merge* acquisition acquistion merg* It is important to note that KQL queries do not support suffix matching. It means you cannot use a wildcard (*) operator before a word or phrase in a KQL query. We can use Property restrictions in a KQL query in the following format. There should not be any space between the Property name, the Property operator, and the Property value: <Property Name><Property Operator><Property Value> For example, author "John Doe" will return content whose author is John Doe; filetype:xlsx will return Excel spreadsheets; and title:"KQL Query" will return results with the content KQL query in the title: You can combine these property restrictions to build complex KQL queries. For example, the following query will return the content authored by John Doe or Jane Doe. It can be used in the following formats. Both the formats will return the same results: author:"John Doe" author:"Jane Doe" author:"John Doe" OR author:"Jane Doe" If you want to search for all the word documents authored by Jane Doe, you will use either of the formats: author:"Jane Doe" filetype:docx author:"Jane Doe" AND filetype:docx Now let's take a look at the use of the Proximity operators called NEAR and ONEAR, which are used the search items in close proximity to each other. The NEAR operator matches the results where the search terms are in close proximity without preserving the order of the terms: <expression> NEAR(n=5) <expression> Here, n >= 0 with a default value of 8 indicates the maximum distance used between the terms; for example, merger NEAR acquistion. This will return results where the word merger is followed by acquisition and vice versa by up to eight other words. If you want to find content where the term acquisition is followed by the term merger for up to five terms but not the other way round, use the ONEAR operator that maintains the order of the terms specified in the query. The syntax is the same as the NEAR operator with a default value of n = 8: "acquisition" ONEAR(n=5) "merger" Searching and removing emails from the server There will be times when you as an Exchange administrator would get request to log or delete specific items from the user's mailboxes. The Search-Mailbox cmdlet helps you to search a mailbox or a group of mailboxes for a specific item, and it also allows you to delete them. You need to be part of the Mailbox Search and Mailbox Import Export RBAC roles to be able to search and delete messages from a user's mailbox. The following example searches John Doe's mailbox for emails with subject "Credit Card Statement" and logs the result in the Mailbox Search Log folder in the administrator's mailbox: Search-Mailbox -Identity "John Doe" -SearchQuery 'Subject:"Credit Card statement"' -TargetMailbox administrator -TargetFolder "MailboxSearchLog" -LogOnly -LogLevel Full The following example searches all mailboxes for attachments that have word "Virus" as the file name and logs it in Mail box Search log in the administrator's mailbox: Get-Mailbox -ResultSize unlimited | Search-Mailbox -SearchQuery attachment:virus* -TargetMailbox administrator -TargetFolder "MailboxSearchLog" -LogOnly -LogLevel Full You can use the search mailbox to delete content as well. For example, the following cmdlet will delete all emails with subject line "Test Email" from Amy Albert's mailbox: Search-Mailbox -Identity "Amy Albert" -SearchQuery 'Subject:"Test Email"' -DeleteContent If you want to keep a backup of Amy Albert's mailbox content to a "BackupMailbox" before permanently deleting them, use the following command: Search-Mailbox -Identity "Amy Albert" -SearchQuery 'Subject:"Test Email"' -TargetMailbox "BackupMailbox" -TargetFolder "amya-DeletedMessages" -LogLevel Full -DeleteContent Enable Auditing and understanding its usage We will discuss about the following two types of audit logs available in Exchange 2013: Administrator audit logs Mailbox audit logs Administrator audit logs Administrator audit logs are used to log when a cmdlet is executed from Exchange Management Shell or Exchange Admin Center except the cmdlets that are used to display information such as the Get-* and Search-* cmdlets. By default, Administrator audit log is enabled for new Exchange 2013/2016 installations. The following command will audit all cmdlets. Note that this is the default behavior. So, if this is a new installation of Exchange 2013 and 2016, you don't have to make any changes. You have to only run this if you have made some changes using the Set-AdminAuditLogConfig cmdlet earlier: Set-AdminAuditLogConfig -AdminAuditLogCmdlets * Now, let's say you have a group of delegated administrators managing your Exchange environment, and you want to ensure that all the management tasks are logged. For example, you want to audit cmdlets that make changes to the mailbox, distribution groups, and management roles. You will type the following cmdlet: Set-AdminAuditLogConfig -AdminAuditLogCmdlets *Mailbox,*Management*,*DistributionGroup* The previous command will audit the cmdlets along with the specified parameters. You can take this a step further by specifying which parameters you want to monitor. For example, you are trying to understand why there is an unequal distribution of mailboxes in your databases and incorrect entries in the Custom Attribute properties for your user mailboxes. You will run the following command that will only monitor these two properties: Set-AdminAuditLogConfig -AdminAuditLogParameters Database,Custom* By default, 90 days is the age of the audit logs and can be changed using the -AdminAuditLogAgeLimit parameter. The following command sets the audit login age to 2 years: Set-AdminAuditLogConfig -AdminAuditLogAgeLimit 730.00:00:00 By default, the cmdlet with a Test verb is not logged as it generates lot of data. But, if you are troubleshooting an issue and want to keep a record of it for a later review, you can enable them using this: Set-AdminAuditLogConfig -TestCmdletLoggingEnabled $True Disabling and enabling to view the admin audit log settings can be done using the following commands: Set-AdminAuditLogConfig -AdminAuditLogEnabled $False Set-AdminAuditLogConfig -AdminAuditLogEnabled $True Get-AdminAuditLogConfig Once Auditing is enabled, you can search the audit logs using the Search-AdminAuditLog and New-AdminAuditLogsearch cmdlets. The following example will search the logs for the Set-Mailbox cmdlets with the following parameters from 1st January 2014 to 1st December 2014 for users—Holly Holt, Susan Burk, and John Doe: Search-AdminAuditLog -Cmdlets Set-Mailbox -Parameters ProhibitSendQuota,ProhibitSendReceiveQuota,IssueWarningQuota -StartDate 01/01/2014 -EndDate 12/01/2014 -UserIds hollyh,susanb,johnd This command will search for any changes made for Amy Albert's mailbox configuration from 1st July to 1st October 2015: Search-AdminAuditLog -StartDate 07/01/2015 -EndDate 10/01/2015 -ObjectID contoso.com/Users/amya This cmdlet is similar to the previous cmdlet with one difference that it uses the parameter called -StatusMailRecipients to send email with the subject line a called "Mailbox Properties Changes" to amya@contoso.com: New-AdminAuditLogSearch -Cmdlets Set-Mailbox -Parameters ProhibitSendQuota, ProhibitSendReceiveQuota, IssueWarningQuota, MaxSendSize, MaxReceiveSize -StartDate 08/01/2015 -EndDate 10/01/2015 -UserIds hollyh,susanb,johnd -StatusMailRecipients amya@contoso.com -Name "Mailbox Properties changes" Mailbox audit logs Mailbox audit logging feature in Exchange 2013 and 2016 allows you to log mailbox access by owners, delegates, and administrators. They are stored in Recoverable Items in the Audits subfolder. By default, the logs are retained for up to 90 days. You need to use Set-Mailbox with the AuditLogAgeLimit parameter to increase the retention period of the audit logs. The following command will enable mailbox audit logging for John Doe's mailbox, and the logs will be retained for 6 months: Set-Mailbox -Identity "John Doe" -AuditEnabled $true -AuditLogAgeLimit 180.00:00:00 The command disables audit logging for Holly Holt's mailbox: Set-Mailbox -Identity "Holly Holt" -AuditEnabled $false If you just want to log the SendAs and SendOnBehalf actions on Susan Burk's mailbox, type this: Set-Mailbox -Identity "Susan Burk" -AuditDelegate SendAs,SendOnBehalf -AuditEnabled $true The following command logs the Hard Delete action by the Mailbox owner for Amy Albert's mailbox: Set-Mailbox -Identity "Amy Albert" -AuditOwner HardDelete -AuditEnabled $true Now that we have enabled auditing, let's see how to search audit logs for the mailboxes using the Search-MailboxAuditLog cmdlet. The following example searches the audit logs for mailboxes of John Doe, Amy Albert, and Holly Holt for the actions performed by logon types called Admin and Delegate from 1st September to 1st October 2015. A maximum of 2000 results will be displayed as specified by the Result size parameter: Search-MailboxAuditLog -Mailboxes johnd,amya,hollyh -LogonTypes Admin,Delegate -StartDate 9/1/2015 -EndDate 10/1/2015 -ResultSize 2000 You can use pipelines and search the operation of Hard Delete in this example with the Where-Object cmdlet in Susan Burk's mailbox from 1st September to 17th September 2015: Search-MailboxAuditLog -Identity susanb -LogonTypes Owner -ShowDetails -StartDate 9/1/2015 -EndDate 9/17/2015 | Where-Object {$_.Operation -eq "HardDelete"} Once you have enabled the mailbox audit logging, you can also use Exchange Admin Center by navigating to compliance management, auditing tab and Run a non-owner mailbox access report.... The following screenshot shows the search criteria that you can use to search the mailboxes accessed by non-owners: Writing a basic script The Recoverable Items folder has its own storage quota and has Deletions, Versions, Purges, Audits, Discovery Holds, and Calendar Logging as subfolders. This script will loop through the mailboxes and export the size of these subfolders to a CSV file. The $Output is an empty array used later to store the output of the script. The $Mbx array stores the list of mailboxes. We then use Foreach to loop through the mailboxes in $Mbx. Note the usage of two if-else statements for the Audits and Discovery Holds section in the script, which are present to ensure that we don't get errors if the user is not enabled for Mailbox Auditing and In-Place holds respectively. We have created a new object to create a new instance of a PowerShell object and used the Add-Member cmdlet custom Properties to that object and store it in the $report variable for each mailbox in the list. The results are then added to the $Output array defined earlier. Finally, Export-CSV is used to export the output to the Recoverable Items subfolder called size.csv in the current working directory: $Output = @() Write-Host "Retrieving the List of mailboxes" $mbx = @(Get-Mailbox -Resultsize Unlimited) foreach ($Mailbox in $mbx) {     $Name = $Mailbox.Name     Write-Host "Checking $Name Mailbox"       $AuditsFoldersize = ($mailbox | Get-MailboxFolderStatistics -FolderScope RecoverableItems | Where {$_.Name -eq "Audits"}).FolderSize     if ($AuditsFolderSize -ne $Null) {$AuditsFoldersize} else {$AuditsFoldersize = 0}     $DiscoveryHoldsFoldersize = ($mailbox | Get-MailboxFolderStatistics -FolderScope RecoverableItems | Where {$_.Name -eq "DiscoveryHolds"}).FolderSize     if ($DiscoveryHoldsFoldersize -ne $Null) {$DiscoveryHoldsFoldersize} else {$DiscoveryHoldsFoldersize = 0}     $PurgesFoldersize = ($mailbox | Get-MailboxFolderStatistics -FolderScope RecoverableItems | Where {$_.Name -eq "Purges"}).FolderSize     $VersionsFoldersize = ($mailbox | Get-MailboxFolderStatistics -FolderScope RecoverableItems | Where {$_.Name -eq "Versions"}).FolderSize     $report = New-Object PSObject     $report | Add-Member NoteProperty -Name "Name" -Value $Name     $report | Add-Member NoteProperty -Name "Audits Sub Folder Size" -Value $AuditsFoldersize     $report | Add-Member NoteProperty -Name "Deletions Sub Folder Size" -Value $DeletionsFoldersize     $report | Add-Member NoteProperty -Name "DiscoveryHolds Sub Folder Size" -Value $DiscoveryHoldsFoldersize     $report | Add-Member NoteProperty -Name "Purges Sub Folder Size" -Value $PurgesFoldersize     $report | Add-Member NoteProperty -Name "Versions Sub Folder Size" -Value $VersionsFoldersize     $Output += $report     Write-Host "$Name, $AuditsFoldersize, $DeletionsFoldersize, $DiscoveryHoldsFoldersize, $PurgesFoldersize, $VersionsFoldersize" }   Write-Host "Writing output to RecoverableItemssubfolderssize.csv"   $Output | Export-CSV RecoverableItemssubfolderssize.csv -NoTypeInformation Summary In this Article, you learned the use of various types of In-place holds and eDiscovery search. You also learned how they can help organizations meet their regulatory compliance requirements. You learned how to log admin actions and mailbox access by the Administrator audit and the mailbox logging functionality in the Exchange server 2013/2016 and Exchange online. The tools and cmdlets explained in this Article will help organizations retain content that is important for them and search and send it to appropriate parties at a later date for a review. Resources for Article:   Further resources on this subject: Exchange Server 2010 Windows PowerShell: Managing Mailboxes [article] Exchange Server 2010 Windows PowerShell: Working with Distribution Groups [article] Installing Microsoft Forefront UAG [article]
Read more
  • 0
  • 0
  • 6367

article-image-retopology-3ds-max
Packt
06 Nov 2012
6 min read
Save for later

Retopology in 3ds Max

Packt
06 Nov 2012
6 min read
(For more resources related to this topic, see here.) High poly model import Different applications are biased to different file formats and may therefore have different import procedures. The Send To functionality between 3ds Mudbox and 3ds Max(which is possible as both are Autodesk products).This is essentially a .fbx transfer. If you are using ZBrush, you will want to get used to the GoZequivalent transfer feature. Note that GoZ must be run from ZBrush to 3ds Max before it can go in the other direction. GoZ also works the free, mini-modeler tool from Pixologic(who make ZBrush too)called Sculptris, which is available at http://www.pixologic.com/sculptris/. In the following example, we'll directly export from Sculptris, a model made from a sphere(so it needs retopology to get a clean base mesh). We'll export it as a .obj and import it to 3ds Max in order to show a few of the idiosyncrasies of this situation. With a model that is sculpted from a primitive base, such as a sphere or box, there are no meaningful texture coordinates, so it would be impossible to paint the model. Although many sculpting programs, including Sculptris, do automapping, the results are seldom optimal. Importing a model into Sculptris The following steps detail the instructions on importing a model into Sculptris: Install Sculptris 6 Alpha and run it. Note that the default scene is a sphere made of triangle faces that dynamically subdivide where you paint. Use the brush tools to experiment with this a while. Click on Open and browse the provided content for this article, and open Packt3dsMaxChapter 9Creature.sc1. The file format .sc1 is native to Sculptris. To get this model to work in 3ds Max, you will need to choose Export and save it instead as Sculptris.obj. Importing the Sculptris.OBJ mesh in 3ds Max After we have imported a model into Sculptris, we'll move on to see how we can save this file into 3ds Max. The importing part is fairly easy. In 3ds Max, choose File | Import and browse to Sculptris.obj, the mesh you just exported from Sculptris. You could also try the example .obj called Packt3dsMaxChapter 9RetopoBullStart.obj. The import options you set matter a lot. You will need to make sure that the options Import as single mesh and Import as Editable Poly are on. This makes sure that the symmetrical object employed in the Sculptris scene (actually a separate mesh that conforms to the model) doesn't prevent the import. While importing, you should also swap the Normals radio button from the From SM group to Auto Smooth, to avoid the triangulated mesh looking faceted. A model begun in Sculptris won't contain any smoothing information when sent to 3ds Max and will come in faceted if you don't choose Auto Smooth. After importing, another way to do the same thing is to apply a Smooth modifier. The Auto Smooth value should be 90 or so, to reduce the likelihood of any sharp creases. Finally, once the model is imported into the 3ds Max scene, move it in the Z plane so it is standing on the ground plane, and make sure its pivot is at 0,0,0. This can be done by choosing Edit | Transform Toolbox and clicking on Origin in the Pivot section. Note that the model's edges are all tiny triangles. This is a result of the way Sculptris adds detail to a model. Retopology will help us get a quad-based model to continue working from. The idea of retopology is to build up a new, nicely constructed model on top of the high-resolution model. The high-resolution model serves as a guide surface. If you are curious, apply an Unwrap UVW modifier to the model and see how its UV mapping looks. Probably a bit scary. A high-resolution model such as this one (250K polys) is virtually impossible to manually UV map,at least not quickly. So we need to simplify the model. If you can't see the Ribbon, go to Customize | Show UI | Show Ribbon, or press the icon in the main toolbar. Then click on the Freeform tab. With the creature mesh selected, click on Grid in the Freeform tab. This specifies the source to which we'll conform the new mesh that we're going to generate next. We don't want to conform to the grid, so change this to Draw On: Surface and then assign the source mesh using the Pick button below the Surface button, shown in the following screenshot: Each time you relaunch 3ds Max to keep working on the retopology, you'll have to reassign the high-resolution mesh as the source surface in the same way. You could also use Draw On: Selection, which would be handy if the source was, in fact, a bunch of different meshes. There is an Offset value you can adjust so that the mesh you'll generate next will sit slightly above the source mesh that can help reduce frustration from the lower-resolution mesh, which is likely to sink in places within the more curvy, high-resolution mesh. If you're just starting out, try leaving the setting alone and see how it turns out. An additional way to help see what you are doing is to apply a semitransparent material or low Visibility value to the high-resolution model (or press Alt + X while it is selected). Next, in a nested part of the Ribbon, we have to set a new object or model to work on (that doesn't exist yet). Click on the PolyDraw rollout at the bottom of the Freeform tab. Having expanded PolyDraw, click on the New Object button and we're ready to start retopologizing. I would strongly suggest raising the Min Distance value in the PolyDraw section, so when you create the first polygons they aren't too small. When using the Strips brush, usually I set the Min Distance to around 25-35, but it depends on the model scale and the level of detail you want. Just like with modeling, when you retopologize, it is best to move from large forms to small details. The object will be called something like Box001, an Editable Poly beginning in the Vertex mode. You can rename it to Retopo or something more memorable. Turn on the Strips mode and make sure Edged Faces is toggled on (F4) so you can see the high-resolution model's center line. Starting at the head, draw a strip of polygons along the symmetry line so that there's an edge on either side. As this model is symmetrical, we only have to work on half of it. If you hold the mouse over the Strips mode icon , you'll get a tool tip that explains how Strips are made, and if you press Y, you can watch a video demo albeit drawing on the Grid. Note that the size of the polygons, as you draw, is determined by the Min Distance value under PolyDraw. Bear in mind that apart from the Min Distance value, the size of the polygons drawn also depends on the current viewport zoom. This is handy because when working on tighter detail, you'll tend to zoom in closer to the source mesh.
Read more
  • 0
  • 0
  • 6363

article-image-backbase-4-ria-development-hello-backbase-four-variations
Packt
28 Dec 2009
11 min read
Save for later

Backbase 4 RIA Development: Hello Backbase in four variations

Packt
28 Dec 2009
11 min read
The Backbase page skeleton There is one more thing we would like to take care of before we really start. It will save a lot of useless book space if we can explain what a typical starter page for the Backbase framework looks like and then forget about it. Of course, the examples that are supplied with this book are all ready to execute and therefore this source code will repeat the skeleton page code where required. For any Backbase enabled page, you need an HTML file, usually named index.html, which looks like this: <!-- --><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html > <head> <meta http-equiv="Content-Type" content="text/xhtml; charset=UTF-8" /> <title>The Title of your Application</title> <script type="text/javascript" src="../../backbase/4_3_1/engine/boot.js" > </script> </head> <body> <script type="application/backbase+xml"> <xi:include href="../../backbase/4_4_1/bindings/config.xml"> </xi:include> <!-- YOUR APPLICATION CODE GOES HERE --> </script> </body></html> The version number of the Backbase Client Framework release is specified in the [version] folder name (for example, 4_4_1). If your version of the Backbase Client Framework is different from the one shown here, you must adapt the code samples accordingly. There are some interesting points: If you are including third-party libraries or your own JavaScript libraries, you should include them in the head section of the HTML document, as usual. At the place where it says: <!-- YOUR APPLICATION CODE GOES HERE -->, you can put your application code. We will call this a Backbase area. The code that you can put here can be ordinary XHTML, widgets that are provided by Backbase, or widgets that you have built yourself. The <!-- YOUR APPLICATION CODE GOES HERE --> part is contained within script tags with type="application/backbase+xml". The type attribute signals the Client Runtime that it should process the contents. The xml part of the type attribute says that the contents should be proper XML. There can be multiple Backbase area's areas. In fact, there can be as many areas as you like. This is convenient if you are converting an older web application to a Backbase application or when you have large chunks of conventional HTML in your application. As the Backbase framework takes some overhead to process this HTML, there is a performance advantage to put code that does not require processing by the Client Runtime outside a Backbase area. The code in a Backbase must adhere to XHTML standards and most importantly, all tags must be properly closed. This can be a source of errors if you are converting an older application where for example <input> and <img> tags are often not closed. Another XHTML violation to watch out for is that attribute values in tags must be enclosed in quotes and all attributes specified must have a value. For example, you should code selected="selected" instead of just selected in a select box. The Backbase JavaScript engine in boot.js is loaded in the header of the HTML page. It is very important to make sure that you have a proper path specification here. Many times, when you set up a new application, you get an empty page at your first try to see your application. The cause is almost always that your path specification is wrong. If this happens to you, it is convenient to use a tool like Firebug to see what the server returns and why it cannot find the Backbase libraries. To use the Backbase widgets, you must include the configuration files, also called implementation bindings for the tags: <xi:include href="../../backbase/4_4_1/bindings/config.xml"></xi:include> The config.xml file contains an additional include for the specific skin you want to use. The default is the chameleon skin . As an alternative, you can use the system skin. Similar to the earlier point, your path specification must be correct; otherwise your page will most likely stay empty. The inclusion of the configuration files is done with the statement: xi:include. We make use here of XInclude, or XML Inclusions, which is a W3C standard for merging XML files. This facility makes it possible to code your web pages in a more modular way by dividing your code in smaller chunks, which can be combined at runtime. See http://www.w3.org/TR/xinclude/ for details. Backbase has implemented the XInclude standard in its framework according to the standard and you see it used here to include the configuration files. We will see more of it later in this article. The HTML tag contains two namespace declarations— target="_blank">>From now on, we will usually take for granted that you know how to surround our example code with the right skeleton code. "Hello Backbase" in four variations In the previous section,we showed what a Backbase starter page looks like. So finally, we can show real Backbase code. It is time to say "Hello Backbase!" We will do so by showing typical "Hello World" examples as follows: The first example shows a simple alert when you click on the Click me text. It serves to make sure that we have the right setup for our applications. The second and third examples are a bit more interesting: a balloon from the Backbase Tag Library is shown, with the text that you typed in an input field. The difference between the two is the use of JavaScript or the XML Execution Language, as you will see. The fourth example is an AJAX example. It involves communication with a server, which echoes the text typed in, together with a timestamp. The response is added to earlier responses without refreshing the page. Directly Download the example code for the article. The downloadable files contain instructions on how to use them. We assume that you have a web development environment set up now and that you have put the Backbase libraries at the right place. We will take a follow-along approach for explaining the "Hello World!" examples, but of course you can also just execute the ready-to-run downloaded source code instead of typing the code yourself. Start with creating a new folder named bookApps, or whatever name you like better. Next, create a subfolder of the bookApps folder named helloWorld. Verifying the installation of the Backbase framework Create an HTML file named hello1.html and put this file in the helloWorld folder. Copy the skeleton file that we saw in the previous section into hello1.html. Remember the following: In this file, we made sure that the Backbase Framework Client Runtime will be loaded because of the <script> tag in the head section of the HTML document. The <script> tag in the body section of the HTML document has a type declaration, application/backbase+xml, which tells the client runtime to process whatever is contained within the tag. The first thing that the client runtime is asked to process is the inclusion of the config.xml file, which contains the bindings that define the UI widgets. The position where <!-- YOUR APPLICATION CODE GOES HERE --> is placed tells the runtime that it should process whatever we replace this with. Namespace declarations are needed for all the namespaces used, in the tag where they are used, or a parent tag within the document. Replace <!-- YOUR APPLICATION CODE GOES HERE --> with the following content: <div> <e:handler event="click" type="text/javascript"> alert('Backbase says hello!'); </e:handler> Click me </div> To see your first "Hello" example in action, you can either double-click on hello1.html in the Windows explorer (if you are running Windows), or, if you have started your local server, you can open a browser and type something like this in the address bar: http://localhost/bookApps/helloWorld/hello1.html. After clicking on the Click me text, you should see a result that is similar to what is shown in the following picture: What if you do not see anything? The most common problem that could be the cause is that the path to boot.js or config.xml is not correct. If you are running with a server, check that it is running properly, and that it can find your hello1.html. When all is well: Congratulations! The Backbase Client Framework is running successfully. Let us look at the code: The interesting part of the code is the event handler for the div element that contains the Click me text. The e:handler tag is part of the XML Execution Language (XEL), a custom markup language that is provided with the Backbase Client Framework, and that can be used as a replacement for JavaScript in many cases. The namespace that we need for using XEL is declared in the e:handler tag itself; it could also have been declared in the <div> or <html> tags. Between the start and end e:handler tags, you can code either JavaScript, as in this example, or XEL, as we will see in the next "Hello World!" example. You could have coded the example also as "Hello World" without the Backbase event handler: <div onclick="alert('Backbase says hello!');"> Click me! </div>. At first sight, this is shorter, so why would we need Backbase for this? Well, usually, you need more in the event handler than just a short alert. In such case, you have two choices: either clutter your page with hard to read JavaScript or create a JavaScript function that you put in the head section. Before you know it, you will have many of these functions, which become hard to maintain and organize. In the case of the XEL event handler, you can write well-formatted and well-structured JavaScript code that stays local to the widget where you put the event handler. Of course, you can define more global functionality as well and you will see examples of this also. XML namespaces! In this first example, you saw again a new XML namespace, this time for XEL. We already saw the XHTML and the XInclude namespace declaration in the page skeleton; in the next section you will see the Backbase Tag Library, the Commands, and the Forms namespace. Yes, that is a lot of namespaces. We promise that you will find out how useful these are and that you will get used to it. This was a very simple example that made sure the Backbase framework is working right. In the next three examples, we will expand your knowledge by demonstrating a personalized "Hello World", using a tag from the Backbase Tag Library. The last "Hello World" example will demonstrate the AJAX functionality of the Backbase Client Framework by showing a form with one input field, which, when submitted, causes a response to be displayed somewhere in the page without a page refresh. "Hello World" using a Backbase balloon This section contains a pair of examples showing how to create a BTL balloon that is filled with custom text. The balloon widget displays an image similar to that of a dialogue box in a comic book. The balloon can contain text, images, or other widgets. The user can click on the x icon in the balloon to close it or the balloon can be displayed for a limited amount of time. The balloon is positioned in relationship to its parent widget. The balloon widget is similar to a toolTip because they represent information that becomes available only after an action is performed. Most often, these widgets are used to present contextual information about a widget in your application. This is not the easiest example for showing a Backbase GUI widget from the Backbase Tag Library. However, we have chosen it because we wanted to show an example that illustrates the power of using pre-built widgets. The example is done twice, to show that BTL can be coded in two ways, either by using an event handler with JavaScript content, or by using no JavaScript at all. The second version of the example shows the Backbase-specific XML Execution Language (XEL) and Backbase Commands instead of JavaScript. Any combination of these two styles is also possible. Below is a picture of what the result of trying the example will look like: The user will type a name, and after clicking OK, the balloon will appear. The user can click on the x to close it. Otherwise, it will disappear automatically after a while.
Read more
  • 0
  • 0
  • 6362
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at $19.99/month. Cancel anytime
article-image-scripting-capabilities-elasticsearch
Packt
08 Jan 2016
19 min read
Save for later

The scripting Capabilities of Elasticsearch

Packt
08 Jan 2016
19 min read
In this article by Rafał Kuć and Marek Rogozinski author of the book Elasticsearch Server - Third Edition, Elasticsearch has a few functionalities in which scripts can be used. Even though scripts seem to be a rather advanced topic, we will look at the possibilities offered by Elasticsearch. That's because scripts are priceless in certain situations. Elasticsearch can use several languages for scripting. When not explicitly declared, it assumes that Groovy (http://www.groovy-lang.org/) is used. Other languages available out of the box are the Lucene expression language and Mustache (https://mustache.github.io/). Of course, we can use plugins that will make Elasticsearch understand additional scripting languages such as JavaScript, Mvel, or Python. One thing worth mentioning is this: independently from the scripting language that we will choose, Elasticsearch exposes objects that we can use in our scripts. Let's start by briefly looking at what type of information we are allowed to use in our scripts. (For more resources related to this topic, see here.) Objects available during script execution During different operations, Elasticsearch allows us to use different objects in our scripts. To develop a script that fits our use case, we should be familiar with those objects. For example, during a search operation, the following objects are available: _doc (also available as doc): An instance of the org.elasticsearch.search.lookup.LeafDocLookup object. It gives us access to the current document found with the calculated score and field values. _source: An instance of the org.elasticsearch.search.lookup.SourceLookup object. It provides access to the source of the current document and the values defined in the source. _fields: An instance of the org.elasticsearch.search.lookup.LeafFieldsLookup object. It can be used to access the values of the document fields. On the other hand, during a document update operation, the variables mentioned above are not accessible. Elasticsearch exposes only the ctx object with the _source property, which provides access to the document currently processed in the update request. As we have previously seen, several methods are mentioned in the context of document fields and their values. Let's now look at the examples of how to get the value for a particular field using the previously mentioned object available during search operations. In the brackets, you can see what Elasticsearch will return for one of our example documents from the library index (we will use the document with identifier 4): _doc.title.value (and) _source.title (crime and punishment) _fields.title.value (null) A bit confusing, isn't it? During indexing, the original document is, by default, stored in the _source field. Of course, by default, all fields are present in that _source field. In addition to this, the document is parsed, and every field may be stored in an index if it is marked as stored (that is, if the store property is set to true; otherwise, by default, the fields are not stored). Finally, the field value may be configured as indexed. This means that the field value is analyzed and placed in the index. To sum up, one field may land in an Elasticsearch index in the following ways: As part of the _source document As a stored and unparsed original value As an indexed value that is processed by an analyzer In scripts, we have access to all of these field representations. The only exception is the update operation, which—as we've mentioned before—gives us access to  only the _source document as part of the ctx variable. You may wonder which version you should use. Well, if we want access to the processed form, the answer would be simple—use the _doc object. What about _source and _fields? In most cases, _source is a good choice. It is usually fast and needs fewer disk operations than reading the original field values from the index. This is especially true when you need to read values of multiple fields in your scripts—fetching a single _source field is faster than fetching multiple independent fields from the index. Script types Elasticsearch allows us to use scripts in three different ways: Inline scripts: The source of the script is directly defined in the query In-file scripts: The source is defined in the external file placed in the Elasticsearch config/scripts directory As a document in the dedicated index: The source of the script is defined as a document in a special index available by using the /_scripts API endpoint Choosing the way of defining scripts depends on several factors. If you have scripts that you will use in many different queries, the file or the dedicated index seems to be the best solution. "Scripts in the file" is probably less convenient, but it is preferred from the security point of view—they can't be overwritten and injected into your query, which might have caused a security breach. In-file scripts This is the only way that is turned on by default in Elasticsearch. The idea is that every script used by the queries is defined in its own file placed in the config/scripts directory. We will now look at this method of using scripts. Let's create an example file called tag_sort.groovy and place it in the config/scripts directory of our Elasticsearch instance (or instances if we are running a cluster). The content of the mentioned file should look like this: _doc.tags.values.size() > 0 ? _doc.tags.values[0] : 'u19999' After a few seconds, Elasticsearch should automatically load a new file. You should see something like this in the Elasticsearch logs: [2015-08-30 13:14:33,005][INFO ][script                   ] [Alex Wilder] compiling script file [/Users/negativ/Developer/ES/es-current/config/scripts/tag_sort.groovy] If you have a multinode cluster, you have to make sure that the script is available on every node. Now we are ready to use this script in our queries. A modified query that uses our script stored in the file looks as follows: curl -XGET 'localhost:9200/library/_search?pretty' -d '{   "query" : {     "match_all" : { }   },   "sort" : {     "_script" : {       "script" : {         "file" : "tag_sort"        },        "type" : "string",        "order" : "asc"      }   } }' First, we will see the next possible way of defining a script inline. Inline scripts Inline scripts are a more convenient way of using scripts, especially for constantly changing queries or ad-hoc queries. The main drawback of such an approach is security. If we do this, we allow users to run any kind of query, including any kind of script that can be used by attackers. Such an attack can execute arbitrary code on the server running Elasticsearch with rights equal to the ones given to the user who is running Elasticsearch. In the worst-case scenario, an attacker could use security holes to gain superuser rights. This is why inline scripts are disabled by default. After careful consideration, you can enable them by adding this to the elasticsearch.yml file: script.inline: on After allowing the inline script to be executed, we can run a query that looks as follows: curl -XGET 'localhost:9200/library/_search?pretty' -d '{   "query" : {     "match_all" : { }   },   "sort" : {     "_script" : {       "script" : {         "inline" : "_doc.tags.values.size() > 0 ? _doc.tags.values[0] : "u19999""        },        "type" : "string",        "order" : "asc"      }   } }' Indexed scripts The last option for defining scripts is to store them in the dedicated Elasticsearch index. From the same security reasons, dynamic execution of indexed scripts is by default disabled. To enable indexed scripts, we have to add a configuration similar option to the one that we've added to be able to use inline scripts. We need to add the following line to the elasticsearch.yml file: script.indexed: on After adding the above property to all the nodes and restarting the cluster, we will be ready to start using indexed scripts. Elasticsearch provides additional dedicated endpoints for this purpose. Let's store our script: curl -XPOST 'localhost:9200/_scripts/groovy/tag_sort' -d '{   "script" :  "_doc.tags.values.size() > 0 ? _doc.tags.values[0] : "u19999"" }' The script is ready, but let's discuss what we just did. We sent an HTTP POST request to the special _scripts REST endpoint. We also specified the language of the script (groovy in our case) and the name of the script (tag_sort). The body of the request is the script itself. We can now move on to the query, which looks as follows: curl -XGET 'localhost:9200/library/_search?pretty' -d '{   "query" : {     "match_all" : { }   },   "sort" : {     "_script" : {       "script" : {         "id" : "tag_sort"        },        "type" : "string",        "order" : "asc"      }   } }' As we can see, this query is practically identical to the query used with the script defined in a file. The only difference is the id parameter instead of file. Querying with scripts If we look at any request made to Elasticsearch that uses scripts, we will notice some similar properties, which are as follows: script: The property that wraps the script definition. inline: The property holding the code of the script itself. id – This is the property that defines the identifier of the indexed script. file: The filename (without extension) with the script definition when the in file script is used. lang: This is the property defining the script language. If it is omitted, Elasticsearch assumes groovy. params: This is an object containing parameters and their values. Every defined parameter can be used inside the script by specifying that parameter name. Parameters allow us to write cleaner code that will be executed in a more efficient manner. Scripts that use parameters are executed faster than code with embedded constants because of caching. Scripting with parameters As our scripts become more and more complicated, the need for creating multiple, almost identical scripts can appear. Those scripts usually differ in the values used, with the logic behind them being exactly the same. In our simple example, we have used a hardcoded value to mark documents with an empty tags list. Let's change this to allow the definition of a hardcoded value. Let's use in the file script definition and create the tag_sort_with_param.groovy file with the following contents: _doc.tags.values.size() > 0 ? _doc.tags.values[0] : tvalue The only change we've made is the introduction of a parameter named tvalue, which can be set in the query in the following way: curl -XGET 'localhost:9200/library/_search?pretty' -d '{   "query" : {     "match_all" : { }   },   "sort" : {     "_script" : {       "script" : {         "file" : "tag_sort_with_param",         "params" : {           "tvalue" : "000"         }        },        "type" : "string",        "order" : "asc"      }   } }' The params section defines all the script parameters. In our simple example, we've only used a single parameter, but of course, we can have multiple parameters in a single query. Script languages The default language for scripting is Groovy. However, you are not limited to only a single scripting language when using Elasticsearch. In fact, if you would like to, you can even use Java to write your scripts. In addition to that, the community behind Elasticsearch provides support of more languages as plugins. So, if you are willing to install plugins, you can extend the list of scripting languages that Elasticsearch supports even further. You may wonder why you should even consider using a scripting language other than the default Groovy. The first reason is your own preferences. If you are a Python enthusiast, you are probably now thinking about how to use Python for your Elasticsearch scripts. The other reason could be security. When we talked about inline scripts, we told you that inline scripts are turned off by default. This is not exactly true for all the scripting languages available out of the box. Inline scripts are disabled by default when using Grooby, but you can use Lucene expressions and Mustache without any issues. This is because those languages are sandboxed, which means that security-sensitive functions are turned off. And of course, the last factor when choosing the language is performance. Theoretically, native scripts (in Java) should have better performance than others, but you should remember that the difference can be insignificant. You should always consider the cost of development and measure the performance. Using something other than embedded languages Using Groovy for scripting is a simple and sufficient solution for most use cases. However, you may have a different preference and you would like to use something different, such as JavaScript, Python, or Mvel. For now, we'll just run the following command from the Elasticsearch directory: bin/plugin install elasticsearch/elasticsearch-lang-javascript/2.7.0 The preceding command will install a plugin that will allow the use of JavaScript as the scripting language. The only change we should make in the request is putting in additional information about the language we are using for scripting. And of course, we have to modify the script itself to correctly use the new language. Look at the following example: curl -XGET 'localhost:9200/library/_search?pretty' -d '{   "query" : {     "match_all" : { }   },   "sort" : {     "_script" : {       "script" : {         "inline" : "_doc.tags.values.length > 0 ? _doc.tags.values[0] :"u19999";",         "lang" : "javascript"       },       "type" : "string",       "order" : "asc"     }   } }' As you can see, we've used JavaScript for scripting instead of the default Groovy. The lang parameter informs Elasticsearch about the language being used. Using native code If the scripts are too slow or if you don't like scripting languages, Elasticsearch allows you to write Java classes and use them instead of scripts. There are two possible ways of adding native scripts: adding classes that define scripts to the Elasticsearch classpath, or adding a script as a functionality provided by plugin. We will describe the second solution as it is more elegant. The factory implementation We need to implement at least two classes to create a new native script. The first one is a factory for our script. For now, let's focus on it. The following sample code illustrates the factory for our script: package pl.solr.elasticsearch.examples.scripts; import java.util.Map; import org.elasticsearch.common.Nullable; import org.elasticsearch.script.ExecutableScript; import org.elasticsearch.script.NativeScriptFactory; public class HashCodeSortNativeScriptFactory implements NativeScriptFactory {     @Override     public ExecutableScript newScript(@Nullable Map<String, Object> params) {         return new HashCodeSortScript(params);     }   @Override   public boolean needsScores() {     return false;   } } This class should implement the org.elasticsearch.script.NativeScriptFactory class. The interface forces us to implement two methods. The newScript() method takes the parameters defined in the API call and returns an instance of our script. Finally, needsScores() informs Elasticsearch if we want to use scoring and that it should be calculated. Implementing the native script Now let's look at the implementation of our script. The idea is simple—our script will be used for sorting. The documents will be ordered by the hashCode() value of the chosen field. Documents without a value in the defined field will be first on the results list. We know that the logic doesn't make much sense, but it is good for presentation as it is simple. The source code for our native script looks as follows: package pl.solr.elasticsearch.examples.scripts; import java.util.Map; import org.elasticsearch.script.AbstractSearchScript; public class HashCodeSortScript extends AbstractSearchScript {   private String field = "name";   public HashCodeSortScript(Map<String, Object> params) {     if (params != null && params.containsKey("field")) {       this.field = params.get("field").toString();     }   }   @Override   public Object run() {     Object value = source().get(field);     if (value != null) {       return value.hashCode();     }     return 0;   } } First of all, our class inherits from the org.elasticsearch.script.AbstractSearchScript class and implements the run() method. This is where we get the appropriate values from the current document, process it according to our strange logic, and return the result. You may notice the source() call. Yes, it is exactly the same _source parameter that we met in the non-native scripts. The doc() and fields() methods are also available, and they follow the same logic that we described earlier. The thing worth looking at is how we've used the parameters. We assume that a user can put the field parameter, telling us which document field will be used for manipulation. We also provide a default value for this parameter. The plugin definition We said that we will install our script as a part of a plugin. This is why we need additional files. The first file is the plugin initialization class, where we can tell Elasticsearch about our new script: package pl.solr.elasticsearch.examples.scripts; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.script.ScriptModule; public class ScriptPlugin extends Plugin {   @Override   public String description() {    return "The example of native sort script";   }   @Override   public String name() {     return "naive-sort-plugin";   }   public void onModule(final ScriptModule module) {     module.registerScript("native_sort",       HashCodeSortNativeScriptFactory.class);   } } The implementation is easy. The description() and name() methods are only for information purposes, so let's focus on the onModule() method. In our case, we need access to script module—the Elasticsearch service connected with scripts and scripting languages. This is why we define onModule() with one ScriptModule argument. Thanks to Elasticsearch magic, we can use this module and register our script so that it can be found by the engine. We have used the registerScript() method, which takes the script name and the previously defined factory class. The second file needed is a plugin descriptor file: plugin-descriptor.properties. It defines the constants used by the Elasticsearch plugin subsystem. Without thinking more, let's look at the contents of this file: jvm=true classname=pl.solr.elasticsearch.examples.scripts.ScriptPlugin elasticsearch.version=2.0.0-beta2-SNAPSHOT version=0.0.1-SNAPSHOT name=native_script description=Example Native Scripts java.version=1.7 The appropriate lines have the following meaning: jvm: This tells Elasticsearch that our file contains Java code classname: This describes the main class with the plugin definition elasticsearch.version and java.version: They tell about the Elasticsearch and Java versions needed for our plugin name and description: These are an informative name and a short description of our plugin And that's it! We have all the files needed to fire our script. Note that now it is quite convenient to add new scripts and pack them as a single plugin. Installing a plugin Now it's time to install our native script embedded in the plugin. After packing the compiled classes as a JAR archive, we should put it into the Elasticsearch plugins/native-script directory. The native-script part is a root directory for our plugin and you may name it as you wish. In this directory, you also need the prepared plugin-descriptor.properties file. This makes our plugin visible to Elasticsearch. Running the script After restarting Elasticsearch (or the entire cluster if you are running more than a single node), we can start sending the queries that use our native script. For example, we will send a query that uses our previously indexed data from the library index. This example query looks as follows: curl -XGET 'localhost:9200/library/_search?pretty' -d '{   "query" : {     "match_all" : { }   },   "sort" : {     "_script" : {       "script" : {         "script" : "native_sort",         "lang" : "native",         "params" : {           "field" : "otitle"         }       },       "type" : "string",       "order" : "asc"     }   } }' Note the params part of the query. In this call, we want to sort on the otitle field. We provide the script name as native_sort and the script language as native. This is required. If everything goes well, we should see our results sorted by our custom sort logic. If we look at the response from Elasticsearch, we will see that documents without the otitle field are at the first few positions of the results list and their sort value is 0. Summary In this article, we focused on querying, but not about the matching part of it—mostly about scoring. You learned how Apache Lucene TF/IDF scoring works. We saw the scripting capabilities of Elasticsearch and handled multilingual data. We also used boosting to influence how scores of returned documents were calculated and we used synonyms. Finally, we used explain information to see how document scores were calculated by query. Resources for Article:   Further resources on this subject: An Introduction to Kibana [article] Indexing the Data [article] Low-Level Index Control [article]
Read more
  • 0
  • 0
  • 6356

article-image-working-business-rules-define-decision-points-oracle-soa-suite-11g-r1
Packt
29 Jun 2010
9 min read
Save for later

Working with Business Rules to Define Decision Points in Oracle SOA Suite 11g R1

Packt
29 Jun 2010
9 min read
Calling a business rule from BPEL Save the rule, and then switch back to our composite and double-click the LeaveRequest BPEL process to edit it. Drag a Business Rule from the BPEL Activities and Components palette into your BPEL process (before the Human Task activity). This will open the Business Rule dialog (as shown in the following screenshot): First, we need to specify a name for the Business Rule activity within our BPEL process, so give it a meaningful name such as LeaveApprovalRules. Next we need to specify the Business Rule Dictionary that we wish to use. If we click on the drop-down list, it will list all the dictionaries within our composite application, which in our case is LeaveApprovalRules that we have just defined. Select this and the rule dialog will be updated (as shown in the following screenshot) to enable us to specify additional information about how we want to invoke the rule. First, we need to select the decision service that we want to invoke from BPEL. Our rule only contains a single decision service, LeaveApprovalDecisionService, so select it. Once we've specified the service, we need to specify how we want to invoke the decision service. We specify this through the Operation attribute. Here we have two options: Execute function and reset the session Execute function If we choose the option Execute function and thus don't reset the session, if we were then to call the decision service several times within the same instance of our BPEL process, each new invocation would reuse the same session and would also evaluate facts asserted in any previous invocation. For our purposes, we just need to assert a single fact and run the ruleset, so accept the default value of Execute function and reset the session. Assigning facts The final step to invoke our business rules is to assign BPEL variables to the input and output facts. Click on the green plus symbol (as shown in the preceding screenshot), and this will launch the Decision Fact Map window, as shown in the following screenshot: At first glance, this looks like the standard Create Copy Operation window that we use when carrying out assigns within BPEL (which in reality is exactly what it is). The key difference is that we are using this to assign values to the input facts to be submitted to the rules engines, so the Type on the To side of the copy operation is a Business Rule Facts. The reverse is true for an output fact, where we use this dialog to map the output from the decision service back into a corresponding BPEL variable. For our purpose, we just want to map the initial LeaveRequest in the process inputVariable into the corresponding fact, as shown in the preceding screenshot. Then we will map the output fact, which will contain our updated LeaveRequest back into our inputVariable. When JDeveloper opens the Decision Fact Map window, the Variables folder for the Business Rules Facts (circled in the preceding screenshot) is closed and it appears that there are no input facts. You must double-click on this to open it and expose the facts. We have now wired the rule invocation into our BPEL process, before finally running our process; we need to modify our process to only invoke the workflow if the leave request hasn't been automatically approved. To do this, just drag a switch onto your process, and then drag your workflow task into the first branch in the switch and define a test to check that the LeaveRequest hasn't been approved. You are now ready to deploy and run your modified process. Using functions Our current rule only approves vacations of one day in duration, requiring all other leave requests to be manually approved. Ideally, we would like to approve holidays of varying duration as long as sufficient notice has been given, for example: Approve vacations of one day in duration with a start date that's two weeks or more in the future Approve if for 2-3 days and more than 30 days in the future Approve if 5 days or less and more than 60 days in the future Approve if 10 days or less and more than 120 days in the future To write these rules, we will need to calculate the duration of the leave period, as well as calculate how long it is before the start date. Out of the box, the rule engine provides the Duration extension methods, which allow us to calculate the number of days between two dates, but doesn't allow us to exclude weekends. So we will need to write our own logic to calculate these values. Rather than embedding this logic directly in each rule, best practice dictates that we place this logic into a separate function. This not only ensures that we have a single version of the logic to implement but minimizes the size of our rules, thus making them simpler and easier to maintain. For our purposes, we will create the following functions: startsIn: Which returns the number of days before the specified start date leaveDuration: Which returns the number of days from the start date to the end date, excluding weekends Creating a function To create our first function, within the rule editor, click on the Functions tab. This will list all the functions currently defined to our ruleset. To create a new function, click on the green plus icon, as shown in the following screenshot: This will add a new function with a default name (for example, Function_1) to our list. Click on the function name to select it and update it to startsIn. From the drop-down list, select the Return Type of the function, which is int in our case. Next, we need to specify the arguments we wish to pass to our function. Click on the green plus sign, as shown in the following screenshot, and this will add an argument to our list. Here we can specify the argument name (for example, startDate), and from the drop-down list, the argument Type, which should be XMLGregorianCalendar (when creating XML facts, the JAXB processor maps the type xsd:date to javax.xml.datatype.XMLGregorianCalendar). The list of valid types is made up of the basic types (for example, int, double, char, and so on), plus the XML facts (excluding object factories) and the Java Facts (excluding the Rules Extension Method) defined in our rules dictionary. The final step is to implement the business logic of our function, which consists of one or more actions. We enter these actions in the Body section of the function. The first action we need to create is one that creates a local variable of type calendar, which holds the current date. To do this, click on <insert action> within the Body section of our function. The rule editor will display a drop-down list that lists all the available actions. For our purpose, we want to create a new variable and assign a value to it, so select the assign new action, as shown in the preceding screenshot. This will insert atemplate for the assign new action into our function body (as shown in the following screenshot). We then configure the action by clicking on each part within the template and defining it as appropriate. The first part we need to define is the type of variable we wish to create. Click on the &lttype> element within our &ltassign> statement, and the rule editor displays a drop-down list displaying all the available types. For our purposes, select Calendar. Next, click on var. This will prompt us to enter the name of the variable that we want to create. Specify today, and hit enter. Finally, we need to specify the value we want to initialize our variable with. Click on the &ltexpression> element. The rule editor will display a drop-down box listing all the valid values we can assign to our variable, as shown in the following screenshot: Select Calendar.getInstance(), which will initialize our variable to hold the current date. For our second action, we want to calculate the number of days before the specified start date and place the result into the variable duration. To calculate this, we will make use of the Duration extension method provided with the rules engine. We will do this by defining another assign new action in a similar way to the previous action. The key difference is how we specify the &ltexpression>. This time, instead of selecting a value from the drop-down list, click on the Expression Builder icon (circled in the preceding screenshot) to launch the Expression Builder for the rules editor. The Expression Builder provides a graphical tool for writing rule expressions and is accessed from various parts of the rule editor. It consists of the following areas: Expression: The top textbox contains the rule expression that you are working on. You can either type data directly in here or use the Expression Builder to insert code fragments to build up the expression required. Variables, Functions, Operators, Constants: This part of the Expression Builder lets you browse the various components that you can insert into your expression. Once you've located the component that you wish to use, click the Insert Into Expression button, and this will insert the appropriate code fragment into the expression.<> The code fragment is inserted at the point within the expression that the cursor is currently positioned. Content Preview: This box displays a preview of the content that would be inserted into the expression if you clicked the Insert Into Expression button.
Read more
  • 0
  • 1
  • 6349

article-image-design-install-and-configure
Packt
18 Mar 2014
4 min read
Save for later

Design, Install, and Configure

Packt
18 Mar 2014
4 min read
(For more resources related to this topic, see here.) In this article, we will cover the following key subjects: Horizon Workspace Architecture Overview Designing a solution Sizing guidelines vApp deployment Step-by-step configuration Install Certificates Setting up Kerberos Single Sign-On (SSO) Reading this article will provide you with an introduction to the solution, and also provides you with useful reference points throughout the book that will help you install, configure, and manage a Horizon Workspace deployment. A few things are out of scope for this article, such as setting up vSphere, configuring HA, and using certificates. We will assume that the core infrastructure is already in place. We start by looking at the solution architecture and then how to size a deployment, based on best practice, and suitable to meet the requirements of your end users. Next we will cover the preparation steps in vCenter and then deploy the Horizon Workspace vApp. There are then two steps to installation and configuration. First we will guide you through the initial command-line-based setup and then finally the web-based Setup Wizard. Each section is described in easy to follow steps, and shown in detail using actual screenshots of our lab deployment. So let's get started with the architecture overview. The Horizon Workspace architecture The following diagram shows a more detailed view of how the architecture fits together: The Horizon Workspace sizing guide We have already discussed that Horizon Workspace is made up of five virtual appliances. However, for production environments, you will need to deploy multiple instances to provide for high availability, offer load balancing, and support the number of users that you need in your environment. For a Proof of Concept (POC) or pilot deployment, this is of less importance. Sizing the Horizon Workspace virtual appliances The following diagram shows the maximum number of users that each appliance can accommodate. Using these maximum values, you can calculate the number of appliances that you need to deploy. For example, if you had 6,000 users in your environment, you would need to deploy a single connector-va appliance, three gateway-va appliances, one service-va appliance, seven data-va appliances, and a single configurator-va appliance. Please note that data-va should be sized using N+1. The first data-va appliance should never contain any user data. For high availability, you may want to use two connector-va appliances and two service-va appliances. Sizing for Preview services If you plan to use a Microsoft Preview Server, this needs to be sized based on the requirements shown in the following diagram: If we use our previous example of 6,000 users, then to use Microsoft Preview, you would require a total of six Microsoft Preview Servers. The Horizon Workspace database You have a few options for the database. For a POC or pilot environment, you can use the internal database functionality. In a production deployment, you would use an external database option, using either VMware PostgreSQL or Oracle 11g. This allows you to have a highly available and protected database. The VMware recommendation is PostgreSQL, and the following diagram details the sizing information for the Horizon Workspace database: External access and load balancing considerations In a production environment, high availability, redundancy, and external access is a core requirement. This needs planning and configuration. For a POC or pilot deployment, this is usually not of high importance but should be something to be aware of. To achieve high availability and redundancy, a load balancer is required in front of the gateway-va and the connector-va appliances that are used for Kerberos (Windows authentication). If external access is required, then typically you will also need a load balancer in the Demilitarized Zone (DMZ). This is detailed in the diagram at the beginning of this article. It is not supported to place gateway-va appliances in the DMZ. For more detailed information about load balancing, please visit the following guide: https://communities.vmware.com/docs/DOC-24577 Summary In this article, we had an overview of the Horizon Workspace architecture. We made sure that all the prerequisites are in place before we deploy the Horizon Workspace vApp. This article covers the basic sizing, configuration, and the installation of Horizon Workspace 1.5. Resources for Article: Further resources on this subject: An Introduction to VMware Horizon Mirage [Article] Windows 8 with VMware View [Article] Cloning and Snapshots in VMware Workstation [Article]
Read more
  • 0
  • 0
  • 6349

Packt
07 May 2013
6 min read
Save for later

Using Debug Perspective – setting breakpoints

Packt
07 May 2013
6 min read
(For more resources related to this topic, see here.) In this article we will learn why breakpoints are important, how to set them up, and how to navigate through the code using the Step Into, Step Over, and Step Return breakpoint manipulation options. Let's practice setting up a breakpoint on our sample program. How to do it... I am sure you are aware that in Java, the first method that is executed is the main() method. Our Employee class has its own main() method, so let's set up a breakpoint in it. If you are on Windows and If your project has more than one class, and the main() method is located in a different class from the one you are about to debug, go to the icon and select Debug | Debug Configurations.... Select the class you are about to debug in the left menu and set the Main class option to the class that has the main() method. To set up a breakpoint Go to the main() method of the Employee class. Find andrew.setNumber(123) (on line 110). Right-click on the line number (if you don't see the line number, click on the left margin of the Employee tab and choose Show Line Numbers as shown in the following screenshot). Got to line 110, right-click on the margin again, and click on Toggle Breakpoint. If your breakpoint is successfully set up, you will see the icon right near the line number of the method you wanted to set the breakpoint to. (In our case right near line number 110.) Another way to set a breakpoint is to double-click on the gray field near the line number. To unset the breakpoint, just double-click on it again. Now let's run the debugger by clicking on the icon. If you are asked to switch to Debug Perspective, click Yes. After running the debugger you should see that your program has highlighted the line with the breakpoint, as shown in the following screenshot: This means that the program has stopped executing before line 110 and is waiting for your actions. Before we proceed with exploring how Step Into/ Step Over works, let's take a look at the Variables view. Right now there are two lines: args that represents arguments passed to the main() method and andrew. Expand andrew and you will see the current state of all the class variables as shown in the following screenshot: We will keep on watching this view as it will change when we go through our class. Let's learn how to navigate through the debugger. We navigate with the help of the Step Into/Step Over buttons. Let's see how it works. At this point we are standing at line 110 and there are four options that we can choose. We can Step Into, Step Over, Go to Next breakpoint, or Go Back. Step Into means that we go inside the method and explore its functionality. Let's try it right now. In the top menu there are two buttons: . The first button is responsible for Step Into (F5) and the second one for Step Over (F6). Click on the Step Into (F5) icon. Now you are taken to the setNumber() method. If you take a look at the Variables view, there are two lines now: this, which relates to the class variables, and _number, which is a variable of the local method. Your position is at the if statement evaluating if the number is between certain limits (at line 46). Click on the Step Into (F5) icon again. As there is no method to Step Into, the pointer moves one line down; now it's on number = _number. This line assigns local variables to the class variable. Click on the Step Into (F5) icon again. Right now the pointer should be at line 49. Now let's look at the Variables view again. If you expand this, you will see that the number is highlighted in yellow. This is because the variables have changed their values. See the following screenshot:   This highlighting is very useful, as it allows you to see what variables have changed their values right after it has happened. Before we use Step Into one last time in this exercise, let's also take a look at the Debug view. Sometimes, when the project is big, it is very hard to determine what is the hierarchical structure of the classes and methods, which you are in at the moment. In our case the Debug view shows that we are in the setNumber(int) method on line 49, and if we look below this line, we see that we came here from the main() method on line 110. See the following screenshot: If at any time you want to return back to the calling method (in our case it is the main() method) use Step Return (F7) . Click on the Step Into (F5) icon. As we have reached the end of the setNumber() method, Step Into makes it return back to the main() method, and the pointer points to the next line (line 111 in our case). Also, the Debug view no longer shows setNumber() in its hierarchy. Now, let's consider the situation when you don't want to step into the method but you want to go directly to the next method. In this situation we use Step Over (F6). Note that when you use Step Over, the method is still called but the debugger does not walk you through it. Let's step over the setAge() method. Clicking on Step Over (F6), you might see that you were not prompted inside the setAge() method, but directly to line 112. Take a look at the Variables view. You will see that age is set to 28 (that is what the setAge() method does), despite you not walking through this method. The last two controls that I want to mention in this recipe are Resume (F8) , which allows you to continue running your application until it next faces the breakpoint or the end of the program, and Terminate (Ctrl + F2), which stops the debugging process. Summary This article helped you to learn what a breakpoint is. You also learned how to set breakpoints and how to navigate through the debugger using Step Into, Step Over, and Step Return breakpoint manipulation options. Resources for Article : Further resources on this subject: Android Application Testing: Getting Started [Article] JBoss RichFaces 3.3 Supplemental Installation [Article] JBoss AS plug-in and the Eclipse Web Tools Platform [Article]
Read more
  • 0
  • 0
  • 6347
article-image-unit-and-functional-tests
Packt
21 Aug 2014
13 min read
Save for later

Unit and Functional Tests

Packt
21 Aug 2014
13 min read
In this article by Belén Cruz Zapata and Antonio Hernández Niñirola, authors of the book Testing and Securing Android Studio Applications, you will learn how to use unit tests that allow developers to quickly verify the state and behavior of an activity on its own. (For more resources related to this topic, see here.) Testing activities There are two possible modes of testing activities: Functional testing: In functional testing, the activity being tested is created using the system infrastructure. The test code can communicate with the Android system, send events to the UI, or launch another activity. Unit testing: In unit testing, the activity being tested is created with minimal connection to the system infrastructure. The activity is tested in isolation. In this article, we will explore the Android testing API to learn about the classes and methods that will help you test the activities of your application. The test case classes The Android testing API is based on JUnit. Android JUnit extensions are included in the android.test package. The following figure presents the main classes that are involved when testing activities: Let's learn more about these classes: TestCase: This JUnit class belongs to the junit.framework. The TestCase package represents a general test case. This class is extended by the Android API. InstrumentationTestCase: This class and its subclasses belong to the android.test package. It represents a test case that has access to instrumentation. ActivityTestCase: This class is used to test activities, but for more useful classes, you should use one of its subclasses instead of the main class. ActivityInstrumentationTestCase2: This class provides functional testing of an activity and is parameterized with the activity under test. For example, to evaluate your MainActivity, you have to create a test class named MainActivityTest that extends the ActivityInstrumentationTestCase2 class, shown as follows: public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> ActivityUnitTestCase: This class provides unit testing of an activity and is parameterized with the activity under test. For example, to evaluate your MainActivity, you can create a test class named MainActivityUnitTest that extends the ActivityUnitTestCase class, shown as follows: public class MainActivityUnitTest extends ActivityUnitTestCase<MainActivity> There is a new term that has emerged from the previous classes called Instrumentation. Instrumentation The execution of an application is ruled by the life cycle, which is determined by the Android system. For example, the life cycle of an activity is controlled by the invocation of some methods: onCreate(), onResume(), onDestroy(), and so on. These methods are called by the Android system and your code cannot invoke them, except while testing. The mechanism to allow your test code to invoke callback methods is known as Android instrumentation. Android instrumentation is a set of methods to control a component independent of its normal lifecycle. To invoke the callback methods from your test code, you have to use the classes that are instrumented. For example, to start the activity under test, you can use the getActivity() method that returns the activity instance. For each test method invocation, the activity will not be created until the first time this method is called. Instrumentation is necessary to test activities considering the lifecycle of an activity is based on the callback methods. These callback methods include the UI events as well. From an instrumented test case, you can use the getInstrumentation() method to get access to an Instrumentation object. This class provides methods related to the system interaction with the application. The complete documentation about this class can be found at: http://developer.android.com/reference/android/app/Instrumentation.html. Some of the most important methods are as follows: The addMonitor method: This method adds a monitor to get information about a particular type of Intent and can be used to look for the creation of an activity. A monitor can be created indicating IntentFilter or displaying the name of the activity to the monitor. Optionally, the monitor can block the activity start to return its canned result. You can use the following call definitions to add a monitor: ActivityMonitor addMonitor (IntentFilter filter, ActivityResult result, boolean block). ActivityMonitor addMonitor (String cls, ActivityResult result, boolean block). The following line is an example line code to add a monitor: Instrumentation.ActivityMonitor monitor = getInstrumentation().addMonitor(SecondActivity.class.getName(), null, false); The activity lifecycle methods: The methods to call the activity lifecycle methods are: callActivityOnCreate, callActivityOnDestroy, callActivityOnPause, callActivityOnRestart, callActivityOnResume, callActivityOnStart, finish, and so on. For example, you can pause an activity using the following line code: getInstrumentation().callActivityOnPause(mActivity); The getTargetContext method: This method returns the context for the application. The startActivitySync method: This method starts a new activity and waits for it to begin running. The function returns when the new activity has gone through the full initialization after the call to its onCreate method. The waitForIdleSync method: This method waits for the application to be idle synchronously. The test case methods JUnit's TestCase class provides the following protected methods that can be overridden by the subclasses: setUp(): This method is used to initialize the fixture state of the test case. It is executed before every test method is run. If you override this method, the first line of code will call the superclass. A standard setUp method should follow the given code definition: @Override protected void setUp() throws Exception { super.setUp(); // Initialize the fixture state } tearDown(): This method is used to tear down the fixture state of the test case. You should use this method to release resources. It is executed after running every test method. If you override this method, the last line of the code will call the superclass, shown as follows: @Override protected void tearDown() throws Exception { // Tear down the fixture state super.tearDown(); } The fixture state is usually implemented as a group of member variables but it can also consist of database or network connections. If you open or init connections in the setUp method, they should be closed or released in the tearDown method. When testing activities in Android, you have to initialize the activity under test in the setUp method. This can be done with the getActivity() method. The Assert class and method JUnit's TestCase class extends the Assert class, which provides a set of assert methods to check for certain conditions. When an assert method fails, AssertionFailedException is thrown. The test runner will handle the multiple assertion exceptions to present the testing results. Optionally, you can specify the error message that will be shown if the assert fails. You can read the Android reference of the TestCase class to examine all the available methods at http://developer.android.com/reference/junit/framework/Assert.html. The assertion methods provided by the Assert superclass are as follows: assertEquals: This method checks whether the two values provided are equal. It receives the actual and expected value that is to be compared with each other. This method is overloaded to support values of different types, such as short, String, char, int, byte, boolean, float, double, long, or Object. For example, the following assertion method throws an exception since both values are not equal: assertEquals(true, false); assertTrue or assertFalse: These methods check whether the given Boolean condition is true or false. assertNull or assertNotNull: These methods check whether an object is null or not. assertSame or assertNotSame: These methods check whether two objects refer to the same object or not. fail: This method fails a test. It can be used to make sure that a part of code is never reached, for example, if you want to test that a method throws an exception when it receives a wrong value, as shown in the following code snippet: try{ dontAcceptNullValuesMethod(null); fail("No exception was thrown"); } catch (NullPointerExceptionn e) { // OK } The Android testing API, which extends JUnit, provides additional and more powerful assertion classes: ViewAsserts and MoreAsserts. The ViewAsserts class The assertion methods offered by JUnit's Assert class are not enough if you want to test some special Android objects such as the ones related to the UI. The ViewAsserts class implements more sophisticated methods related to the Android views, that is, for the View objects. The whole list with all the assertion methods can be explored in the Android reference about this class at http://developer.android.com/reference/android/test/ViewAsserts.html. Some of them are described as follows: assertBottomAligned or assertLeftAligned or assertRightAligned or assertTopAligned(View first, View second): These methods check that the two specified View objects are bottom, left, right, or top aligned, respectively assertGroupContains or assertGroupNotContains(ViewGroup parent, View child): These methods check whether the specified ViewGroup object contains the specified child View assertHasScreenCoordinates(View origin, View view, int x, int y): This method checks that the specified View object has a particular position on the origin screen assertHorizontalCenterAligned or assertVerticalCenterAligned(View reference View view): These methods check that the specified View object is horizontally or vertically aligned with respect to the reference view assertOffScreenAbove or assertOffScreenBelow(View origin, View view): These methods check that the specified View object is above or below the visible screen assertOnScreen(View origin, View view): This method checks that the specified View object is loaded on the screen even if it is not visible The MoreAsserts class The Android API extends some of the basic assertion methods from the Assert class to present some additional methods. Some of the methods included in the MoreAsserts class are: assertContainsRegex(String expectedRegex, String actual): This method checks that the expected regular expression (regex) contains the actual given string assertContentsInAnyOrder(Iterable<?> actual, Object… expected): This method checks that the iterable object contains the given objects and in any order assertContentsInOrder(Iterable<?> actual, Object… expected): This method checks that the iterable object contains the given objects, but in the same order assertEmpty: This method checks if a collection is empty assertEquals: This method extends the assertEquals method from JUnit to cover collections: the Set objects, int arrays, String arrays, Object arrays, and so on assertMatchesRegex(String expectedRegex, String actual): This method checks whether the expected regex matches the given actual string exactly Opposite methods such as assertNotContainsRegex, assertNotEmpty, assertNotEquals, and assertNotMatchesRegex are included as well. All these methods are overloaded to optionally include a custom error message. The Android reference about the MoreAsserts class can be inspected to learn more about these assert methods at http://developer.android.com/reference/android/test/MoreAsserts.html. UI testing and TouchUtils The test code is executed in two different threads as the application under test, although, both the threads run in the same process. When testing the UI of an application, UI objects can be referenced from the test code, but you cannot change their properties or send events. There are two strategies to invoke methods that should run in the UI thread: Activity.runOnUiThread(): This method creates a Runnable object in the UI thread in which you can add the code in the run() method. For example, if you want to request the focus of a UI component: public void testComponent() { mActivity.runOnUiThread( new Runnable() { public void run() { mComponent.requestFocus(); } } ); … } @UiThreadTest: This annotation affects the whole method because it is executed on the UI thread. Considering the annotation refers to an entire method, statements that do not interact with the UI are not allowed in it. For example, consider the previous example using this annotation, shown as follows: @UiThreadTest public void testComponent () { mComponent.requestFocus(); … } There is also a helper class that provides methods to perform touch interactions on the view of your application: TouchUtils. The touch events are sent to the UI thread safely from the test thread; therefore, the methods of the TouchUtils class should not be invoked in the UI thread. Some of the methods provided by this helper class are as follows: The clickView method: This method simulates a click on the center of a view The drag, dragQuarterScreenDown, dragViewBy, dragViewTo, dragViewToTop methods: These methods simulate a click on an UI element and then drag it accordingly The longClickView method: This method simulates a long press click on the center of a view The scrollToTop or scrollToBottom methods: These methods scroll a ViewGroup to the top or bottom The mock object classes The Android testing API provides some classes to create mock system objects. Mock objects are fake objects that simulate the behavior of real objects but are totally controlled by the test. They allow isolation of tests from the rest of the system. Mock objects can, for example, simulate a part of the system that has not been implemented yet, or a part that is not practical to be tested. In Android, the following mock classes can be found: MockApplication, MockContext, MockContentProvider, MockCursor, MockDialogInterface, MockPackageManager, MockResources, and MockContentResolver. These classes are under the android.test.mock package. The methods of these objects are nonfunctional and throw an exception if they are called. You have to override the methods that you want to use. Creating an activity test In this section, we will create an example application so that we can learn how to implement the test cases to evaluate it. Some of the methods presented in the previous section will be put into practice. You can download the example code files from your account at http://www.packtpub.com. Our example is a simple alarm application that consists of two activities: MainActivity and SecondActivity. The MainActivity implements a self-built digital clock using text views and buttons. The purpose of creating a self-built digital clock is to have more code and elements to use in our tests. The layout of MainActivity is a relative one that includes two text views: one for the hour (the tvHour ID) and one for the minutes (the tvMinute ID). There are two buttons below the clock: one to subtract 10 minutes from the clock (the bMinus ID) and one to add 10 minutes to the clock (the bPlus ID). There is also an edit text field to specify the alarm name. Finally, there is a button to launch the second activity (the bValidate ID). Each button has a pertinent method that receives the click event when the button is pressed. The layout looks like the following screenshot: The SecondActivity receives the hour from the MainActivity and shows its value in a text view simulating that the alarm was saved. The objective to create this second activity is to be able to test the launch of another activity in our test case. Summary In this article, you learned how to use unit tests that allow developers to quickly verify the state and behavior of an activity on its own. Resources for Article: Further resources on this subject: Creating Dynamic UI with Android Fragments [article] Saying Hello to Unity and Android [article] Augmented Reality [article]
Read more
  • 0
  • 0
  • 6345

article-image-show-additional-information-users-and-visitors-your-plone-site
Packt
12 Oct 2009
5 min read
Save for later

Show Additional Information to Users and Visitors of Your Plone Site

Packt
12 Oct 2009
5 min read
(For more resources on Plone, see here.) What's a portlet, anyway? A portlet is a chunk of information that can be shown outside of the main content area of a page. In the following screenshot of Plone's default home page, the Log in box and the calendar are portlets. Plone's default theme has two portlet managers that control the assignment of portlets on the right and left sidebars of the page. You can place portlets into these slots on the page. It's also possible to add portlet manager slots to a custom theme so that you can display portlets in other areas of the page, but that's beyond the scope of this book. For more information, refer to: http://plone.org/documentation/how-to/adding-portlet-managers. There are two things that we need to know about portlets before we dive into adding them: Portlets can only be added to portlet managers. They can't be added into the body content of your pages. Portlets can be assigned to folders, content types, or user groups, and will cascade down through the site hierarchy unless you explicitly block inheritance. Plone's built-in portlets Plone ships with a generous assortment of basic portlets. Here's a quick list of Plone's default portlet offerings: Login: Shows Plone's login box to anonymous users; is hidden if a user is already logged in Collection portlet: Shows the results of a Collection Review list: Visible only to the users with the Reviewer role; this portlet shows a list of items that users have submitted for review before publishing RSS feed: Shows a list of items in an RSS feed Classic portlet: A wrapper for Zope 2 style portlets, which may have been developed prior to the advent of Plone 3 and its new portlet system Calendar portlet: Shows a simple calendar that highlights the dates of upcoming events for your site Search: Shows Plone's search box useful if you have chosen to disable the standard search box, and want to show it in a sidebar instead Recent items: Shows the most recently-published content items on your site Static text portlet: Shows a chunk of static, editable HTML content; this is one of Plone's most versatile and useful portlets Navigation: Shows the navigation tree Events: Shows upcoming published events on your site You're likely only to use Classic portlets if you are using an add-on product that hasn't fully embraced the new style of building portlets, or if you are building your own custom portlets. Add-on portlets Many add-on products for Plone will supply one or more relevant portlets when the product is installed. There are also additional standalone portlets available as separate add-on products. Among the most useful standalone add-on portlets are: TAL Portlet: A portlet that allows you to write your own simple portlets in Plone's templating language, TAL. Optionally, you could just write a Classic portlet. Feedmixer: A portlet that allows you to aggregate multiple RSS feeds into a single portlet. These products can be found in the Products section of Plone.org. Adding portlets There are three ways to add portlets to your site: Add portlets to specific locations on your site. Add portlets that are associated with specific content types—for example, a portlet that shows on all News Items. Add portlets that are shown only to specific groups of users in your site. Adding portlets to specific sections of your site We'll start with adding portlets to a specific section of your site, as this is the most common and the simplest thing to do. Log in to your site (via the Log in portlet) and look at the bottom of the rightmost sidebar for the Manage portlets link. This will take you to the Manage portlets screen. Managing Portlets PeacefullyBecause you were on the front page of your site, when you clicked on the Manage portlets link, you are now managing the portlets for your entire site. If you only want to manage portlets for a single section of your site, first navigate to that section, and then click on the Manage portlets link. The header of the Manage Portlets screen will tell you which section of the site you are in. The Manage Portlets screen tells you that certain portlets are already assigned to all of the pages of your site. In the example above, the left sidebar portlet manager has the Navigation portlet and the Log in portlet. The right sidebar portlet manager has the Review List, News, Events and Calendar portlets. Moving and Removing PortletsYou can move existing portlets around within a portlet manager by clicking on the up and down arrows within the portlet. You can remove a portlet from the portlet manager by clicking on the red X. To add a portlet to your site, select the Add portlet... drop-down menu at the top of either the right or left sidebar, and choose a portlet type to be added. For practice, let's try adding a static content portlet to the right sidebar. This screen contains the familiar Kupu-powered rich text editing widget, along with: A Portlet header (title) field. A Portlet footer field. A optional hyperlink field, which will be clickable from the portlet header and footer. An Omit portlet border checkbox. If selected, this hides the portlet header, footer, and border. This is very useful if you only want to place an image or some fl oating text in your sidebar. Enter some text into your new portlet, click on the Save button at the bottom of the screen, and then click on the Home tab to return to your site's homepage. You should now see your new static text portlet. If you click around the site, you'll continue to see the portlet on all of the pages of your site.
Read more
  • 0
  • 0
  • 6331

article-image-null-10
Packt
27 Nov 2011
2 min read
Save for later

PacktLib now Offers a Joomla! Library

Packt
27 Nov 2011
2 min read
Packt has today announced a new subscription on PacktLib for Joomla! developers. Housing 26 books, this library will enable Joomla! developers to get up and running quickly, as well as extend their skills and knowledge to become serious professionals. Recently announced as the winner of the best 2011 Open Source CMS, a resurgent Joomla!, now with a six month development cycle, has proved itself to be one of the leading open source content management systems on the market. The Joomla! library consists of information relating to the development of building media rich, dynamic and interactive Joomla! websites. The extensive variety of topics within this open source technology includes eCommerce, search engine optimisation, content administration, multimedia, themes and templates, creating a social network with JomSocial, enhancing a Joomla! site with JavaScript and jQuery, interacting with users by utilising ChronoForms, web security and much more. This source of Joomla! books will enable readers to build powerful websites and online applications by way of add-ons, extensions and plugins in addition to understanding the framework in which this technology is based on. This resource is ideal for beginners who want to learn more about building a functional and well-designed website. Many books in this library provide step-by-step instructions as well as examples to guide readers in setting up a functional and visually appealing website. In addition to this, those who have experience with using Joomla! can find more advanced features to install onto their website making this library a comprehensive resource on Joomla! for readers with different skill levels. Packt was the first publisher to bring an English book on Joomla! to market and has long been a supporter of Joomla! through the Open Source Royalty scheme. With 26 books on this technology, subscribers of the Joomla! library will have full access to an archive of up-to-date information on the content management system. Moreover, future books added to the library will also be made available to subscribers as long as they have a subscription. This resource will give site administrators the tools to create and develop successful websites as well as the ability to search for specific information and find answers to problems on the PacktLib platform. For more information, please visit http://packtlib.packtpub.com/
Read more
  • 0
  • 0
  • 6324
article-image-getting-started-mule
Packt
26 Aug 2013
10 min read
Save for later

Getting Started with Mule

Packt
26 Aug 2013
10 min read
(For more resources related to this topic, see here.) Mule ESB is a lightweight Java programming language. Through ESB, you can integrate or communicate with multiple applications. Mule ESB enables easy integration of existing systems, regardless of the different technologies that the applications use, including JMS, web services, JDBC, and HTTP. Understanding Mule concepts and terminologies Enterprise Service Bus (ESB) is an application that gives access to other applications and services. Its main task is to be the messaging and integration backbone of an enterprise. An ESB is a distributed middleware system to integrate different applications. All these applications communicate through the ESB. It consists of a set of service containers that integrate various types of applications. The containers are interconnected with a reliable messaging bus. Getting ready An ESB is used for integration using a service-oriented approach. Its main features are as follows: Polling JMS Message transformation and routing services Tomcat hot deployment Web service security We often use the abbreviation, VETRO, to summarize the ESB functionality: V– validate the schema validation E– enrich T– transform R– route (either itinerary or content based) O– operate (perform operations; they run at the backend) Before introducing any ESB, developers and integrators must connect different applications in a point-to-point fashion. How to do it... After the introduction of an ESB, you just need to connect each application to the ESB so that every application can communicate with each other through the ESB. You can easily connect multiple applications through the ESB, as shown in the following diagram: Need for the ESB You can integrate different applications using ESB. Each application can communicate through ESB: To integrate more than two or three services and/or applications To integrate more applications, services, or technologies in the future To use different communication protocols To publish services for composition and consumption For message transformation and routing   What is Mule ESB? Mule ESB is a lightweight Java-based enterprise service bus and integration platform that allows developers and integrators to connect applications together quickly and easily, enabling them to exchange data. There are two editions of Mule ESB: Community and Enterprise. Mule ESB Enterprise is the enterprise-class version of Mule ESB, with additional features and capabilities that are ideal for clustering and performance tuning, DataMapper, and the SAP connector. Mule ESB Community and Enterprise editions are built on a common code base, so it is easy to upgrade from Mule ESB Community to Mule ESB Enterprise. Mule ESB enables easy integration of existing systems, regardless of the different technologies that the applications use, including JMS, web services, JDBC, and HTTP. The key advantage of an ESB is that it allows different applications to communicate with each other by acting as a transit system for carrying data between applications within your enterprise or across the Internet. Mule ESB includes powerful capabilities that include the following: Service creation and hosting: It exposes and hosts reusable services using Mule ESB as a lightweight service container Service mediation: It shields services from message formats and protocols, separate business logic from messaging, and enables location-independent service calls Message routing: It routes, filters, aggregates, and re-sequences messages based on content and rules Data transformation: It exchanges data across varying formats and transport protocols Mule ESB is lightweight but highly scalable, allowing you to start small and connect more applications over time. Mule provides a Java-based messaging framework. Mule manages all the interactions between applications and components transparently. Mule provides transformation, routing, filtering, Endpoint, and so on. How it works... When you examine how a message flows through Mule ESB, you can see that there are three layers in the architecture, which are listed as follows: Application Layer Integration Layer Transport Layer Likewise, there are three general types of tasks you can perform to configure and customize your Mule deployment. Refer to the following diagram: The following list talks about Mule and its configuration: Service component development: This involves developing or re-using the existing POJOs, which is a class with attributes and it generates the get and set methods, Cloud connectors, or Spring Beans that contain the business logic and will consume, process, or enrich messages. Service orchestration: This involves configuring message processors, routers, transformers, and filters that provide the service mediation and orchestration capabilities required to allow composition of loosely coupled services using a Mule flow. New orchestration elements can be created also and dropped into your deployment. Integration: A key requirement of service mediation is decoupling services from the underlying protocols. Mule provides transport methods to allow dispatching and receiving messages on different protocol connectors. These connectors are configured in the Mule configuration file and can be referenced from the orchestration layer. Mule supports many existing transport methods and all the popular communication protocols, but you may also develop a custom transport method if you need to extend Mule to support a particular legacy or proprietary system. Spring beans: You can construct service components from Spring beans and define these Spring components through a configuration file. If you don't have this file, you will need to define it manually in the Mule configuration file. Agents: An agent is a service that is created in Mule Studio. When you start the server, an agent is created. When you stop the server, this agent will be destroyed. Connectors: The Connector is a software component. Global configuration: Global configuration is used to set the global properties and settings. Global Endpoints: Global Endpoints can be used in the Global Elements tab. We can use the global properties' element as many times in a flow as we want. For that, we must pass the global properties' reference name. Global message processor: A global message processor observes a message or modifies either a message or the message flow; examples include transformers and filters. Transformers: A transformer converts data from one format to another. You can define them globally and use them in multiple flows. Filters: Filters decide which Mule messages should be processed. Filters specify the conditions that must be met for a message to be routed to a service or continue progressing through a flow. There are several standard filters that come with Mule ESB, which you can use, or you can create your own filters. Models: It is a logical grouping of services, which are created in Mule Studio. You can start and stop all the services inside a particular model. Services: You can define one or more services that wrap your components (business logic) and configure Routers, Endpoints, transformers, and filters specifically for that service. Services are connected using Endpoints. Endpoints: Services are connected using Endpoints. It is an object on which the services will receive (inbound) and send (outbound) messages. Flow: Flow is used for a message processor to define a message flow between a source and a target. Setting up the Mule IDE The developers who were using Mule ESB over other technologies such as Liferay Portal, Alfresco ECM, or Activiti BPM can use Mule IDE in Eclipse without configuring the standalone Mule Studio in the existing environment. In recent times, MuleSoft (http://www.mulesoft.org/) only provides Mule Studio from Version 3.3 onwards, but not Mule IDE. If you are using the older version of Mule ESB, you can get Mule IDE separately from http://dist.muleforge.org/mule-ide/releases/. Getting ready To set Mule IDE, we need Java to be installed on the machine and its execution path should be set in an environment variable. We will now see how to set up Java on our machine. Firstly, download JDK 1.6 or a higher version from the following URL: http://www.oracle.com/technetwork/java/javase/downloads/jdk6downloads-1902814.html. In your Windows system, go to Start | Control Panel | System | Advanced. Click on Environment Variables under System Variables, find Path, and click on it. In the Edit window, modify the path by adding the location of the class to its value. If you do not have the item Path, you may select the option of adding a new variable and adding Path as the name and the location of the class as its value. Close the window, reopen the command prompt window, and run your Java code. How to do it... If you go with Eclipse, you have to download Mule IDE Standalone 3.3. Download Mule ESB 3.3 Community edition from the following URL: http://www.mulesoft.org/extensions/mule-ide. Unzip the downloaded file and set MULE_HOME as the environment variable. Download the latest version of Eclipse from http://www.eclipse.org/downloads/. After installing Eclipse, you now have to integrate Mule IDE in the Eclipse. If you are using Eclipse Version 3.4 (Galileo), perform the following steps to install Mule IDE. If you are not using Version 3.4 (Galileo), the URL for downloading will be different. Open Eclipse IDE. Go to Help | Install New Software…. Write the URL in the Work with: textbox: http://dist.muleforge.org/muleide/updates/3.4/ and press Enter. Select the Mule IDE checkbox. Click on the Next button. Read and accept the license agreement terms. Click on the Finish button. This will take some time. When it prompts for a restart, shut it down and restart Eclipse. Mule configuration After installing Mule IDE, you will now have to configure Mule in Eclipse. Perform the following steps: Open Eclipse IDE. Go to Window | Preferences. Select Mule, add the distribution folder mule as standalone 3.3; click on the Apply button and then on the OK button. This way you can configure Mule with Eclipse. Installing Mule Studio Mule Studio is a powerful, user-friendly Eclipse-based tool. Mule Studio has three main components: a package tree, a palette, and a canvas. Mule ESB easily creates flows as well as edits and tests them in a few minutes. Mule Studio is currently in public beta. It is based on drag-and-drop elements and supports two-way editing. Getting ready To install Mule Studio, download Mule Studio from http://www.mulesoft.org/download-mule-esb-community-edition. How to do it... Unzip the Mule Studio folder. Set the environment variable for Mule Studio. While starting with Mule Studio, the config.xml file will be created automatically by Mule Studio. The three main components of Mule Studio are as follows: A package tree A palette A canvas A package tree A package tree contains the entire structure of your project. In the following screenshot, you can see the package explorer tree. In this package explorer tree, under src/main/java, you can store the custom Java class. You can create a graphical flow from src/main/resources. In the app folder you can store the mule-deploy.properties file. The folders src, main, and app contain the flow of XML files. The folders src, main, and test contain flow-related test files. The Mule-project.xml file contains the project's metadata. You can edit the name, description, and server runtime version used for a specific project. JRE System Library contains the Java runtime libraries. Mule Runtime contains the Mule runtime libraries. A palette The second component is palette. The palette is the source for accessing Endpoints, components, transformers, and Cloud connectors. You can drag them from the palette and drop them onto the canvas in order to create flows. The palette typically displays buttons indicating the different types of Mule elements. You can view the content of each button by clicking on them. If you do not want to expand elements, click on the button again to hide the content. A canvas The third component is canvas; canvas is a graphical editor. In canvas you can create flows. The canvas provides a space that facilitates the arrangement of Studio components into Mule flows. In the canvas area you can configure each and every component, and you can add or remove components on the canvas.
Read more
  • 0
  • 0
  • 6314

article-image-component-communication-reactjs
Richard Feldman
30 Jun 2014
5 min read
Save for later

Component Communication in React.js

Richard Feldman
30 Jun 2014
5 min read
You can get a long way in React.js solely by having parent components create child components with varying props, and having each component deal only with its own state. But what happens when a child wants to affect its parent’s state or props? Or when a child wants to inspect that parent’s state or props? Or when a parent wants to inspect its child’s state? With the right techniques, you can handle communication between React components without introducing unnecessary coupling. Child Elements Altering Parents Suppose you have a list of buttons, and when you click one, a label elsewhere on the page updates to reflect which button was most recently clicked. Although any button’s click handler can alter that button’s state, the handler has no intrinsic knowledge of the label that we need to update. So how can we give it access to do what we need? The idiomatic approach is to pass a function through props. Like so: var ExampleParent = React.createClass({ getInitialState: function() { return {lastLabelClicked: "none"} }, render: function() { var me = this; var setLastLabel = function(label) { me.setState({lastLabelClicked: label}); }; return <div> <p>Last clicked: {this.state.lastLabelClicked}</p> <LabeledButton label="Alpha Button" setLastLabel={setLastLabel}/> <LabeledButton label="Beta Button" setLastLabel={setLastLabel}/> <LabeledButton label="Delta Button" setLastLabel={setLastLabel}/> </div>; } }); var LabeledButton = React.createClass({ handleClick: function() { this.props.setLastLabel(this.props.label); }, render: function() { return <button onClick={this.handleClick}>{this.props.label}</button>; } }); Note that this does not actually affect the label’s state directly; rather, it affects the parent component’s state, and doing so will cause the parent to re-render the label as appropriate. What if we wanted to avoid using state here, and instead modify the parent’s props? Since props are externally specified, this would be a lot of extra work. Rather than telling the parent to change, the child would necessarily have to tell its parent’s parent—its grandparent, in other words—to change that grandparent’s child. This is not a route worth pursuing; besides being less idiomatic, there is no real benefit to changing the parent’s props when you could change its state instead. Inspecting Props Once created, the only way for a child’s props to “change” is for the child to be recreated when the parent’s render method is called again. This helpfully guarantees that the parent’s render method has all the information needed to determine the child’s props—not only in the present, but for the indefinite future as well. Thus if another of the parent’s methods needs to know the child’s props, like for example a click handler, it’s simply a matter of making sure that data is available outside the parent’s render method. An easy way to do this is to record it in the parent’s state: var ExampleComponent = React.createClass({ handleClick: function() { var buttonStatus = this.state.buttonStatus; // ...do something based on buttonStatus }, render: function() { // Pretend it took some effort to determine this value var buttonStatus = "btn-disabled"; this.setState({buttonStatus: buttonStatus}); return <button className={buttonStatus} onClick={this.handleClick}> Click this button! </button>; } }); It’s even easier to let a child know about its parent’s props: simply have the parent pass along whatever information is necessary when it creates the child. It’s cleaner to pass along only what the child needs to know, but if all else fails you can go as far as to pass in the parent’s entire set of props: var ParentComponent = React.createClass({ render: function() { return <ChildComponent parentProps={this.props} />; } }); Inspecting State State is trickier to inspect, because it can change on the fly. But is it ever strictly necessary for components to inspect each other’s states, or might there be a universal workaround? Suppose you have a child whose click handler cares about its parent’s state. Is there any way we could refactor things such that the child could always know that value, without having to ask the parent directly? Absolutely! Simply have the parent pass the current value of its state to the child as a prop. Whenever the parent’s state changes, it will re-run its render method, so the child (including its click handler) will automatically be recreated with the new prop. Now the child’s click handler will always have an up-to-date knowledge of the parent’s state, just as we wanted. Suppose instead that we have a parent that cares about its child’s state. As we saw earlier with the buttons-and-labels example, children can affect their parent’s states, so we can use that technique again here to refactor our way into a solution. Simply include in the child’s props a function that updates the parent’s state, and have the child incorporate that function into its relevant state changes. With the child thus keeping the parent’s state up to speed on relevant changes to the child’s state, the parent can obtain whatever information it needed simply by inspecting its own state. Takeaways Idiomatic communication between parent and child components can be easily accomplished by passing state-altering functions through props. When it comes to inspecting props and state, a combination of passing props on a need-to-know basis and refactoring state changes can ensure the relevant parties have all the information they need, whenever they need it. About the Author Richard Feldman is a functional programmer who specializes in pushing the limits of browser-based UIs. He’s built a framework that performantly renders hundreds of thousands of shapes in HTML5 canvas, a writing web app that functions like a desktop app in the absence of an Internet connection, and much more in between.
Read more
  • 0
  • 0
  • 6309
Modal Close icon
Modal Close icon