Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
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-testing-and-debugging-grok-10-part-2
Packt
11 Feb 2010
8 min read
Save for later

Testing and Debugging in Grok 1.0: Part 2

Packt
11 Feb 2010
8 min read
Adding unit tests Apart from functional tests, we can also create pure Python test cases which the test runner can find. While functional tests cover application behavior, unit tests focus on program correctness. Ideally, every single Python method in the application should be tested. The unit test layer does not load the Grok infrastructure, so tests should not take anything that comes with it for granted; just the basic Python behavior. To add our unit tests, we'll create a module named unit_tests.py. Remember, in order for the test runner to find our test modules, their names have to end with 'tests'. Here's what we will put in this file: """ Do a Python test on the app. :unittest: """ import unittest from todo.app import Todo class InitializationTest(unittest.TestCase): todoapp = None def setUp(self): self.todoapp = Todo() def test_title_set(self): self.assertEqual(self.todoapp.title,u'To-do list manager') def test_next_id_set(self): self.assertEqual(self.todoapp.next_id,0) The :unittest: comment at the top, is very important. Without it, the test runner will not know in which layer your tests should be executed, and will simply ignore them. Unit tests are composed of test cases, and in theory, each should contain several related tests based on a specific area of the application's functionality. The test cases use the TestCase class from the Python unittest module. In these tests, we define a single test case that contains two very simple tests. We are not getting into the details here. Just notice that the test case can include a setUp and a tearDown method that can be used to perform any common initialization and destruction tasks which are needed to get the tests working and finishing cleanly. Every test inside a test case needs to have the prefix 'test' in its name, so we have exactly two tests that fulfill this condition. Both of the tests need an instance of the Todo class to be executed, so we assign it as a class variable to the test case, and create it inside the setUp method. The tests are very simple and they just verify that the default property values are set on instance creation. Both of the tests use the assertEqual method to tell the test runner that if the two values passed are different, the test should fail. To see them in action, we just run the bin/test command once more: $ bin/testRunning tests at level 1 Running todo.FunctionalLayer tests: Set up in 2.691 seconds. Running: .......2009-09-30 22:00:50,703 INFO sqlalchemy.engine.base.Engine.0x...684c PRAGMA table_info("users") 2009-09-30 22:00:50,703 INFO sqlalchemy.engine.base.Engine.0x...684c () Ran 7 tests with 0 failures and 0 errors in 0.420 seconds. Running zope.testing.testrunner.layer.UnitTests tests: Tear down todo.FunctionalLayer ... not supported Running in a subprocess. Set up zope.testing.testrunner.layer.UnitTests in 0.000 seconds. Ran 2 tests with 0 failures and 0 errors in 0.000 seconds. Tear down zope.testing.testrunner.layer.UnitTests in 0.000 seconds. Total: 9 tests, 0 failures, 0 errors in 5.795 seconds Now, both the functional and unit test layers contain some tests and both are run one after the other. We can see the subtotal for each layer at the end of its tests as well as the grand total of the nine passed tests when the test runner finishes its work. Extending the test suite Of course, we just scratched the surface of which tests should be added to our application. If we continue to add tests, hundreds of tests may be there by the time we finish. However, this article is not the place to do so. As mentioned earlier, its way easier to have tests for each part of our application, if we add them as we code. There's no hiding from the fact that testing is a lot of work, but there is great value in having a complete test suite for our applications. More so, when third parties might use our work product independently. Debugging We will now take a quick look at the debugging facilities offered by Grok. Even if we have a very thorough test suite, chances are there that we will find a fair number of bugs in our application. When that happens, we need a quick and effective way to inspect the code as it runs and find the problem spots easily. Often, developers will use print statements (placed at key lines) throughout the code, in the hopes of finding the problem spot. While this is usually a good way to begin locating sore spots in the code, we often need some way to follow the code line by line to really find out what's wrong. In the next section, we'll see how to use the Python debugger to step through the code and find the problem spots. We'll also take a quick look at how to do post-mortem debugging in Grok, which means jumping into the debugger to analyze program state immediately after an exception has occurred. Debugging in Grok For regular debugging, where we need to step through the code to see what's going on inside, the Python debugger is an excellent tool. To use it, you just have to add the next line at the point where you wish to start debugging: import pdb; pdb.set_trace() Let's try it out. Open the app.py module and change the add method of the AddProjectForm class (line 108) to look like this: @grok.action('Add project') def add(self,**data): import pdb; pdb.set_trace() project = Project() project.creator = self.request.principal.title project.creation_date = datetime.datetime.now() project.modification_date = datetime.datetime.now() self.applyData(project,**data) id = str(self.context.next_id) self.context.next_id = self.context.next_id+1 self.context[id] = project return self.redirect(self.url(self.context[id])) Notice that we invoke the debugger at the beginning of the method. Now, start the instance, go to the 'add project' form, fill it up, and submit it. Instead of seeing the new project view, the browser will stay at the 'add form' page, and display the waiting for... message. This is because control has been transferred to the console for the debugger to act. Your console will look like this: > /home/cguardia/work/virtual/grok1/todo/src/todo/app.py(109)add() -> project = Project() (Pdb) | The debugger is now active and waiting for input. Notice that the line number where debugging started, appears right beside the path of the module where we are located. After the line number, comes the name of the method, add(). Below that, the next line of code to be executed is shown. The debugger commands are simple. To execute the current line, type n: (Pdb) n > /home/cguardia/work/virtual/grok1/todo/src/todo/app.py(110)add() -> project.creator = self.request.principal.title (Pdb) You can see the available commands if you type h: (Pdb) h Documented commands (type help <topic>): ======================================== EOF break condition disable help list q step w a bt cont down ignore n quit tbreak whatis alias c continue enable j next r u where args cl d exit jump p return unalias b clear debug h l pp s up Miscellaneous help topics: ========================== exec pdb Undocumented commands: ====================== retval rv (Pdb) The list command id is used for getting a bird's eye view of where in the code are we: (Pdb) list 105 106 @grok.action('Add project') 107 def add(self,**data): 108 import pdb; pdb.set_trace() 109 project = Project() 110 -> project.creator = self.request.principal.title 111 project.creation_date = datetime.datetime.now() 112 project.modification_date = datetime.datetime.now() 113 self.applyData(project,**data) 114 id = str(self.context.next_id) 115 self.context.next_id = self.context.next_id+1 (Pdb) As you can see, the current line is shown with an arrow. It's possible to type in the names of objects within the current execution context and find out their values: (Pdb) project <todo.app.Project object at 0xa0ef72c> (Pdb) data {'kind': 'personal', 'description': u'Nothing', 'title': u'Project about nothing'} (Pdb) We can of course, continue stepping line by line through all of the code in the application, including Grok's own code, checking values as we proceed. When we are through reviewing, we can click on c to return control to the browser. At this point, we will see the project view. The Python debugger is very easy to use and it can be invaluable for finding obscure bugs in your code.
Read more
  • 0
  • 0
  • 3018

article-image-call-control-using-3cx
Packt
11 Feb 2010
9 min read
Save for later

Call Control using 3CX

Packt
11 Feb 2010
9 min read
Let's get started! Ring groups Ring groups are designed to direct calls to a group of extensions so that a person can answer the call. An incoming call will ring at several extensions at once, and the one who picks up the phone gets control of that call. At that point, he/she can transfer the call, send it to voicemail, or hang up. Ring groups are my preferred call routing method. Does anyone really like those automated greetings? I don't. We will of course, set those up because they do have some great uses. However, if you like your customers to get a real live voice when they call, you have two choices—either direct the call to an extension or use a ring group and have a few phones ring at once. To create a ring group, we will use the 3CX web interface. There are several ways to do this. From the top toolbar menu, click Add | Ring Group. In the following screenshot, I chose Add | Ring Group: The following screenshot shows another way of adding a ring group using the Ring Groups section in the navigation pane on the left-hand side. Then click on the Add Ring Group button on the toolbar: Once we click Add Ring Group, 3CX will automatically create a Virtual machine number for this ring group as shown in the next screenshot. This helps the system keep track of calls and where they are. This number can be changed to any unused number that you like. As a reseller, I like to keep them the same from client to client. This creates some standardization among all the systems. Now it's time to give the ring group a Name. Here I use MainRingGroup as it lets me know that when a call comes in, it should go to the Main Ring Group. After you create the first one, you can make more such as SalesRingGroup, SupportRingGroup, and so on. We now have three choices for the Ring Strategy: Prioritized Hunt: Starts hunting for a member from the top of the Ring Group Members list and works down until someone picks up the phone or goes to the Destination if no answer section. Ring All: If all the phones in the Ring Group Members section ring at the same time then the first person to pick up gets the call. Paging: This is a paid feature that will open the speakerphone on Ring Group Members. Now you will need to select your Ring Time (Seconds) to determine how long you want the phones to ring before giving up. The default ring time is 20 seconds, which all my clients agree is too long. I'd recommend 10-15 seconds, but remember, if no one picks up the phone, then the caller goes to the next step, such as a Digital Receptionist. If the next step also makes the caller wait another 10-20 seconds, he/she may just hang up. You also need to be sure that you do not exceed the phone company's timeout of diverting calls to their voicemail (which could be turned off) or returning a busy signal. Adding ring group members Ring Group Members are the extensions that you would like the system to call or page in a ring group. If you select the Prioritized Hunt strategy, it will hunt from the top and go down the list. Ring All and Paging will get everyone at once. The listbox on the left will show you a list of available extensions. Select the ones you want and click the Add button. If you are using Prioritized Hunt, you can change the order of the hunt by using the Up and Down buttons. Destination if no answer The last setting as shown in the next screenshot illustrates what to do when no one answers the call. The options are as follows: End Call: Just drop the call, no chance for the caller to talk to someone. Connect to Extension: Ring the extension of your choice. Connect to Queue / Ring Group: This sends the caller to a call queue (discussed later in the Call queues section)) or to another ring group. A second ring group could be created for stage two that calls the same group plus additional extensions. Connect to Digital Receptionist: As a person didn't pick up the call, we can now send it to an automated greeting/menu system. Voicemail box for Extension: As the caller has already heard phones ringing, you may just want to put him/her straight to someone's voicemail. Forward to Outside Number: If you have had all the phones in the building ringing and no one has picked up, then you might want to send the caller to a different phone outside of your PBX system. Just make sure that you enter the correct phone number and any area codes that may be required. This will use another simultaneous call license and another phone line. If you have one line only, then this is not the option you can use. Digital Receptionist setup A Digital Receptionist (DR) is not a voicemail box; it's an automated greeting with a menu of choices to choose from. A DR will answer the phone for you if no one is available to answer the phone (directly to an extension or hunt group) or if it is after office hours. You need to set up a DR unless you want all incoming calls to go to someone's voicemail. You will also need it if you want to present the caller with a menu of options. Let's see how to create a DR. Recording a menu prompt The first thing you need to do in order to create a DR is record a greeting. There are a couple of ways to do this. However, first let's create the greeting script. In this greeting, you will be defining your phone menu; that is, you will be directing calls to extensions, hunts, agent groups, and the dial by name directory. Following is an example: Thank you for calling. If you know your party's extension, you may dial it at any time. Or else, please listen to the following options: For Rob, dial 1 For the sales group, dial 2 For Zachary, dial 4 Solicitors, please dial 8 For a dial by name directory, dial 9 I suggest having it written down. This makes it easier to record and also gives the person setting up the DR in 3CX a copy of the menu map. Now that you know what you want your callers to hear when they call, it's time to get it recorded so that we can import it into 3CX. You have a couple of options for recording the greeting script. It doesn't matter which option you use or how you obtain this greeting file, as long as the end format is correct. You can hire a professional announcer, put it to music, and obtain the file from him/her. You can record it using any audio software you like such as Windows Sound Recorder, or any audio recording software. The file needs to be a .wav or an .mp3 file saved in PCM, 8KHz, 16 bit, Mono format. If you have Windows Sound Recorder only, I'd suggest that you try out Audacity. Audacity is an open source audio file program available at http://audacity.sourceforge.net/. Audacity gives you a lot more power such as controlling volume, combining several audio tracks (a music track to go with the announcer), using special effects, and many other cool audio tools. I'm not an expert in it but the basics are easy to do. First, hit the Audacity website and download it, then install it using the defaults. Now let's launch Audacity and set it up to use the correct file format, which will save us any issues later. Start by clicking Edit | Preferences. On the Quality tab, select the Default Sample Rate as 8000 Hz. Then change the Default Sample Format to 16-bit as shown in the following screenshot: Now, on the File Formats tab, select WAV (Microsoft 16 bit PCM) from the drop-down list and click OK: Now that those settings are saved, you can record your greeting without having to change any formats. Now it's time to record your greeting. Click on the red Record button as shown in the following screenshot. It will now use your PC's microphone to record the announcer's voice and when the recording is done, click on the Stop button. Press Play to hear it, and if you don't like it, start over again: If you like the way your greeting sounds, then you will need to save it. Click File | Export As WAV... or Export As MP3.... Save it to a location that you remember (for example, c:3CX prompts is a good place) with a descriptive filename. While you are recording this greeting, you might as well record a few more if you have plans for creating multiple DRs: Creating the Digital Receptionist With your greeting script in hand, it's time to create your first DR. In the navigation pane on the left side, click Digital Receptionist, then click Add Digital Receptionist as shown in the following screenshot: Or on the top menu toolbar, click Add | Digital Receptionist: Just like your ring group, the DR gets a Virtual extension number by default, Feel free to change it or stick with it. Give it a Name, (I like to use the same name as the audio greeting filename.) Now, click Browse... and then Add. Browse to your c:3CX prompts directory and select your .wav or .mp3 file as shown in the following screenshot: Next, we need to create the menu system as shown in the following screenshot. We have lots of options available. You can connect to an extension or ring group, transfer directly to someone's voicemail, end the call (my solicitors' option), or start the call by name feature (discussed in the Call by name setup section). At any time during playback, callers can dial the extension number; they don't have to hear all the options. I usually explain this in the DR recorded greeting.
Read more
  • 0
  • 0
  • 7649

article-image-exploring-adempiere-client-and-performing-tasks-part-2
Packt
08 Feb 2010
4 min read
Save for later

Exploring ADempiere Client and Performing Tasks: Part 2

Packt
08 Feb 2010
4 min read
Maintaining a log of data changes The system will show the history of our data changes only if we have already activated the Maintain Change Log feature. There are two ways of activating this feature: Role-based: This feature can be set up in the Role, which is associated with the user, upon login to the ADempiere client. To activate this auditing feature, navigate to the Menu | System Admin | General Rules | Security | Role window. Set the active tab to Role, and select your targeted role. Find and select the Maintain Change Log checkbox, as shown in the following screenshot: Table based: You can activate this feature based on the Table. The Table is a place where you save information in your databases. Activate this feature by logging in with the System user ID and System Administrator as the role. Open the Menu | Application Dictionary | Table and Column window. Find your table, and select the Maintain Change Log checkbox Standard window fields When you enter or view information in part C of the ADempiere window, there will be a couple of standard fields available. Client and Organization fields ADempiere has a feature to set up both multi-client and multi-organizational transactions. You can set up as many clients and organizations as you need. We will discuss how to set up clients and organizations later. To segregate information, the Client and Organization fields are used to save both the client (or company) and the organization (or division) information in each ADempiere information or data. The following screenshot shows us an example of the client and organization fields in the Business Partner window:   Active checkbox fields Within certain windows, there is another standard field available. This is known as the Active checkbox. Generally, this checkbox should be available in a window that is used to enter some data that is being repeatedly used within applications as references (something similar to master data). Some examples of windows that contain Active checkboxes are Warehouse,Business Partner, Price List, and so on. Although this master data will not to be used in your further transactions, you are advised to not remove or delete this information for data integrity purposes. Instead, mark these information records as inactive by deselecting the Active checkbox. Performing tasks The ADempiere window has editing features, similar to other applications that run on operating systems such as Linux and Microsoft Windows. However, it has several additional features that are unique to ADempiere itself. Data management Take a look at the main menu (part A) and toolbar (part B) area of your window. A list of icons related to data and record management is as follows: Icon Description Shortcut New: Click on this button when you want to add some information or data. F2 Save: After you finish entering or updating your data, click on this button to save the information to the database. F4 Cancel: Use this button to cancel or ignore your changes. Esc Copy Record: Duplicate the value of existing records to new records Shift+F2 Delete: Delete active records. For some data, you cannot delete the records. This is intended for auditing purposes. Instead, you can set their status to inactive. F3 Delete multiple: Delete selected records or items. You will be prompted with a Delete Selected Items window, which contains a list of record IDs and document numbers, before proceeding with the deletion. Ctrl+D ReQuery: Get the latest data, for the active records, from the databases. F5 Grid Toggle: Show detailed information of one record only. This is suitable for adding (entering) or editing data. F8 Grid Toggle: Shows the list of data or records in a grid mode. F8
Read more
  • 0
  • 0
  • 1418

article-image-normalizing-dimensional-model
Packt
08 Feb 2010
3 min read
Save for later

Normalizing Dimensional Model

Packt
08 Feb 2010
3 min read
First Normal Form Violation in Dimension table Let’s revisit the author problem in the book dimension. The AUTHOR column contains multiple authors, a first-normal-form violation, which prevents us from querying book or sales by author. BOOK dimension table BOOK_SK TITLE AUTHOR PUBLISHER CATEGORY SUB-CATEGORY 1 Programming in Java King, Chan Pac Programming Java 2 Learning Python Simpson Pac Programming Python 3 Introduction to BIRT Chan, Gupta, Simpson (Editor) Apes Reporting BIRT 4 Advanced Java King, Chan Apes Programming Java Normalizing and spinning off the authors into a dimension and adding an artificial BOOK AUTHOR fact solves the problem; it is an artificial fact as it does not contain any real business measure.  Note that the Editor which is an author’s role is also “normalized” into its column in the AUTHOR table (It is related to author, but not actually an author’s name). AUTHOR table AUTHOR_SK AUTHOR_NAME 1 King 2 Chan 3 Simpson 4 Gupta BOOK AUTHOR table BOOK_SK AUTHOR_SK ROLE COUNT 1 1 Co-author 1 1 2 Co-author 1 2 3 Author 1 3 2 Co-author 1 3 3 Editor 1 3 4 Co-author 1 4 1 Co-author 1 4 2 Co-author 1 Note the artificial COUNT measure which facilitates aggregation always has a value of numeric 1. SELECT name, SUM(COUNT) FROM book_author ba, book_dim b, author_dim aWHERE ba.book_sk = b.book_sk AND ba.author_sk = a.author_skGROUP BY name You might need to query sales by author, which you can do so by combining the queries of each of the two stars (the two facts) on their common dimension (BOOK dimension), producing daily book sales by author. SELECT dt, title, name, role, sales_amt FROM (SELECT book_sk, dt, title, sales_amt FROM sales_fact s, date_dim d, book_dim b WHERE s.book_sk = b.book_sk AND s.date_sk = d.date_sk) sales, (SELECT b.book_sk, name, role FROM book_author ba, book_dim b, author_dim a WHERE ba.book_sk = b.book_sk AND ba.author_sk = a.author_sk) authorWHERE sales.book_sk = author.book_sk Single Column with Repeating Value in Dimension table Columns like the PUBLISHER, though not violating any normal form, is also good to get normalized, which we accomplish by adding an artificial fact, PUBLISHED BOOK fact, and its own dimension, PUBLISHER dimension. This normalization is not exactly the same as that in normalizing first-normal-form violation; the PUBLISHER dimension can correctly be linked to the SALES fact, the publisher surrogate key must be added though in the SALES fact. PUBLISHER table   PUBLISHER_SK PUBLISHER 1 Pac 2 Apes BOOK PUBLISHER table BOOK_SK PUBLISHER_SK COUNT 1 1 1 1 2 1 2 3 1 3 2 1 3 3 1 3 4 1 4 1 1 4 2 1 Related Columns with Repeating Value in Dimension table CATEGORY and SUB-CATEGORY columns are related, they form a hierarchy. Each of them can be normalized into its own dimension, but they need to be all linked into one artificial fact. Non-Measure Column in Fact table The ROLE column inside the BOOK AUTHOR fact is not a measure; it violates the dimensional modeling norm; to resolve we just need to spin it off into its own dimension, effectively normalizing the fact table. ROLE dimension table and sample rows   ROLE_SK ROLE 1 Author 2 Co-Author 3 Editor BOOK AUTHOR table with normalized ROLE BOOK_SK AUTHOR_SK ROLE_SK COUNT 1 1 2 1 1 2 2 1 2 3 1 1 3 2 2 1 3 3 3 1 3 4 2 1 4 1 2 1 4 2 2 1   Summary This article shows that both dimensional table and fact table in a dimensional model can be normalized without violating its modeling norm. If you have read this article, you may be interested to view : Solving Many-to-Many Relationship in Dimensional Modeling
Read more
  • 0
  • 0
  • 2549

article-image-exploring-adempiere-client-and-performing-tasks-part-1
Packt
08 Feb 2010
5 min read
Save for later

Exploring ADempiere Client and Performing Tasks: Part 1

Packt
08 Feb 2010
5 min read
At the start of a training session, a student from the class asks the following question: I have just installed ADempiere on my computer and launched the ADempiere Web Start client to log in to the application. However, I do not understand what to do with the application's screens. Even though I am already familiar with Microsoft Windows, the structure of these screens is quite new for me. Could you please explain these screens to me? This is not a naive question. Like all new users who do not have experience in operating ERP software applications, this student needs to know the purpose of the screen along with information on the buttons, tabs, and so on inside each screen. Once the users know the main function of a certain screen, they will use and operate the software more effectively. The Connection aspect of ADempiere Our pre-installed ADempiere application will contain a sample company data called GardenWorld company. To make ourselves familiar with ADempiere, we will access this company data, using a predefined user ID and password. Launch your ADempiere application server, and then launch the ADempiere Web Start client. Checking the ADempiere client version With ADempiere patches being frequently available, we need to know the version of ADempiere client that we are working on. In the ADempiere Web Start client/fat client (not web-based version), through the ADempiere Login window, you can find the information that indicates the version of ADempiere in use. In this window, you can find the ADempiere client version by examining the information in the format 3.4.2s+P20091109. With this information, the system tells you that you are using: The ADempiere 3.4.2s (stable) version The latest patches installed on the system released on November, 09 2009 The predefined user ID and password Coming to the ADempiere Login window, the system supplies us with a GardenAdmin User ID and an obscured Password. The question is: What exactly is the GardenAdmin password? Within your current connection window, the system will serve us with the GardenAdmin user ID. However, this is not the only user ID that is available. Our ADempiere installation has a common list of user IDs and passwords, as mentioned in the following table: No User ID Password 1 System System 2 SuperUser System 3 GardenAdmin GardenAdmin 4 GardenUser GardenUser We can try all of these user IDs in the Adempiere Login window. When typing these user IDs and passwords, check the Caps Lock status. The system will check the capitalization of the characters being typed. When supplied with a wrong password, you will get a User does not match password error message. After typing your GardenAdmin password, you will be directed to the Defaults tab of the Adempiere Login window. Here, you have an option to set the Role, Client, Organization, Warehouse, Date, and Printer values. Leave the information as it is, and click on the OK button. You are now playing with a preconfigured GardenWorld sample client. Understanding the Client and System users With the default ADempiere installation, we can group users into the following types: Client users System users The type of user is determined by the kind of Role being used when connecting to the ADempiere system. A Client user is a type of user who has the rights to access Client information (for example, GardenWorld Client), whereas a System user is a type of user who has the rights to perform system-related tasks, such as accessing and configuring the Application Dictionary through the System Client. With the Application Dictionary, you can perform low-level configuration, such as: Configure the Table and Column definitions to save your data Construct a Window, Tab, and fields to build your ADempiere window Set up a Report and Process to generate your reports Most of these parts can be done without altering the ADempiere source code. Any information in the Application Dictionary is user-extensible and can include user-specific configuration.   The GardenAdmin user ID is an example of a Client user. This user ID should be able to connect to the ADempiere server with the GardenWorld Admin or the GardenWorld User role. The System and SuperUser user IDs are examples of System users. When logging in to the ADempiere system, these IDs can connect with the System Administrator role.   SuperUser can be used to access both System and Client information. Changing our ADempiere server connection During our testing phase, it's quite common to have multiple ADempiere servers. At least, we will have both a demo and a production ADempiere application server environment. You can choose your target ADempiere server by clicking on the Server field on the Adempiere Login w indow, as shown in the following screenshot: During ADempiere installation, you will see an ADempiere Connection window. Complete the Application Host field with the target IP address (or computer name) of the ADempiere server, and leave the other fields with their default values. Ensure the connection between the client and the server computer by clicking on the Test Application Server button. If this button displays a green check mark, then the system will automatically put the information in the database connection information into this window. You can verify the database connection by clicking on the Test Database button. When both of these buttons display a green check mark, this means that we have successfully connected to both, the ADempiere server and the database server. Finalize this task by clicking on the OK button.
Read more
  • 0
  • 0
  • 3115

article-image-build-your-own-application-access-twitter-using-java-and-netbeans-part-1
Packt
05 Feb 2010
6 min read
Save for later

Build your own Application to access Twitter using Java and NetBeans: Part 1

Packt
05 Feb 2010
6 min read
Due to the fact that writing a Java app to control your Twitter account is quite a long process and requires several features, I intend to divide this article in several sections, so you can see in extreme detail all the bells and whistles involved in writing Java applications. Downloading and installing NetBeans for your developing platform To download NetBeans, open a web browser window and go to the NetBeans website. Then click on the Download button and select the All IDE download bundle. After downloading NetBeans, install it with the default options. Creating your SwingAndTweet project Open NetBeans and select File | New Project to open the New Project dialog. Now select Java from the Categories panel and Java Application from the Projects panel. Click on Next to continue. The New Java Application dialog will show up next. Type SwingAndTweet in the Project Name field, mark the Use Dedicated Folder for Storing Libraries option, deselect the Create Main Class box (we’ll deal with that later), make sure the Set as Main Project box is enabled and click on Next to continue: NetBeans will create the SwingAndTweet project and will show it under the Projects tab, in the NetBeans main window. Right click on the project’s name and select JFrame Form... in the pop-up menu: The New JFrame Form window will appear next. Type SwingAndTweetUI in the Class Name field, type swingandtweet in the Package field and click on Finish to continue: NetBeans will open the SwingAndTweetUI frame in the center panel of the main screen. Now you’re ready to assemble your Tweeter Java application! Now let me explain a little bit about what we did in the previous exercise: First, we created a new Java application called SwingAndTweet. Then we created a Swing JFrame component and we named it SwingAndTweetUI, because this is going to act as the foundation, where we’re going to put all the other Swing components required to interact with Twitter. Now I’m going to show you how to download and integrate the Twitter4J API to your SwingAndTweetJava application. Downloading and integrating the Twitter4J API into your NetBeans environment For us to be able to use the powerful classes and methods from the Twitter4J API, we need to tell NetBeans where to find them and integrate them into our Java applications. Open a web browser window, go to http://repo1.maven.org/maven2/net/homeip/yusuke/twitter4j/ and search for the latest twitter4j.2.X.X.jar file, or download the most recent version at the time of this writing from here:http://repo1.maven.org/maven2/net/homeip/yusuke/twitter4j/2.0.9/twitter4j-2.0.9.jar. Once you download it in your computer, go to NetBeans, right-click on the SwingAndTweet project and select Properties from the context menu. Once at the project properties screen, select the Libraries category under the Categories panel, click on the Add JAR/Folder... button at the middle-right part of the screen to open the Add JAR/Folder dialog, navigate to the directory where you downloaded the twitter4j-2.X.X.jar file and double click on it to add it to your project’s library path: Click on OK to close the Project Properties dialog and return to the NetBeans main screen. Ok, you have integrated the Twitter4J API to your SwingAndTweet application. Now, let’s see how to log into your Twitter account from our Java application... Logging into Twitter from Java and seeing your last Tweet In the following exercise, I’ll show you how easy it is to start communicating with Twitter from a Java application, thanks to the Twitter class from the Twitter4J API. You‘ll also learn how to check your last tweet through your Java application. Let’s see how to log into a Twitter account: Go to the Palette window and locate the JLabel component under the Swing Controls section; then drag and drop it into the TweetAndSwing JFrame component: Now drag a Button and a Text Editor, too. Once you have the three controls inside the SwingAndTweetUI JFrame control, arrange them as shown below: The next step is to change their names and captions, to make our application look more professional. Right click on the JLabel1 control, select Edit from the context menu, type My Last Tweet and hit Enter. Do the same procedure with the other two controls: erase the text in the jTextField1 control and type Login in the jButton1 control. Rearrange the jLabel1 and jTextField1 controls, and drag one of the ends of jTextField1 to increase its length all you can. Once done, your application will look like this: And now, let’s inject some life to our application! Double click on the JButton1 control to open your application’s code window. You’ll be inside a java method called jButton1ActionPerformed. This method will execute every time you click on the Login button, and this is where we’re going to put all the code for logging into your Twitter account. Delete the // TODO add your handling code here: line and type the following code inside the JButton1ActionPerformed method: Remember to replace username and password with your real Twitter username and password. If you look closely at the line numbers, you‘ll notice there are five error icons on lines 82, 84, 85,  88 and 89. That’s because we need to add some import lines at the beginning of your code, to indicate NetBeans where to find the Twitter and JOptionPane classes, and the TwitterException. Scroll up until you locate the package swingandtweet; line; then add the following lines: Now all the errors will disappear from your code. To see your Java application in action, press F6 or select Run  Run | Main Project from the NetBeans main menu. The Run Project window will pop up, asking you to select the main class for your project. The swingandtweet.SwingAndTweetUI class will already be selected, so just click on OK to continue. Your SwingAndTweetUI application window will appear next, showing the three controls you created. Click on the Login button and wait for the SwingAndTweet application to validate your Twitter username and password. If they’re correct, the following dialog will pop up: Click on OK to return to your SwingAndTweet application. Now you will see your last tweet on the textbox control: If you want to be really sure it’s working, go to your Twitter account and update your status through the Web interface; for example, type Testing my Java app. Then return to your SwingAndTweet application and click on the Login button again to see your last tweet. The textbox control will now reflect your latest tweet: As you can see, your SwingAndTweet Java application can now communicate with your Twitter account! Click on the X button to close the window and exit your SwingAndTweet application.
Read more
  • 0
  • 0
  • 6140
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 €18.99/month. Cancel anytime
article-image-linux-e-mail-providing-webmail-access-part-2
Packt
05 Feb 2010
4 min read
Save for later

Linux E-mail: Providing Webmail Access (Part 2)

Packt
05 Feb 2010
4 min read
Installing SquirrelMail SquirrelMail may be installed either though a package or directly from source. While no source code compilation takes place in either method, upgrades are made easier using the packages. Many of the various Linux and Unix distributions include the SquirrelMail package. Install the appropriate package from your distribution to use the binary method. On many Linux distributions, this may be an RPM file that begins with squirrelmail…. However, an updated version of SquirrelMail may not be included or available for your specific distribution. The following are the advantages of using the version of SquirrelMail provided with a Linux distribution: It will be very simple to install SquirrelMail. It will require much less configuration as it will be configured to use the standard locations chosen by your Linux distributer. Updates will be very easy to apply, and migration issues may be dealt with by the package management system. The following are the disadvantages of using the version of SquirrelMail provided with a Linux distribution: It may not be the latest version. For example, a more recent version that may fix a security vulnerability may have been released, but Linux distributors may not have created a new package yet. Sometimes Linux distributions alter packages by applying patches. These patches may affect the operation of the package, and may make getting support or help more difficult. Source installation If you do not install SquirrelMail through your distribution, you will need to obtain the appropriate tarball. To do so, visit the SquirrelMail website at http://www.squirrelmail.org , and click download it here. At the time of writing, this link is http://www.squirrelmail.org/download.php There are two versions available for download, a stable version and a development version. Unless you have specific reasons for choosing otherwise, it is generally best to choose the stable version. Download and save this file to an intermediate location. $ cd /tmp$ wget http://squirrelmail.org/countdl.php?fileurl=http%3A%2F%2Fprdownloads.sourceforge.net%2Fsquirrelmail%2Fsquirrelmail-1.4.19.tar.gz Next, unpack the tarball (.tar.gz) file. You may use the following command: $ tar xfz squirrelmail-1.4.19.tar.gz Move the folder just created to your web root folder. This is the directory from which Apache serves pages. In this case, we will assume that /var/www/html is your web root. We will also rename the clumsy squirrelmail-1.4.3a folder to a more simple mail folder. You will need to have superuser root privileges in order to do this on most systems. # mv squirrelmail-1.4.19 /var/www/html/mail# cd /var/www/html/mail Here we have used the name mail, so the URL that users will use will be http://www.sitename.com/mail. You can choose another name, such as webmail,and use that directory name instead of mail in the commands that you enter. It is also useful and secure to create a data directory for SquirrelMail that is outside the main web root, so that this folder will be inaccessible from the Web. # mv /var/www/html/mail/data /var/www/sqmdata It is important to make this newly created folder writable by the web server. To be able to do this, you must know the user and group that your web server runs under. This may be nobody and nobody, apache and apache, or something else. You will want to verify this; it will be listed in your httpd.conf file as the User and Group entries. # chown -R nobody:nobody /var/www/sqmdata Finally, we will create a directory to store attachments. This directory is special in that, although the web server should have write access to write the attachments, it should not have read access. We create this directory and assign the correct permissions with the following commands: # mkdir /var/www/sqmdata/attachments# chgrp -R nobody /var/www/sqmdata/attachments# chmod 730 /var/www/sqmdata/attachments SquirrelMail has now been properly installed. All of the folders have been set up with correct permissions that will secure intermediate files from prying eyes. If a user aborts a message that contains an uploaded attachment,the attachment file on the web server will not be removed. It is a goodpractice to create a cron job on the server that erases excess files fromthe attachment directory. For example, create a file called remove_orphaned_attachments and place it in the /etc/cron.dailydirectory. Edit the file to have these lines:#!/bin/sh#!/bin/shrm `find /var/www/sqmdata/attachments -atime +2 | grep -v"."| grep -v _`This will run daily and search the SquirrelMail attachments directory forfiles which are orphaned, and delete them.
Read more
  • 0
  • 0
  • 1376

article-image-integrating-lotus-quickplacequickr-ibm-lotus-notes-and-domino-851
Packt
05 Feb 2010
7 min read
Save for later

Integrating Lotus QuickPlace/Quickr with IBM Lotus Notes and Domino 8.5.1

Packt
05 Feb 2010
7 min read
The Lotus brand within the IBM Software group represents the "people facing" side of the overall IBM product family. This does not necessarily mean the end user uses no other IBM products, but the Lotus brand is the front end of the IBM SOA  Interaction Services component. The following diagram shows the interaction between these components. Each can be deployed as a separate infrastructure piece and provide value. However, when  they are leveraged as an integrated solution, the possibilities are nearly endless. WebSphere Portal Server provides an on-the-glass integration solution for your enterprise. It allows you to create composite role-based applications from different data sources. For more information, visit http://www.ibm.com/websphere/portal Web Content Management is now an integrated piece of the WebSphere Portal Server. It provides an end user driven content authoring and content delivery system. Visit http://www.ibm.com/websphere/portal Lotus Notes/Domino is IBM's fagship messaging and collaboration product, deployed to over 100 million users. It provides a foundation on which many of the other value-added products build. Visit http://www.ibm.com/software/sw-lotus/products/product4.nsf/wdocs/dominohomepage Lotus QuickPlace/Quickr is IBM's team collaboration product. It provides template-based services and a set of content connectors, allowing end users to quickly create interactive team places, all without the need for administrator intervention. Visit http://www.ibm.com/software/sw-lotus/products/product3.nsf/wdocs/ltwhome Lotus Sametime is IBM's unified communications and collaboration product. It provides enterprise-class instant messaging and web conferencing services, as well as a platform for many other capabilities. This includes telephony and voice integration services. Visit http://www.ibm.com/software/sw-lotus/products/product3.nsf/wdocs/st75home Lotus Connections is IBM's "social networking" product. It provides a new category of integrated application services covering the following areas: activities, dogear, blogs, communities, and profles. Visit http://www.ibm.com/software/sw-lotus/products/product3.nsf/wdocs/connections This article does not cover all the products available under the Lotus brand. For additional information on these, visit http://www.lotus.com Lotus QuickPlace/Quickr The Lotus QuickPlace product has been available for several years. QuickPlace has become recognized as a leader in web-based team collaboration, and it is used in many large corporations throughout the world. In early 2007, IBM announced two important changes to the QuickPlace product family: The new version of Lotus QuickPlace will be renamed Lotus Quickr A new J2EE-based version of QuickPlace will be introduced, also called Lotus Quickr These two versions of Quickr (one based on Domino and one based on WebSphere Portal) form a single product. They do, however, have very different deployment architectures. From an end user's standpoint, they should be viewed as collaboration appliances. They will be presented with a consolidated list of places where they  are involved so that the end users can easily navigate. This will be the case regardless of the backend deployment architecture. The goal of these changes to QuickPlace/Quickr is simplification. IBM wants the product to be so simple that an end user can, with a few clicks, generate productive services. There is also a focus on server deployment simplification. One of the key components of Quickr is the connector technology that it introduces. These connectors will allow for direct and programmatic interaction with the data stored in the Quickr places. Connectors that will be shipping with Quickr 8.0 are the following: Notes Sametime File System/Windows Explorer RSS/ATOM In this section, we will cover each edition and discuss how it integrates with Domino. We will not be covering how to install the product itself; this is covered in detail within the product documentation. Quickr with services for Domino The Domino-based edition of Quickr should be thought of as a signifcant upgrade to the existing QuickPlace product line. This product has been maturing over many years, and this new release provides many new capabilities. These include native support for wikis and blogs "out of the box". Installing Lotus Quickr The basic installation process for Quickr with service for Domino is very simple. It involves installing a base Domino server v7.0.2 FP1. The Quickr product components are then installed on top of this server. Directory integration After installation, there is some additional configuration required, depending on the intended usage. They are: User/group directory configuration is used to control the authorization and authentication of the environment Sametime integration is used to enable presence awareness within the places QPServlet confguration is used for WebSphere Portal integration The user/group directory configuration allows you to select one of three directory types: Internal place level directory allows for registration of users at a place level. The users are independent of any corporate directory that may be in place. Generally this is used to support external user access. Lotus Domino Directory allows users and groups to be stored in the names.nsf database (public address book) and corresponding directories surfaced via directory assistance. LDAP directory allows for users in a supported native LDAP directory (for example, Domino, IBM Tivoli Directory Server, Microsoft Active Directory, Novelle Directory, or Sun One Directory). This configuration allows for the refinement of the settings used to interact with the LDAP source. The directory can be configured by first logging as an administrative user. In the following screenshot, we have logged in as user in Admin from the Domino Directory. Next, select the User Directory option from Site Administration. The following screen shows the default value of No Directory selected. This is the base setup where the contacts.nsf database for each place will be used as a user directory. It is possible to change the user directory by clicking the Change Directory button. This lets you choose between No Directory, LDAP Server, and Domino Server. If LDAP Server is selected, then options for connecting to the directory server will be displayed, as shown in the following screenshot: This screen contains the following felds: Name provides the host name of the LDAP Directory Server. Port number is the LDAP TCP/IP port used to communicate with the server. Check for SSL connection with LDAP User Directory enables SSL  encryption of the LDAP traffic. Note that this is an "all or nothing" selection. It is not possible to only encrypt parts of the conversation with the  LDAP server. Search base controls determines where in the LDAP tree to search for users and groups. For a Domino LDAP directory this value is generally left blank. This is because groups in Domino, as seen through LDAP, have no organizational component (for example, cn=Sales Users). Narrow searches to the place name further restricts the LDAP search to users that contain the Quickr place name (for instance, Sales). Check to use credentials specified below when searching the directory controls whether or not anonymous access is used for the LDAP directory. It is very common to have read-only binding credentials to search the directory. Username provides the user's distinguished Name for the LDAP server (for example, cn=quickrbind, ou=Admin, o=Acme). Password is the password for the username above. Authentication Timeout controls the time in seconds for the login operation to timeout. The default is 120 seconds. Search Timeout controls the time in seconds for LDAP searches to timeout. The default is 120 seconds.
Read more
  • 0
  • 0
  • 8345

article-image-oracle-11g-streams-rules-part-2
Packt
05 Feb 2010
10 min read
Save for later

Oracle 11g Streams: RULES (Part 2)

Packt
05 Feb 2010
10 min read
Rule based transformation—eat your heart out transformers! As with all good rules, some are made to be broken; or maybe changed. In some circumstances we need to have rules that govern change. In Advance Replication, a number one rule is that a replicated table must have the same structure at all master sites. The column names and data types have to be identical or the "apply" of a deferred transaction will fail. With Streams, we can now break this rule by adding a new rule that allows the LCR to "morph" to a new structure. We call this ability Rule Based Transformation; and it is done via complex rules and action context. When you plan your Rule Based Transformation design, you want to remember that Rule Based Transformation rules are only evaluated with positive Rule Sets. If the Rule Set is negative, the Rule Based Transformation is ignored. Declarative versus User Created In the real world, there are many ways to accomplish the same thing; just as there are many ways to model data. You may run into a situation where the table structure in one master database may be different from the structure of the table in another master database but data must be replicated between them. It could be that a table column at one master is a VARCHAR2, but is a DATE at another master site. Or perhaps the column does not exist at all. Rule Based Transformation provides the ability to capture the LCR and convert it to the necessary structure needed to apply it at the destination site. This is not to be confused with transformations accomplished via the DBMS_TRANSFORMATION package. That is a different fish (and doesn't swim in this stream). A special note concerning SUBSET Rules and transformations. A SUBSET Rule has an internal row_migration transformation assigned to it when it is created. This internal transformation will always be the first one executed before any other transformations. Another thing to keep in mind is the amount of "transformation" that will be applied to the LCR. If extensive transformations need to be made to the LCR, you may wish to consider using a custom DML handler instead to take advantage of the apply parallel capabilities. The remainder of this section is going to use the premise that we have an LCR that we need to change a column name for, before we send it out from the source site. The LCR is generated on a table which has a different column name than the corresponding table at all the other sites. This being the case, we are going to create the transformation at the Capture process. There are two ways to accomplish this; either by using a declarative transformation or a user created transformation. We will review each, and then apply the method to our LCR that needs a column name change. Depending on the Transformation type, you can use one of the following views to find information concerning the transformation: Declarative: DBA_STREAMS_TRANSFORMATIONS User Created: DBA_STREAMS_TRANSFORM_FUNCTION Declarative Transformation As of 10g, Oracle provides commonly used transformations in the DBMS_STREAMS_ADM package. These transformations are referred to as declarative transformations. Declarative transformations only work with row LCR's (aka DML LCR's). The row LCR can be a Streams captured LCR (basic or synchronous), or a user created message. The procedures allow you to add transformation rules to do the following: Add a column (DBMS_STREAMS_ADM.ADD_COLUMN) Delete a column (DBMS_STREAMS_ADM.DELETE_COLUMN) Rename a column (DBMS_STREAMS_ADM.RENAME_COLUMN) Rename a table (DBMS_STREAMS_ADM.RENAME_TABLE) Rename a schema (DBMS_STREAMS_ADM.RENAME_SCHEMA) Special considerations when DBMS_STREAMS_ADM.ADD_COLUMN Be aware that the DBMS_STREAMS_ADM.ADD_COLUMN procedure does not support a number of data types. These include: LOBS (BLOB, CLOB, NCLOB, BFILE, and so on) LONG, LONG RAW, and so on ROWID User-defined types (including object types, REFs, varrays, nested tables, and so on) Oracle-supplied types (including ANY types, XML types, spatial types, and media types) For more information on DBMS_STREAMS_ADM Declarative Transformation subprograms, please refer to the Oracle Database PL/SQL Packages and Types Reference. For our purposes, we want to use the DBMS_STREAMS_ADM.RENAME_COLUMN to create a declarative transformation. In our example, we will work with the JOB_HISTORY table from the Oracle Example HR Schema. We will assume that at our source database the HR.JOB_HISTORY table has a column named DEPARTMENT_ID, and at the destination database the corresponding column in the HR.JOB_HISTORY is DEPT_ID. Declarative Transformations can only be added to an existing rule. If the rules specifi ed do not exist, an error is raised. Also, the transformation will be owned by STRM_ADMIN so make sure you have explicitly granted all privileges on HR.JOB_HISTORY to STRM_ADMIN. First we find the rule to which we wish to add the declarative transformation, logged in as STRM_ADMIN we can look at the USER_RULES view: SQL> select * from user_rules;RULE_NAME------------------------------RULE_CONDITION-------------------------------------RULE_EVALUATION_CONTEXT_OWNER RULE_EVALUATION_CONTEXT_NAME------------------------------ ------------------------------RULE_ACTION_CONTEXT(ACTX_LIST(NVN_NAME, NVN_VALUE()))--------------------------------------------------------------RULE_COMMENT--------------------------------------------------------------HR1((:dml.get_object_owner() = 'HR') and :dml.get_source_database_name()= 'STRM1')SYS STREAMS$_EVALUATION_CONTEXTHR2((:ddl.get_object_owner() = 'HR' or :ddl.get_base_table_owner() ='HR') and :ddl.get_source_database_name() = 'STRM1' )SYS STREAMS$_EVALUATION_CONTEXT HR1 is our Row LCR (:dml) rule, so we will add To create our declarative transformation Rule, we issue the following command: beginDBMS_STREAMS_ADM.RENAME_COLUMN(rule_name => 'strm_admin.HR1',table_name => 'HR.JOB_HISTORY',from_column_name => 'DEPARTMENT_ID',to_column_name => 'DEPT_ID',value_type => '*', -- defaultstep_number => 0, --defaultoperation => 'ADD' -–default);end;/ We can now check the rule in the USER_RULES view: SQL> select * from user_rules where rule_name = 'HR1';RULE_NAME------------------------------RULE_CONDITION-------------------------------------------------------------RULE_EVALUATION_CONTEXT_OWNER RULE_EVALUATION_CONTEXT_NAME------------------------------ ------------------------------RULE_ACTION_CONTEXT(ACTX_LIST(NVN_NAME, NVN_VALUE()))-------------------------------------------------------------RULE_COMMENT-------------------------------------------------------------HR1((:dml.get_object_owner() = 'HR') and :dml.get_source_database_name()= 'STRM1')SYS STREAMS$_EVALUATION_CONTEXTRE$NV_LIST(RE$NV_ARRAY(RE$NV_NODE('STREAMS$_INTERNAL_TRANS',ANYDATA()))) Notice that the RULE_COMMENT now has an entry indicating the inclusion of the transformation rule. We can also look at the DBA_STREAMS_TRANSFORMATION view: SQL> select rule_owner, rule_name, transform_type,2 from_column_name, to_column_name, value_type,3 declarative_type, precedence, step_number4 from dba_streams_transformations;RULE_OWNER------------------------------RULE_NAME TRANSFORM_TYPE------------------------------ --------------------------FROM_COLUMN_NAME TO_COLUMN_NAME VAL-------------------- -------------------- ---DECLARATIVE_TYPE PRECEDENCE STEP_NUMBER-------------------- ---------- -----------STRM_ADMINHR1 DECLARATIVE TRANSFORMATIONDEPARTMENT_ID DEPT_ID *RENAME COLUMN 2 0 To remove the declarative transformation from the rule, we use the same procedure we used to create the transformation, but set the operation parameter to REMOVE: beginDBMS_STREAMS_ADM.RENAME_COLUMN(rule_name => 'strm_admin.HR1',table_name => 'HR.JOB_HISTORY',from_column_name => 'DEPARTMENT_ID',to_column_name => 'DEPT_ID',operation => 'REMOVE' -–default);end;/ Note: Removing the declarative transformation does not clear the RULE_COMMENT we see in the USER_RULES view. However, it does clear the entry from the DBA_STREAMS_TRANSFORMATION view . For more detailed information on using the DBMS_STREAMS_ADM.RENAME_COLUMN, and other declarative transformation procedures, please refer to the Oracle PL/SQL Packages and Types Reference, and the Oracle Streams Concepts and Administration Guide. User Created Rule Based Transformations (UCRBT) You can also create your own Rule Based Transformations. These transformations are referred to as user-created transformations (imagine that). The steps for creating a UCRBT are pretty basic. Create the PL/SQL function that performs the transformation. The function should receive the LCR as a SYS.ANYDATA IN parameter The function should return either an LCR a SYS.ANYDATA or STREAMS$_ANYDATA_ARRAY If the function returns a STREAMS$_ANYDATA_ARRAY, it can only be associated with a capture rule Grant the EXECUTE privilege on the function to the appropriate user as necessary. Create or locate the rules for which the transformation will be used. Set the custom rule-based transformation for each rule by running the SET_RULE_TRANSFORM_FUNCTION procedure. In this example, we will setup a UCRBT that makes the same transformation as the previous declarative transformation. The UCRBT is going to be owned by STRM_ADMIN so make sure you have explicitly granted all privileges on HR.JOB_HISTORY to STRM_ADMIN. The code for this example can be found in the UCRBT.sql code file. First we create the PL/SQL function to accomplish the transformation; STRM_ADMIN will be the function owner, so make sure you are logged in as STRM_ADMIN in this example: CREATE OR REPLACE FUNCTION DEPT_COLNAME_CHANGE (evt IN SYS.AnyData)RETURN SYS.AnyData ISlcr SYS.LCR$_ROW_RECORD;obj_name VARCHAR2(30);rc NUMBER;BEGINIF evt.GetTypeName='SYS.LCR$_ROW_RECORD' THENrc := evt.getObject(lcr);obj_name := lcr.GET_OBJECT_NAME();IF obj_name = 'JOB_HISTORY' THENlcr.RENAME_COLUMN('DEPARTMENT_ID','DEPT_ID','*');RETURN SYS.ANYDATA.ConvertObject(lcr);END IF;END IF;RETURN evt;END;/ Because STRM_ADMIN is the function owner, we do not need to grant EXECUTE on the function. If the function was created in a different schema, then we would want to explicitly grant execute on the function to STRM_ADMIN. Next we determine which rule to which to add the transformation function. You can either create a new rule at this point, or use an existing rule. We will use our HR1 rule from above (we can do this because we removed the Declarative RENAME_COLUMN transformation from the rule in our last step of the Declarative Transformation example). select * from dba_rules; Then, we use the DBMS_STREAMS_ADM.SET_RULE_TRANSFORM_FUNCTION procedure to add the transformation function to the desired rule: BEGINDBMS_STREAMS_ADM.SET_RULE_TRANSFORM_FUNCTION(rule_name => 'HR1',transform_function => 'strm_admin.DEPT_COLNAME_CHANGE');END;/ We will now see the transformation in the DBA/ALL_STREAMS_TRANSFORM_FUNCTION view: SQL> select * from all_streams_transform_function;RULE_OWNER------------------------------RULE_NAME VALUE_TYPE------------------------------ --------------------TRANSFORM_FUNCTION_NAME CUSTOM_TYPE----------------------------------- -----------STRM_ADMINHR1 SYS.VARCHAR2"STRM_ADMIN"."DEPT_COLNAME_CHANGE" ONE TO ONE For more detailed information on UCRBT, please reference the Usage Notes for the DBMS_STREAMS_ADM.SET_RULE_TRANSFORM_FUNCTION procedure in the Oracle PL/SQL Packages and Types Reference, and the Oracle Streams Concepts and Administration Guide. Transformation Order of Execution It is possible to have a combination of declarative and user defined transformations assigned to a single rule. This being the case, how do you know which ones get executed when? Especially, if you have not assigned step numbers. There is a default order of execution for transformation that help keep the rule from running amuck. If the rule is a Subset rule, then Row Migration is always executed first Next are Declarative Rule based transformations These are further ordered by the step number specified for each transformation if they have been assigned. If the step numbers are not assigned, the transformations are executed in the following order: Delete_Column Rename_Column Add_Column Rename_Table Rename_Schema Last (but not the least), the User Created Rule-Based Transformation is executed.
Read more
  • 0
  • 0
  • 2702

article-image-linux-e-mail-providing-webmail-access-part-1
Packt
05 Feb 2010
10 min read
Save for later

Linux E-mail: Providing Webmail Access (Part 1)

Packt
05 Feb 2010
10 min read
The webmail solution A webmail solution is a program or a series of scripts that is run on a server, is accessible over the web, and provides access to e-mail functions similar to a conventional mail client. It is used by Yahoo! Mail, Microsoft Hotmail, Microsoft Outlook Web Access, and Gmail as the primary interface to their e-mail solutions. You may already be familiar with various forms of webmail. Though we will be examining the SquirrelMail webmail solution specifically, the benefits and drawbacks of SquirrelMail apply to most webmail systems in the market. From this point of view, we will approach the issue from a general perspective, and then in detail for the SquirrelMail package. The benefits This section will focus on the advantages offered by installing and maintaining a webmail solution. As with any list, it is not entirely comprehensive. Many benefits will be specific to a particular case; it is important to carefully examine and consider how the following qualities impact your individual situation. The main benefits we will explore in this section are as follows: Easy and quick access with little or no setup Easy remote access No need to maintain client software or configuration Provision of a user interface to configure mail server options Possible security benefits Easy and quick access Although well suited to certain situations, traditional mail access solutions can often be difficult to set up and maintain. Generally, this involves installing software on a client's local computer and configuring it. This can be difficult, especially in cases where users need to set up the software themselves. Configuration can often be even more problematic as some users may not be competent enough to follow even a very detailed set of instructions. These instructions also need to be provided and maintained for many different mail clients on many different platforms. However, a webmail solution does not have most of these problems. All of the user's settings can be configured on the server as the application itself resides on the server. This translates to almost zero set up time for the user. Once they have received their login credentials, they can visit the webmail site and instantly have access to all of their mail. The user is able to access the site instantly to send and receive e-mail. As the Internet is so common now, many users will be familiar with webmail sites such as Google Mail and Windows Live Hotmail, which offer free e-mail services. However, the user interface provided by an open source package may be more primitive and lack some visual features. Squirrelmail provides access to e-mail, including the ability to send and receive attachments, and offers a good user interface. It is also worth mentioning that a webmail solution can offer what certain traditional mail clients call groupware features. These features let groups communicate and coordinate in ways that complement e-mail communication. Examples of groupware components are private calendars, shared calendars, meeting scheduling, To-do lists, and other similar tools. These applications can be preconfigured so that a user can instantly begin using them without having to configure them on their own. Several SquirrelMail plugins which implement these features are available from the SquirrelMail website. Easy remote access Another problem with traditional mail access software is that it is not portable, as an e-mail client needs to be installed and configured on a computer. Once it has been downloaded, installed, and configured on a particular computer, it is accessible only on that computer. Without webmail, users on the road will not be able to access e-mail from friends' computers, mobile devices, or Internet booths at airports. However, in a webmail solution, e-mail can be accessed from any location with an Internet connection. Employees can access their work e-mail from any computer with an Internet connection and a suitable browser. As the administrator, you can choose to permit or deny users from accessing e-mail in insecure situations. By requiring the connection to be encrypted, you can ensure that when a user is in a remote location, their communication with the server is secure. No need to maintain clients Even if software mail clients have been installed and properly configured, they must be maintained. When a new version is released, all clients must be updated. This is not necessarily an easy task. Software that does not work as expected can result in a large number of support-desk calls. Updating the software on each client can be a very large administrative burden. In fact, many expensive software packages are designed for the specific purpose of updating software on individual machines automatically. Despite this, problems specific to each local machine often arise and must be solved individually. It may also be difficult to convey instructions or notifications to remote branch locations or remote workers. With a webmail solution, this is not necessary. In contrast to this, a webmail solution is centrally maintained and administered. The webmail application resides on the server. With webmail, only the web server and the webmail package need to be upgraded. Any exceptions or problems that arise can be dealt with before or during the upgrade. The software upgrade itself can be run through on a test system before it is deployed on a live system. Although changes in settings are rare with SquirrelMail, it is possible to update a user's settings to make them compatible with the changes introduced in an updated version. Additionally, while upgrading or changing a mail server platform, testing effort can be greatly reduced as only supported browser versions need to be tested. It is advisable to mandate particular browser versions for corporate computers. In contrast with e-mail clients, there is no need to test on all of the possible clients and software platforms. Configuring mail server interface via the user interface Many traditional desktop e-mail clients provide only e-mail functionality and nothing more. Often there is no support for other essential tasks (such as changing the access password) that are performed on behalf of a mail user. Certain configuration options that reside on the server may require additional software applications or external solutions to provide for these needs. Examples of mail server options that may need to be configured include each user's password and junk mail filtering settings. In the case of the SquirrelMail webmail application, many plugins have been developed that provide these features. For example, a user is able to change his/her password directly from the webmail interface. Also, there are plugins and systems that allow users to easily sign up without any direct human intervention. This may be useful if you are interested in providing a service where users can sign up without needing an administrative overhead. Possible security benefits This issue can be seen in two different ways—it is for this reason that the title is listed as "Possible" security benefits. Nonetheless, this is still an interesting point to examine. In the software client access model, e-mail is traditionally downloaded onto the local user's computer, being stored in one or more personal folders. From a security perspective, this may be a bad thing. Users of the system may not be as conscientious or knowledgeable about computer security as a trained computer administrator might be. It is often much easier to gain unauthorized access to an end user's computer than a properly configured and secured server. The implication is that someone who stole a company laptop might be able to access all the e-mail stored on that computer. There is one more disadvantage associated with the client access model. Even if an employee is terminated, he/she may still have access to all of the e-mail that  resides on his/her local office computer. It may take a certain amount of time before important information may be secured. A disgruntled worker might easily connect an external storage source to their local office computer and download any data they desire. It is also worth noting that in a webmail model, all e-mail is centrally stored. If an attacker were to gain access to the central e-mail server, he/she might access all the e-mail stored on that server. However, it is possible that an attacker will gain access to all the e-mail if the central mail server is compromised even if a webmail system is not used. The disadvantages This section focuses on the disadvantages resulting from providing and supporting a webmail solution. The warning given in the previous section applies: This list is not entirely comprehensive. Each situation is unique, and may bring its unique disadvantages. We will go over the following disadvantages of a webmail solution: Performance issues Compatibility with large e-mail volumes Compatibility with e-mail attachments Security issues Performance The traditional e-mail client is designed in the client-server model. One mail server accepts and delivers e-mail to and from other mail servers. However, a desktop mail client can offer many additional productivity-enhancing features such as message sorting, searching, contact list management, attachment handling, along with more recent ones such as spam filtering and message encryption. Each of these features may require a certain amount of processing power. The required level of processing power may be negligible when it comes to storing one user's e-mail on a desktop computer, but providing these features may be problematic when applied on a larger scale to a single server. When examining the performance issue, it is important to consider the number of potential users that will access the webmail application and size a server accordingly. A single server may be able to easily handle something like 300 users, but if the number of users increases significantly, server load may become an issue. For example, searching through several years' archived mail may take a few seconds on a client's computer. When one user performs this task using webmail, the load will be similar. However, if many clients request this operation at short intervals or concurrently, it may be difficult for the server to process all the requests in a timely manner. This may result in pages being served at a slower rate or, in extreme circumstances, the server failing to respond. Optimally, load testing in the appropriate conditions should be performed if there is any concern that a server may not be able to handle a particular load of users. Compatibility with large e-mail volumes The webmail solution is not well suited to large mail volumes. This disadvantage is related to the previous one, but is more related to the amount of data sent. Even with a relatively low number of users, a large volume of e-mails may be difficult to manage in a webmail application. There are mainly the following two reasons for this: Firstly, every e-mail viewed and every folder listed must be sent from the server each time. With a traditional e-mail client, the client software can manage e-mail messages, creating lists and views to suit the user. However, with a webmail solution, this is performed on the server. So, if there are many users, this overhead may use a significant proportion of the server's resources. Secondly, each interaction with the webmail application requires a Hypertext Transfer Protocol (HTTP) request and response. These messages will typically be larger than those between an e-mail server and a desktop e-mail client. There may also be less parallelism when using a webmail client, inother words, fewer things going on at the same time. A desktop e-mail client may be able to check for new e-mails in several folders at the same time, but a webmail client will typically perform these tasks one after the other, if they occur automatically at all.
Read more
  • 0
  • 0
  • 2946
article-image-new-features-domino-designer-85
Packt
05 Feb 2010
7 min read
Save for later

New features in Domino Designer 8.5

Packt
05 Feb 2010
7 min read
There are many exciting changes and additions to Domino Designer 8.5. We will begin with the introduction of the Eclipse based integrated development environment. Domino Designer 8.5, which is also known as Domino Designer on Eclipse or DDE, takes advantage of Eclipse technology to deliver a more powerful developer environment. The look and feel is more consistent with Notes client version 8.x. The new UI will be examined at a high level. The next major feature addition that will be covered is XPages. XPages are a new type of design element being introduced in the 8.5 release that will revolutionize Domino Web Applications. XPages enable application developers to quickly and easily create rich Domino web applications with a Web 2.0 look and feel. Finally, we will review improvements to CSS support, enhancements to HTML generation, JavaScript controls, a new method related to ID Vault: ResetUserPassword, and changes to web services. Domino Designer on Eclipse Now in 8.5 the Domino Designer client is based on Eclipse, as the Notes client was in 8.x. Eclipse is an award-winning, open source platform for the construction of powerful software development tools and rich desktop applications. This architectural change allows the new designer client to become an open source pluggable environment. By allowing the use of plugins, objects can be built, re-used, and shared. Some of the differences in the new 8.5 Designer client can be seen when examining the processes associated with Domino Designer. It is useful to know how they relate to one another and what component each controls. Prior to release 8.5 designer clients, when you launched designer.exe, nlnotes.exe would be spawned. This is the process in which pre-8.5 Domino Designer ran. Now in the 8.5 Designer client, designer.exe loads and spawns nlnotes.exe. On faster machines, designer.exe shows up briefly, and may not be seen at all. Then the notes2.exe process spawns and designer.exe quits. notes2.exe is the Java process that corresponds to the Eclipse shell. Finally, nlnotes.exe spawns ntaskldr.exe after DDE opens. Some other things you may notice are that launch and exit take longer than in previous versions. This is due to the Eclipse startup and shutdown sequences. This can lead to problems on exit or launch. If you experience a problem with launch or exit, it may be due to one of the following issues. Due to the longer exit time, the user may have initiated launch before all prior processes had been killed, or the user may have initiated the launch sequence multiple times. It is also possible that, on prior exit, the client did not shut down all processes. With a few exceptions, the launch process will be able to compensate for these errors. However, if you still can't launch or exit the 8.5 designer client, you can try the following, manually. Kill the nlnotes.exe and notes2.exe processes with the task manager, or if the client still will not launch or exit, log off the system to completely kill all process threads. The new Eclipse-based GUI Now that the 8.5 Designer client is Eclipse based, there is a new UI. The default perspective in 8.5 is the Domino Designer perspective. There are other perspectives available in Domino Designer 8.5, each suited to a particular task. You can select a different perspective from the menu, select Window | Open Perspective | Other, as seen in the following screenshot: Not all perspectives have a corresponding layout in the UI. Perspectives can be customized to suit individual preferences. One way is by resizing the views and editors. You can resize views and editors in one of two ways. Click the Maximize/Restore button located in the title bar of the view or editor. Or, click and drag the border of a view or editor. Views and editors can also be hidden by clicking the view Close button. Use the menu pick Window | Show Eclipse Views to reopen closed views. You can use this menu pick to open any Eclipse view, including those from other perspectives. To return to the current perspective's default layout use the menu pick Window | Reset Perspective.... XPages For a while now it has been difficult to create elegant web applications for Notes/Domino. XPages are a new type of design element being introduced in the 8.5 release, that will allow application developers to quickly and easily create rich Domino web applications with a Web 2.0 look and feel. Applications built using XPages are supported for web use only, for the 8.5 release. To enhance the appearance and functionality for web use, existing applications can be extended to utilize XPages. The standard design elements must be included in the database for use in the Notes client and the application. If a new application is targeted for both Notes client and web users, then you can also include XPages for use on the Web. XPages are built on top of JSF, or Java Server Faces, technology. XPages also have built-in Ajax support, which allows application developers to take advantage of Ajax features such as type-ahead and partial page refresh. They are created in pure XML markup. When the application developer adds controls to XPages using drag and drop, the XML is generated automatically. XPages does not require any additional steps to install on a Domino server. When you create a new XPage in an application, you start with a blank page similar to what you see when a new form or page is created. You then build the XPage by dragging and dropping controls onto the XPage to add functionality. A wide array of controls is available out of the box, which enables application developers to quickly and easily get a web application up and running. Some examples of the controls available are a pager, rich text editor, date picker, tabbed panel, and many more. Controls can also be combined into a single object, called a custom control. Custom controls are similar to sub-forms, as they can be used in other XPages in the current application or copied into other applications for reuse. Just like with sub-forms, if a change is made to a custom control in an application, that change is propagated out to all other instances of that custom control in that application. There is a default system template in the 8.5 release that uses XPages. The discussion template has been enhanced to include XPages in 8.5. Improvements to CSS Support Now in Domino Designer 8.5 you can edit and create CSS. Previously, you would have to use an external editor to do this. Not only can you create custom stylesheets, but you can import existing ones. You can also group your favorite stylesheets and script resources into a theme to provide a common look and feel in your application and map style classes to UI controls. This will save developer time and effort when adding CSS to applications. To create a new stylesheet: Click File | New | Style Sheet Resource from the main Eclipse menu. In the New Style Sheet dialog box, do the following: In the Name field, type the name of the stylesheet. By default, Domino Designer adds a CSS file extension to this name In the Application field, select an application for the stylesheet. Click OK Another method of creating a stylesheet, is by double-clicking Resources | Style Sheets in the Applications navigator and then clicking New Style Sheet in the editor.
Read more
  • 0
  • 0
  • 8149

article-image-oracle-11g-streams-rules-part-1
Packt
05 Feb 2010
7 min read
Save for later

Oracle 11g Streams: RULES (Part 1)

Packt
05 Feb 2010
7 min read
Streams is all about the rules; literally. The action context that a Streams process takes is governed by the rule conditions. When you create a rule, Oracle generates system conditions, and evaluation contexts, that are used to evaluate each LCR to determine if the action context for the process should be accomplished. We have already addressed a number of these system conditions during our TAG discussion; for instance INCLUDE_TAGGED_LCR=FALSE generates a system evaluation for theLCR$_ROW_RECORD_TYPE :dml.is_null_tag='Y' subprogram. For more information on LCR Types, reference Oracle Database PL/SQL Packages and Types Reference manual. You can control what system evaluations are included in the rule by the parameter values you specify, as well as add user-defined evaluations with the AND_CONDITION parameter. There is a lot going on under the calm surface water of rules. Understanding how this activity flows together will help you become more advanced in creating rules to manipulate your Streams throughout your current environment. So, let's grab our snorkels and masks, and stick our heads under the surface and take a look. Rule components Rules have three components: conditions, evaluation context, and action context. These components coordinate with the "when", "what", and "how" of the LCR being processed. The conditions tell the Streams process "when" the LCR should be processed, the evaluation context defines "what" data/information the Streams process uses to process the LCR, and the action context tells the Streams process "how" to handle the LCR. Rule conditions The rule condition is essentially the "where clause". The conditions are evaluated against the properties of the LCR and return either TRUE or FALSE The conditions can contain compound expressions and operators (AND, OR, NOT, and so on).The final evaluation returned from the condition (TRUE or FALSE) is the final result of all the compound expressions. An example of a system-generated condition would be that of our good friend :dml.is_null_tag = 'Y' (generated by the INCLUDE_TAGGED_LCR=FALSE parameter of the DBMS_STREAMS_ADM.ADD_*_RULE procedures). On rule creation, the condition is passed in as a string (so make sure to escape any single quotes within the string). ':dml.get_object_owner() = ''OE'' and :dml.get_tag() =HEXTORAW(''22'')' It is important to remember that you want to keep your rule conditions as simple as possible. Complex rule conditions can have a significant impact on performance. The rule condition created by our Sub-Setting example is an example of a complex rule as it includes a PL/SQL call to a function. Also, rule conditions that contain NOT, or != can also impact performance. Rule Evaluation Context The rule evaluation context defines data external to the LCR properties that can be referenced in the rule conditions. This is comparable to the SQL statement from clause. This reference is a database object that contains the external data. The evaluation context provides the rule conditions with the necessary information for interpreting and evaluating the conditions that reference external data. If the evaluation context references objects, the rule owner must have the proper privileges to reference the object (select and execute) as the rule condition is evaluated in the schema of the evaluation context owner. Information contained in an Evaluation Context might include table aliases used in the condition, variable names and types, and/or a function to use to evaluate the rules to which the evaluation context is assigned. Evaluation Context structure can get a bit confusing. To get a better feel of it, you may want to start by looking at the following database views: DBA/ALL/USER_EVALUATION_CONTEXT_TABLES: table alias used DBA/ALL/USER_EVALUATION_CONTEXT_VARS: variable types used DBA/ALL/USER_EVALUATION_CONTEXTS: functions used Streams system created rules (created using DBMS_STREAMS_ADM) will create rules using the standard Oracle-supplied SYS.STREAMS$_EVALUATION_CONTEXT rule evaluation context. This evaluation context is composed of a variable_types> list for the :dml and :ddl variables, and the evaluation function SYS.DBMS_STREAMS_INTERNAL.EVALUATION_CONTEXT_FUNCTION as seen in the previous DBA views. You can create your own evaluation context using the DBMS_RULE_ADM.CREATE_EVALUATION_CONTEXT procedure: DBMS_RULE_ADM.CREATE_EVALUATION_CONTEXT(evaluation_context_name IN VARCHAR2,table_aliases IN SYS.RE$TABLE_ALIAS_LIST DEFAULT NULL,variable_types IN SYS.RE$VARIABLE_TYPE_LIST DEFAULT NULL,evaluation_function IN VARCHAR2 DEFAULT NULL,evaluation_context_comment IN VARCHAR2 DEFAULT NULL); If you create a custom Evaluation Context that uses the SYS.DBMS_STREAMS_INTERNAL.EVALUATION_CONTEXT_FUNCTION, it must include the same variables and types as in the SYS.STREAMS$_EVALUATION_CONTEXT (a.k.a. :dml and :ddl). Variable_types> can be defined using SYS.RE$VARIABLE_TYPE_LIST, which in turn accepts individual variable types defined using SYS.RE$VARIABLE_TYPE. Similarly, if you create a custom function to use as the evaluation function, it must have the following signature: FUNCTION evaluation_function_name(rule_set_name IN VARCHAR2,evaluation_context IN VARCHAR2,event_context IN SYS.RE$NV_LIST DEFAULT NULL,table_values IN SYS.RE$TABLE_VALUE_LIST DEFAULT NULL,column_values IN SYS.RE$COLUMN_VALUE_LIST DEFAULT NULL,variable_values IN SYS.RE$VARIABLE_VALUE_LIST DEFAULT NULL,attribute_values IN SYS.RE$ATTRIBUTE_VALUE_LIST DEFAULT NULL,stop_on_first_hit IN BOOLEAN DEFAULT FALSE,simple_rules_only IN BOOLEAN DEFAULT FALSE,true_rules OUT SYS.RE$RULE_HIT_LIST,maybe_rules OUT SYS.RE$RULE_HIT_LIST);RETURN BINARY_INTEGER; Where the returned BINARY_INTEGER value must be one of the following: DBMS_RULE_ADM.EVALUATION_SUCCESSDBMS_RULE_ADM.EVALUATION_CONTINUEDBMS_RULE_ADM.EVALUATION_FAILURE For more information on creating custom Evaluation Contexts and evaluation functions and Rule Types, refer to the Oracle Database PL/SQL Packages and Types Reference manual, and The Oracle Streams Extended Examples manual. Once an Evaluation Context is created it can be assigned to a rule or a rule set using the evaluation_context parameter of the appropriate DBMS_RULE_ADM procedure. The Evaluation Context for a Rule can be different than the Evaluation Context for a Rule Set to which the Rule might be assigned. The bottom line is that a Rule must be able to associate itself with an Evaluation Context at some level. We will revisit this concept as we discuss Rule Creation a little later on this section. Action Context The rule action context is just that, the action information that the rule evaluation engine returns to the client application, to be acted upon by the client application, when the rule evaluates to true. This is not the action itself, but values to be used by the action code that are specific to the rule. The action context is of the SYS.RE$NV_LIST type, which contains an array of name-value pairs and is associated to a rule condition. A rule condition can only have one action context. The action context itself is optional and can contain zero to many name-value pairs. The SYS.RE$NV_LIST has the following construct: TYPE SYS.RE$NV_LIST AS OBJECT(actx_list SYS.RE$NV_ARRAY); Subprograms are: ADD_PAIR (name IN VARCHAR2,value IN ANYDATA);GET_ALL_NAMES ()RETURN SYS.RE$NAME_ARRAY;GET_VALUE (name IN VARCHAR2)RETURN ANYDATA;REMOVE_PAIR (name IN VARCHAR2); For more information on creating and populating Action Contexts types, refer to the Oracle Database PL/SQL Packages and Types Reference manual. For more information on Rule components refer to the Oracle Streams Concepts and Administration manual.
Read more
  • 0
  • 0
  • 2418

article-image-n-way-replication-oracle-11g-streams-part-1
Packt
05 Feb 2010
4 min read
Save for later

N-Way Replication in Oracle 11g Streams: Part 1

Packt
05 Feb 2010
4 min read
N-way replication refers to a Streams environment where there are multiple sources. In this article, we will still use the STRM1 and STRM2 databases but with a little twist; making both databases the source. By making both STRM1 and STRM2 sources, we need to first consider a couple of unique situations and do a little more pre-planning, specifically for N-Way replication. The concepts and techniques used to configure a 2-way replication can then be used to scale to N-way replication. We all need to crawl before we run, the better you crawl (understand) this article, the easier it will be to scale up to N-way replication. Pay close attention and learn the technique so that you can implement it well. We need to repeat this—Streams is not Failover. We need to repeat this—Streams is not Failover. No, that is not a typo. The authors are passionate about Streams and want to see you successfully implement it. To successfully implement Streams, you need to know not to step into the trap of using it for Failover. Both authors have done some work where Failover was the requirement. Streams is not a Failover solution. Failover is handled by Oracle Data Guard, NOT Oracle Streams. Streams is about distributing the data to multiple locations. On more than one occasion, Streams was used as a Failover technology because it can distribute data to multiple locations. Do not fall into the trap of using the wrong tool for the wrong job. Streams distributes (replicates) data. As such, there will always be some difference between the databases in a Streams environment. All replication technology has this problem. The only time where all of the databases are in sync is, when there is no activity and all replication has been applied to all target locations. If you need Failover, then use the proper tool. Oracle Data Guard is for Failover. It has the necessary processes to guarantee a different level of failover from a primary site to a secondary site, whereas Streams is a Replication tool that distributes data. Just remember the following, when there is a discussion of Replication and Failover that comes up: Streams distributes data, it is built for replication Data Guard is built for Failover Pre-planning for N-way replication When we set up N-way replication, we must consider the possibility of a collision of data. Since we have multiple sources of data, it is possible for the exact same data to be inputted on any or all of the sources at the exact same time. When this happens, it is a conflict. This example is just one type of conflict that can happen in N-way replication environments. The types of conflict that can occur are as follows: Update conflict: When transactions from different databases try to update the same row at nearly the same time. Delete conflict: When one transaction deletes a row and the next transaction tries to update or delete the row. Transactions originate from different databases. Unique conflict: When transactions from different databases violate a primary or unique constraint, the first transaction is accepted. The second transaction obtains the conflict. Foreign key conflict : This happens when a transaction from a Source tries to insert a child record before the parent record exists. The good news is that Oracle has provided built-in conflict resolution in Streams that solves the most common situations. The built-in solutions are as follows: OVERWRITE DISCARD MAXIMUM MINIMUM We will provide an example of conflict resolution after we build our N-way replication. In our case, we will use MAXIMUM. As part of the pre-planning for N-way replication, we highly suggest creating a simple table such as the Setup Table. Avoiding Conflict As conflict requires additional pre-planning and configuration, one begins to wonder, "Are there techniques so that we can configure N-way replication without the possibility of conflict?" The simple answer to the question is "Yes". The not-so simple answer is that there is some configuration magic that needs to be done and the devil is in the details. Limiting who and what can be updated is one method of avoiding conflict. Think of it this way— there is no conflict if we agree to who and what can update the specific data. User 1 can only update his specific data and no one else can do that. Similarly, user 2 can only update his specific data. So, user 1 and user 2 can never cause a conflict. Now this may be a little bit difficult depending on the application. This can be implemented with the use of offset sequences. One sequence produces only odd values, and another produces only even values. We could also use a combination of sequence and some unique characteristics of the database.
Read more
  • 0
  • 0
  • 2200
article-image-n-way-replication-oracle-11g-streams-part-2
Packt
05 Feb 2010
7 min read
Save for later

N-Way Replication in Oracle 11g Streams: Part 2

Packt
05 Feb 2010
7 min read
Streaming STRM2 to STRM1 Now the plan for setting up Streams for STRM2. It is the mirror image of what we have done above, except for the test part. On STRM2, log in as STRM_ADMIN. -- ADD THE QUEUE, a good queue name is STREAMS_CAPTURE_Q -- ADD THE CAPTURE RULE -- ADD THE PROPAGATION RULE -- INSTANTIATE TABLE ACROSS DBLINK -- DBLINK TO DESTINATION is STRM1.US.APGTECH.COM -- SOURCE is STRM2.US.APGTECH.COM On STRM1 log in as STRM_ADMIN. -- ADD THE QUEUE: A good queue name is STREAMS_APPLY_Q -- ADD THE APPLY RULE Start everything up and test the Stream on STRM2. Then check to see if the record is STREAM'ed to STRM1. -- On STRM2 log in as STRM_ADMIN -- ADD THE QUEUE :A good queue name is STREAMS_CAPTURE_Q -- STRM_ADMIN@STRM2.US.APGTECH.COM>BEGINDBMS_STREAMS_ADM.SET_UP_QUEUE(queue_table => '"STREAMS_CAPTURE_QT"',queue_name => '"STREAMS_CAPTURE_Q"',queue_user => '"STRM_ADMIN"');END;/commit;-- ADD THE CAPTURE RULE-- STRM_ADMIN@STRM2.US.APGTECH.COM>BEGINDBMS_STREAMS_ADM.ADD_TABLE_RULES(table_name => '"LEARNING.EMPLOYEES"',streams_type => 'capture',streams_name => '"STREAMS_CAPTURE"',queue_name => '"STRM_ADMIN"."STREAMS_CAPTURE_Q"',include_dml => true,include_ddl => true,include_tagged_lcr => false,inclusion_rule => true);END;/commit;-- ADD THE PROPAGATION RULE-- STRM_ADMIN@STRM2.US.APGTECH.COM>BEGINDBMS_STREAMS_ADM.ADD_TABLE_PROPAGATION_RULES(table_name => '"LEARNING.EMPLOYEES"',streams_name => '"STREAMS_PROPAGATION"',source_queue_name =>'"STRM_ADMIN"."STREAMS_CAPTURE_Q"',destination_queue_name =>'"STRM_ADMIN"."STREAMS_APPLY_Q"@STRM1.US.APGTECH.COM',include_dml => true,include_ddl => true,source_database => 'STRM2.US.APGTECH.COM',inclusion_rule => true);END;/COMMIT; Because the table was instantiated from STRM1 already, you can skip this step. -- INSTANTIATE TABLE ACROSS DBLINK-- STRM_ADMIN@STRM2.US.APGTECH.COM>DECLAREiscn NUMBER; -- Variable to hold instantiation SCN valueBEGINiscn := DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER();DBMS_APPLY_ADM.SET_TABLE_INSTANTIATION_SCN@STRM1.US.APGTECH.COM(source_object_name => 'LEARNING.EMPLOYEES',source_database_name => 'STRM1.US.APGTECH.COM',instantiation_scn => iscn);END;/COMMIT; -- On STRM1, log in as STRM_ADMIN. -- ADD THE QUEUE, a good queue name is STREAMS_APPLY_Q-- STRM_ADMIN@STRM1.US.APGTECH.COM>BEGINDBMS_STREAMS_ADM.SET_UP_QUEUE(queue_table => '"STREAMS_APPLY_QT"',queue_name => '"STREAMS_APPLY_Q"',queue_user => '"STRM_ADMIN"');END;/COMMIT;-- ADD THE APPLY RULE-- STRM_ADMIN@STRM1.US.APGTECH.COM>BEGINDBMS_STREAMS_ADM.ADD_TABLE_RULES(table_name => '"LEARNING.EMPLOYEES"',streams_type => 'apply',streams_name => '"STREAMS_APPLY"',queue_name => '"STRM_ADMIN"."STREAMS_APPLY_Q"',include_dml => true,include_ddl => true,include_tagged_lcr => false,inclusion_rule => true);END;/commit; Start everything up and Test. -- STRM_ADMIN@STRM1.US.APGTECH.COM>BEGINDBMS_APPLY_ADM.SET_PARAMETER(apply_name => 'STREAMS_APPLY',parameter => 'disable_on_error',value => 'n');END;/COMMIT;-- STRM_ADMIN@STRM1.US.APGTECH.COM>DECLAREv_started number;BEGINSELECT DECODE(status, 'ENABLED', 1, 0) INTO v_startedFROM DBA_APPLY where apply_name = 'STREAMS_APPLY';if (v_started = 0) thenDBMS_APPLY_ADM.START_APPLY(apply_name => '"STREAMS_APPLY"');end if;END;/COMMIT;-- STRM_ADMIN@STRM2.US.APGTECH.COM>DECLAREv_started number;BEGINSELECT DECODE(status, 'ENABLED', 1, 0) INTO v_startedFROM DBA_CAPTURE where CAPTURE_NAME = 'STREAMS_CAPTURE';if (v_started = 0) thenDBMS_CAPTURE_ADM.START_CAPTURE(capture_name => '"STREAMS_CAPTURE"');end if;END;/ Then on STRM2: -- STRM_ADMIN@STRM2.US.APGTECH.COM>ACCEPT fname PROMPT 'Enter Your Mom's First Name:'ACCEPT lname PROMPT 'Enter Your Mom's Last Name:'Insert into LEARNING.EMPLOYEES (EMPLOYEE_ID, FIRST_NAME, LAST_NAME,TIME) Values (5, '&fname', '&lname', NULL);dbms_lock.sleep(10); --give it time to replicate Then on STRM1, search for the record. -- STRM_ADMIN@STRM1.US.APGTECH.COM>Select * from LEARNING.EMPLOYEES; We now have N-way replication. But wait, what about conflict resolution?Good catch; all of this was just to set up N-way replication. In this case, it is a 2-way replication. It will work the majority of the time; that is until there is conflict. Conflict resolution needs to be set up and in this example the supplied/built-in conflict resolution handler MAXIMUM will be used. Now, let us cause some CONFLICT! Then we will be good people and create the conflict resolution and ask for world peace while we are at it! Conflict resolution Conflict between User 1 and User 2 has happened. Unbeknown to both of them, they have both inserted the exact same row of data to the same table, at roughly the same time. User 1's insert is to the STRM1 database. User 2's insert is to the STRM2 database. Normally the transaction that arrives second will raise an error. It is most likely that the error will be some sort of primary key violation and that the transaction will fail. We do not want that to happen. We want the transaction that arrives last to "win" and be committed to the database. At this point, you may be wondering "How do I choose which conflict resolution to use?" Well, you do not get to choose, the Business Community that you support will determine the rules most of the time. They will tell you how they want conflict resolution handled. Your responsibility is to know what can be solved with built-in conflict resolutions and when you will need to create custom conflict resolution. Going back to User 1 and User 2. In this particular case, User 2's insert arrives later than User 1's insert. Now the conflict resolution is added using the DBMS_APPLY_ADM package, specifically the procedure DBMS_APPLY_ADM.SET_UPDATE_CONFLICT_ HANDLER which instructs the APPLY process on how to handle the conflict. Scripts_5_1_CR.sql shows the conflict resolution used to resolve the conflict between User 1 and User 2. Since it is part of the APPLY process, this script is run by the Streams Administrator. In our case, that would be STRM_ADMIN. This type of conflict can occur on either STRM1 or STRM2 database, so the script will be run on both databases. The numbers to the left are there for reference reasons. They are not in the provided code. -- Scripts_5_1_CR.sql1. DECLARE2. cols DBMS_UTILITY.NAME_ARRAY;3. BEGIN4. cols(0) := 'employee_id';5. cols(1) := 'first_name';6. cols(2) := 'last_name';7. cols(3) := 'time';8. DBMS_APPLY_ADM.SET_UPDATE_CONFLICT_HANDLER(9. object_name => 'learning.employees',10. method_name => 'MAXIMUM',11. resolution_column => 'time',12. column_list => cols);13. END;14. /15. Commit; So what do these 15 magical lines do to resolve conflict?Let us break it down piece by piece logically first, and look at the specific syntax of the code. Oracle needs to know where to look when a conflict happens. In our example, that is the learning.employees table. Furthermore, Oracle needs more than just the table name. It needs to know what columns are involved. Line 9 informs Oracle of the table. Lines 1 -7 relate to the columns. Line 8 is the actual procedure name. What Oracle is supposed to do when this conflict happens, is answered by Line 10. Line 10 instructs Oracle to take the MAXIMUM of the resolution_column and use that to resolve the conflict. Since our resolution column is time, the last transaction to arrive is the "winner" and is applied.
Read more
  • 0
  • 0
  • 1641

article-image-packaging-python-project-using-doit
Packt
05 Feb 2010
6 min read
Save for later

Packaging a Python Project using doit

Packt
05 Feb 2010
6 min read
The article won't attempt to reproduce doit documentation, but will explain how it could be used to solve a specific problem in a practical way. For a complete introduction of doit, and a description of all its features, please refer to the project documentation. Debian packaging or bazaar knowledge isn't required to follow the discussion, but it would be helpful. Background When working on a project's source code, a developer usually needs to perform different repetitive administrative tasks that are required to compile, test and distribute the source code. In general, those tasks are pretty similar from project to project; although, the details may greatly vary depending on the application type, target platform, software development cycle, etc. As a consequence, the implementation of custom scripts that automate them is needed as a part of the maintenance of the source code. Given that, this is a very common problem, many task automation tools have been created, make is one of the most well-known among them and is used as a reference to compare with other similar tools. As the reader probably knows, make provides an imperative way to automate small tasks by defining in a file (a makefile) a series of rules that have a target file, multiple dependency files and a set of commands. To reach a given target, make must ensure that target file isn't outdated and that all the dependency files are present before running the commands that will generate the target file. During this process, the evaluation of other rules might be needed to fulfill the required dependencies. Although this approach may look simple, it has been really successful in many projects for years. However, since it tries to solve a general problem, it doesn't perfectly fit in every situation. This fact has led to the creation of similar tools that attempt to address some of the drawbacks of make.: The makefile format forces the developer to learn a new mini-language. Rules are statically defined. Just one target file per rule is allowed. With the advent of dynamic programming languages, a new generation of make-like tools that solved those issues were designed. For example, rake did a really good job in providing a familiar environment for ruby developers who wanted to use an advanced task automation tool without having to learn something new other than an API. With regard to python developers, many of these tools are currently available for them with different goals in their designs. One that I find particularly interesting is doit because it doesn't have any of the make problems listed above. In particular: It's really simple to use because it uses python itself as the language to write the configuration statements needed. Tasks, the equivalent to make's rules, may have as many targets as needed, which makes things simpler when the execution of a command entails the creation of multiple files. Task themselves aren't defined in the configuration, but task generators. This is really flexible when dependencies and/or targets depend on variables that need to be evaluated at run time. The problem Let's imagine that we are working on checkbox-editor, a simple python project hosted in Launchpad that provides an easy GTK interface to write test cases for checkbox. The way the application is delivered to users is by means of .deb packages for the latest Ubuntu distributions in a Personal Package Archive or PPA, so we'd like to be able to: Package the application at any time. Install the package locally for testing. Upload the package automatically to a PPA. Fortunately, the project's trunk branch already has the configuration files needed to generate a .deb package using the usual set of tools, so we're going to focus on the process of writing the file needed to generate and upload the desired packages. Of course, since we don't like to waste our time, we only want to generate the files needed for packaging when necessary; that's is to say, we're going to follow make's approach of generating target files only when they aren't up-to-date. Tasks In this section, a file that contains the tasks generators, which are required to automate the package generation using doit, will be created step by step. The same way as a makefile is created with all the rules for make; in doit, the default file name with the task generators is dodo.py. Of course, another file name can be used by passing an argument to doit, but we'll stick to the usual name in this example. In the code snippets that will be displayed in the following sections, some global variables will be used mainly to get the name of some files. For now, just assume that they're available in the task generators methods. The code that calculates those variables value will be shown at the end of the article. Identification There are two different classes of packages: source and binary ones. Binary packages are the ones that are compiled for an specific architecture, and that are expected to be installed directly into the destination hardware without any problem. These are the type of packages that we need to generate to accomplish the goal of installing a package locally for testing purposes. Hence, two of the tasks that we need to automate are the generation of the binary package and it's installation. Source packages are useful to distribute the source code of an application in a platform independent way, so that anyone can take a look at the code, fix it or compile it for another architecture if needed. This is also the package that must be uploaded to a Launchpad PPA, since it will take care to compile it for different architectures and publish the binary packages for them. Consequently, two more tasks that should be automated are the generation of a source package and the upload to the Launchpad PPA. Before creating any package is generated, we also need to generate a copy of the source code with the latest changes. This is not absolutely needed; but it's advised since the package generation process creates some temporary files. The diagram of the tasks that have just been identified is the following: Tasks that should be automated Code The first task before any package generation is copying the source code to a new directory (for example, pkg), to keep the development directory clean from the temporary files created during the packaging process. The code that implements this task is as follows: 1 def task_code(): 2 """ 3 Create package directory and copy source files 4 (bzr branch not used to take into account uncommited changes) 5 """ 6 def copy_file(from_file, to_file): 7 dir = os.path.dirname(to_file) 8 if dir and not os.path.isdir(dir): 9 os.makedirs(dir) 10 print from_file, '=>', to_file 11 shutil.copyfile(from_file, to_file) 12 shutil.copystat(from_file, to_file) 13 return True 14 15 yield {'name': 'clean', 16 'actions': None, 17 'clean': ['rm -rf pkg']} 18 19 for target, dependency in zip(PKG_FILES, SRC_FILES): 20 yield {'name': dependency, 21 'actions': [(copy_file, (dependency, target))], 22 'dependencies': [dependency], 23 'targets': [target]}
Read more
  • 0
  • 0
  • 2137
Modal Close icon
Modal Close icon