It's all about the answers!

Ask a question

IBM Rational Build Forge Java API - How to use QueryFilter


Makara Tan (1621) | asked Oct 25 '10, 6:45 p.m.
I refer the link at http://www.ibm.com/developerworks/rational/downloads/08/bf_java_api_guide/index.html

The pdf file did assist with my development work and at the moment I am stagnating when I came across two classes called Log
(com.buildforge.services.client.dbo.Log) and QueryFilter (com.buildforge.services.common.db.QueryFilter).

My aim is to search for a specific value in any log entries. If the value can be found in a log entry, I like to get the log's Step, Build and Project details.

The pdf do not explain in depth how to use com.buildforge.services.common.db.QueryFilter in order for me to query the Log. I tried to search on the IBM site but there are no information on the QueryFilter.

Are you able to assist in providing more details about the QueryFilter?

Your assistance would be greatly appreciated.

Thank you.

6 answers



permanent link
Brent Ulbricht (2.5k11) | answered Oct 26 '10, 4:56 p.m.
JAZZ DEVELOPER
I refer the link at http://www.ibm.com/developerworks/rational/downloads/08/bf_java_api_guide/index.html

The pdf file did assist with my development work and at the moment I am stagnating when I came across two classes called Log
(com.buildforge.services.client.dbo.Log) and QueryFilter (com.buildforge.services.common.db.QueryFilter).

My aim is to search for a specific value in any log entries. If the value can be found in a log entry, I like to get the log's Step, Build and Project details.

The pdf do not explain in depth how to use com.buildforge.services.common.db.QueryFilter in order for me to query the Log. I tried to search on the IBM site but there are no information on the QueryFilter.

Are you able to assist in providing more details about the QueryFilter?

Your assistance would be greatly appreciated.

Thank you.


Hi,

This is kind of a contrived example of getting some data about a log. The QueryFilter comes in very handy when trying to increase performance by going after particular columns of data that are in the database. However, this requires understanding the database schema.


import com.buildforge.services.client.api.APIClientConnection;

import com.buildforge.services.client.dbo.Build;
import com.buildforge.services.client.dbo.Log;
import com.buildforge.services.client.dbo.Project;
import com.buildforge.services.client.dbo.Result;

import com.buildforge.services.common.api.APIConstants;
import com.buildforge.services.common.api.APIException;

import com.buildforge.services.common.db.ColumnRef;
import com.buildforge.services.common.db.QueryFilter;
import com.buildforge.services.common.db.QueryResponse;
import com.buildforge.services.common.db.SqlCond;

import java.util.ArrayList;
import java.util.List;

/**
* This is an example of retrieving some data with the
* Log findFiltered method.
*/
public class LogFindFilter {

private static final String TEST_PROJECT_NAME = "P_1";

/**
* Since this is an example, the main method will do all the
* logic. Normally, this type of logic would be architected
* in a different way.
*
* @param args The command line arguments
* @throws Exception Any exceptions
*/
public static void main(String[] args) throws Exception {
APIClientConnection conn = new APIClientConnection("localhost", 3966);
conn.authUser("root", "root");

Project project = Project.findByName(conn, TEST_PROJECT_NAME);
if (project == null) {
throw new Exception("Could not find project named \"" + TEST_PROJECT_NAME + "\".");
}

List<Build> builds = Build.findByProjectUuid(conn, project.getUuid());
if (builds.size() <= 0) {
throw new Exception("Could not find any builds for project \"" + TEST_PROJECT_NAME + "\".");
}

Build build = builds.get(0);
List<Result> results = build.getResults();
if (results.size() <= 0) {
throw new Exception("Did not find any results for build with tag of \"" + build.getTag() + "\".");
}

Result result = results.get(0);
List<Log> logs = result.getLogs();
if (logs.size() <= 0) {
throw new Exception("Did not find any logs for result with description \"" + result.getDescription() + "\".");
}
Log log = logs.get(0);

QueryFilter filter = new QueryFilter();
List<ColumnRef> columns = new ArrayList<ColumnRef>();
columns.add(new ColumnRef(APIConstants.KEY_LOG_UUID));
columns.add(new ColumnRef(APIConstants.KEY_LOG_TYPE));
columns.add(new ColumnRef(APIConstants.KEY_LOG_MESSAGE));
filter.setColumnList(columns);
filter.setWhere(SqlCond.eq(new ColumnRef(APIConstants.KEY_LOG_UUID), log.getUuid()));
QueryResponse response = Log.findFiltered(conn, filter);
if (response == null) {
throw new Exception("Unexpected null return from Log findFiltered method call.");
}
List<Object> rowData = response.getRowData();
if (rowData.size() != 1) {
throw new Exception("Expected only 1 row to be returned.");
}
Object[] data = rowData.get(0);
if (data.length != 3) {
throw new Exception("Expected 3 data elements to be returned but only had " + data.length + ".");
}
System.out.println("KEY_LOG_UUID: " + data[0]);
System.out.println("KEY_LOG_TYPE: " + data[1]);
System.out.println("KEY_LOG_MESSAGE: " + data[2]);

conn.logout();
conn.close();
}

}


bju

permanent link
Makara Tan (1621) | answered Oct 27 '10, 11:57 p.m.
Thank you bju.

Where do I find th information about the database schema?

Having observe your code, here is my code which give you an idea what I am trying to achieve:

APIClientConnection conn = new APIClientConnection("localhost", 3966);
conn.authUser("root", "root");


QueryFilter filter = new QueryFilter();
List<ColumnRef> columns = new ArrayList<ColumnRef>();
columns.add(new ColumnRef(APIConstants.KEY_LOG_UUID));
columns.add(new ColumnRef(APIConstants.KEY_LOG_TYPE));
columns.add(new ColumnRef(APIConstants.KEY_LOG_MESSAGE));
filter.setColumnList(columns);
filter.setWhere(SqlCond.like(new ColumnRef(APIConstants.KEY_LOG_MESSAGE), "error here"));

QueryResponse response = Log.findFiltered(conn, filter);

List<Object> rowData = response.getRowData();
if (rowData.size() > 0)
{
for( Object[] aRow: rowData)
{
System.out.println("KEY_LOG_UUID: " + aRow);
System.out.println("KEY_LOG_TYPE: " + aRow);
System.out.println("KEY_LOG_MESSAGE: " + aRow);
System.out.println("\n");

}

}

conn.logout();
conn.close();



How do I query two tables? Here is my plain english query:
Return a list of Step's name, Step's start time and Step's duration where the APIConstants.KEY_LOG_MESSAGE contains "error here"

I believe the Step table will contains the followings:
APIConstants.KEY_STEP_STEP_ID
APIConstants.KEY_STEP_START_TIME
APIConstants.KEY_STEP_DURATION


Your assistance would be greatly appreciated.

permanent link
Brent Ulbricht (2.5k11) | answered Nov 02 '10, 2:09 p.m.
JAZZ DEVELOPER
Hi,

This example code doesn't use QueryFilter, but I'm wondering if it would satisfy your requirements. You might adapt it and try it in your environment to see how it performs. I find it quite easier to code and understand than using QueryFilter. If it doesn't perform well enough, it may be useful to look further at a QueryFilter solution.


import com.buildforge.services.client.api.APIClientConnection;

import com.buildforge.services.client.dbo.Build;
import com.buildforge.services.client.dbo.Log;
import com.buildforge.services.client.dbo.Project;
import com.buildforge.services.client.dbo.Result;

import java.util.List;

/**
* This is an example of searching the log data without
* QueryFilter.
*/
public class LogContains {

private static final String TEST_PROJECT_NAME = "P_1";
private static final String SEARCH_STRING = "TESTING_123";

/**
* Since this is an example, the main method will do all the
* logic. Normally, this type of logic would be architected
* in a different way.
*
* @param args The command line arguments
* @throws Exception Any exceptions
*/
public static void main(String[] args) throws Exception {

APIClientConnection conn = new APIClientConnection("localhost", 3966);
conn.authUser("root", "root");

Project project = Project.findByName(conn, TEST_PROJECT_NAME);
if (project == null) {
throw new Exception("Could not find project named \"" + TEST_PROJECT_NAME + "\".");
}

List<Build> builds = Build.findByProjectUuid(conn, project.getUuid());
if (builds.size() <= 0) {
throw new Exception("Could not find any builds for project \"" + TEST_PROJECT_NAME + "\".");
}

Build build = builds.get(0);

List<Result> results = build.getResults();
if (results.size() <= 0) {
throw new Exception("Did not find any results for build with tag of \"" + build.getTag() + "\".");
}

for (Result result : results) {
List<Log> logs = result.getLogs();
if (logs.size() <= 0) {
throw new Exception("Did not find any logs for result with description \"" + result.getDescription() + "\".");
}
for (Log log : logs) {
if (log.getMessageText().contains(SEARCH_STRING)) {
System.out.println("**********************************************");
System.out.println(" " + result.getDescription());
System.out.println(" Start Timestamp: " + result.getStartTimestamp());
System.out.println(" Duration: " + result.getDuration());
System.out.println(" Line: " + log.getLineId() + " " + log.getType() + " " + log.getMessageText());
System.out.println("**********************************************");
}
}
}

conn.logout();
conn.close();

}

}


Brent Ulbricht
Build Forge Test

permanent link
Makara Tan (1621) | answered Nov 04 '10, 6:40 p.m.
hi bju,

Thank you for the code. I've looked at your code examples and unfortunately it is not what I am after; the performance is too slow. I prefer the QueryFilter because it is quicker; I am scanning thousands of projects, steps, jobs and logs.

It seems the QueryFilter solution is design for one table at a time; hence it will not suit to my solution.

Since QueryFilter solution is not feasible, do you have any knowledge of SqlQuery? I tried to find some document pertaining SqlQuery on the IBM site and unfortunately the information is not there.

From what I understand, SqlQuery can query multiple tables.

I got a code example that query a table and at the moment it is stagnating:
APIClientConnection conn = new APIClientConnection("localhost", 3966);

conn.authUser("root", "root");

SqlQuery qry = new SqlQuery()
.select(new ColumnRef(APIConstants.KEY_LOG_UUID))
.from(new TableRef(APIConstants.KEY_LOG_DBO))
.where( SqlCond.like(new ColumnRef(APIConstants.KEY_LOG_MESSAGE), "custom error=%"));

I am unsure how SqlQuery returns a result...

Do you have any ideas how the SqlQuery works?

permanent link
Steven Vaughan (22111) | answered Nov 05 '10, 10:12 a.m.
JAZZ DEVELOPER
Neither QueryFilter nor SqlQuery are currently meant for public
consumption, which is why they live down in the common package
rather than in the meant-for-public-consumption client package.
We can go down the route of explaining the low-level request and
return semantics of this undocumented and unintended (for the
public) functionality or you can do straight JDBC to the backing
database for full access to the entire schema.

-steve

hi bju,

Thank you for the code. I've looked at your code examples and unfortunately it is not what I am after; the performance is too slow. I prefer the QueryFilter because it is quicker; I am scanning thousands of projects, steps, jobs and logs.

It seems the QueryFilter solution is design for one table at a time; hence it will not suit to my solution.

Since QueryFilter solution is not feasible, do you have any knowledge of SqlQuery? I tried to find some document pertaining SqlQuery on the IBM site and unfortunately the information is not there.

Do you have any ideas how the SqlQuery works?

permanent link
Makara Tan (1621) | answered Nov 08 '10, 8:04 p.m.
Thank you.

Given the response thread above, I shall stick to the current solutions and look into JDBC (BIRT).

Thank you very much for your assistance.

Your answer


Register or to post your answer.


Dashboards and work items are no longer publicly available, so some links may be invalid. We now provide similar information through other means. Learn more here.