Thursday, June 21, 2012

Open Services Gateway Initiative (OSGi)

"OSGi is a component framework specification that brings modularity to the Java platform. OSGi enables the creation of highly cohesive, loosely coupled modules that can be composed into larger applications. What’s more, each module can be individually developed, tested, deployed, updated, and managed with minimal or no impact to the other modules."
Craig Walls,
Modular Java

Wednesday, June 20, 2012

Is it possible to delete users? - RTC 4.0

By definition, users can not be deleted, only users can be archived. That tells us the online help of RTC 4.0 (Managing Users) :

Archiving and restoring users

It seems that users are not physically deleted from the repository because they can leave the database inconsistent as they may have associated objects such as WI, plans, reports, streams, etc.

But what about a procedure that creates/load users with their users id wrong?
Diving for the Java API I found that there is a public interface com.ibm.team.repository.client.IContributorManager with the following method:
 
void deleteContributor (IContributorHandle contributorHandle,
                        org.eclipse.core.runtime.IProgressMonitor monitor)
                        throws TeamRepositoryException

Interesting is not it?

Carefully, I develop a process to delete repository users.
Environment:
- Windows 2003 Server sp2
- IBM WebSphere Application Server 7.0 fp 19
- IBM DB2 9.5
- IBM Rational Team Concert 4.0 

The process is performed on the repository JTS.

Apparently, users have been deleted from the repository, but when looking at the trace file (ccm.log), I have the following error:
WARN ility.contributor.internal.ContributorSynchronizer  - CRJAZ1765E An error occurred while synchronizing user data with the Jazz Team Server.
com.ibm.team.repository.common.ItemNotFoundException: CRJAZ0215I The following record was not found in the database: com.ibm.team.repository.common.model.impl.ContributorRecordHandleImpl@ecc0ecc (stateId: [UUID _cmTyJLYsEeGak91zCxBafg], itemId: [UUID _cmKBJ7YsEeGak91zCxBafg], origin: <unset>, immutable: <unset>) .........

Does the process have deleted users correctly? This is what I feared, that the database can be inconsistent.
The funny thing is that only affects users who have associated objects such as WI, plans, reports, streams, etc.

I made ​​a Java program that searches the tables and fields with the value of this UUID. The result, there are records with this value in the following tables:
- REPOSITORY.DELETED_ITEMS
- COMPATIBILITYPACK.URI_MAPPING

I make the following query on the database:
SELECT * FROM REPOSITORY."DELETED_ITEMS" WHERE ITEM_UUID = '_cmKBJ7YsEeGak91zCxBafg';
SELECT * FROM COMPATIBILITYPACK.."URI_MAPPING" WHERE ITEM_ITEM_ID = '_cmKBJ7YsEeGak91zCxBafg';

 
The tables do not have anything related then I delete the record of the database:
DELETE FROM REPOSITORY."DELETED_ITEMS" WHERE ITEM_UUID = '_cmKBJ7YsEeGak91zCxBafg';
DELETE FROM COMPATIBILITYPACK."URI_MAPPING" WHERE ITEM_ITEM_ID = '_cmKBJ7YsEeGak91zCxBafg';
 

I delete the trace file and restart the JTS and CCM servers checking that no errors appears.

Conclusions: 
- In this version of RTC, it seems that this method should not be used for user management

Recommendations:
- Run the users batch mechanism in test environments

Java program (Using DB2 database):

package  jif.develop.db;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

 
/** 
 * @author Jorge Iglesias
 */
public class FindDB2ItemID {
        public static void main(String[] args) {
                // RTC 4.0 vmware
                String server = "xxx.xxx.xxx.xx"; //
                String alias = "CCM";
                int portNumber = 50000;
                String userId = "xxxx";
                String password = "xxxx";

                try {
                        String url = "jdbc:db2://" + server + ":" + portNumber + "/" + alias;
                        Class.forName("com.ibm.db2.

jcc.DB2Driver").newInstance();
                        Properties props = new Properties();
                        props.setProperty("user", userId);
                        props.setProperty("password", password);

                        // In Partitioned Database environment, set this to the node number
                        // to which you wish to connect (leave as "0" in non-Partitioned
                        // Database environment)
                        props.setProperty("
CONNECTNODE", "0");
                        Connection conn = DriverManager.getConnection(
url, props);
                        // enable transactions
                        conn.setAutoCommit(false);

                        DatabaseMetaData metadata=conn.getMetaData();
            System.out.println(metadata.
getDriverName());
            System.out.println("Driver version: "
+metadata.getDriverVersion());

            System.out.println("Database product name: "
+metadata.
getDatabaseProductName());
            System.out.println("Database product version: "
+metadata.
getDatabaseProductVersion());
            System.out.println("Database version: "
+metadata.
getDatabaseMajorVersion());
            System.out.println("." +metadata.
getDatabaseMinorVersion());
            String[] names = {"TABLE"};
            ResultSet schemas = metadata.getSchemas();
                        List<String> schemaNames = new ArrayList<String>();
            while (schemas.next()) {
                String tableName = schemas.getString("TABLE_
SCHEM");
                schemaNames.add(tableName);
            }

            for (String stringSchema : schemaNames) {
                ResultSet tables = metadata.getTables(null,
stringSchema,
null, names);

                        List<String> tablesNames = new ArrayList<String>();

                while (tables.next()) {
                    String tableName = tables.getString("TABLE_NAME")
;
                                tablesNames.add(tableName);
                }

                for (String stringTable : tablesNames) {
                        System.out.println("*** SCHEMA : " + stringSchema + "
***");
                        System.out.println("*** TABLE : " + stringTable + "
***");
                        Statement statement = conn.createStatement();
                                ResultSet resultset = statement.executeQuery("SELECT * FROM "
+ stringSchema + ".\""+stringTable+"\"");

                                ResultSetMetaData metadataTable =
resultset.getMetaData();
                                int noOfColumns = metadataTable.getColumnCount()
;
                                //Ids examples:
                                //   comp = "_6tXCELYoEeGak91zCxBafg";
                                //   comp = "_c8qcprYsEeGak91zCxBafg";
                                //   comp = "_cmKBJ7YsEeGak91zCxBafg";
                                String comp = "Unassigned";

                                while (resultset.next()) {
                                        for (int i = 1; i <= noOfColumns; i++) {
                                                String rsValue = resultset.getString(i);
                                                if (rsValue != null) {
                                                        if (comp.compareToIgnoreCase(
rsValue) == 0) {
                                                                System.err.println("FOUND ON SCHEMA: " + stringSchema);
                                                                System.err.println("FOUND ON TABLE: " + stringTable);
                                                        }
                                                }
                                        }
                                }
                        }
                        }

            // makes all changes made since the previous commit/rollback
permanent
                // and releases any database locks currrently held by the
Connection.
                conn.commit();

                // immediately disconnects from database and releases JDBC
resources
                conn.close();

                } catch (Exception e) {
                        // TODO Bloque catch generado automáticamente
                        e.printStackTrace();
                }
        }
}

Tuesday, June 12, 2012

Extending RTC (RSA & WAS) - Configuring SDK and Debug

Environment:
- Windows 2003 Server sp2
- IBM WebSphere Application Server 7.0 fp 19
- IBM DB2 9.5
- IBM Rational Team Concert 4.0 RC4a
- IBM Rational Software Architect 8.0

Procedure:

1) Enable debugging on the server side:
1.1) Open WAS admin console and go to Application servers > server2 > Process definition > Java Virtual Machine
1.2) The port can be any one that are not in use, but in our case the port
 7778


1.3) Stop and Start server

2) With ccm, admin and jts stopped, change server files:

- {wasprofileserver}\config\cells\{wasnodecell}\applications\ccm_war.ear\deployments\ccm_war\ccm.war\WEB-INF\web.xml 
- {wasprofileserver}\config\cells\{wasnodecell}\applications\admin_war.ear\deployments\admin_war\admin.war\WEB-INF\web.xml
- {wasprofileserver}\config\cells\{wasnodecell}\applications\jts_war.ear\deployments\jts_war\jts.war\WEB-INF\web.xml

Uncomment the block that deals with the commandline -console argument



3) Start applications

4) Now you need to download the RTC-SDK (you must be logged in jazz.net) and then unpack it.
Note:  the structure of folders and directories is very long. JazzTeam recommends use 7-zip

5) Open the RSA (or Eclipse with jazz plugin installed) and go to menu Window -> Preferences
5.1)Select Plug-in Development -> Target Platform. Select Running Platform and click the "Edit"


5.2) "Add" a new location for this platform:


5.3) Select source "Installation"


5.4) Type the path where you extracted the SDK and click Finish



5.5) The eclipse will recognize the plugins, then finish the dialog


5.6) Open the view "Plugins" and select all
5.7) Right-click, select "Add to Java Search". This step may take a while to complete.


Now, our server and our client should be read to extending RTC and debugging.