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

7019 Articles
article-image-find-closest-mashup-plugin-ruby-rails
Packt
16 Oct 2009
10 min read
Save for later

Find closest mashup plugin with Ruby on Rails

Packt
16 Oct 2009
10 min read
Building a kiosk locator feature for your site Your company has just deployed 500 multi-purpose payment kiosks around the country, cash cows for the milking. Another 500 more are on the way, promising to bring in the big bucks for all the hardworking employees in the company. Naturally your boss wants as many people as possible to know about them and use them. The problem is that while the marketing machine churns away on the marvels and benefits of the kiosks, the customers need to know where they are located to use them. He commands you: "Find a way to show our users where the nearest kiosks to him are, and directions to reach them!" What you have is a database of all the 500 locations where the kiosks are located, by their full address. What can you do? Requirements overview Quickly gathering your wits, you penned down the following quick requirements: Each customer who comes to your site needs to be able to find the closest kiosk to his or her current location. He or she might also want to know the closest kiosk to any location. You want to let the users determine the radius of the search. Finding the locations of the closest kiosks, you need to show him how to reach them. You have 500 kiosks now, (and you need to show where they are) but another 500 will be coming, in 10s and 20s, so the location of the kiosks need to be specified during the entry of the kiosks. You want to put all of these on some kind of map. Sounds difficult? Only if you didn't know about web mashups! Design The design for this first project is rather simple. We will build a simple database application using Rails and create a main Kiosk class in which to store the kiosk information including its address, longitude, and latitude information. After populating the database with the kiosk information and address, we will use a geolocation service to discover its longitude and latitude. We store the information in the same table. Next, we will take the kiosk information and mash it up with Google Maps and display the kiosks as pushpins on the online map and place its information inside an info box attached to each pushpin. Mashup APIs on the menu In this article we will be using the following services to create a 'find closest' mashup plugin: Google Maps APIs including geocoding services Yahoo geocoding services (part of Yahoo Maps APIs) Geocoder.us geocoding services Geocoder.ca geocoding services Hostip.info Google Maps Google Maps is a free web-based mapping service provided by Google. It provides a map that can be navigated by dragging the mouse across it and zoomed in and out using the mouse wheel or a zoom bar. It has three forms of views—map, satellite and a hybrid of map and satellite. Google Maps is coded almost entirely in JavaScript and XML and Google provides a free JavaScript API library that allows developers to integrate Google Maps into their own applications. Google Maps APIs also provide geocoding capabilities, that is, they able to convert addresses to longitude and latitude coordinates. We will be using two parts of Google Maps: Firstly to geocode addresses as part of GeoKit's APIs Secondly to display the found kiosk on a customized Google Maps map Yahoo Maps Yahoo Maps is a free mapping service provided by Yahoo. Much like Google Maps it also provides a map that is navigable in a similar way and also provides an extensive set of APIs. Yahoo's mapping APIs range from simply including the map directly from the Yahoo Maps website, to Flash APIs and JavaScript APIs. Yahoo Maps also provides geocoding services. We will be using Yahoo Maps geocoding services as part of GeoKit's API to geocode addresses. Geocoder.us Geocoder.us is a website that provides free geocoding of addresses and intersections in the United States. It relies on Geo::Coder::US, a Perl module available for download from the CPAN and derives its data from the TIGER/Line data set, public-domain data from the US Census Bureau. Its reliability is higher in urban areas but lower in the other parts of the country. We will be using Geocoder.us as part of GeoKit's API to geocode addresses. Geocoder.ca Geocoder.ca is a website that provides free geocoding of addresses in the United States and Canada. Like Geocoder.us. it uses data from TIGER/Line but in addition, draws data from GeoBase, the Canadian government-related initiative that provides geospatial information on Canadian territories. We will be using Geocoder.ca as part of GeoKit's API to geocode addresses. Hostip.info Hostip.info is a website that provides free geocoding of IP addresses. Hostip.info offers an HTTP-based API as well as its entire database for integration at no cost. We will be using Hostip.info as part of GeoKit's API to geocode IP addresses. GeoKit GeoKit is a Rails plugin that enables you to build location-based applications. For this article we will be using GeoKit for its geocoding capabilities in two ways: To determine the longitude and latitude coordinates of the kiosk from its given address To determine the longitude and latitude coordinates of the user from his or her IP address GeoKit is a plugin to your Rails application so installing it means more or less copying the source files from the GeoKit Subversion repository and running through an installation script that adds certain default parameters in your environment.rb file. To install the GeoKit, go to your Rails application folder and execute this at the command line: $./script/plugin install svn://rubyforge.org/var/svn/geokit/trunk This will copy the necessary files to your RAILS_ROOT/vendor/plugins folder and run the install.rb script. Configuring GeoKit After installing GeoKit you will need to configure it properly to allow it to work. GeoKit allows you to use a few sets of geocoding APIs, including Yahoo, Google, Geocoder.us, and Geocoder.ca. These geocoding providers can be used directly or through a cascading failover sequence. Using Yahoo or Google requires you to register for an API key but they are free. Geocoder.us is also free under certain terms and conditions but both Geocoder.us and Geocoder.ca have commercial accounts. In this article I will briefly go through how to get an application ID from Yahoo and a Google Maps API key from Google. Getting an application ID from Yahoo Yahoo's application ID is needed for any Yahoo web service API calls. You can use the same application ID for all services in the same application or multiple applications or one application ID per service. To get the Yahoo application ID, go to https://developer.yahoo.com/wsregapp/index.php and provide the necessary information. Note that for this application you don't need user authentication. Once you click on submit, you will be provided an application ID. Getting a Google Maps API key from Google To use Google Maps you will need to have a Google Maps API key. Go to http://www.google.com/apis/maps/signup.html. After reading the terms and conditions you will be asked to give a website URL that will use the Google Maps API. For geocoding purposes, this is not important (anything will do) but to display Google Maps on a website, this is important because Google Maps will not display if the URL doesn't match. However all is not lost if you have provided the wrong URL at first; you can create any number of API keys from Google. Configuring evironment.rb Now that you have a Yahoo application ID and a Google Maps API key, go to environment.rb under the RAILS_ROOT/config folder. Installing GeoKit should have added the following to your environment.rb file: # Include your application configuration below # These defaults are used in GeoKit::Mappable.distance_to and in acts_as_mappable GeoKit::default_units = :miles GeoKit::default_formula = :sphere # This is the timeout value in seconds to be used for calls to the geocoder web # services. For no timeout at all, comment out the setting. The timeout unit is in seconds. # GeoKit::Geocoders::timeout = 3 # These settings are used if web service calls must be routed through a proxy. # These setting can be nil if not needed, otherwise, addr and port must be filled in at a minimum. If the proxy requires authentication, the username and password can be provided as well. GeoKit::Geocoders::proxy_addr = nil GeoKit::Geocoders::proxy_port = nil GeoKit::Geocoders::proxy_user = nil GeoKit::Geocoders::proxy_pass = nil # This is your yahoo application key for the Yahoo Geocoder # See http://developer.yahoo.com/faq/index.html#appid and http://developer.yahoo.com/maps/rest/V1/geocode.html GeoKit::Geocoders::yahoo = <YOUR YAHOO APP ID> # This is your Google Maps geocoder key. # See http://www.google.com/apis/maps/signup.html and http://www.google.com/apis/maps/documentation/#Geocoding_Examples GeoKit::Geocoders::google = <YOUR GOOGLE MAPS KEY> # This is your username and password for geocoder.us # To use the free service, the value can be set to nil or false. For usage tied to an account, the value should be set to username:password. # See http://geocoder.us and http://geocoder.us/user/signup GeoKit::Geocoders::geocoder_us = false # This is your authorization key for geocoder.ca. # To use the free service, the value can be set to nil or false. For usage tied to an account, set the value to the key obtained from Geocoder.ca # See http://geocoder.ca and http://geocoder.ca/?register=1 GeoKit::Geocoders::geocoder_ca = false # This is the order in which the geocoders are called in a failover scenario # If you only want to use a single geocoder, put a single symbol in the array. # Valid symbols are :google, :yahoo, :us, and :ca # Be aware that there are Terms of Use restrictions on how you can use the various geocoders. Make sure you read up on relevant Terms of Use for each geocoder you are going to use. GeoKit::Geocoders::provider_order = [:google,:yahoo] Go to the lines where you are asked to put in the Yahoo and Google keys and change the values accordingly. Make sure the keys are within apostrophes. Then go to the provider order and put in the order you want (the first will be tried; if that fails it will go to the next until all are exhausted): GeoKit::Geocoders::provider_order = [:google,:yahoo] This completes the configuration of GeoKit. YM4R/GM YM4R/GM is another Rails plugin, one that facilitates the use of Google Maps APIs. We will be using YM4R/GM to display the kiosk locations on a customized Google Map. This API essentially wraps around the Google Maps APIs but also provides additional features to make it easier to use from Ruby. To install it, go to your Rails application folder and execute this at the command line: $./script/plugin install svn://rubyforge.org/var/svn/ym4r/Plugins/GM/trunk/ym4r_gm During the installation, the JavaScript files found in the RAILS_ROOT/vendors/plugin/javascript folder will be copied to the RAILS_ROOT/public/javascripts folder. A gmaps_api_key.yml file is also created in the RAILS_ROOT/config folder. This file is a YAML representation of a hash, like the database.yml file in which you can set up a test, development, and production environment. This is where you will put in your Google Maps API key (in addition to the environment.rb you have changed earlier). For your local testing you will not need to change the values but once you deploy this in production on an Internet site you will need to put in a real value according to your domain.
Read more
  • 0
  • 0
  • 2386

article-image-oracle-essbase-system-9-components
Packt
16 Oct 2009
7 min read
Save for later

Oracle Essbase System 9 Components

Packt
16 Oct 2009
7 min read
A lot has changed with Essbase since the early days back in the 1990's. Essbase itself has grown and flourished into the world's leading OLAP analytic software and now includes all of the bells and whistles you'd expect and more. The purpose of this article is to go over some exciting new additions to the Essbase family. No longer is it just Essbase, the multidimensional OLAP database. The future of Essbase, beginning with Essbase version 9.x, is now Essbase System 9. Essbase System 9 is now a suite of analytical applications or components of which Essbase is the cornerstone. Some of the components enhance the overall abilities of the suite and some are targeted more to specific computing purposes. Overview of System 9 components When Oracle purchased Hyperion and several other companies, they set out to organize their product catalog and bring together a standardized naming convention as well as standardized software versioning. The Essbase suite of tools and applications is no exception as Essbase version 9.x has become Essbase System 9, and there never really was a commercially released Essbase version 8.x. Oracle now has plans to further integrate the Essbase suite of tools and components into their product catalog and we'll just need to wait and see how this plays out with version 11 and beyond. What we are giving you in this article is a high level look at each new Essbase tool or component and also a slightly lower level look at the hot new additions to the Essbase family. Not to detract from any of the other Essbase family members, but the new Oracle Smart View, for one, is an awesome tool to have in your toolbox. Essbase Analytic Services (Essbase agent) The term Essbase analytic services, while commonly thought to refer to the Essbase suite of applications, actually refers to the common Essbase system structure that is built around the Essbase analytic database engine technology. We know this sounds confusing, but here is how it works. In your Essbase toolbox, you can have many different tools. Some of them are optional and can be added at an additional expense and some of them must be included from the beginning for proper system installation. No matter what tools you want to add to your Essbase toolbox, the Essbase agent or Essbase analytic services must be included and it is the cornerstone of the Essbase suite of applications. The Essbase agent is what you install on your server in order to make it an Essbase analytic server. The Essbase agent is what you use to build, deploy, and maintain your Essbase databases. In a nutshell, Essbase Analytic Services is the heart and soul of your Essbase system. Essbase Planning Also known as Hyperion Planning or even Oracle Planning, Essbase Planning is a centralized Microsoft Excel and web-based planning and forecasting tool that combines data from various internal business activities such as finance, marketing, and so on, into one integrated tool. Planning uses the data to provide a closer look at the company's overall business operations and helps improve the forecast predictability accuracy. Planning makes use of Essbase in an ingenious way. The data for each business activity is stored in its own custom Essbase database or cube. Several business activities can share the same cube and have their own set of dimensions and members. Therefore, Essbase must be started and running in the background so Planning can access the cubes. The various Planning functions are then supported by Planning's seamless accessing of the data from the Essbase cubes and by using the stored business rule feature to apply the customer defined business rules to the data for planning and analysis purposes. The storing of complex business rules to facilitate proper analysis of the data is a huge benefit of Oracle Planning and is accomplished within the module by utilizing a small space on a relational database such as an Oracle or SQL server database. With the aid of pre-packaged process modules, Essbase Planning can also greatly shorten the length of time typically required for budget and forecast cycles, thus lowering the total cost of ownership for this product. Essbase Analytics It's funny, but the word analytics is being tossed about rather often these days.Pretty much anything you do with OLAP or multidimensional database tools,can be termed analytics. In Essbase however, Essbase analytics, to some, usually refers to Essbase's other database engine, the ASO database engine. The reason given for this is that the typical Essbase ASO database is primarily used for presentation, analysis, and reporting which are all analytic functions. The Essbase BSO database, while analytic itself, can also be considered transactional as well. The Essbase analytics nickname dates back to the advent of the ASO database architecture when all you had was the BSO architecture. The new ASO architecture was the analytic tool. Yes, it's funny how Essbase is an analytical package and inside that package is an analytic piece but that's just how it is. Try not to get hung up on the terminology here though. When considering your options, you need to look at all of the same things you have always looked at. How large will the system be? What are the business customer's requirements? What type of system am I building here? When you answer these questions, it will matter less what you call what you are doing than choosing the right tools. Hyperion Application Link/Oracle Application Link The name pretty much says it all. Hyperion Application Link is a suite of ETL tools that allows the user or programmer to integrate Oracle products, like Essbase, with other third party software packages, especially transactional database packages. Hyperion Application Link (HAL) can integrate all of your data loading and ETL functions into one place and offer improved performance. When gathering data for your Essbase application, you may encounter data from many different sources. HAL allows you to set up a link to your favorite Oracle database using an ODBC connection.HAL will also allow you to load data from conveniently delivered flat files too. In fact, you can usually accomplish just about all of your data loading needs for your Essbase System 9 installation by using HAL. Oracle Business Rules This tool can be a tremendous time saver. The Oracle Business Rules tool allows the programmer to create, store, execute, and manage complex business rules as specified by the business customer and as it relates to thebusiness process and the data. All of this is accomplished by using an easy to understand user interface with graphical depictions of the various elements that go into a rule. Imagine a business process that dictates the values for next month's sales commitments as follows: If the actual sales for the prior month are not received by the 15th of the current month, then the committed sales for the current month are to equal the sales number that was forecasted from the prior month If the actual sales for the prior month are received by the 15th, then the number used for the current month's committed sales will be equal to the prior month actual sales * 1.15. This is just one example of a business rule being automatically executed against the data for the users of the system. There are endless possibilities on how to make good use of this tool. The advantages of the Oracle Business Rules tool are clear, especially in today's fast-paced business world where static structures in data load and calculation scripts need almost continual modifying.With the Hyperion Business Rules tool, the dynamic nature of the business can more effectively be supported with the creation of minimal maintenance dynamic rules.
Read more
  • 0
  • 0
  • 2775

article-image-exceptions-and-logging-apache-struts-2
Packt
16 Oct 2009
8 min read
Save for later

Exceptions and Logging in Apache Struts 2

Packt
16 Oct 2009
8 min read
Handling exceptions in Struts 2 Struts 2 provides a declarative exception handling mechanism that can be configured globally (for an entire package), or for a specific action. This capability can reduce the amount of exception handling code necessary inside actions under some circumstances, most notably when underlying systems, such as our services, throw runtime exceptions (exceptions that we don't need to wrap in a try/catch or declare that a method throws). To sum it up, we can map exception classes to Struts 2 results. The exception handling mechanism depends on the exception interceptor. If we modify our interceptor stack, we must keep that in mind. In general, removing the exception interceptor isn't preferred. Global exception mappings Setting up a global exception handler result is as easy as adding a global exception mapping element to a Struts 2 configuration file package definition and configuring its result. For example, to catch generic runtime exceptions, we could add the following: <global-exception-mappings><exception-mapping result="runtime"exception="java.lang.RuntimeException"/></global-exception-mappings> This means that if a java.lang.RuntimeException (or a subclass) is thrown, the framework will take us to the runtime result. The runtime result may be declared in an element, an action configuration, or both. The most specific result will be used. This implies that an action's result configuration might take precedence over a global exception mapping. For example, consider the global exception mapping shown in the previous code snippet. If we configure an action as follows, and a RuntimeException is thrown, we'll see the locally defined runtime result, even if there is a global runtime result. <action name="except1"class="com.packt.s2wad.ch09.examples.exceptions.Except1"><result name="runtime">/WEB-INF/jsps/ch9/exceptions/except1-runtime.jsp</result>... This can occasionally lead to confusion if a result name happens to collide with a result used for an exception. However, this can happen with global results anyway (a case where a naming convention for global results can be handy). Action-specific exception mappings In addition to overriding the result used for an exception mapping, we can also override a global exception mapping on a per-action basis. For example, if an action needs to use a result named runtime2 as the destination of a RuntimeException, we can configure an exception mapping specific to that action. <action name="except2"class="com.packt.s2wad.ch09.examples.exceptions.Except1"><exception-mapping result="runtime2"exception="java.lang.RuntimeException"/>... As with our earlier examples, the runtime2 result may be configured either as a global result or as an action-specific result. Accessing the exception We have many options regarding how to handle exceptions. We can show the user a generic "Something horrible has happened!" page, we can take the user back and allow them to retry the operation or refill the input form, and so on. The appropriate course of action depends on the application and, most likely, on the type of exception. We can display exception-specific information as well. The exception interceptor pushes an exception encapsulation object onto the stack with the exception and exceptionStack properties. While the stack trace is probably not appropriate for user-level error pages, the exception can be used to help create a useful error message, provide I18N property keys for messages (or values used in messages), suggest possible remedies, and so on. The simplest example of accessing the exception property from our JSP is to simply display the exception message. For example, if we threw a RuntimeException, we might create it as follows: throw newRuntimeException("Runtime thrown from ThrowingAction"); Our exception result page, then, could access the message using the usual property tag (or JSTL, if we're taking advantage of Struts 2's custom request processor): <s:property value="exception.message"/> The underlying action is still available on the stack—it's the next object on the value stack. It can be accessed from the JSP as usual, as long as we're not trying to access properties named exception or exceptionStack, which would be masked by the exception holder. (We can still access an action property named exception using OGNL's immediate stack index notation—[1].exception.) Architecting exceptions and exception handling We have pretty good control over what is displayed for our application exceptions. It is customizable based on exception type, and may be overridden on a per-action basis. However, to make use of this flexibility, we require a well-thought-out exception policy in our application. There are some general principles we can follow to help make this easier. Checked versus unchecked exceptions Before we start, let's recall that Java offers two main types of exceptions—checked and unchecked. Checked exceptions are exceptions we declare with a throws keyword or wrapped in a try/catch block. Unchecked exceptions are runtime exceptions or a subclass. It isn't always clear what type we should use when writing our code or creating our exceptions. It's been the subject of much debate over the years, but some guidelines have become apparent. One clear thing about checked exceptions is that they aren't always worth the aggravation they cause, but may be useful when the programmer has a reasonable chance of recovering from the exception. One issue with checked exceptions is that unless they're caught and wrapped in a more abstract exception (coming up next), we're actually circumventing some of the benefits of encapsulation. One of the benefits being circumvented is that when exceptions are declared as being thrown all the way up a call hierarchy, all of the classes involved are forced to know something about the class throwing the exception. It's relatively rare that this exposure is justifiable. Application-specific exceptions One of the more useful exception techniques is to create application-specific exception classes. A compelling feature of providing our own exception classes is that we can include useful diagnostic information in the exception class itself. These classes are like any other Java class. They can contain methods, properties, and constructors. For example, let's assume a service that throws an exception when the user calling the service doesn't have access rights to the service. One way to create and throw this exception would be as follows: throw new RuntimeException("User " + user.getId()+ " does not have access to the 'update' service."); However, there are some issues with this approach. It's awkward from the Struts 2's standpoint. Because it's a RuntimeException, we have only one option for handling the exception—mapping a RuntimeException to a result. Yes, we could map the exception type per-action, but that gets unwieldy. It also doesn't help if we need to map two different types of RuntimeExceptions to two different results. Another potential issue would arise if we had a process that examined exceptions and did something useful with them. For example, we might send an email with user details based on the above exception. This would amount to parsing the exception message, pulling out the user ID, and using it to get user details for inclusion in the email. This is where we'd need to create an exception class of our own, subclassed from RuntimeException. The class would have encapsulated exception related information, and a mechanism to differentiate between the different types of exceptions. A third benefit comes when we wrap lower-level exceptions—for example, a Spring-related exception. Rather than create a Spring dependency up the entire call chain, we'd wrap it in our own exception, abstracting the lower-level exception. This allows us to change the underlying implementation and aggregate differing exception types under one (or more) application-specific exception. One way of creating the above scenario would be to create an exception class that takes a User object and a message as its constructor arguments: package com.packt.s2wad.ch09.exceptions;public class UserAccessException extends RuntimeException {private User user;private String msg;public UserAccessException(User user, String msg) {this.user = user;this.msg = msg;}public String getMessage() {return "User " + user.getId() + " " + msg;}} We can now create an exception mapping for a UserAccessException (as well as a generic RuntimeException if we need it). In addition, the exception carries along with it the information needed to create useful messages: throw new UserAccessException(user,"does not have access to the 'update' service."); "Self-documenting" of code could be made even safer, in the sense of ensuring that it's only used in the ways in which it is intended. We could add an enum to the class to encapsulate the reasons the exception can be thrown, including the text for each reason. We'll add the following inside  our UserAccessException: public enum Reason {NO_ROLE("does not have role"),NO_ACCESS("does not have access");private String message;private Reason(String message) {this.message = message;}public String getMessage() { return message; }}; We'll also modify the constructor and getMessage() method to use the new Reason enumeration. public UserAccessException(User user, Reason reason) {this.user = user;this.reason = reason;}public String getMessage() {return String.format("User %d %s.",user.getId(), reason.getMessage());} Now, when we throw the exception, we explicitly know that we're using the exception class correctly (at least type-wise). The string message for each of the exception reasons is encapsulated within the exception class itself. throw new UserAccessException(user,UserAccessException.Reason.NO_ACCESS); With Java 5's static imports, it might make even more sense to create static helper methods in the exception class, leading to the concise, but understandable code: throw userHasNoAccess(user);
Read more
  • 0
  • 1
  • 10849

article-image-drools-jboss-rules-50-flow-part-1
Packt
16 Oct 2009
10 min read
Save for later

Drools JBoss Rules 5.0 Flow (Part 1)

Packt
16 Oct 2009
10 min read
Loan approval service Loan approval is a complex process starting with customer requesting a loan. This request comes with information such as amount to be borrowed, duration of the loan, and destination account where the borrowed amount will be transferred. Only the existing customers can apply for a loan. The process starts with validating the request. Upon successful validation, a customer rating is calculated. Only customers with a certain rating are allowed to have loans. The loan is processed by a bank employee. As soon as an approved event is received from a supervisor, the loan is approved and money can be transferred to the destination account. An email is sent to inform the customer about the outcome. Model If we look at this process from the domain modeling perspective, in addition to the model that we already have, we'll need a Loan class. An instance of this class will be a part of the context of this process. The screenshot above shows Java Bean, Loan, for holding loan-related information. The Loan bean defines three properties. amount (which is of type BigDecimal), destinationAccount (which is of type Account; if the loan is approved, the amount will be transferred to this account), and durationYears (which represents a period for which the customer will be repaying this loan). Loan approval ruleflow We'll now represent this process as a ruleflow. It is shown in the following figure. Try to remember this figure because we'll be referring back to it throughout this article. The preceding figure shows the loan approval process—loanApproval.rf file. You can use the Ruleflow Editor that comes with the Drools Eclipse plugin to create this ruleflow. The rest of the article will be a walk through this ruleflow explaining each node in more detail. The process starts with Validate Loan ruleflow group. Rules in this group will check the loan for missing required values and do other more complex validation. Each validation rule simply inserts Message into the knowledge session. The next node called Validated? is an XOR type split node. The ruleflow will continue through the no errors branch if there are no error or warning messages in the knowledge session—the split node constraint for this branch says: not Message() Code listing 1: Validated? split node no errors branch constraint (loanApproval.rf file). For this to work, we need to import the Message type into the ruleflow. This can be done from the Constraint editor, just click on the Imports... button. The import statements are common for the whole ruleflow. Whenever we use a new type in the ruleflow (constraints, actions, and so on), it needs to be imported. The otherwise branch is a "catch all" type branch (it is set to 'always true'). It has higher priority number, which means that it will be checked after the no errors branch. The .rf files are pure XML files that conform with a well formed XSD schema. They can be edited with any XML editor. Invalid loan application form If the validation didn't pass, an email is sent to the customer and the loan approval process finishes as Not Valid. This can be seen in the otherwise branch. There are two nodes-Email and Not Valid. Email is a special ruleflow node called work item. Email work item Work item is a node that encapsulates some piece of work. This can be an interaction with another system or some logic that is easier to write using standard Java. Each work item represents a piece of logic that can be reused in many systems. We can also look at work items as a ruleflow alternative to DSLs. By default, Drools Flow comes with various generic work items, for example, Email (for sending emails), Log (for logging messages), Finder (for finding files on a file system), Archive (for archiving files), and Exec (for executing programs/system commands). In a real application, you'd probably want to use a different work item than a generic one for sending an email. For example, a custom work item that inserts a record into your loan repository. Each work item can take multiple parameters. In case of email, these are: From, To, Subject, Text, and others. Values for these parameters can be specified at ruleflow creation time or at runtime. By double-clicking on the Email node in the ruleflow, Custom Work Editor is opened (see the following screenshot). Please note that not all work items have a custom editor. In the first tab (not visible), we can specify recipients and the source email address. In the second tab (visible), we can specify the email's subject and body. If you look closer at the body of the email, you'll notice two placeholders. They have the following syntax: #{placeholder}. A placeholder can contain any mvel code and has access to all of the ruleflow variables (we'll learn more about ruleflow variables later in this article). This allows us to customize the work item parameters based on runtime conditions. As can be seen from the screenshot above, we use two placeholders: customer.firstName and errorList. customer and errorList are ruleflow variables. The first one represents the current Customer object and the second one is ValidationReport. When the ruleflow execution reaches this email work item, these placeholders are evaluated and replaced with the actual values (by calling the toString method on the result). Fault node The second node in the otherwise branch in the loan approval process ruleflow is a fault node. Fault node is similar to an end node. It accepts one incoming connection and has no outgoing connections. When the execution reaches this node, a fault is thrown with the given name. We could, for example, register a fault handler that will generate a record in our reporting database. However, we won't register a fault handler, and in that case, it will simply indicate that this ruleflow finished with an error. Test setup We'll now write a test for the otherwise branch. First, let's set up the test environment. Then a new session is created in the setup method along with some test data. A valid Customer with one Account is requesting a Loan. The setup method will create a valid loan configuration and the individual tests can then change this configuration in order to test various exceptional cases. @Before public void setUp() throws Exception { session = knowledgeBase.newStatefulKnowledgeSession(); trackingProcessEventListener = new TrackingProcessEventListener(); session.addEventListener(trackingProcessEventListener); session.getWorkItemManager().registerWorkItemHandler( "Email", new SystemOutWorkItemHandler()); loanSourceAccount = new Account(); customer = new Customer(); customer.setFirstName("Bob"); customer.setLastName("Green"); customer.setEmail("bob.green@mail.com"); Account account = new Account(); account.setNumber(123456789l); customer.addAccount(account); account.setOwner(customer); loan = new Loan(); loan.setDestinationAccount(account); loan.setAmount(BigDecimal.valueOf(4000.0)); loan.setDurationYears(2); Code listing 2: Test setup method called before every test execution (DefaulLoanApprovalServiceTest.java file). A tracking ruleflow event listener is created and added to the knowledge session. This event listener will record the execution path of a ruleflow—store all of the executed ruleflow nodes in a list. TrackingProcessEventListener overrides the beforeNodeTriggered method and gets the node to be executed by calling event.getNodeInstance(). loanSourceAccount represents the bank's account for sourcing loans. The setup method also registers an Email work item handler. A work item handler is responsible for execution of the work item (in this case, connecting to the mail server and sending out emails). However, the SystemOutWorkItemHandler implementation that we've used is only a dummy implementation that writes some information to the console. It is useful for our testing purposes. Testing the 'otherwise' branch of 'Validated?' node We'll now test the otherwise branch, which sends an email informing the applicant about missing data and ends with a fault. Our test (the following code) will set up a loan request that will fail the validation. It will then verify that the fault node was executed and that the ruleflow process was aborted. @Test public void notValid() { session.insert(new DefaultMessage()); startProcess(); assertTrue(trackingProcessEventListener.isNodeTriggered( PROCESS_LOAN_APPROVAL, NODE_FAULT_NOT_VALID)); assertEquals(ProcessInstance.STATE_ABORTED, processInstance.getState()); } Code listing 3: Test method for testing Validated? node's otherwise branch (DefaultLoanApprovalServiceTest.java file). By inserting a message into the session, we're simulating a validation error. The ruleflow should end up in the otherwise branch. Next, the test above calls the startProcess method. It's implementation is as follows: private void startProcess() { Map<String, Object> parameterMap = new HashMap<String, Object>(); parameterMap.put("loanSourceAccount", loanSourceAccount); parameterMap.put("customer", customer); parameterMap.put("loan", loan); processInstance = session.startProcess( PROCESS_LOAN_APPROVAL, parameterMap); session.insert(processInstance); session.fireAllRules(); } Code listing 4: Utility method for starting the ruleflow (DefaultLoanApprovalServiceTest.java file). The startProcess method starts the loan approval process. It also sets loanSourceAccount, loan, and customer as ruleflow variables. The resulting process instance is, in turn, inserted into the knowledge session. This will enable our rules to make more sophisticated decisions based on the state of the current process instance. Finally, all of the rules are fired. We're already supplying three variables to the ruleflow; however, we haven't declared them yet. Let's fix this. Ruleflow variables can be added through Eclipse's Properties editor as can be seen in the following screenshot (just click on the ruleflow canvas, this should give the focus to the ruleflow itself). Each variable needs a name type and, optionally, a value. The preceding screenshot shows how to set the loan ruleflow variable. Its Type is set to Object and ClassName is set to the full type name droolsbook.bank.model.Loan. The other two variables are set in a similar manner. Now back to the test from code listing 3. It verifies that the correct nodes were triggered and that the process ended in aborted state. The isNodeTriggered method takes the process ID, which is stored in a constant called PROCESS_LOAN_APPROVAL. The method also takes the node ID as second argument. This node ID can be found in the properties view after clicking on the fault node. The node ID—NODE_FAULT_NOT_VALID—is a constant of type long defined as a property of this test class. static final long NODE_FAULT_NOT_VALID = 21;static final long NODE_SPLIT_VALIDATED = 20; Code listing 5: Constants that holds fault and Validated? node's IDs (DefaultLoanApprovalServiceTest.java file). By using the node ID, we can change node's name and other properties without breaking this test (node ID is least likely to change). Also, if we're performing bigger re-factorings involving node ID changes, we have only one place to update—the test's constants. Ruleflow unit testingDrools Flow support for unit testing isn't the best. With every test, we have to run the full process from start to the end. We'll make it easier with some helper methods that will set up a state that will utilize different parts of the flow. For example, a loan with high amount to borrow or a customer with low rating.Ideally we should be able to test each node in isolation. Simply start the ruleflow in a particular node. Just set the necessary parameters needed for a particular test and verify that the node executed as expected.Drools support for snapshots may resolve some of these issues; however, we'd have to first create all snapshots that we need before executing the individual test methods. Another alternative is to dig deeper into Drools internal API, but this is not recommended. The internal API can change in the next release without any notice.
Read more
  • 0
  • 0
  • 2831

article-image-using-graphs-manage-networks-and-devices-cacti-08
Packt
16 Oct 2009
4 min read
Save for later

Using Graphs to Manage Networks and Devices with Cacti 0.8

Packt
16 Oct 2009
4 min read
Creating graphs If you are familiar with RRDTool, then you know Cacti is designed to harness the power of RRDTool's data storage and graphing functionality. If you are not, don't worry—Cacti will create graphs without extensive configuration input from users. Built-in graph templates will make your life easier, so it is not necessary to understand the functionality of each field to create graphs for network-attached devices. Each graph stores different sets of parameters that control different aspects of each graph. If you want to know more about RRDTool, please visit http://oss.oetiker.ch/rrdtool/. At the time of creating graphs, you will face a bit of a stiff learning curve. Stay on course, it will be over soon and you will be able to create graphs for different devices very quickly. Cacti can create graphs for any SNMP-enabled, network-attached devices. This can be a switch, router, server, desktop computer, printer, IPS, UPS, and so on. Initially, we will not talk about the custom template and the data-query script development for any SNMP-enabled devices. Instead, we will use the default options in Cacti. In order to build a custom template, we need to understand the SNMP protocol and command-line tools of the Net-SNMP application suite. Let's create graphs based on the available templates and devices. Adding a device Before we add a graph, we need to add a device for which you want to create the graph. In order to do that, click on Devices under Management. Cacti will open the Devices view panel. It will look like this: If you click Add in the top right-hand corner, it will open a new form to add a new device. The first two fields, Description and Hostname, are both required for the default configuration. The other fields in the Device section (Notes and Disable Device) can be left as is. If your host template exists in the drop-down, be sure to select the template. Since we are starting with an SNMP-enabled device, if you are not sure which template to select, you can select the Generic SNMP-enabled host template. It is important to know that adding a template to a device will not lock down the device to any specific configuration, as graph templates and queries can be added and removed from a device at anytime. The following screenshot shows how the Add a device form looks. If you look closely at the drop-down, there are very few templates. But you can add device-specific templates as required. The following web site has an excellent collection of Cacti scripts and templates. This web site is aimed at providing tips and tricks to Debian users from novice to expert. The owner also collects and updates all sorts of scripts and templates from the Cacti forum for easy access: http://www.debianhelp.co.uk/cactitemplates.htm Device fields definition Every device that we add has different attributes and values. The following table will clarify the attributes. It is wise to understand all the fields before adding a device in Cacti. Fields Descriptions Description Giving host a meaningful name. This name will be shown in the first column of the device view panel. Hostname Fully qualified hostname or IP. If a fully qualified hostname is being used such as linuxbox1.example.com, Dynamic Name Services (DNS) will be used to resolve the hostname. Host Template Host template is responsible for the types of data that need to be gathered from a specific type of host. Notes Adding notes for the host, anything that is specific to the host. Disable Host Check this box to disable all the checks for this device. This means no polling for this device. Downed Device Detection NONE: Disable downed device detection. Ping and SNMP: Perform both tests. SNMP: Perform SNMP check. Ping: Use ping method. Ping Method ICMP Ping: Perform ICMP test. ICMP on Linux/Unix require root privileges. TCP Ping: Perform a TCP test. UDP Ping: Perform UDP test. Ping Port This option is available for only TCP and UDP Ping. Define the port number here and make sure the firewall is not blocking that port. Ping Timeout Value This value is measured in milliseconds. After the defined time, the test will fail. Ping Retry Count Defines how many times Cacti will ping a host before failing. SNMP Version Version 1: Supported by most of the SNMP-enabled devices. One thing you need to remember is that it doesn't support a 64-bit counter. Version 2: This is also known as SNMPv2c. Supported by most of the SNMP-enabled devices. Version 3: Version 3 supports authentication and encryption.
Read more
  • 0
  • 0
  • 4719

article-image-simplifying-parallelism-complexity-c
Packt
16 Oct 2009
7 min read
Save for later

Simplifying Parallelism Complexity in C#

Packt
16 Oct 2009
7 min read
Specializing the algorithms for segmentation with classes So far, we have been developing applications that split work into multiple independent jobs and created classes to generalize the algorithms for segmentation. We simplified the creation of segmented and parallelized algorithms, generalizing behaviors to simplify our code and to avoid repeating the same code on every new application. However, we did not do that using inheritance, a very powerful object-oriented capability that simplifies code re-use. C# is an object-oriented programming language that supports inheritance and offers many possibilities to specialize behaviors to simplify our code and to avoid some synchronization problems related to parallel programming. How can we use C# object-oriented capabilities to define specific segmented algorithms prepared for running each piece in an independent thread using ParallelAlgorithm and ParallelAlgorithmPiece as the base classes? The answer is very simple—by using inheritance and the factory method class creational pattern (also known as virtual constructor). Thus, we can advance into creating a complete framework to simplify the algorithm optimization process. Again, we can combine multithreading with object-oriented capabilities to reduce our development time and avoid synchronization problems. Besides, using classes to specialize the process of splitting a linear algorithm into many pieces will make it easier for the developers to focus on generating very independent parts that will work well in a multithreading environment, while avoiding side-effects. Time for action – Preparing the parallel algorithm classes for the factory method You made the necessary changes to the ParallelAlgorithmPiece and the ParallelAlgorithm classes to possibly find planets similar to Mars in the images corresponding to different galaxies. NASA's CIO was impressed with your parallel programming capabilities. Nevertheless, he is an object-oriented guru, and he gave you the advice to apply the factory method pattern to specialize the parallel algorithm classes in each new algorithm. That could make the code simpler, more re-usable, and easier to maintain. He asked you to do so. The NASA scientists would then bring you another huge image processing challenge for your parallel programming capabilities—a sunspot analyzer. If you resolve this problem using the factory method pattern or something like that, he will hire you! However, be careful, because you must avoid some synchronization problems! First, we are going to create a new project with tailored versions of the ParallelAlgorithmPiece and ParallelAlgorithm classes. This way, later, we will be able to inherit from these classes and apply the factory method pattern to specialize in parallel algorithms: Create a new C# Project using the Windows Forms Application template in Visual Studio or Visual C# Express. Use SunspotsAnalyzer as the project's name. Open the code for Program.cs. Replace the line [STAThread] with the following line (before the Main method declaration): [MTAThread] Copy the file that contains the original code of the ParallelAlgorithmPiece and the ParallelAlgorithm classes (ParallelAlgorithm.cs) and include them in the project. Add the abstract keyword before the declarations of theParallelAlgorithmPiece and the ParallelAlgorithm classes, as shown in the following lines (we do not want to create instances directly from these abstract classes): abstract class ParallelAlgorithmPieceabstract class ParallelAlgorithm Change the ThreadMethod method declaration in the ParallelAlgorithmPiece class (add the abstract keyword to force us to override it in subclasses): public abstract void ThreadMethod(object poThreadParameter); Add the following public abstract method to create each parallel algorithm piece in the ParallelAlgorithm class (the key to the factory method pattern): public abstract ParallelAlgorithmPieceCreateParallelAlgorithmPiece(int priThreadNumber); Add the following constructor with a parameter to the ParallelAlgorithmPiece class: public ParallelAlgorithmPiece(int priThreadNumberToAssign){priThreadNumber = priThreadNumberToAssign;} Copy the original code of the ParallelAlgorithmPiece class CreatePieces method and paste it in the ParallelAlgorithm class (we move it to allow creation of parallel algorithm pieces of different subclasses). Replace the lloPieces[i].priBegin and lloPieces[i].priEnd private variables' access with their corresponding public properties access lloPieces[i].piBegin and lloPieces[i].piEnd. Change the new CreatePieces method declaration in the ParallelAlgorithm class (remove the static clause and add the virtual keyword to allow us to override it in subclasses and to access instance variables): public virtual List<ParallelAlgorithmPiece>CreatePieces(long priTotalElements, int priTotalParts) Replace the line lloPieces[i] = new ParallelAlgorithmPiece(); in the CreatePieces method declaration in the ParallelAlgorithm class with the following line of code (now the creation is encapsulated in a method, and also, a great bug is corrected, which we will explain later): lloPieces.Add(CreateParallelAlgorithmPiece(i)); Comment the following line of code in the CreatePieces method in the ParallelAlgorithm class (now the new ParallelAlgorithmPiece constructor assigns the value to piThreadNumber): //lloPieces[i].piThreadNumber = i; Replace the line prloPieces = ParallelAlgorithmPiece. CreatePieces(priTotalElements, priTotalParts); in the CreateThreads method declaration in the ParallelAlgorithm class with the following line of code (now the creation is done in the new CreatePieces method): prloPieces = CreatePieces(priTotalElements, priTotalParts); Change the StartThreadsAsync method declaration in the ParallelAlgorithm class (add the virtual keyword to allow us to override it in subclasses): public virtual void StartThreadsAsync() Change the CollectResults method declaration in the ParallelAlgorithm class (add the abstract keyword to force us to override it in subclasses): public abstract void CollectResults(); What just happened? The code required to create subclasses to implement algorithms, following a variation of the factory method class creational pattern, is now held in the ParallelAlgorithmPiece and ParallelAlgorithm classes. Thus, when we create new classes that will inherit from these two classes, we can easily implement a parallel algorithm. We must just fill in the gaps and override some methods, and we can then focus on the algorithm problems instead of working hard on the splitting techniques. We also solved some bugs related to the previous versions of these classes. Using C# programming language's excellent object-oriented capabilities, we can avoid many problems related to concurrency and simplify the development process using high-performance parallel algorithms. Nevertheless, we must master many object-oriented design patterns to help us in reducing the complexity added by multithreading and concurrency. Defining the class to instantiate One of the main problems that arise when generalizing an algorithm is that the generalized code needed to coordinate the parallel algorithm must create instances of the subclasses that represent the pieces. Using the concepts introduced by the factory method class creational pattern, we solved this problem with great simplicity. We made the necessary changes to the ParallelAlgorithmPiece and ParallelAlgorithm classes to implement a variation of this design pattern. First, we added a constructor to the ParallelAlgorithmPiece class with the thread or piece number as a parameter. The constructor assigns the received value to the priThreadNumber private variable, accessed by the piThreadNumber property: public ParallelAlgorithmPiece(int priThreadNumberToAssign){priThreadNumber = priThreadNumberToAssign;} The subclasses will be able to override this constructor to add any additional initialization code. We had to move the CreatePieces method from the ParallelAlgorithmPiece class to the ParallelAlgorithm class. We did this because each ParallelAlgorithm subclass will know which ParallelAlgorithmPiece subclass to create for each piece representation. Thus, we also made the method virtual, to allow it to be overridden in subclasses. Besides, now it is an instance method and not a static one. There was an intentional bug left in the previous CreatePieces method. As you must master lists and collections management in C# in order to master parallel programming, you should be able to detect and solve this little problem. The method assigned the capacity, but did not add elements to the list. Hence, we must use the add method using the result of the new CreateParallelAlgorithmPiece method. lloPieces.Add(CreateParallelAlgorithmPiece(i)); The creation is now encapsulated in this method, which is virtual, and allows subclasses to override it. The original implementation is shown in the following lines: public virtual ParallelAlgorithmPiece CreateParallelAlgorithmPiece(int priThreadNumber){return (new ParallelAlgorithmPiece(priThreadNumber));} It returns a new ParallelAlgorithmPiece instance, sending the thread or piece number as a parameter. Overriding this method, we can return instances of any subclass of ParallelAlgorithmPiece. Thus, we let the ParallelAlgorithm subclasses decide which class to instantiate. This is the principle of the factory method design pattern. It lets a class defer instantiation to subclasses. Hence, each new implementation of a parallel algorithm will have its new ParallelAlgorithm and ParallelAlgorithmPiece subclasses. We made additional changes needed to keep conceptual integrity with this new approach for the two classes that define the behavior of a parallel algorithm that splits work into pieces using multithreading capabilities.
Read more
  • 0
  • 0
  • 2494
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-navigating-online-drupal-community
Packt
16 Oct 2009
9 min read
Save for later

Navigating the Online Drupal Community

Packt
16 Oct 2009
9 min read
Recipe 87: Creating an issue Page Bookmark IngredientsWeb Browser The issue queue is the central place of progress for Drupal modules. It serves as a place to find answers, patches, new ideas, and work on common concerns. Issues are referenced by number. On occasion, a web page will contain an issue queue number in text form rather than a full link to the issue. This recipe, once set up, simply saves the trouble of having to type drupal.org/node/ into the browser address bar. Just select the number and the bookmark will take you there. In Firefox add a new Bookmark onto the toolbar. Select Bookmarks | Organize Bookmarks | Bookmarks Toolbar | Organize | New Bookmark Set the Name to Drupal Issue and set the Location to the following: javascript:inum=escape(getSelection());location.href='http://www.drupal.org/node/'+inum. Visit a web page that contains an issue number and select the issue number text. For instance, try http://cvs.drupal.org/viewvc.py/drupal/contributions/modules/views/modules/views_taxonomy.inc. (Be sure to exclude the surrounding space and pound sign when selecting the number.) Click the Drupal Issue button in the bookmark toolbar. Recipe notes This bookmark approach may be replicated to visit a URL containing any selectable text. For instance, below is a variation to display all of your delicious bookmarks tagged with the selected text. (Delicious.com—also found at http://del.icio.us, is a wonderful online bookmark service.) Replace <ACCOUNTNAME> with your delicious.com account. Name: DeliciousLocation: javascript_tag=escape(getSelection());location.href='http://delicious.com/<ACCOUNTNAME>/'+tag Recipe 88: Searching the Views issue queue IngredientsWeb Browser In this recipe we look closely at how to search the Views issue queue. The lessons apply to all other Drupal projects as well. It is always a good idea to search the issue queue for related content before posting. Log on to drupal.org (if you are not already a member of the Drupal site, become a member). Basic Search Visit http://drupal.org/project/issues/views. At this main issue queue page you may search for text or filter by Status, Priority, Category, Version, or Component. These options are discussed in further detail below. You may also sort the table of issues by clicking on the table header. By default, the table is sorted by date. Advanced Search Go to the Views issue queue Advanced Search page. Visit the URL directly, at http://drupal.org/project/issues/search/views. From the project page (drupal.org/project/views), find the Issues block on the left, and click on the Advanced Search link. From the issue queue (drupal.org/project/issues/views), the Advanced Search Link appears under the title. There are a variety of routes to get there: Get to know the search options. Although there are ten form elements to choose, most users will routinely use just a few, leaving the other options blank. Search For (Routinely used): Enter search text. Use quotation marks to create a phrase. Assigned: This field is generally used by issue maintainers. Submitted by: This is most often used to find your own issues, though it could be used to see what other Drupal users are posting as well. Participant: This is also used to find your own posts. Note that Submitted by finds only the initial post by a user in the issue queue. Participant additionally includes responses to initial posts. Status: Leave blank to get all statuses. You may also select multiple options. For instance, you could select all issues designated as needs work, needs review, and reviewed & tested by the community. Scroll down the list and note Status filters such as closed issues, duplicates, issues that the maintainer won't fix, and features noted as by design. These are the statuses that are excluded if you select -Open Issues-. Priority: Leave blank to get all priorities. Category: Leave blank to get all categories. Version (Routinely used): A relative new option, 5.x issues saves you the trouble of having to Shift+click on each Drupal 5 release name. Component: The views module issue queue offers more component options than most modules. As a result, users may not always be familiar with properly assigning a component when they create an issue. A search of exposed filters components, for instance, may not find as many results as a text search of "exposed filters." Component can occasionally be a helpful selection, but is most often left blank. Issue Tags: These may be a challenge to search since few people add tag issues. This may become a more popular option in the future. Recipe notes Search ideas: Find all your posts by filling in your drupal.org user name under participant. Find patches by selecting all of the four patch statuses. Find all documentation issues connected to Views for Drupal 5.x. Go to another issue queue http://drupal.org/project/issues/search/<MODULENAME> and search for the word Views. From the module issue pages http://drupal.org/project/issues/<MODULENAME> you may also review module Statistics, and Subscribe to issues. Subscribe to your Own Issues (the default), None, or All Issues. I don't recommend the latter for the Views module as you will be setting yourself up for a deluge of email. Search across all projects at http://drupal.org/search/issues. Recipe 89: Posting an issue Posting a New issue If you are new to posting Drupal issues, consider just reading the issue queue for at least several days before posting. This will help you to get a sense of the culture of issue queue interaction. If you don't already have an account on drupal.org get one. Look for the User login block on the home page, and click on Create new account. Complete the steps to login. Search the issue queue before you post! (Recipe 88). If your topic already has an associated active issue, reply rather than posting a new issue.Also, before posting to the issue queue in a panic read the Drupal Troubleshooting FAQ http://drupal.org/Troubleshooting-FAQ. For instance, standard fare is to increase memory in the face of the White Screen of Death (WSOD) or to disable buggy modules by setting the status = 0 in the system table. Be sure to know which version of the module you're using. Is it the dev (development) version? Is it the latest recommended release? The version number can generally be found at http://YOURSITE.com/admin/build/modules. To start a new issue, go to http://drupal.org/project/issues/<MODULENAME> and click on Create a new issue. This directs the browser to: http://drupal.org/node/add/project-issue/<MODULENAME>. For the Views module, the link at http://drupal.org/node/add/project-issue/views offers guidance (in bold!) for posting. Read it! Much of it applies to Views 2 but it contains useful information for Views 1 users as well. Required fields for a new issue include Version, Component, Category, Title, and Description. Be thoughtful with these details. For instance, do not title your issue HELP??!! A much more useful description would be something like Missing taxonomy terms in filters. Priority should generally be left as normal. Critical is reserved for occasions then the module simply does not work. Responding to an existing issue You may also respond to an existing issue by selecting the Add New Comment link or one of the Reply links on an individual issue page. Another option is just to scroll down to the bottom of the issue page, and begin entering a response. Unlike some forum tools, in which replies are indented, all new comments are given a new comment number, and added to the bottom of the comments. When responding to an issue you may take a variety of actions: Change the Issue Title. In general, don't change this unless you have a very good reason (for instance, if the original title is misleading, or spelled wrong). Some people are used to forums where a response can have a different name as the original post. In the issue queue, changing the name when responding to an issue actually changes the name of the issue. This is generally best left untouched. Change the Project. A question that someone asks in the Views issue queue may be more appropriately managed in the issue queue for a different module. This is a rare change generally left to the maintainer of one of the two modules who will know in which issue queue a discussion belongs. Change the Version number, Component, Category, or Priority. These changes are rare (correcting the version number is probably the most common). When changes are made, they are noted in the post as shown below: Change Assign. Do not assign someone other than yourself to an issue. Assign yourself if you are sure that you will soon fix the issue. It is quite common to leave this as Unassigned. Change the Status. For instance: Mark an issue as a duplicate (always provide a pointer to the issue it duplicates). Note that a patch is reviewed and tested by the community. Post a question, patch, answer, or idea related to the issue in the Comment section. Open the Input format fieldset below the comment field to see what markup is available. Note the <code> tag, for instance (and remember to close it with a </code> tag). Attach a file. Recipe notes Remember that respondents and maintainers are volunteers. They are generally very busy people who want to help, but they do not have time to do free consulting. See the following pages for spirited discussions about issue queue etiquette: http://acko.net/blog/whats-wrong-with-drupal http://paul.leafish.co.uk/articles/drupal/on_subscribing_to_module_portingupdating_issues One discussion theme is the merit of simply sending the word subscribe to the issue queue. People sometimes do this so that they can track an issue—receiving an email alert each time something new is posted. On drupal.org it is possible to subscribe to a node only if you leave a comment, but most people prefer comments with substance. You may create functionality similar to the Drupal issue queue on your own site by installing the project, project_issue, and comment_upload modules.
Read more
  • 0
  • 0
  • 3868

article-image-maintaining-optimizing-and-upgrading-your-site-drupal-6-part-1
Packt
16 Oct 2009
7 min read
Save for later

Maintaining, Optimizing and Upgrading Your Site in Drupal 6: Part 1

Packt
16 Oct 2009
7 min read
We will consider the example of an imaginary web site created for a restaurant called Good Eatin' Bistro. Chef Wanyama is the owner of the Good Eatin' Bistro, a popular upscale restaurant. You can check this web site at http://goodeatin.drupalbyexample.com/. Web site backups A strong backup plan is critical for any successful web site. A good backup plan will protect against hardware failure, allow you to transfer your web site to another host, and allow you to recover from malicious hacking into your web site. When you create a backup plan, you should also test the restoration from this backup to make sure that the backup works correctly. In this section, we will explore ways of performing backups regardless of the host that you are using. Your hosting provider may also offer a solution that will back up files and databases either one time, or on a recurring basis. If your host does provide backup capabilities, you should review them to see if they suit your needs completely, or if you want to augment them or replace them with the techniques in this section. Manually backing up a site Good Eatin' Goal: Back up the web site without using a custom backup module. Additional modules needed: None. Basic steps If you do not want to use a dedicated module to perform your backups, you can manually download the files and the database information that make up the site. However, this can be more time-intensive and error-prone than using a custom backup module. A manual backup has two steps, in which you must first back up the files that make up the site and then back up the database information. To back up the files for the web site, use the following procedure: Begin by opening the utility that you use to transfer files to the web site. This could be an FTP client, or an online file manager. My favorite FTP client is FileZilla, which is a freely-available open source client. The FileZilla client can be downloaded from http://filezilla-project.org/. Select the backup location on your local computer to which you want to copy the files, and select the root directory of your web server as the remote directory. You may want to date the backup folder so that you can maintain a history of the site. Next, download the files to your local directory. If you want, you can compress the files into a ZIP file or a compressed archive. To reduce the amount of data that you need to download, you should be able to download just the sites directory, because that folder contains all of the custom files, pictures, themes, and modules that you have added to the site. To back up the database information, you can use your web site provider's database management utility. Many hosts provide phpMyAdmin for this purpose. If you are unsure whether or not your host gives you access to phpMyAdmin, you can contact their customer support group to check. Begin by opening phpMyAdmin and selecting the database that has your site information within it. The screen should be similar to the following: If you have multiple databases available on the host, you may need to select the database that you want to work with in the drop-down list at the upper left corner of the screen. Next, select the Export tab at the top of the screen. phpMyAdmin will prompt you to select the tables that you want to download and the format that you want to download in, as shown in the following screenshot: If you want to be able to rebuild the database at a later time, you should export all the tables in SQL format. Next, you will need to specify the name of the file to download to. You can use __DB__ as the database name. You may want to zip the file to reduce storage space. Then click Go to begin the download process. You will be prompted for the location to which you want to save the exported data. When you are ready to restore the web site from backup, you simply reverse the process. You should always import into a blank database, to avoid conflicts with existing data. You can either drop or delete all of the titles in the existing database, or you can create a new database to import the data into. After you have cleaned out your database, select the Import tab in phpMyAdmin. Now navigate to the file that you exported earlier, and click Go to begin the import. You may need to delete all of the tables in the database before you import the data, depending on the options you chose when you exported the data. To reload the files, simply open your FTP client, select the same directories that you used when creating the backup and then upload the files, rather than downloading them. Automatic site backups Good Eatin' Goal: Back up a web site so that it can be stored for easy recovery. Additional modules needed: Backup and Migrate (http://drupal.org/project/backup_migrate). Basic steps Although you can manually back up your files and database, this process can be time-consuming and error prone. Luckily, the Backup and Migrate module makes this process easier, and optimizes the backups to exclude unnecessary data. Begin by downloading and installing the Back up and Migrate module. You can now back up your data by selecting Content management and then Backup and migrate, from the Administer menu. The Backup and Migrate module allows you to fully customize the backup files that are created. You can control which tables are included in the backup, and whether or not the data in the table is backed up. By default, the Backup and Migrate module does not back up cache information, session information, or watchdog information, because data in these tables is temporary and can easily be re-created. There are a variety of other options that you can choose from, which control how the resulting file is named, how it is compressed, and where it is compressed to. Once you have set the options as desired, click Backup Database to begin the backup process. If you have selected the Download option, the file will be sent to your computer so that you can store it. If you select the Save to Files Directory option, the backup file will be saved onto the server so that you can download it later, either directly from the server or using the Saved Backups tab. If you would like the Backup and Migrate module to back up your database automatically on a regular basis, you can schedule the back up to occur at specified intervals by clicking on the Backup Schedule tab, as shown here: Please note that the backups created by the Backup and Migrate module do not include the files from the site, so you will still need to back up these files independently. You can minimize the backup file size by only backing up the files that the users can upload. These files are typically stored in the files directory. The process for backing up files is identical to the process used in the section on manual backups. Restoring a site from a backup Good Eatin' Goal: Restore information from a backup file created by the Backup and Migrate module. Additional modules needed: Backup and Migrate (http://drupal.org/project/backup_migrate). Basic steps Restoring a backup created by the Backup and Migrate module is a simple process. Navigate to the Backup and Migrate manager by selecting Content management and then Backup and Migrate, from the Administer menu. Next, click on the Restore/Import DB tab. Navigate to the location of your backup file. After you have selected the backup file, click on Restore Database to begin the restore process. Please read all displayed warnings carefully, and make sure that you test the import on a test installation for your site before running it on your production site. If you are sure that you want to proceed with the import, agree to the confirmation and click restore. You may also need to import any saved files, if the server file system is not fully up-to-date. We discussed this previously in the section on manual backups.
Read more
  • 0
  • 0
  • 1367

article-image-voice-menus-and-ivr-asterisknow
Packt
16 Oct 2009
3 min read
Save for later

Voice Menus and IVR in AsteriskNOW

Packt
16 Oct 2009
3 min read
Four Rules of IVR IVR systems can be hell to use; the main reason for this is that people designing IVR systems tend to complicate their functionality beyond the normal usage scope of a human being. The following four rules will enable you to implement a usable, humanly accessible, and maintainable IVR. Rule 1—Keep it narrow: Your IVR should be kept as simple as possible. Make sure that each of your steps in the IVR environment is not longer than five options. Most IVR users aren't able to remember all the options of an IVR system, when presented with a multitude of IVR options. Rule 2—Keep it shallow: Your IVR system's depth is in direct relation to the complexity of the IVR application. If your application has more than four levels, you need to revise your IVR plan. Most people (including yours truly) become extremely aggravated when confronted with an IVR system that is asking for too much information. Rule 3—Enable escape routes: Always give your IVR user the ability to break out of the IVR flow and talk to a live person. Some people simply can't handle the usage of an IVR system. Rule 4—If it works, don't fix it!: For some reason, companies tend to change their IVR flows every other day to support a new business model. An IVR system that constantly changes is a nightmare for users, as they never get used to the options of the system. If you must perform an update, make sure that your update doesn't affect that system in such a way that the users need to re-learn the system. Voice Menus—AsteriskNOW's IVR Generator AsteriskNOW provides a highly simplistic IVR generator, rightfully named—Voice Menus. The main usage of an IVR in a PBX is the implementation of an "Auto Attendant". Some PBX systems refer to auto-attendant and IVR as two different things. In AsteriskNOW, they are one and the same. At this point, click the Voice Menus link, located on your left-hand main menu. The following should appear on your screen: This interface enables editing, creation, or deletion of voice menus. Each menu is built from a set of operational directives (Steps) and functional keys (Keypress Events). Each voice menu also receives a mandatory name (Name), a form of logical entity description, and an Extension number (optional). The extension number enables PBX extensions or external users to dial into the specific voice menu indicated by the extension number. Voice Menu Steps—The Voice Menu Flow Steps are performed one after the other, in the order they appear on the screen. There are seventeen possible steps, available through the AsteriskNOW GUI. Once a step had been selected, the GUI will change, indicating the requirement for additional fields to be filled. The seventeen available steps are as follows:
Read more
  • 0
  • 0
  • 4754

article-image-joomla-15-template-reference-part-2
Packt
16 Oct 2009
4 min read
Save for later

Joomla! 1.5 Template Reference: Part 2

Packt
16 Oct 2009
4 min read
Common Joomla! CSS As you can see, via template overrides, you can pretty much define any CSS ids or classes you want. For those of you who are into creating and tweaking template overrides, unless you're going to create a highly custom, private, not-for-the-public template, my recommendation is you continue to use Joomla's general CSS ids and classes for component and module output as much as possible. This is a good way to ensure your template is familiar to other Joomla! administrators, especially if you want to offer your template to the public or for commercial sale. It's easy for them to look up and customize CSS rules rather than forcing them to discover all the new and interestingly-named CSS ids and classes you created. For those of us working with Joomla's core output or the Beez template overrides (which attempts to use Joomla's standard CSS), here is a list of some of the most common CSS ids and classes. Those of you familiar with Joomla! 1.0 template design will be pleased to find these haven't really changed. This list has been put together after a bit of research and a lot of experimentation with the Web Developer Toolbar CSS tools. It is probably not complete, but if you account for these items in your CSS rules, you'll be pretty well covered for most Joomla! projects, and it will be easy to spot any ids or classes not covered here and add them to your CSS sheet. The Joomla.org forum has a post with a fairly comprehensive list, most of which you'll recognize here, so it's definitely worth checking out: http://forum.joomla.org/viewtopic.php?t=125508. Joomla! 1.5 CSS ids #active_menu This is generated by the type="modules" include. Use it to style and control the currently selected main menu item. #blockrandom This is generated by the type="component" include when you're using the wrapper. This is the iFrame's id. #contact_email_copy This is generated by the type="component" include when you're in the contact form page view. This is a field name id. #contact_text This is generated by the type="component" include when you're in the contact form page view. This is a field name id. #emailForm This is generated by the type="component" include when you're in the contact form page view. This is a field name id. #mainlevel This is generated by the type="modules" include. Use it to style and control the main menu div holding each main menu item. #mod_login_password This is generated by the type="modules" include. This is a field name id. #mod_login_remember This is generated by the type="modules" include. This is a field name id. #mod_login_username This is generated by the type="modules" include. This is a field name id. #poll This is generated by the type="modules" include by the poll module. You can control the placement of the entire id with this. #search_ordering This is generated by the type="component" include when you're in the search form page view. This is a field name id. #search_searchword This is generated by the type="component" include when you're in the search form page view. This is a field name id. #searchphraseall This is generated by the type="component" include when you're in the search form page view. This is a field name id. #searchphraseany This is generated by the type="component" include when you're in the search form page view. This is a field name id. #searchphraseexact This is generated by the type="component" include when you're in the search form page view. This is a field name id. #voteid1,#voteid2,#voteid3, and so on This is generated by the type="modules" include. This is generated by the poll module and are field name ids for the radio buttons.    
Read more
  • 0
  • 0
  • 1784
article-image-user-input-validation-tapestry-5
Packt
16 Oct 2009
9 min read
Save for later

User Input Validation in Tapestry 5

Packt
16 Oct 2009
9 min read
Adding Validation to Components The Start page of the web application Celebrity Collector has a login form that expects the user to enter some values into its two fields. But, what if the user didn't enter anything and still clicked on the Log In button? Currently, the application will decide that the credentials are wrong and the user will be redirected to the Registration page, and receive an invitation to register. This logic does make some sense; but, it isn't the best line of action, as the button might have been pressed by mistake. These two fields, User Name and Password, are actually mandatory, and if no value was entered into them, then it should be considered an error. All we need to do for this is to add a required validator to every field, as seen in the following code: <tr> <td> <t:label t_for="userName"> Label for the first text box</t:label>: </td> <td> <input type="text" t_id="userName" t_type="TextField" t:label="User Name" t_validate="required"/> </td></tr><tr> <td> <t:label t_for="password"> The second label</t:label>: </td><td> <input type="text" t_id="password" t_label="Password" t:type="PasswordField" t_validate="required"/></td></tr> Just one additional attribute for each component, and let's see how this works now. Run the application, leave both fields empty and click on the Log In button. Here is what you should see: Both fields, including their labels, are clearly marked now as an error. We even have some kind of graphical marker for the problematic fields. However, one thing is missing—a clear explanation of what exactly went wrong. To display such a message, one more component needs to be added to the page. Modify the page template, as done here: <t:form t_id="loginForm"> <t:errors/> <table> The Errors component is very simple, but one important thing to remember is that it should be placed inside of the Form component, which in turn, surrounds the validated components. Let's run the application again and try to submit an empty form. Now the result should look like this: This kind of feedback doesn't leave any space for doubt, does it? If you see that the error messages are strongly misplaced to the left, it means that an error in the default.css file that comes with Tapestry distribution still hasn't been fixed. To override the faulty style, define it in our application's styles.css file like this: DIV.t-error LI{ margin-left: 20px;} Do not forget to make the stylesheet available to the page. I hope you will agree that the efforts we had to make to get user input validated are close to zero. But let's see what Tapestry has done in response to them: Every form component has a ValidationTracker object associated with it. It is provided automatically, we do not need to care about it. Basically, ValidationTracker is the place where any validation problems, if they happen, are recorded. As soon as we use the t:validate attribute for a component in the form, Tapestry will assign to that component one or more validators, the number and type of them will depend on the value of the t:validate attribute (more about this later). As soon as a validator decides that the value entered associated with the component is not valid, it records an error in the ValidationTracker. Again, this happens automatically. If there are any errors recorded in ValidationTracker, Tapestry will redisplay the form, decorating the fields with erroneous input and their labels appropriately. If there is an Errors component in the form, it will automatically display error messages for all the errors in ValidationTracker. The error messages for standard validators are provided by Tapestry while the name of the component to be mentioned in the message is taken from its label. A lot of very useful functionality comes with the framework and works for us "out of the box", without any configuration or set-up! Tapestry comes with a set of validators that should be sufficient for most needs. Let's have a more detailed look at how to use them. Validators The following validators come with the current distribution of Tapestry 5: Required—checks if the value of the validated component is not null or an empty string. MinLength—checks if the string (the value of the validated component) is not shorter than the specified length. You will see how to pass the length parameter to this validator shortly. MaxLength—same as above, but checks if the string is not too long. Min—ensures that the numeric value of the validated component is not less than the specified value, passed to the validator as a parameter. Max—as above, but ensures that the value does not exceed the specified limit. Regexp—checks if the string value fits the specified pattern. We can use several validators for one component. Let's see how all this works together. First of all, let's add another component to the Registration page template: <tr> <td><t:label t_for="age"/>:</td> <td><input type="text" t_type="textfield" t_id="age"/></td></tr> Also, add the corresponding property to the Registration page class, age, of type double. It could be an int indeed, but I want to show that the Min and Max validators can work with fractional numbers too. Besides, someone might decide to enter their age as 23.4567. This will be weird, but not against the laws. Finally, add an Errors component to the form at the Registration page, so that we can see error messages: <t:form t_id="registrationForm"> <t:errors/> <table> Now we can test all the available validators on one page. Let's specify the validation rules first: Both User Name and Password are required. Also, they should not be shorter than three characters and not longer than eight characters. Age is required, and it should not be less than five (change this number if you've got a prodigy in your family) and not more than 120 (as that would probably be a mistake). Email address is not required, but if entered, should match a common pattern. Here are the changes to the Registration page template that will implement the specified validation rules: <td> <input type="text" t_type="textfield" t_id="userName" t:validate="required,minlength=3,maxlength=8"/></td>...<td> <input type="text" t_type="passwordfield" t_id="password" t:validate="required,minlength=3,maxlength=8"/></td>...<td> <input type="text" t_type="textfield" t_id="age" t:validate="required,min=5,max=120"/></td>...<input type="text" t_type="textfield" t_id="email" t:validate="regexp"/> As you see, it is very easy to pass a parameter to a validator, like min=5 or maxlength=8. But, where do we specify a pattern for the Regexp validator? The answer is, in the message catalog. Let's add the following line to the app.properties file: email-regexp=^([a-zA-Z0-9_.-])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,4})+$ This will serve as a regular expression for all Regexp validators applied to components with ID email throughout the application. Run the application, go to the Registration page and, try to submit the empty form. Here is what you should see: Looks all right, but the message for the age could be more sensible, something like You are too young! You should be at least 5 years old. We'll deal with this later. However for now, enter a very long username, only two characters for password and an age that is more than the upper limit, and see how the messages will change: Again, looks good, except for the message about age. Next, enter some valid values for User Name, Password and Age. Then click on the check box to subscribe to the newsletter. In the text box for email, enter some invalid value and click on Submit. Here is the result: Yes! The validation worked properly, but the error message is absolutely unacceptable. Let's deal with this, but first make sure that any valid email address will pass the validation.   Providing Custom Error Messages We can provide custom messages for validators in the application's (or page's) message catalog. For such messages we use keys that are made of the validated component's ID, the name of validator and the "message" postfix. Here is an example of what we could add to the app.properties file to change error messages for the Min and Max validators of the Age component as well as the message used for the email validation: email-regexp-message=Email address is not valid.age-min-message=You are too young! You should be at least 5 years old.age-max-message=People do not live that long! Still better, instead of hard-coding the required minimal age into the message, we could insert into the message the parameter that was passed to the Min validator (following the rules for java.text.Format), like this: age-min-message=You are too young! You should be at least %s years old. If you run the application now and submit an invalid value for age, the error message will be much better: You might want to make sure that the other error messages have changed too. We can now successfully validate values entered into separate fields, but what if the validity of the input depends on how two or more different values relate to each other? For example, at the Registration page we want two versions of password to be the same, and if they are not, this should be considered as an invalid input and reported appropriately. Before dealing with this problem however, we need to look more thoroughly at different events generated by the Form component.  
Read more
  • 0
  • 0
  • 4197

article-image-competitive-service-and-contract-management-sap-business-one-implementation-part-1
Packt
16 Oct 2009
5 min read
Save for later

Competitive Service and Contract Management in SAP Business ONE Implementation: Part 1

Packt
16 Oct 2009
5 min read
What we will learn in this article? In this article, we will cover the service module and highlight how it fits in with the sales and opportunities management functionality. The key features, from taking a service call to contracting management, will be explained. In order to establish a practical platform for this, a case study will be expanded to utilize the service module. As a part of this section, a complete workflow will be configured from setting the right parameters in the admin section to connecting the information for service personnel. We will learn about : Key terms - The common terminology related to service management will be covered. There is nothing major waiting for you here. We will simply learn what the terms entail with regards to the SAP system. Service module core functions – In this section, the available functions and features will be put into perspective—what is available and how much we can expect from it. For example, you will learn what service operations mean. Case study and your own project – The available features of the service module will then be implemented for the case study. By doing so, knowledge will be provided to implement the service module in your own business. We will review some guidelines which will enable you to translate the case study implementation into a set of activities for your own project. Key terms Let's start with the key terms related to service and contract management in SAP Business ONE. By looking at the key terms, you will get an understanding of what can be accomplished with this module Service contract templates In the admin section, we can define the service contract templates that can later be used as a basis for actual contracts. Please note the template character. All of the parameters we define here will automatically populate the relevant details in the contract once a template is selected. The following screenshot shows that a contract template can be created not only on a per-customer basis, but also for item groups, and a specific item based on serial numbers. In addition, please note the Reminder setting. You can set a reminder which will provide an alert prior to the expiry of the contract. This way, you can be sure that you contact all customers and allow them to renew their contracts. Serial number contract The most common usage may be the Serial Number contract type. Each product will have a specific contractual service eligibility based on the serial number. Consequently, if a customer purchases an item that is managed by a serial number, a warranty contract template can be associated. This will create a customer equipment card. Customer contract However, please note that this concept does not need to be used only for items and serial numbers. As you can see in the previous screenshot, we can create contract templates for customers and whole item groups. For the case study, I will use this concept to create a service contract for key customers. We can then use the service functionality in SAP to make sure these customers get priority treatment. You see, we can use the service functionality in this creative way to improve our service quality. Item group contract Just as we may decide to use the service module to guarantee a specific response time to customers, we can make sure that a specific product line is managed. For example, if you have a new specifi c product line that requires technical expertise for implementation, then a service contract may be offered to customers. Therefore, all customers who purchase an item that belongs to this group will be eligible to purchase a contract and receive the relevant expert support. Customer equipment card The customer equipment card applies to the contracts that are managed by a serial number. Since the serial number contract applies a unique contract situation for each item, you will need to have the relevant information to be able to categorize a service call. For example, you need to know the serial number to identify the customer and the relevant warranty that remains for the specific serial number. In addition, if a customer calls you, you"ll want to be able to look up all of the serial numbers for this customer. This can be done using the customer equipment card. Please note that a customer equipment card is automatically created if a customer purchases an item that is managed by a serial number. You can assign a service contract when this happens on the level of sales order. Service calls Service calls are incoming service requests from business partners. The following screenshot shows that service calls can have many sources. For example, service calls may come via emails, phone calls, web requests, or any other defined Origin. I am highlighting this because, in essence, you can use the service module for any activity where you want to apply a specifi c response time management. Queues As mentioned above, the service module can be used to manage any kind of service-related activity. Queues allow your personnel to be associated with named groups. In the following screenshot, I have created two queues. The first queue is for 1st Level and the second queue for Resolution and Sales. Consequently, I assign personnel who can best accomplish the relevant tasks to each queue as follows: Knowledge base As you work on service calls, you can build a knowledge base that documents how problems were resolved. For example, if the problem resolution department resolved a problem, it will be documented as a part of the service call. If the service call is for a serialized item, then this knowledge is available to the first-level support the next time a problem is reported for the same item type. Therefore, this can take the workload off of the specialized personnel as they can avoid repetitive tasks. In addition, new employees can benefit from the knowledge already acquired for resolved service calls.
Read more
  • 0
  • 0
  • 6105

article-image-creating-matrix-report-using-analysis-services-cube
Packt
16 Oct 2009
4 min read
Save for later

Creating a matrix report using the Analysis Services Cube

Packt
16 Oct 2009
4 min read
Reviewing Jayaram's other OLAP related articles may greatly help in understanding this article. Creating the CUBE will be essential to work with this hands-on. If you are already experienced and have an appropriate CUBE to work with you may directly go to the section on deriving a dataset. The CUBE used in this hands-on is a simple one. It does not even have a "Time" dimension although Microsoft in Visual Studio gives a warning that you should have one. However for the purposes of demonstration and doing the hands-on a CUBE without the "Time" dimension should be adequate. The two previous articles on creating a CUBE provide the necessary background for this article. Create a data source with a CUBE Create an Analysis Services Cube (herein called MyNwind.cube) using the TestNorthwind as the database. The Measures and Dimensions for this cube are as shown in the next figure. Start your Report Builder 2.0. Make sure you have started the reporting services using the Reporting Services Configuration Manager. In Report Builder 2.0 click on New | Data source... under Report Data. Provide the following information: Name: SrcCubeSelect connection type: Microsoft SQL Server Analysis ServicesConnection String: Data Source=Hodentek2SANGAM; Initial Catalog=NwindRTM Herein NwindRTM is the name of the Datasource in the Analysis Server. (Alternately you may build this source as shown). Click OK on the Data Source Properties window. Add a dataset to the report Right click on SrcCube and choose Add DataSet... In the Dataset Properties window make the following changes: Name: QryCubeData source: SrcCubeQuery Type: text Click on Query Designer... button. At first you will see only the Metadata of the cube displayed as in the left side of the next figure. Expand Customers, Orders, and Products in the dimensions and drop them on the list header in the bottom pane on the right hand side of the next figure. Drag and drop Freight from Orders under Measures as shown. For each of the dimensions using an operator create a filter expression as shown. For example, the Products included in the query range from Product IDs 3 to 9; the Customer ID (some specific ones are chosen), similarly theCategory ID (only those with ID's 2, 3, 4, and 5 are included in the query). The design of the query with these filtering choices is as shown in the previous figure. The filtering tool is very flexible and all the items namely Dimension, Hierarchy, Operator and Filter Expression can be designed in this interface using either drop-down pick lists choices or drop-downs with checkboxes as shown here. Run the query by clicking on the toolbar item (!) and review the results. Click OK on the Query Designer. The Dataset Properties window shows up with this query designed according to your choices in the query item window as shown. Close the Dataset Properties window. Report Design In Report Builder 2.0 click on New Table or Matrix wizard. In the Choose a dataset window accept the default and click Next. Drag and drop Customer_ID in the Row Groups drop area. Drag and drop Order_ID below Customer_ID in the Row Groups drop area. Drag and drop Product_ID in the Column Groups drop area. Drag and drop Freight into the Values drop area and click on Next. In the Choose the layout window accept Expand/collapse groups and choose the option Stepped, subtotal above. Click Next and choose some style (herein Ocean) and click Finish. The final report design is as shown here. Click Home | Run. The report gets displayed after processing as shown here. The orders from a particular customer have been expended in this view. Summary Report Builder 2.0 can used to author reports based on Analysis Services Cubes. The interface is very flexible and the Query Designer is very easy to use as shown in this article. If you have read this article you may be interested to view : Creating an Analysis Services Cube with Visual Studio 2008 - Part 1 Creating an Analysis Services Cube with Visual Studio 2008 - Part 2
Read more
  • 0
  • 0
  • 3698
article-image-jbi-binding-components-netbeans-ide-6
Packt
16 Oct 2009
4 min read
Save for later

JBI Binding Components in NetBeans IDE 6

Packt
16 Oct 2009
4 min read
Binding Components Service Engines are pluggable components which connect to the Normalized Message Router (NMR) to perform business logic for clients. Binding components are also standard JSR 208 components that plug in to NMR and provide transport independence to NMR and Service Engines. The role of binding components is to isolate communication protocols from JBI container so that Service Engines are completely decoupled from the communication infrastructure. For example, BPEL Service Engine can receive requests to initiate BPEL process while reading files on the local file system. It can receive these requests from SOAP messages, from a JMS message, or from any of the other binding components installed into JBI container. Binding Component is a JSR 208 component that provides protocol independent transport services to other JBI components. The following figure shows how binding components fit into the JBI Container architecture: In this figure, we can see that the role of BC is to send and receive messages both internally and externally from Normalized Message Router using protocols, specific to the binding component. We can also see that any number of binding components can be installed into the JBI container. This figure shows that like Service Engines (SE), binding components do not communicate directly with other binding components or with Service Engines. All communication between individual binding components and between binding components and Service Engines is performed via sending standard messages through the Normalized Message Router. NetBeans Support for Binding Components The following table lists which binding components are installed into the JBI container with NetBeans 5.5 and NetBeans 6.0:   As is the case with Service Engines, binding components can be managed within the NetBeans IDE. The list of Binding Components installed into the JBI container can be displayed by expanding the Servers | Sun Java System Application Server 9 | JBI | Binding Components node within the Services explorer. The lifecycle of binding components can be managed by right-clicking on a binding component and selecting a lifecycle process—Start, Stop, Shutdown, or Uninstall. The properties of an individual binding component can also be obtained by selecting the Properties menu option from the context menu as shown in the following figure. Now that we've discussed what binding components are, and how they communicate both internally and externally to the Normalized Message Router, let's take a closer look at some of the more common binding components and how they are accessed and managed from within the NetBeans IDE. File Binding Component The file binding component provides a communications mechanism for JBI components to interact with the file system. It can act as both a Provider by checking for new files to process, or as a Consumer by outputting files for other processes or components. The figure above shows the file binding component acting as a Provider of messages. In this scenario, a message has been sent to the JBI container, and picked up by a protocol-specific binding component (for example, a SOAP message has been received). A JBI Process then occurs within the JBI container which may include routing the message between many different binding components and Service Engines depending upon the process. Finally, after the JBI Process has completed, the results of the process are sent to File Binding Component which writes out the result to a file. The figure above shows the file binding component acting as a Consumer of messages. In this situation, the File Binding Component is periodically polling the file system looking for files with a specified filename pattern in a specified directory. When the binding component finds a file that matches its criteria, it reads in the file and starts the JBI Process, which may again cause the input message to be routed between many different binding components and Service Engines. Finally, in this example, the results of the JBI Process are output via a Binding Component. Of course, it is possible that a binding component can act as both a provider and a consumer within the same JBI process. In this case, the file binding component would be initially responsible for reading an input message from the file system. After any JBI processing has occurred, the file binding component would then write out the results of the process to a file. Within the NetBeans Enterprise Pack, the entire set of properties for the file binding component can be edited within the Properties window. The properties for the binding component are displayed when either the input or output messages are selected from the WSDL in a composite application as shown in the following figure.
Read more
  • 0
  • 0
  • 1826

Packt
16 Oct 2009
6 min read
Save for later

Network Configuration—IPv6 with FreeBSD

Packt
16 Oct 2009
6 min read
Several methods were introduced to reduce the usage of IP addresses in the internet including: Classless Interdomain Routing (CIDR): This introduced the death of classful addressing (for example Class A, B, C) by a new subnetting method which is not limited, unlike the classful method. Network Address Translation (NAT): Using NAT you do not need to use public IP addresses on your internal hosts. Using CIDR subnets and NAT only helped IPv4 to live a few years longer, but was not the ultimate cure to the problem. Besides the addressing issues, there were other problems with IPv4 which could not be easily solved. These issues include the following: The size of internet routing tables was growing rapidly and this forced backbone providers to upgrade their networking gears. The IPv4 was very inefficient for high throughput links and did not support QoS by nature. Back in the early 90s, IETF had started a workgroup to solve the deficiencies of the IP protocol. In 1995, the IETF published the initial drafts of IPv6 as the next generation IP. Since then, the protocol has matured enormously and been implemented in many operating systems. IPv6 Facts If you are not familiar with IPv6, here is a very quick look at the difference between IPv4 and IPv6. (For a more detailed insight into IPv6 and its configuration in various operating systems, it is recommended that you read Running IPv6 book by Iljitsch van Beijnum). Fact One—Addressing Addressing in IPv6 is quite different from legacy IPv4 addresses. IPv6 uses 128-bit address space unlike the 32-bit addressing system in IPv4. A typical IPv6 address would look like—2002:a00:1:5353:20a:95ff:fef5:246e Fact Two—Address Types There are 4 types of addresses in IPv6: Unicast: A typical IPv6 address you use on a host. Multicast: Addresses that start with ff:: are equivalent to IPv4 multicast. Anycast: A typical IPv6 address that is used on a router. Reserved: Includes loopback, link-local, site-local, and so on. Fact Three—ARP There is no ARP! MAC to IP mapping is no longer needed as MAC addresses are embedded into IPv6 addresses. Instead, ND is born. ND is used to auto-configure addresses on hosts, duplicated detection, and so on. Fact Four—Interface Configuration If you are new to IPv6, you will be shocked to see an IPv6 address, telling yourself that you are in trouble assigning addresses to interfaces or remembering the addresses. However, it is not all that hard. In most cases, you can have your host autoconfigure IPv6 address on its interfaces. Typically, you should set this up only on your network gateway (router) manually. Using IPv6 Running FreeBSD 7, the kernel is already IPv6 enabled. However, you should manually enable IPv6 in the UserLand, by adding the following line to the /etc/rc.conf configuration file: ipv6_enable="YES" And manually start the appropriate rc script (or reboot the system) for the changes to take effect: # /etc/rc.d/network_ipv6 start This will enable IPv6 on all interfaces that are IPv6 capable. This behavior is changed by modifying the following variable in the /etc/rc.conf file: ipv6_network_interfaces="fxp0 bge0" This will enable IPv6 support on specified interfaces. The default value for this variable is auto. Once you enable IPv6, interfaces will discover the IPv6 enabled routers on the network and build their own IPv6 addresses based on the network prefix they receive from the router. Configuring Interfaces In a typical scenario, IPv6 network stack will automatically look for an IPv6 enabled router on the same network for each interface and try to automatically configure the IPv6 address on the interface. The following is an example of an automatically configured interface(replace the $ with %): # ifconfig ed0 ed0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 ether 00:1c:42:8d:5d:bf inet6 fe80::21c:42ff:fe8d:5dbf$ed0 prefixlen 64 scopeid 0x1 inet 192.168.0.225 netmask 0xffffff00 broadcast 192.168.0.255 inet6 2a01:3c8::21c:42ff:fe8d:5dbf prefixlen 64 autoconf media: Ethernet autoselect (10baseT/UTP) Beside the IPv4 address, there are two IPv6 addresses on the interface. One address begins with fe80:: and identified with the scopeid 0x1 tag, which is called a link-local address. Another address begins with 2a01:3c8::, which is the unicast address of this interface. The unicast address prefix is obtained from the IPv6 router on the network. The whole address is created using the 64 bits Extended Unique Identifier (EUI-64) algorithm, which consists of the hosts MAC address with some minor modifications. The link-local address (that is from the reserved address pool) always starts with fe80:: and is used for local network usage. This can be compared with RFC1819 private addresses that are suitable for local use. The network stack will automatically assign a link-local address to each IPv6 enabled interface, regardless whether an IPv6 router is discovered on the network. This means that in a scenario of a home network or a lab network, you do not need to run an IPv6 router or have a valid IPv6 prefix in order to establish an IPv6 network. All the hosts will be automatically provisioned with a link-local address, so they can exchange IPv6 traffic. The network discovery protocol (NDP) helps the host find the router on the network and then create a unicast address for the interface. NDP is known as the equivalent to ARP protocol in IPv6. The ndp(8) utility is used to control the behavior of this protocol: # ndp -a Neighbor Linklayer Address Netif Expire S Flags 2a01:3c8:: 0:16:cb:98:d4:bf ed0 20s R R 2a01:3c8::21c:42ff:fe8d:5dbf 0:1c:42:8d:5d:bf ed0 permanent R fe80::216:cbff:fe98:d4bf$ed0 0:16:cb:98:d4:bf ed0 23h58m48s S R fe80::21c:42ff:fe8d:5dbf$ed0 0:1c:42:8d:5d:bf ed0 permanent R fe80::1%lo0 (incomplete) lo0 permanent R The above example shows the discovered IPv6 hosts(replace the $ with %). The ed0 interface is connected to an IPv6 enabled network and receives a valid prefix via a router (the first entry of the list). The second entry is the unicast address of the ed0. The third and the fourth entries are link-local address for the router and our host. And the last entry belongs to the local host. As you have seen so far, there are some special (reserved) IPv6 addresses. The following table shows a list of reserved addresses:   Address Name Description :: Unspecified Equivalent to 0.0.0.0 in Pv4 ::1 Loopback address Equivalent to 127.0.0.1 in IPv4 fe80:: Link-local fec0:: Site-local ff00:: Multicast   In case you want to configure the static IPv6 address on an interface, it can be done as in a typical IPv4 scenario: # ifconfig vr0 inet6 2a01:3c8::21c:42ff:dead:beef prefixlen 64 This will manually configure an IP address on the specified interface. Note the prefixlen keyword that is equivalent to subnet mask in IPv4.
Read more
  • 0
  • 0
  • 4973
Modal Close icon
Modal Close icon