Data Integration Guide with SQL Database by Example Version 2017 Winter Release Status: March 28, 2017 Copyright © Mindbreeze GmbH, A-4020 Linz, 2017. All rights reserved. All hardware and software names used are registered trade names and/or registered trademarks of the respective manufacturers. These documents are highly confidential. No rights to our software or our professional services, or results of our professional services, or other protected rights can be based on the handing over and presentation of these documents. Distribution, publication or duplication is not permitted. . Data Integration Guide with SQL Database by Example 2 Table of Contents 1 Introduction___________________________________________________________________ 4 1.1 Preparation ________________________________________________________________ 4 1.2 Prerequisites on the Microsoft SQL Server ________________________________________ 4 1.3 Example Description _________________________________________________________ 4 2 Configuration of Talend Job for Data Integration ____________________________________ 5 2.1 Setup Database Connection ___________________________________________________ 6 2.2 Import Database Table Schema ________________________________________________ 7 2.3 Configure the Talend Job _____________________________________________________ 9 2.3.1 Setup SQL-Input _________________________________________________________ 9 2.3.2 Setup Mindbreeze Index Output ____________________________________________ 10 2.3.3 Setup Column Mapping (tMap) _____________________________________________ 11 2.4 Export the Talend Job _______________________________________________________ 14 3 Configuration of Mindbreeze ____________________________________________________ 16 3.1 Adapting the categoryDescriptor.xml ____________________________________________ 17 3.1.1 Adding own Metadata Columns ____________________________________________ 17 3.1.2 Replacing the Icons______________________________________________________ 18 3.1.3 Adding Custom Actions ___________________________________________________ 18 4 Troubleshooting Problems _____________________________________________________ 20 4.1 Talend Job Problems ________________________________________________________ 20 4.1.1 Talend Job Test Run not running ___________________________________________ 20 4.1.2 Data Type Errors ________________________________________________________ 20 4.2 Problems with Mindbreeze Search Results _______________________________________ 21 4.2.1 No Search Results ______________________________________________________ 21 4.2.2 No Content in Search Results ______________________________________________ 21 4.2.3 Properties not shown in Search Results ______________________________________ 21 5 Appendix ____________________________________________________________________ 22 5.1 categoryDescriptor.xml ______________________________________________________ 22 Data Integration Guide with SQL Database by Example 3 1 Introduction This guide will help to integrate an SQL database table into Mindbreeze Enterprise Search. Based on a demo database table hosted on a Microsoft SQL Server the full procedure of setting up the Talend job through configuration within Mindbreeze and finally some troubleshooting hints will be shown in this paper. 1.1 Preparation You will need to take care of the following steps in order to get this example to work: Mindbreeze installation (this example is shown on a Mindbreeze installation running on Microsoft Windows). Mindbreeze license including the Data Integration Connector. Talend Open Studio >= 5.0.2 (as installed on Mindbreeze InSpire appliance) – with the configuration of the Mindbreeze user components (for details see the configuration white paper for the Data Integration Connector) Reachable Microsoft SQL server hosting the target database table to be crawled. SQL service user able to connect to the Microsoft SQL server and having read permissions on the desired database. 1.2 Prerequisites on the Microsoft SQL Server In order to be able to connect to the Microsoft SQL server from within the Talend Open Studio you need to turn on the following connection properties: SQL Server Browser (this service needs to be running and is required to retrieve database schemas). SQL Server Protocols: TCP/IP (this protocol is required to connect from the Talend connector). SQL Server Authentication: the “SQL Server Authentication mode” is required to connect from the Talend connector. The service user used to connect to the SQL database for crawling the data needs to have login permissions and full read access to the target database (at least “Select” and “View Definition” permissions on the target table). 1.3 Example Description The example database table used for this paper “supportticket” is intended to be used for storing the basic data of support tickets and is defined on the SQL server the following way. Data Integration Guide with SQL Database by Example 4 2 Configuration of Talend Job for Data Integration After all prerequisites are fulfilled you can start creating a new Talend job for crawling the SQL database table and mapping the required table columns to extracted metadata attributes for the Mindbreeze search. Start the Talend Open Studio for Data Integration (e.g.: C:\TOS_DI-r78327-V5.0.2\TOS_DI-winx86_64.exe). Open either the existing Mindbreeze Demo project (from the Mindbreeze InSpire appliance) or create a new project. The next step is to create a new job (defining the input source, the column mapping and the resulting output properties) and specify the job name. Data Integration Guide with SQL Database by Example 5 2.1 Setup Database Connection Create a new database connection to your Microsoft SQL Server by means of navigating in the Repository window to “Metadata > Db Connections” and choosing the context menu entry “Create connection” and assign a connection name (without spaces and special chars). Choose DB Type “Microsoft SQL Server” and fill in the connection properties: Login: <myTestuser> Password: <myPassword> Server: localhost Port: 1433 Database: <testdb> Schema: (blank) Additional parameters: instance=SQLEXPRESS Data Integration Guide with SQL Database by Example 6 Finally, you could test the connection with the “Check” button. 2.2 Import Database Table Schema The next step is to import the database table schema for the desired table (supportticket). Select “Retrieve Schema” from the context menu of your database connection. You can skip any filter restrictions and proceed with “Next” to the selection of the table schema of the “” database table. Data Integration Guide with SQL Database by Example 7 After selecting the schema for table it can be imported with the “Finish” button and it will be available as data input source for the job in the “Table schemas” of your “Db Connections”. You should check and maybe adapt the column data types in the schema definition (especially for data types of kind date or datetime) by means of editing the schema again (“Edit Schema” from the context menu). Verify if the date parser format for your values from the database are correctly or change the „Date Pattern“ appropriately: In our example we have to change the „Date Pattern“ from the default value of “dd-MM-yyyy” to the data representation in our database table (as seen above): “ yyyy-MM-dd”. The time part for datetime values will be passed directly and recognized without any special definition. Data Integration Guide with SQL Database by Example 8 This screenshot shows the correctly adapted first Date Pattern for the column createdon. The second column has not been changed yet but also needs to be changed to the same value: “ yyyyMM-dd”. Finally save the changed Schema settings. 2.3 Configure the Talend Job A simple Talend job normally consists of 3 objects: The input data source where the data comes from (in this example this is the SQL database input) The output data source where the data should be sent to (for Mindbreeze Data Integration jobs this will always be the “MindbreezeIndexOutput”) And processing instructions how to map the input data to the output data (the “tMap” is a commonly used element to define such a mapping) 2.3.1 Setup SQL-Input Drag and drop the table schema of the “supportticket” database table from the left tree to the job workspace and select “tMSSqlInput” as type of component to create. Data Integration Guide with SQL Database by Example 9 2.3.2 Setup Mindbreeze Index Output The next step is to add the output datasource by searching for the term “ Mindbreeze” in the Palette of Talend components and dragging the “MindbreezeIndexOutput” element to the right side of the workspace. Note: If you do not find any Mindbreeze components in the palette the user components may not have been setup correctly in the global Talend preferences. Data Integration Guide with SQL Database by Example 10 2.3.3 Setup Column Mapping (tMap) The last but most important step is to configure the mapping of the input data to the output data required for the Mindbreeze crawler. Therefore, we search for the term “tmap” in the palette and drag the “tMap” component to the middle of the workspace. In order to complete the job we have to connect the 3 components by means of dragging a connection line with the “right” mouse button from the input to the tMap and also from the tMap to the output. Finally it should look like this: Now we “only” need to setup the column mapping by opening the tMap-properties with a “doubleclick”. For every Data Integration job we will need at least the following 4 properties which are required by the Mindbreeze crawler: key: … should be mapped to a unique ID column for that data source. Must be of type “String”. title: … the column or content for this property will be used as title in the search results extension: … normally you should define the value to „txt“ in order to tell Mindbreeze to filter textual content as text. categoryClass: … could be used to separate the results of this data source from other results Note: These internal properties need to have a valid value and must not be “null” so check for “null”-values with IF-like expressions and assign alternative values in that cases. Data Integration Guide with SQL Database by Example 11 You can always test the result of the current mapping by means of saving the changes and starting a test run of the job. Because we only have yet mapped those four base columns we will only get those data in the result of the test run. So let us extend the mapping to get all essential columns into the output. There are some additional Mindbreeze internal columns, which could be used for mapping additional properties: acl: (list of string values) in the format: "TestUser1||GRANT" date: (type "Date") … will be used as the internal date property of search results and normally displayed with the results. modificationDate: (type "Date") … will be used for updating indexed documents in the index (normally not displayed in the search results) content: (type "String") … this property is used to store the full-text-indexed content of the search result. Data Integration Guide with SQL Database by Example 12 Now we have extended the mapping with some of the optional internal columns and will get an extended output from the test-run also including the date properties (you could check them for correctness against the original database data) and the content (displayed as binary data – but should contain values if the original data source contains a text for the corresponding record) We could now map all of the other remaining properties from the database (maybe we will not need every column) to a property name of our decision (it could get the same name or a better one). If you like you can modify some property values using Java-expressions like the following one: row1.subject == null ? "no subject" : row1.priority + ": " + row1.subject Note: You should always prevent null-values to reduce logging of avoidable errors. Data Integration Guide with SQL Database by Example 13 And if we run the job we will hopefully get all the properties we wanted to have and which should be available for the Mindbreeze search afterwards. 2.4 Export the Talend Job Finally we have to save and export the Talend job. Data Integration Guide with SQL Database by Example 14 Specify that the exported job should be extracted and keep in mind the target directory of this export. Locate the exported job on the file system and look up the generated class name in the run script: C:\mes\TalendJobs\SupportTicket_0.1\SupportTicket\SupportTicket_run.bat For the configuration of the Talend job within Mindbreeze you will need the base job path (containing the „lib“ folder: “C:\mes\TalendJobs\SupportTicket_0.1” and the class name found in the run script: “mindbreeze.supportticket_0_1.SupportTicket”. Data Integration Guide with SQL Database by Example 15 3 Configuration of Mindbreeze Create a new Index with a reasonable display name an appropriate Index path on the file system. Then create a new Data Source and select “DataIntegation” as Category (Note: if this option is not available you did forget to install the Data Integration-plugin ZIP-file) and choose a Source Name which will be displayed in the search client. Last but not least you have to define the Talend Job properties: Directory of Job: … the base path of the exported Talend job (containing the „lib“ folder) Main Class: … the main Java class as generated into the run script Save the changes and restart the Mindbreeze Node service. If everything was set up correctly you should find a log message like the following in the Mindbreeze log of the Data Integration Crawler (e.g. C:\mes\logs\current\logmescrawler_launchedservice-DataIntegration_Support+Tickets\2015-02-27_12-4448.581290\log-mescrawler_launchedservice.log): 2015-02-27 12:44:57.394226 [5268] com.mindbreeze.enterprisesearch.connectors.commons.crawlerbase.CrawlRun INFO: Finished crawling run 1 successfully - statistics: itemsFound: 8 Finally check if you receive search results within the Mindbreeze search client. Data Integration Guide with SQL Database by Example 16 The default presentation of the custom Data Integration source already shows title, date and the content but we would also like some other properties to be displayed so we have to adapt the categoryDescriptor.xml for the Data Integration plugin. Note: If you have to change the Talend job later on and have made major changes you should delete the old index from file system and re-create it. 3.1 Adapting the categoryDescriptor.xml As a good starting point for building your own categoryDescriptor.xml you should take the original Data Integration plugin ZIP-file and modify it for your needs. Most customization can be done by modifying the categoryDescriptor.xml. The default one for the Data Integration connector looks somehow like this: <?xml version="1.0" encoding="UTF-8"?> <category id="DataIntegration" supportsPublic="true"> <name>Data Integration</name> </category> But you could also take a look at another categoryDescriptor.xml from another of the basic plugins shipped with our product. E.g. the WebConnector-Plugin already contains a list of translated metadata properties and also a specific Open action. 3.1.1 Adding own Metadata Columns A Metadata definition looks like following example: <metadata> <metadatum aggregatable="true" id="current_state" visible="true"> <name xml:lang="en">Ticket State</name> <name xml:lang="de">Ticket State</name> </metadatum> ... </metadata> Data Integration Guide with SQL Database by Example 17 … the ID is the mapping to identify the column as it was defined by the tMap output column name. The following properties can be defined additionally to language specific names: aggregatable: if this option is true the column will be available as filter property (should only be defined for properties with values allowing clustering the results – on the other hand if the value is unique for each result it is useless to define the column aggregatable) visible: defines whether the column is displayed in the default result representation 3.1.2 Replacing the Icons The small icon that is shown in the data sources list in the search client is represented by the “categoryIcon.png” file in the ZIP archive of the plugin. You could simply replace that icon with an 16x16 Icon of your decision You could also specify a preview icon for the results with the icon-Tag inside the categoryDescriptor.xml. It requires a unique ID, size attributes defining height and width and the image itself is encoded as Base64-Value within the value-attribute. <context> <Icon alt="Ticket" height="16" width="16" id="tag:mindbreeze.com,2007/contextitems/contexticon;ticket" mimetype="image/png" type="tag:mindbreeze.com,2007/contextitems/contexticon" value=" iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA sTAAALEwEAmpwYAAAAB3RJTUUH3wIXECgw/xAFagAAAS1JREFUOMvFkz1uwkAUhL/nNV4Zesw9wgUILYq4 gymCgCiRIG3gCkAOEnMFTgMNFT8W65cCpOAIAqmY8knzaTQ7C/eWvA8Gpd1uN3HOPQFyo0+NMYm1tkcrjm uzJNH/apYk2orjmu+c88tRxHq91tVqJSJ/hBBhu9kQRZGWo0icc74PoFmGqspkPMZae9G/3W55brdJ01Q0 ywA4AIAgCPgYDi+agyAAYL/fIyLo8e4fKlEKhQKf0+nZBM45ur1eDoTqCeCo17e36/WrctpTDtDtdAjD8K zROUej0eCxXs/dc4DhaJSjh2FIsVi8nkA8D0Dn87kU/B9mpVLhoVr99ZICoOJ5AuAbY/bLxQJAms3mzQte LhYYY5wM+v1SmqbT45S5ecqe9xVY+3L3z8g3o1Sele9r3SQAAAAASUVORK5CYII= " /> </context> 3.1.3 Adding Custom Actions It is possible to define custom actions based on some specific meta data. For example to open a ticket search result in a custom ticketing web application. <context> <Menu> <Action name="Open" pattern="http://intranet.mycompany.com/ticketing/show.html?ticketid={{mes:key}}"> <name xml:lang="en">Open Ticket</name> <name xml:lang="de">Ticket Öffnen</name> </Action> </Menu> </context> You could apply your modified categoryDescriptor.xml by uploading the changed plugin ZIParchive from the Mindbreeze Config UI. Note: It is recommended to rename any modified plugin with a custom name for better detection of changes on product updates. Data Integration Guide with SQL Database by Example 18 Another possibility to apply only the categoryDescriptor.xml is by means of using the mesextension commandline tool (this could be useful for testing): C:\ >mesextension --interface=categorydescriptor --category=DataIntegration --file=C:\Temp\categoryDescriptor.xml --overwrite install After applying these changes, you have to restart the Mindbreeze Node service and you should receive a beautiful representation of the search results including all additional metadata properties (also in the filters on the right if defined aggregatable). Data Integration Guide with SQL Database by Example 19 4 Troubleshooting Problems 4.1 Talend Job Problems First of all we have to ensure that the Talend job does run in the Talend Open Studio. Then we have to check that every property we want to search for within Mindbreeze is already included the result of the test run of the Talend job, because otherwise Mindbreeze will not ever get this data to process. 4.1.1 Talend Job Test Run not running If the Talend job does not run, you should check the “Problems” view (Note: there are two different Problem views – a general one of Eclipse and another one of Talend – you can open those views from within the “Window > Show view…” menu). One reason for having problems with running the Talend job is an unclean environment which could be solved by refreshing the workspace and trying again or sometimes you even have to close the whole Talend Studio cleanup some temporary files from the file system and restart the Studio again. 4.1.2 Data Type Errors If you get an error of “Type mismatch”, you should check the mapping of input and output data types. Often an ID column from the intput is received as numeric value and is expected on the output side as String-value – so you need to convert the value with Java-expressions. Data Integration Guide with SQL Database by Example 20 4.2 Problems with Mindbreeze Search Results 4.2.1 No Search Results If you do not retrieve any search results (by an “ALL” in the new Data Integration data source) you should check the following possible reasons: Check the log file of the Data Integration crawler For example you may see the following error message in the log file: 2015-02-27 12:37:32.643950 [812] com.mindbreeze.enterprisesearch.connectors.commons.crawlerbase.CrawlRun ERROR: CrawlRun was unsuccessful, cause: java.lang.ClassNotFoundException: Mindbreeze.supportticket_0_1.SupportTicket This error was caused by a wrong spelling of the class name with an upper case first letter instead of a lower case one: mindbreeze.supportticket_0_1.SupportTicket Restart the Mindbreeze Node service and check the new log file. Check the access restrictions on this index (“Unrestricted Public Access”) 4.2.2 No Content in Search Results If the search results do not display any textual content below the base properties it may not have been crawled correct because of following possible reasons: Source data is not mapped to internal column “content” “extension” property is set wrong (for textual content you must set it to the value “ txt”) 4.2.3 Properties not shown in Search Results If the desired property is not one of the basic internal properties it will not be shown by default. You need to define the property either in the categoryDescriptor.xml as visible metadata or explicitly in the search app. You should also check if the property was correctly retrieved by the Talend job from within the test run result. Data Integration Guide with SQL Database by Example 21 5 Appendix 5.1 categoryDescriptor.xml Here is the full content of the categoryDescriptor.xml used for this example: <?xml version="1.0" encoding="UTF-8"?> <category id="DataIntegration" supportsPublic="true"> <name>Data Integration</name> <metadata> <metadatum aggregatable="true" id="current_state" visible="true"> <name xml:lang="en">Ticket State</name> <name xml:lang="de">Ticket Status</name> </metadatum> <metadatum aggregatable="true" id="priority" visible="true"> <name xml:lang="en">Ticket Priority</name> <name xml:lang="de">Ticket Priorität</name> </metadatum> <metadatum aggregatable="true" id="category" visible="true"> <name xml:lang="en">Ticket Category</name> <name xml:lang="de">Ticket Kategorie</name> </metadatum> <metadatum aggregatable="true" id="datasource/modificationDate" visible="true"> <name xml:lang="en">Modification Date</name> <name xml:lang="de">Änderungsdatum</name> </metadatum> <metadatum aggregatable="true" id="assigned_to" visible="true"> <name xml:lang="en">Assigned To</name> <name xml:lang="de">Zugeordnet zu</name> </metadatum> <metadatum aggregatable="false" id="customer_name" visible="true"> <name xml:lang="en">Customer Name</name> <name xml:lang="de">Kundenname</name> </metadatum> <metadatum aggregatable="false" id="customer_email" visible="true"> <name xml:lang="en">Customer E-Mail</name> <name xml:lang="de">Kunden E-Mail</name> </metadatum> <metadatum aggregatable="true" id="customer_city" visible="true"> <name xml:lang="en">Customer City</name> <name xml:lang="de">Wohnort des Kunden</name> </metadatum> <metadatum aggregatable="true" id="customer_zipcode" visible="true"> <name xml:lang="en">Customer ZIP Code</name> <name xml:lang="de">ZIP Code des Kunden</name> </metadatum> </metadata> <context> <Menu> <Action name="Open" pattern="http://intranet.mycompany.com/ticketing/show.html?ticketid={{mes:key}}"> <name xml:lang="en">Open Ticket</name> Data Integration Guide with SQL Database by Example 22 <name xml:lang="de">Ticket Öffnen</name> </Action> </Menu> <Icon alt="Ticket" height="89" width="64" id="tag:mindbreeze.com,2007/contextitems/contexticon;ticket" mimetype="image/png" type="tag:mindbreeze.com,2007/contextitems/contexticon" value=" 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" /> Data Integration Guide with SQL Database by Example 23 </context> </category> Data Integration Guide with SQL Database by Example 24