2011년 12월 22일 목요일

SCM - scm 커맨드 자료 모음

https://jazz.net/wiki/bin/view/Main/SCMCommandLine



RAM REST API 유스케이스 시나리오

https://jazz.net/wiki/bin/view/Main/RamRestScenario
http://publib.boulder.ibm.com/infocenter/ramhelp/v7r5m1/index.jsp

This use case scenario is an example of how to use the IBM® Rational® Asset Managers REST APIs to query, retrieve, and publish assets. In this use case scenario, Rational Asset Manager integrates with an automated build system, such as IBM Rational Build Forge or Ant scripts. The scenario is from the perspective of the automated build system.


Run a nightly build of implementations for a software release and publish or replace any implementations by using the Rational Asset Manager REST Services API.

Prerequisites

  1. Rational Asset Manager server URL (for example, http://server:8080/ram/)
  2. User ID and password for authentication
  3. Name and version of the release asset (for example, Name: Credit Verification Service Release, Version: 1.0) 
샘플은 https://jazz.net/wiki/bin/view/Main/RamRestExamples


  •  Query for the software releases to build
  • Retrieve the content needed for the build
  • Update an existing implementation asset
  • Create an implementation asset
  • Client API - 라이센스 부여


    repo.login(monitor);

    //static String userID = "jyyie";
    IContributorManager contributorManager = repo.contributorManager();
    IContributor contributor = contributorManager.fetchContributorByUserId(userID, monitor);

    // Print licenses types in repository
    ILicenseAdminService licenseService =
    (ILicenseAdminService)((TeamRepository)repo).getServiceInterface(ILicenseAdminService.class);
    IContributorLicenseType licenseTypes[] = licenseService.getLicenseTypes();
    System.out.println("");
    for(IContributorLicenseType licenseType : licenseTypes){
    String id = licenseType.getId();
    System.out.println(id);
    }

    /*
    com.ibm.team.rrc.reviewer
    com.ibm.team.rrc.author
    com.ibm.team.rrc.system
    com.ibm.team.rtc.stakeholder
    com.ibm.team.rtc.contributor
    com.ibm.team.rtc.developer
    com.ibm.rtc.developer-iep
    com.ibm.team.rtc.buildsystem
    com.ibm.team.rtc.cc-connector
    com.ibm.team.rtc.cq-connector
    com.ibm.rqm.viewer
    com.ibm.rqm.tester
    com.ibm.rqm.functional
    com.ibm.team.lpa.system
    com.ibm.team.clm.datacollector
    com.ibm.team.rrc.author.floating

    com.ibm.team.rtc.contributor.floating
    com.ibm.team.rtc.developer.floating
    com.ibm.rqm.tester.floating
    com.ibm.clm.professional.floating

    */

    2011년 12월 20일 화요일

    래쇼날 라이센스 키 발급 절차

    http://publib.boulder.ibm.com/infocenter/cqhelp/v8r0m0/topic/com.ibm.rational.licensing.doc/topics/t_access_license_key_center.htm

    IBM Rational License Key Center를 통한 license key 발급 절차

    IBM Rational® License Key Center는 온라인 라이센싱 도구로써 IBM Rational License Key 를 발급받거나 반환할 수 있습니다.

    IBM Rational License Key Center의 회사 account의 멤버여야 합니다. IBM에 Rational 제품구매를 주문한 사람은 회사 account의 administrator로 설정되며 Rational License Key Center에 로그인할 수 있는 임시 비밀번호가 포함된 환영 메일을 받게 됩니다.

    Rational License Key Center를 엑세스하는 절차:
    1. IBM Software Support for Rational products 사이트로 들어갑니다.http://www.ibm.com/software/rational/support/licensing/
    2. Rational License Key Center 클릭한 후 Continue 클릭합니다.
    3. Rational License Key Center에 로그인합니다.
    만약 Rational License Key Center에 로그인할 패스워드를 가지고 있지 않다면 다음 방법 중 하나를 따릅니다:
    1. 구매 주문을 한 사람을 연락해서 회사 account의 멤버로 추가해 달라고 요청합니다. 회사 account에 멤버로 추가할려면, Rational License Key Center에 로그인합니다. Account members 기능을 이용해서 새 멤버를 추가합니다. 멤버로 추가되면, 새 멤버는  Rational License Key Center에 로그인할 수 있는 임시 비밀번호가 포함된 환영 메일을 받게 됩니다.
      1. IBM Rational licensing support 사이트에 들어갑니다: http://www.ibm.com/software/rational/support/licensing/.
      2. Rational License Key Center 클릭합니다.
      3. Rational License Key Center 로그인 페이지에서 "Don't have a password?" 링크를 클릭합니다.
      4. 당신의 연락처, IBM Site Number, 구매와 관련된 IBM Sales Order Number 등의 정보를 입력합니다. 구매 주문을 한 사람이 구매시에 받은  IBM Proof of Entitlement (PoE) certificate 이메일 또는 하드카피에서 관련 정보를 찾을 수 있습니다.
      5. 멤버로 추가된 뒤에는  임시 비밀번호가 포함된 환영 메일을 받게 됩니다.
      6. 비밀번호를 사용하여 Rational License Key Center에 로그인합니다.
        Note: 맨 처음 Rational License Key Center에 로그인하면 임시 비밀번호 변경을 요청받게 됩니다.
    Rational licensing support 사이트 http://www.ibm.com/software/rational/support/licensing/ 에는 라이센스 키 발급 절차가 들어 있는 Quick Start Guide를 제공합니다.

    Rational License Key Center는 라이센스 키 발급 후에 라이센스 키 설치 방법를 표시합니다. Converting a trial or evaluation version of the product to the permanent production version is as simple as installing the license key once you generate it from the Rational License Key Center. You do not need to uninstall or reinstall the product.

    Floating 클라이언트 액세스 라이센스 키 설치

    http://publib.boulder.ibm.com/infocenter/clmhelp/v3r0m1/topic/com.ibm.jazz.repository.web.admin.doc/topics/tmanagefloatinglic.html



    Jazz™ Team Server관리 페이지에에서 라이센스 키 관리 섹션을 통해 Floating 클라이언트 액세스 라이센스(CAL) 키를 설치 및 구성할 수 있습니다.

    시작하기 전에

    Jazz Team Server를 독립형 Floating 라이센스 서버로 사용 중인 경우, CAL 키가 설치된 Floating 라이센스 서버가 어느 Jazz Team Server 애플리케이션인지, 그리고 Floating CAL을 지정하는 Jazz Team Server가 어느 서버인지 알아야 합니다.
    Jazz Team Server관리 페이지에 로그인하고 JazzAdmins 그룹의 구성원이어야 합니다.

    프로시저

    1. (Floating 라이센스 서버로 작동하는 Jazz 서버에) Floating CAL 키를 설치하십시오.
      1. 관리 페이지에서 서버 탭을 클릭하십시오.
      2. 라이센싱 분할창에서 라이센스 키 관리를 클릭하십시오.
      3. 라이센스 키 관리 페이지의 Floating 라이센스 서버 영역에서 추가를 클릭합니다.
      4. 라이센스 파일 업로드 대화 상자에 있는 라이센스 활성화 키 업로드 필드에서 찾아보기를 클릭하고 Floating 클라이언트 액세스 라이센스 활성화 키의 위치를 탐색하십시오.
      5. 키 파일을 선택하십시오.
      6. 구입 필드에서 구입한 라이센스의 번호를 입력합니다.
      7. 다음을 클릭하십시오.
      8. 옵션: Floating 라이센스 서버에 연결 페이지에서 이 서버에서의 Floating 기능을 구성하려면 예, 이 서버의 사용자가 해당 라이센스 서버의 floating 라이센스를 구할 수 있음 옆의 선택란을 선택하십시오.
      9. 완료를 클릭합니다.
    2. Floating 라이센스 서버를 가리키도록 다른 Jazz Team Server를 구성하십시오.
      1. Jazz Team Server관리 페이지에서 서버 탭을 클릭하십시오.
      2. 라이센싱 분할창에서 라이센스 키 관리를 클릭하십시오.
      3. 서버 정보 섹션에서 Floating 라이센스 서버 행 위에 커서를 두고 Floating 라이센스 서버 구성 아이콘을 클릭하십시오.
      4. Floating 라이센스 서버 구성 대화 상자의 Floating 라이센스 서버 필드에 서버 경로를 입력합니다. 예를 들어, http://floating-license-server:9080/jts입니다. 여기서 floating-license-server는 서버의 완전한 호스트 이름으로 바뀌어야 합니다.
      5. 서버 연결을 테스트하려면 연결 테스트를 클릭합니다.
      6. 완료를 클릭하십시오.
    3. 옵션: 라이센스의 구입 계수를 수정하려면 다음을 수행하십시오.
      1. Floating 라이센스 서버 영역에서 편집을 클릭하십시오.
      2. 라이센스 구입 필드에서 구입한 라이센스의 번호를 입력하십시오.
      3. 완료를 클릭하십시오.

    결과

    Jazz Team Server는 이제 Floating CAL이 사용자에게 지정될 수 있도록 구성되었습니다. Floating CAL은 사용자가 요청하면 Floating 라이센스 서버에서 자동으로 체크아웃됩니다.  

  • SCM - MS SCCI 지원

    MS-SCCI(MicroSoft Source Code Control Interface)

    Use Case View

    •  "Add to archive": 파일을 SCM에 추가함. 
      • 폴더 경로가 공유루트의 일부일 때: 파일을 새 변경세트에 체크인하고 전달함.
      • 폴더 경로가 공유루트가 아닐 경우: 공유 마법사에서 폴더 경로상의 공유 루트 폴더를 선택하고 파일을 변경세트에 체크인하고 전달함. 
    • "Checkout": 플로우 대상 스트림에 해당 파일을 잠금.
    • "Check in": 새 변경세트에 체크인하고 전달하고 잠금 해제함.
    • "Undo checkout": 현 사용자가 파일에 잠금을 한 경우 잠금을 해제하고, 변경사항을 원상복구함.
    • "Get History": 별도 대화상자에 파일에 대한 히스토리 뷰를 제공함. 



    Logical View



    Implementation View

    • Native COM Plugin (JazzMSSCCIProvider.dll) – C++ code
    • RTC's Default SCM subsystem – Managed code - C# (JazzScmScci.dll) 



    Process View

    Deployment View

    레지스트리 항목:
    • 키: "HKLM\Software\IBM\JazzMSSCCIProvider\SCCServerName"
      값: "Jazz MSSCCI Provider"
    • 키: "HKLM\Software\IBM\JazzMSSCCIProvider\SCCServerPath"
      값: "\JazzMSSCCIProvider.dll"
    • 키: "HKLM\Software\SourceCodeControlProvider\InstalledSCCProviders\Jazz MSSCCI Provider"
      값: "Software\IBM\JazzMSSCCIProvider"
    • 키: "HKLM\Software\SourceCodeControlProvider\ProviderRegKey"
      값: "Software\IBM\JazzMSSCCIProvider"
    • CLSID 추가 


    https://jazz.net/wiki/bin/view/Main/MSSCCI-RTC

    2011년 12월 19일 월요일

    IHS와 Jazz 톰캣 SSL 핸드쉐이크


    SSL Handshake Configuration Between IHS and Jazz Tomcat


    C:\Program Files\IBM\HTTPServer\bin>gsk7cmd -cert -import
    -db ibm-team-ssl.keystore -pw ibm-team -type jks
    -target ihskeys.kdb -target_pw testpass -target_type cms
    -label ibm-team
    -new_label ibm-team

    IHS 리버스 프락시 (테스트용 설정)


    Install IHS

    1. Download the IHS Server.


    2. Place this tar.gz file in the home directory of the to-be IHS server.


    3. Extract the tar and enter the IHS directory.

    tar xvfz IHS.tar.gz
    cd IHS
    


    4. Create a new response file in this directory "responsefile-ihs.txt".
    -OPT silentInstallLicenseAcceptance=true
    -OPT allowNonRootSilentInstall=true
    -OPT disableOSPrereqChecking=true
    -OPT installLocation=/home/idcuser/IBM/HTTPServer
    -OPT httpPort=80
    -OPT runSetupAdmin=false
    -OPT createAdminAuth=false
    -OPT webserverDefinition=\"webserver1\"
    -OPT washostname=\"localhost\"
    


    5. Save and exit the response file.


    6. Install the IHS server using the response file you just created.
    ./install -options "responsefile-ihs.txt" -silent
    

    Setup SSL on IHS Server

    Now that the IHS server is up and running, we need to configure it to work with SSL. To do this, we will create and sign our own certificate and use this for the SSL. These steps are required in order to correctly send requests to Jazz-based products behind the proxy.

    Note You will need to substitute the follow parameters in the code below:
    • testpass (Pick a password)
    • xx.xxx.xxx.xxx (This should be the ip address of the IHS server)
    1. Stop IHS Server
    cd ~/IBM/HTTPServer/bin/
    sudo ./apachectl stop
    


    2. Create the keystore database
    cd ~/IBM/HTTPServer/bin
    ./gsk7cmd -keydb -create -db ihskeys -pw testpass -expire 3650 -stash -type cms
    


    3. Create a self-signed certificate and add it to the the new keystore db
    ./gsk7cmd -cert -create -db ihskeys.kdb -label xx.xxx.xxx.xxx -expire 3650 -dn "CN=xx.xxx.xxx.xxx/O=IBM/C=US" -default_cert yes -pw testpass
    


    4. Modify httpd.conf (/IBM/HTTPServer/conf/httpd.conf) to include the new SSL information.
    • First, make sure that the IBM ssl module is loaded and un-commented.
    LoadModule ibm_ssl_module modules/mod_ibm_ssl.so
    
    • Next, add this to the end of the httpd.conf file. Verify to make sure this is not already un-commented out in httpd.conf somewhere.
    # SSL Configuration
    Listen xx.xxx.xxx.xxx:443 #proxy ip
    
            SSLProxyEngine On
            SSLEnable
            SSLCipherSpec 27
            SSLCipherSpec 21
            SSLCipherSpec 23
            SSLCipherSpec 3A
            SSLCipherSpec 34
            SSLCipherSpec 35
    
    KeyFile "/home/idcuser/IBM/HTTPServer/bin/ihskeys.kdb"
    SSLDisable
    
    5. Save the httpd.conf and restart IHS
    sudo ./apachectl start
    

    Setup SSL Handshake Between Servers

    This step is required in order to proxy SSL requests from the IHS server to the other WAS servers. Since our WAS servers are not using official CA-signed certificates, they are considered Invalid and cause the SSL proxy requests to fail the handshake. These steps are quite involved, so please follow them carefully. 



    You must do these steps in order to get the reverse proxy to work.


    1. Go to the WAS Integration Solutions Console for one of the WAS servers.

    2. Security -> SSL certificate and key management -> Key Stores and Certificates

    3. Create a new Key store
    • Name: was283keys (..where 283 is the last portion of this servers IP. Not required, but will make life easier later.)
    • Path: (something like this) ${CONFIG_ROOT}/cells/vlan690-9-31-192-283Node01Cell/nodes/vlan690-9-31-192-283Node01/was283keys.kdb (Note: Your path WILL be different.)
    • Type: CMSKS
    • Password: Set a password. Make sure you remember this.
    4. Click OK then Save.


    5. Open up NodeDefaultKeyStore.


    6. Choose "Personal certificates" from the right sidebar.


    7. Check the default certificate and do Export.
    • Key Store Password: Probably the default password which is: WebAS
    • Select "Key Store File" radio button
    • Key File Name: ${CONFIG_ROOT}/cells/vlan690-9-31-192-283Node01Cell/nodes/vlan690-9-31-192-283Node01/was283keys.kdb (Should be the same as above)
    • Type: CMSKS
    • Password: (the one you used above)


    8. Export the Key. You can verify that it worked by going back and looking at the key store we created (was283keys) and make sure the "default" certificate is in there.


    9. Next, we have to copy this key store to the IHS server. Something like this should do the trick:
    cd ~/IBM/WebSphere/AppServer/profiles/AppSrv01/config/cells/vlan690-9-31-192-283Node01Cell/nodes/vlan690-9-31-192-283Node01
    scp was283keys.kdb idcuser@:/home/idcuser/IBM/HTTPServer/bin
    


    10. Now switch to the IHS server.


    11. Run this command to add the certificates from our keystore into our existing IHS keystore. Be sure to change the passwords to the one you used above.
    cd ~/IBM/HTTPServer/bin
    ./gsk7cmd -cert -import -db was283keys.kdb -pw password -type cms -target ihskeys.kdb -target_pw password -target_type cms -label default -new_label default_283
    

    12. Restart IHS:
    sudo ./apachectl restart 


    Reverse Proxy Setup using IHS

    The IHS configuration property is located: /home/idcuser/IBM/HTTPServer/conf/httpd.conf

    Make sure that the proxy modules are loaded and uncommented:

    LoadModule proxy_module modules/mod_proxy.so
    LoadModule proxy_connect_module modules/mod_proxy_connect.so
    LoadModule proxy_http_module modules/mod_proxy_http.so
    

    1. In httpd.conf, add the following lines to the bottom of the httpd.conf file:
    ProxyRequests off
    ProxyPreserveHost on
    SSLProxyEngine on
    
    #Proxy setup for a Jazz Foundation Server
    ProxyPass /jazz1/ https://x.xx.xxx.151:9443/jazz1/
    
       ProxyPassReverse /jazz1/
    
    
    #Proxy setup for RTC Server
    ProxyPass /rtc/ https://x.xx.xxx.152:9443/rtc/
     
        ProxyPassReverse /rtc/
    
    
    #Proxy setup for RQM Server
    ProxyPass /jazz/ https://x.xx.xxx.150:9444/jazz/
     
        ProxyPassReverse /jazz/
    
    

    2. Verify that all other proxy-related settings in the httpd.conf file are commented out or disabled.

    3. Restart the IHS Server:
     sudo IBM/HTTPServer/bin/apachectl restart

    2011년 12월 18일 일요일

    이클립스 업데이트 사이트

    참고 : http://wiki.eclipse.org/Eclipse_Project_Update_Sites
    참고 : http://wiki.eclipse.org/Older_Versions_Of_Eclipse
    • Galileo(3.5.2) 원격 업데이트 사이트 : http://download.eclipse.org/releases/galileo


    RTC 차기 릴리즈 개발 계획 (2012년 6월)

    https://jazz.net/projects/rational-team-concert/release-plan/


    Milestones and schedule

    Milestones are builds that have passed integration testing and will be made available for download and trial. A milestone can be promoted to a beta after an additional week or two of production use.
    The milestone and release candidate (RC) schedule is as follows:

    • 2011/08/22 - Milestone 2
    • 2011/09/12 - Milestone 3
    • 2011/10/10 - Milestone 4
    • 2011/10/31 - Milestone 5
    • 2011/11/21 - Milestone 6
    • 2012/01/09 - Milestone 7
    • 2012/01/30 - Milestone 8
    • 2012/02/20 - Release Candidate 0
    • 2012/03/05 - Release Candidate 1 / Beta 1
    • 2012/04/02 - Release Candidate 2
    • 2012/04/23 - Release Candidate 3
    • 2012/05/07 - Release Candidate 4
    • 2012/05/14 - Release Candidate 5
    • 2012/05/21 - Release Candidate 6
    This next release of Rational Team Concert is targeted for 2Q 2012.


    Overview

    Rational Team Concert forms the developer focused role of our Rational solution for Collaborative LifeCycle Management. Rational Team Concert success has grown at a rapid pace and this growth has created the need for managing very large deployments. For the next release, we intend to focus on three areas including improved enterprise deployment, scaling and reliability, enhancements for customers developing complex and embedded systems, and improved consumability and usability.

    Themes

    The following themes guide the planning of this release:


    Application LifeCycle Management - Enterprise Deployment and Reliability: A key advantage of the Jazz platform approach to application lifecycle management is that it can help lower cost of ownership by centralizing the administration of ALM across an enterprise. Our customers are embracing this simpler Jazz platform approach and are deploying much larger communities of users. As more users are deployed, the need for high availability of those services also grows. In this release of Rational Team Concert, we intend to support automated high availability that leverages WebSphere clustering capabilities (169830) Although the primary goal of this work is to automate high availability, the underlying use of clustering will also allow us to begin to exploit horizontal scaling of Rational Team Concert and CLM applications across more distributed servers.


    Application LifeCycle Management - Enterprise Scalability: High availability addresses the enterprise need for availability of users but what about the growth in complexity of the projects being managed? In this release we intend to also introduce planning across projects (169425). Plans are currently limited to iterations inside a project area in RTC 3.0.1 but in this release, we intend to allow users with master plans to track tasks in other project areas. The primary use case for this work is to be able to plan development execution of a cross cutting feature that spans more than one RTC project area. Managing more data means managing more queries. To make it easier to manage many query variations in a single query, we intend to allow queries to support input variables (169822). Do you also have external web based data sets that you would like to use as input to work item custom fields? If that is the case, we plan to allow input from external HTTP value set providers (169820) giving you more flexibility in managing enterprise data sets.


    Systems Market Support - Variant Management: Many of our customers develop complex or embedded applications that require managing many release variants at the same time. One example of this is when you need to deliver a bug fix to a series of release streams and you need a way to verify you have done this to all the variants of your software. We plan to make it easier to find all the streams where a given change set has been delivered. (169818)


    Systems Market Support - Security and Permissions: Often a complex hardware/software development effort involves collaboration across teams spanning outside suppliers who may be delivering parts of a broader solution but all working on the same project area. This requires the ability to provide more flexibility in configuring read access for any combination of users, team areas, and project areas. In this release, we intend to support "access groups", which are a collection of project areas, team areas, and users (170132, 169933) that can be shared at the repository, project area or team area level. A related issue is the need to control visibility to versioned artifacts at the folder or file level and not just at the SCM component level. In this release we intend to make that possible (169819). Some customers also need to be able to delete artifacts for security or other reasons. In RTC 3.0.1 we introduced the ability to delete work items and in this release we intend to add support for deleting versioned SCM artifacts (169816).


    Systems Market Support - Workspace Management: More flexible SCM load rules for customers who need to load components into on disk workspaces that are laid out differently than how they are stored in the repository is also planned. We intend to allow users to save complex load rules to a file and store them for re-use across teams. You can read more about this feature in our New & Noteworthy.


    Consumability and Usability - Simple Versioning: Many extended team members can benefit from taking advantage of versioning, so it would be beneficial to these users to keep the interfaces to versioning simple and easy to use. We intend to add a Windows 7 Explorer integration to provide SCM services targeted at non-developers with simple locking and versioning support using a familiar file system view. (169838).


    Consumability and Usability - Kanban Method Taskboard: Our customers employing lean and agile methods have also asked us to provide Kanban Method support in RTC. Kanban Method helps to optimize the ideal flow of work through the system using a "pull" model and answers questions like "Where is capacity available" and "Am I exceeding my desired limits?" We intend to deliver this by providing a Kanban Method taskboard planning view which will allow limits to be set on state flows in the taskboard viewer. (170002)


    Consumability and Usability - Any platform. Any IDE. One ALM Toolset: We intend to continue to extend our rich developer experience from the Rational Team Concert Client for Microsoft Visual Studio IDE (169839) as well as Eclipse based IDE's such as Rational Developer for System z/Power Systems (169843). We also plan to make performance and usability enhancements for mainframe users of the ISPF client (169841).


    Consumability and Usability - Enhanced Build, Promotion and Deployment: We intend to make available the dependency build, promotion and deployment capabilities previously only available on z/OS on other platforms, starting with IBM i (169845). In addition we plan to enhance build, promotion and deployment by allowing build output (binaries) to be stored in the SCM (169817).


    Consumability and Usability - Hudson Build Engine Support: Rational Team Concert supports incremental adoption which is a key aspect of consumability for different project needs. In keeping with this theme, we intend to extend support for Hudson as a build engine for RTC which should make migration of your build easier if you choose to adopt Rational Team Concert. (169829). With these planned changes we intend to allow development teams to have a built-in choice of build engines that best meets their needs from continuous integration through enterprise solutions such as the Jazz build engine, Hudson, Microsoft Build Engine (MS-Build) and Rational Build Forge. You can use any of the build engines and have RTC manage build health and reporting.
    For more details about the corresponding plan items for these themes, view the detailed release iteration plan.


    Notices

    References in this material to IBM products, programs, or services do not imply that they will be available in all countries in which IBM operates. This material, including any plans contained in the material, may change at any time at IBM's sole discretion, based on market opportunities or other factors, and are not intended to be a commitment to future content, including product or feature availability, in any way. Statements regarding IBM's future direction or intent are subject to change or withdrawal without notice and represent goals and objectives only. Please refer to Terms of Use for more information.
    © Copyright IBM Corporation 2008-2011. All rights reserved.

    JDBC 드라이버 (타입1,2,3,4)

    A JDBC driver is a software component enabling a Java application to interact with a database.[1] JDBC drivers are analogous toODBC drivers, ADO.NET data providers, and OLE DB providers.

    To connect with individual databases, JDBC (the Java Database Connectivity API) requires drivers for each database. The JDBC driver gives out the connection to the database and implements the protocol for transferring the query and result between client and database.
    JDBC technology drivers fit into one of four categories.

    Type 4 Driver - Native-Protocol Driver


    Schematic of the Native-Protocol driver


    The JDBC type 4 driver, also known as the Direct to Database Pure Java Driver, is a database driver implementation that converts JDBC calls directly into a vendor-specific database protocol.Therefore it is called a THIN driver.
    Written completely in Java, type 4 drivers are thus platform independent. They install inside the Java Virtual Machine of the client. This provides better performance than the type 1 and type 2 drivers as it does not have the overhead of conversion of calls into ODBC or database API calls. Unlike the type 3 drivers, it does not need associated software to work.
    As the database protocol is vendor-specific, the JDBC client requires separate drivers, usually vendor-supplied, to connect to different types of databases.

    DB2 JDBC 타입2, 타입4 드라이버 코드 비교

    타입2, 타입4 비교표


     JDBC 드라이버 타입 2 JDBC 드라이버 타입 4 
     톰캣에 넣을 라이브러리db2java.jar
    (Native LIB는 PATH상에)
    db2jcc.jar
    db2jcc_license_cu.jar
     Class Loadingstatic {
        try {
          Class.forName("COM.ibm.db2.jdbc.app.DB2Driver");
        } catch ( Exception e) {
            e.printStackTrace();
        }
    }
    static {
        try {
            Class.forName("com.ibm.db2.jcc.DB2Driver");
        } catch ( Exception e) {
            e.printStackTrace();
        }
    }
     Query & ResultString url = "jdbc:db2:SAMDB";
    String user_id="db2admin";
    String password = "rational";

    Connection conn = null;
    Statement stmt = null;
    ResultSet rs = null;

    try {
        conn = DriverManager.getConnection(url,user_id,password);
        stmt  = conn.createStatement();
        rs = stmt.executeQuery("select id,name from SAMTABLE");
      
        while(rs.next()) {
            int id = rs.getInt(1);
            String name = rs.getString(2);
        }

    } catch ( SQLException e) {
        e.printStackTrace();
    }

    try {
        rs.close();
        stmt.close();
        conn.close();
    } catch ( Exception e) {
        e.printStackTrace();
    }
    String url = "jdbc:db2://localhost:50000/SAMDB";
    String user_id="db2admin";
    String password = "rational";

    Connection conn = null;
    Statement stmt = null;
    ResultSet rs = null;

    try {
        conn = DriverManager.getConnection(url,user_id,password);
        stmt  = conn.createStatement();
        rs = stmt.executeQuery("select id,name from SAMTABLE");
      
        while(rs.next()) {
            int id = rs.getInt(1);
            String name = rs.getString(2);
        }

    } catch ( SQLException e) {
        e.printStackTrace();
    }

    try {
        rs.close();
        stmt.close();
        conn.close();
    } catch ( Exception e) {
        e.printStackTrace();
    }



    DB2 JDBC 드라이버 발전사

    V8 이전의 JDBC driver을 "DB2 JDBC 드라이버"라 칭하고,
    v8 이후에 새롭게 추가된 JDBC driver를 "Universal JDBC 드라이버"라 명명합니다.

    v8 이상에서는 Universal JDBC 드라이버를 사용할 것을 권장합니다.
    http://www.ibm.com/developerworks/data/library/techarticle/dm-0512kokkat/

    JDBC JAR 파일
    • db2java.zip: DB2 JDBC 타입2와 타입3 드라이버
    • db2jcc.jar: Universal JDBC 타입2와 타입4 드라이버

    라이센스 JAR 파일 : Universal JDBC 드라이버 사용시 필요
    • db2jcc_license_cu.jar : LUW(Linux,Unix,Windows) 용
    • db2jcc_license_cisuz.jar : iSeries, z/OS용

    JDBC Drvier 클래스명
    • DB2 JDBC 타입2 드라이버: COM.ibm.db2.jdbc.app.DB2Driver
    • DB2 JDBC 타입3 드라이버: COM.ibm.db2.jdbc.net.DB2Driver
    • Universal JDBC 타입2 드라이버: com.ibm.db2.jcc.DB2Driver
    • Universal JDBC 타입4 드라이버: com.ibm.db2.jcc.DB2Driver

    JDBC URL 형식
    • DB2 JDBC 타입2 드라이버: jdbc:db2:db_name
    • DB2 JDBC 타입3 드라이버: jdbc:db2://host_name:port_name/db_name
    • Universal JDBC 타입2 드라이버: jdbc:db2:db_name
    • Universal JDBC 타입4 드라이버: jdbc:db2://host_name:port_name/db_name

    Windows DB2 사용시 주의점
    Universal JDBC 타입4 드라이버 + SUN JDK 사용시,
    IBM CodeSet으로 자동변환이 안되기 때문에 DATABASE생성시 UTF-8코드로 생성해주어야 함.


    JSON 송신 서블릿 샘플 코드

    1. JSON 코드를 servlet 프로젝트에 추가해 줍니다 : http://www.json.org/java/json.zip






    2. JSON 문자열 형식으로 데이타를 요청자에게 보내는 간단한 샘플 코드입니다.


    public class GuServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;

        static {
            try {
                Class.forName("com.ibm.db2.jcc.DB2Driver");
            } catch ( Exception e) {
                e.printStackTrace();
            }
        }

        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            try {
                doGuJSON(request, response);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            try {
                doGuJSON(request, response);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }


        protected void doGuJSON (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, JSONException {

            String url = "jdbc:db2://localhost:50000/META";
            String user_id="db2admin";
            String password = "rational";

            Connection conn = null;
            Statement stmt = null;
            ResultSet rs = null;
           
            PrintWriter out = null;

            try {
                conn = DriverManager.getConnection(url,user_id,password);
                stmt  = conn.createStatement();
                rs = stmt.executeQuery("select id,name from gu");

                JSONArray listObj = new JSONArray();
                int i=0;
                while(rs.next()) {

                    int id = rs.getInt(1);
                    String name = rs.getString(2);

                    JSONObject itemObj = new JSONObject();
                    itemObj.put("name", name.trim()); //trim trailing white spaces (fixed length string)
                    itemObj.put("id", id);

                    listObj.put(i, itemObj);
                    i++;
                }

                try {
                    response.setCharacterEncoding("UTF-8");
                    out = response.getWriter();
                    out.println(listObj);
                } catch ( Exception e) {
                    e.printStackTrace();
                } finally {
                    try { if (out!=null) out.close(); } catch (Exception e) {}
                }

            } catch ( SQLException se) {
                se.printStackTrace();
            } finally {
                try { if ( rs!=null ) rs.close(); } catch ( Exception e) {}
                try { if ( stmt!=null ) stmt.close(); } catch ( Exception e) {}
                try { if ( conn!=null ) conn.close(); } catch ( Exception e) {}
            }
        }
    }





    3. cURL을 이용한 헤더와 바디 정보


    $ curl -v localhost:8080/MetaServlet/Gu

    * About to connect() to localhost port 8080 (#0)
    * Trying 127.0.0.1... connected
    * Connected to localhost (127.0.0.1) port 8080 (#0)

    > GET /MetaServlet/Gu HTTP/1.1
    > User-Agent: curl/7.19.6 (i686-pc-cygwin) libcurl/7.19.6 OpenSSL/0.9.8n zlib/1.2.3 libidn/1.16 libssh2/1.2
    > Host: localhost:8080
    > Accept: */*
    >

    < HTTP/1.1 200 OK
    < Server: Apache-Coyote/1.1
    < Transfer-Encoding: chunked
    < Date: Sat, 11 Dec 2010 04:54:10 GMT
    <
    [{"name":"강남구","id":1},{"name":"서초구","id":2}]

    * Connection #0 to host localhost left intact
    * Closing connection #0

    RTC plain Java Client LIb의 서블릿에 설정

    1. 서블릿의 WEB-INF/lib에 plainJavaLib들을 추가합니다.
    2. 다음은 TeamPlatform을 통해서 ...



    RTC plain Java Client Lib 개발 환경 설정

    https://jazz.net/wiki/bin/view/Main/RTCSDK20_DevelopmentEnvironmentSetup

    Note: Some of the download archives (particularly the source and JUnit archives) have path lengths longer than 250 characters and cause trouble for some extractor tools on windows. One zip extractor tool that works is 7Zip.


    Plain Java Development

    Step 1: Downloads

    Client for Eclipse IDE, Server 및 Plain Java Client Libraries 파일을 "All Downloads" 페이지에서 다운로드를 받습니다.

    Step 2: Installation

    • $INSTALLDIR에 서버 압축을 풉니다
    • $INSTALLDIR/jazz/client/plainjava에 plain java client 압축을 풉니다.

    Step 3: Hello World Client

    The plain java client library includes a set of snippets which show how to use the basics like creating a work item, creating streams and delivering changes, and creating team and project areas. If you don't want to use the command line as shown in the README.TXT, you can use Rational Team Concert itself to run the snippets as follows:

    • Create a new Java project and in the wizard create the project from an existing directory. Select the directory into which you unzipped the Jazz Plain Java Client Libraries.
    • On the second page of the wizard, select the Add Jars... button and add all the jars from the client library install to the classpath of this new Java project.

    The new project will have the snippets package and the snippets will compile against the jars. You can then start the server and follow the instructions in the snippets/README.TXT file for adding the test user and running the snippets.
    This will provide an easy setup, but it's hard to browse the source code since the source is packaged as plug-in source packages. As a result, there is an alternate setup which will allow browsing the source directly for the plain java client. For regular Eclipse plug-in development, the source packaging is 100% compatible.

    RTC_SCM_리눅스_GUI_&_CMD_사용법.ppt




    개발환경 및 상황따른 사용법
    4상황 1. 리눅스에서 Eclipse UI 이용한 방법
    4상황 2. 리눅스 커맨드를 이용한 작업
    4상황 3. 리눅스 커맨드와 이클립스를 혼용하여 사용하는 방법
    4상황 4. 리눅스 커맨드와 이클립스(Tracking Mode) 혼용하여 사용하는 방법

    RTC scm 커맨드 사용법

    저장소 연결 & 로그인
    scm login -n ccmhost -r https://ccmhost.mycompany.com:9443/ccm -u jazzy

    참고: 로그아웃
    scm logout -r ccmhost

    참고: 프로젝트 영역 목록 보기
    scm list projectareas -r ccmhost

    참고: 팀 영역 목록 보기
    scm list teamareas -r ccmhost






    참고: 스트림 목록 보기 (소유자 : 팀영역)
    scm list streams -r ccmhost


    콤포넌트 만들기(팀 스트림은 미리 GUI를 통해 생성해 둔다)
    scm create component "Squawk"(콤포넌트) "Squawk CMD"(스트림) -r ccmhost

    개인 리파지토리 작업공간 만들기
    scm create workspace "jazzy on Squawk CMD"(개인 리파지토리 작업공간) -s "Squawk CMD"(팀 스트림) -r ccmhost

    PC 개인 작업 공간으로 서버상의 개인 리파지토리내 파일 다운로드
    (.metadata 디렉토리 생성됨)
    scm load -d c:\workspace\CMD -r ccmhost "jazzy on Squawk CMD"(갠 리파지토리 작업 공간) "Squawk"(콤포넌트)

    PC 개인 작업 중인 파일을 서버상의 개인 리파지토리에 업로드하여 공유
    scm share -r ccmhost "jazzy on Squawk CMD"(개인 리파지토리 작업 공간) "Squawk"(콤포넌트) Squawk(콤포넌트 대응 루트폴더명)

    팀 스트림으로 개인 리파지토리내 공유용 변경 세트 전달하여 팀에 공유
    scm deliver -r ccmhost -s "jazzy on Squawk CMD"(From 개인 리파지토리 작업 공간)

    User B : GUI를 통해 Repository Workspace를 만들고 Load into SandBox
    Dog.cpp 파일 수정 후 개인 리파지토리 작업공간들 변경 상태 파악 (Pending Changes)
    scm status

    참고: 비교
    scm diff -r ccmhost file Squawk/CoreSquawk/Dog.cpp baseline 1003(최초 생성된 베이스라인 식별번호)


    개인 리파지토리 작업공간으로 변경내용 체크인 및 변경세트 작성
    scm
    checkin Squawk(루트 폴더내 변경 사항)

    변경세트 주석 붙이기
    scm
    changeset comment 1004(변경세트 식별번호) "Dog translation 01"

    팀 스트림으로 변경 세트 전달하여 공유
    scm
    deliver -r ccmhost -s "jazzy on Squawk CMD"(From 개인 리파지토리 작업공간)
    ----------------------------------------------------------------------------
    다른 사용자가 같은 파일을 수정하고 먼저 팀스트림으로 전달한 경우



    User B : Pending Changes GUI를 사용하여 scm 작업
    User B : GUI Pending Changes를 통해 Accept
    User B : 파일 수정 후 GUI Pending Changes를 통해 SandBox 새로 고치기
    User B : GUI Pending Changes를 통해 Checkin & Comment "Dog translation 02" & Deliver

    파일을 수정하고 개인 리파지토리 작업공간에 체크인 및 변경세트 작성
    scm
    checkin Squawk(루트 폴더 이름)

    변경세트에 주석 붙이기
    scm changeset comment 1006(변경세스 식별 번호) "Dog translation 03"

    파일 수정 후 개인 리파지토리 작업공간들 변경 상태 파악 (Pending Changes)
    scm status

    User B의 변경세트를 리파지토리 작업공간으로 허용
    scm
    accept -r ccmhost

    허용 후 리파지토리 작업공간내 충돌 확인
    scm conflicts -r ccmhost

    충돌 해결 (예로만 참고, 실제는 두 파일 비교 병합 작업을 수행후 해결 필요)
    scm resolve -r ccmhost --proposed Squawk/CoreSquawk/Dog.cpp (충돌이 난 파일이름)

    충돌 해결 후 변경세트를 팀스트림으로 전달
    scm deliver -r ccmhost -s "jazzy on Squawk CMD"(From 개인 리파지토리 작업공간)

    콤포넌트 베이스라인를 개인 리파지토리 작업공간에서 만들고 팀스트림으로 전달
    scm create baseline -r ccmhost "jazzy on Squawk CMD"(개인 리파지토리 작업공간) "Dog translated"(베이스라인명) "Squawk"(콤포넌트명)
    scm deliver -r ccmhost -s "jazzy on Squawk CMD"(From 개인 리파지토리 작업공간)

    ----------------------------------------------------------------------------
    내가 같은 파일을 수정하고 먼저 팀스트림으로 전달한 경우

    내가 먼저 Cat 수정, 체크인 및 전달
    scm checkin Squawk
    scm changeset comment 1007 "Cat translation 01"
    scm deliver -r ccmhost -s "jazzy on Squawk CMD"

    User B : Cat 수정 및 체크인(Pending Changes GUI)
    User B : 수정후 Pending Changes의 SandBox refresh
    User B : Checkin "Cat translation 02"

    User B : Cat 수정 내용 허용 및 충돌 해결 (Pending Changes GUI)
    User B : Accept Incoming ChangeSet
    User B : 충돌편집기 열기 및 수정 그리고 resoved as merged
    User B : Deliver ChangeSet "Cat translation 02"

    Team Process - 프로세스 기본 흐름


     The process framework is split between the client and repository. The basic flow of control is:
    1. User starts process-enabled operation
    2. Client runs client-side advisors (potentially failing the operation)
    3. Client requests that server run the operation
    4. Server runs server-side advisors (potentially failing the operation)
    5. Operation completes on server
    6. Operation completes on client
    7. Client renders successful operation in Team Advisor view 

    Team Process - 오퍼레이션 행위 결정

    출처 : http://jazz.net/library/article/292
    Process behavior lookup in Rational Team Concert 2.0


    사용자가 프로세스 활용 오퍼레이션을 수행할 때는 만족해야 할 전제조건, 실행할 후속조치를 결정하는 데, 이를 일컬어 오퍼레이션 "동작"이라고 합니다. 동작은 사용자에게 지정된 역할, 오퍼레이션이 수행되는 프로세스 영역, 수행되는 시점에 따라 계산됩니다. 정확한 동작을 위해선 이런 여러 요소들을 정확히 조합해야 합니다. 

    프로세스 런타임에 의해 수행될 전제 조건과 후속 조치는 프로세스 XML에서 선택된 단일 "오퍼레이션" 요소로 부터 비롯됩니다. 이런 요소를 일컬어 "오퍼레이션 구성" 또는 "동작 구성" 이라 합니다.  각각의 오퍼레이션 구성은 하나의 유닛 단위로 제한하며, 여러 구성을 조합해서 전제 조건과 후속 조치를 만들지 않습니다. 팀 프로세스가 복잡해 지면, 여러 오퍼레이션 구성을 있게 됩니다. 오퍼레인션 동작은 프로젝트 영역과 각 팀 영역별로 다르게 구성할 수 있습니다. 프로젝트 영역이나 각 팀 영역 내에서도, 각 반복 유형별로 그리고 각 반복 인스턴스별로 동작을 구성할 수 있습니다. 그리고 이들 내에서, 같은 오퍼레이션는 각각의 역할별로 구성할 수 있습니다. 이런 요소들을 살펴보고 정확한 구성을 찾을 수 있습니다.

    어떻게 검색하는 지 간단히 요약하면 다음과 같습니다. 아래에서는 각각을 분해해서 알고리즘을 상세히 알려드리겠습니다. 검색은 해당 오퍼레이션을 지배하는 프로세스 영역으로 부터 출발합니다. 사용자에게 지정된 각각의 역할에 대해, 오퍼레이션에 대한 구성을 지배하는 프로세스 영역에서 먼저 찾고 차례로 거슬러서 프로젝트 영역까지 검색합니다. 하나의 영역에서 여러 반복에 대해 구성을 한 경우에는, 현재 시점에 가정 적합한 구성을 선택합니다. 사용자의 역할들 중 가장 먼저 찾은 동작 구성를 사용합니다.

    Team Process - 오퍼레이션 권한 결정

    출처 : http://jazz.net/library/article/291
    Process permissions lookup in RTC 2.0

    사용자가 프로세스 활용 오퍼레이션을 수행할 때는, 사용자가 시도하는 조치를 수행하도록 허용되는 지를 알아야 합니다. 프로세스에 친숙한 째즈 사용자는 사용자에게 지정된 역할오퍼레이션을 지배하는 프로세스 영역오퍼레이션이 수행되는 시점에 따라 허가 여부를 계산하고 있음을 알고 있습니다. 하지만 이런 요소들이 정확이 어떻게 조합되어 사용자에 대한 허가 여부를 결정하는 것일 까요?


    먼저, 허가에 대한 간단한 소개를 합니다 : 
    모든 역할은 역할에 부여된 허가만을 갖습니다. 한 곳에서 특정 역할에 부여된 해당 오퍼레이션을 수행할 수 있는 허가라 하더라도, 다른 곳에서는 해당 오퍼레이션에 대한 허가를 부여하지 않을 수 있습니다(XML로 표현하면, 해당 오퍼레이션 블록에 하위 "action" 요소를 제거함).  따라서 프로세스 런타임이 허가 여부를 체크할 때는, 기본적으로 XML 요소를 검색하여 사용자에게 허가된 목록을 알아내고, 사용자가 수행할려고 하는 조치 목록을 비교함으로 알 수 있습니다.


    프로세스 허가 검색과정은 오퍼레이션 행위 판정에 기술된 내용과 거의 똑같습니다. 일단 오퍼레이션 동작 검색 방법을 이해하게 되면, 허가 검색 과정도 거의 이해할 수 있습니다. 허가 검색과 동작 검색 간의 핵심적인 차이점은, 동작은 XML로 부터 하나의 "오퍼레이션 동작 구성"를 선택한다면, 허가는 잠재적으로 복수의 "오퍼레이션 허가 구성"을 각각의 사용자 역할에 대해 선택한다는 점입니다. 결과적으로 사용자는 각 역할에 부여된 허가를 (모두) 보유하게 됩니다.


    다음 예제 시나리오를 살펴보죠 : 
    여러분의 팀은 role 1 만이 action A를 수행할 수 있고, role 2 만이 action B를 수행할 수 있도록 구성했습니다. 만약 어떤 사용자에게 role 1과 role 2를 지정했고, action A와 action B를 수행할려고 한다면, 모두 수행할 수 있습니다. 그 까닭은 프로세스 런타임은 먼저 role 1에 대한 구성 정보(action A 수행을 허가함)을 얻고, 다음에는 role 2에 대한 구성 정보(action B 수행을 허가함)를 얻고, 두가지 action에 대해 판단을 한 다음, 해당 오퍼레이션이 수행되도록 허락을 합니다.

    Team Process - 확장 개발 가이드

    https://jazz.net/wiki/bin/view/Main/TeamProcessDeveloperGuide

    This guide is accurate for Foundation 3.0.1, Foundation 3.0, and Foundation 1.0 (RTC 2.0).



    Overview

    project area represents a development project. A project area contains a multi-rooted hierarchy of team areas. (We sometimes refer to both project areas and team areas asprocess areas.)
    A project area is associated with a team process. Part of the team process is a specification of the executable process. Teams specify their process by configuring operations, events, and data.
    A project area may have a set of timelines. Each timeline may be broken down into a set of iterations. An iteration is an interval in the lifetime of the project. An iteration can be decomposed into sub iterations. One timeline can be marked as the project timeline. This is the overall timeline for the project and all its teams. Additional timelines can be defined and root team areas can be assigned to them. When a root team area is assigned to a specific timeline, that team and all child team areas will be governed by the specified timeline instead of the project timeline. (Conceptually, this timeline + team area association can be thought of as a kind of "sub-project" on its own schedule.)
    The project area can also define a set of iteration types which can be assigned to iterations. A project's permissions and behavior can be customized for any given timeline, iteration, or iteration type.
    The process template chosen when creating a project area declares the initial set of timelines, iterations, and iteration types, along with a default executable process. The process template may also define a set of initial setup actions which are run when a newly created project area is initialized.
    An example executable process specification looks like this:
    
        
            
                
                    
                        
                        
                    
                
            
            
                
                      
                
            
        
        
            
                
                    
                        
                        
                    
                
            
            
                
                    
                        
                            
                            
                        
                    
                
            
        
    
    
    
    Each team area can override the permissions and behavior defined in the process specification by specifying a new configuration in its team customization. The actual executable process governing a team area is determined at runtime by the executable process of its project area patched by all overriding configurations. The search path for overriding configurations starts at the team area and goes up the team area hierarchy to the root. From the root it goes to the project area. Configurations can only be overridden if they are not marked as final in any node closer to the end of the search path.
    (A detailed explanation of the runtime's search path can be found in the Process Behavior Lookup article.)
    The specification of an overriding configuration in the team customization looks similar to the process specification with the difference that it only talks about the iterations and roles whose configurations it wants to override.
    
        
            
        
        
            
                
                
            
            
                
                    
                    
                
            
        
    
    

    Components and Process

    Components usually interact with the Team Process component in two ways:
    • a component allows the team process to impact its behavior
    • a component extends the set of choices that are available when configuring behavior
    Components that allow the team process to impact their behavior can do so along three different lines corresponding to the three different kinds of configuration points:
    • Operations when a component wants to allow teams to configure permissions or when the components wants to allow preparation steps such as precondition checking or automated followup actions. These additional contributions to the operation are called advisors and participants. Advisors are run in advance and determine whether or not an operation should be executed. Participants are run after an operation is executed and generally cause additional modifications to the repository related to the operation. (Note: In the user interface, advisors are called "preconditions" and participants are called "follow-up actions".)
    • Configuration data when the component wants to allow the team process to provide XML data. The format of the configuration data is defined by the component. The component can access the data at any point in time and can do whatever it wants with it.
    • Events when a component issues change events for which it wants to allow the process to define server side event handlers.
    Components that want to extend the set of available behaviors may add new participants, advisors and event handlers.

    Open up for Process Interaction

    In order to open up for process interaction the following plug-ins are required:
    • On the server
      • com.ibm.team.process.common
      • com.ibm.team.process.service
    • On the client
      • com.ibm.team.process.common
      • com.ibm.team.process.client

    Operations

    A component can open up for process participation in operations on the server and on the client. Process can "advise and execute" operations or it can merely "advise" them. Simply advising an operation is intended to answer the question for the user "What would happen if I did this now?"

    Process Execution of Operations

    When process is asked to advise and execute an operation, it will first run all advisors which are configured for the operation. Conceptually, advisors decide whether or not an operation should proceed. Advisors report any problems in the form of errors. If no advisors report any errors, the process runtime will invoke the operation. After the operation completes, participants are invoked. If a participant fails for some reason, either throwing an uncaught exception or reporting an error, no further participants are executed. This is the same for both the client and server process.
    There is an important difference between the client and server process, though. The server process runs the entire request to advise and execute an operation in a single transaction. All advisors, the operation, and all participants are run in this transaction and if any errors are detected or any exceptions thrown, the entire transaction is rolled back. But if a participant fails on the client, the operation and any participants which have already run will have already done their work. For this reason, we say that client-side participants (and advisors) may not cause modifications to the repository.

    Process Advising of Operations

    When process is asked to only advise an operation, it will first run all advisors which are configured for the operation. The advisors will produce their errors and then process will call the advise(...) method on the operation. AdvisableOperation#advise(...) is a method which subclasses may optionally implement if the operation has some code that it wants to perform to participate in the advising.
    For example, a client-side operation may support performing server-side checks. The client-side operation would implement advise(...) to call a service method. The service implementation would then ask the server-side process to advise an operation and it would return the result to the client. The client's implementation of advise(...) would then return this result. A concrete example of this scenario can be seen in the implementation of IExampleClientService#save(IExampleItem, boolean)

    Defining Operations on the Server

    • The component defines an operation configuration point:
       
          
       
    
    • Please see ProcessExtensionSchemas to learn about how to define a schema.
    • The component wraps its operation implementation into an AdvisableOperation and passes it to the server-side team process for a certain team or project area. Usually, the operation affects an item that is associated with an area. However, the component decides which area to use.
    • A process enabled server operation should include the operation report generated for the advisable operation into its response to the caller. This can be done by either extending the component specific server response to piggyback the operation report or by defining the service method to return a response of one of the operation response types provided by the process component.
    The implementation of a server-side operation might look something like this:
       public class MySaveOperation extends AdvisableOperation {
          private MyItem itemToSave;
          private MyItem saved;
          private IRepositoryItemService itemService;
          public MySaveOperation(MyItem itemToSave, IProcessArea processArea, IRepositoryItemService itemService) {
             super("com.ibm.example.service.mySaveOperation", itemToSave, processArea);
             this.itemToSave = itemToSave;
             this.itemService = itemService;
          }
          public IOperationReport run(IBehaviorConfiguration configuration, IProgressMonitor monitor) throws TeamRepositoryException {
             saved = (MyItem) service.saveItem(item, monitor);
             return null; // No nested report to return.
          }
          public MyItem getSavedItem() {
             return saved;
          }
       }
    
    The component's service implementation would then invoke this operation:
       public IItemsResponse saveItem(MyItem itemToSave) throws TeamRepositoryException {
          IProcessArea processArea = findProcessArea(itemToSave); // custom component logic
          IRepositoryItemService itemService = getService(IRepositoryItemService.class);
          IProcessServerService processService = getService(IProcessServerService.class);
          IServerProcess serverProcess = processService.getServerProcess(processArea);
    
          MySaveOperation operation = new MySaveOperation(itemToSave, processArea, itemService);
          IOperationReport report = serverProcess.adviseAndExecute(operation);
    
          IItemsResponse response = ProcessCommon.createItemsResponse();  
          response.setOperationReport(report);
          MyItem saved = operation.getSavedItem();
          response.setClientItems(new IExampleItem[] { saved };
    
          return response;
       }
    
    Grouping Operations on the Server (Process Runnables)
    This section is not something most components are expected to utilize.
    A ProcessRunnable is most commonly defined on the client to support implementing a server-side only operation. However, they can also be a useful tool for the purpose of grouping multiple server-side operations so that they will be run in a single transaction and grouped together when they are presented to the user.
    A service method can run any number of process-enabled operations inside the context of a process runnable and it need only return the single report generated for the runnable in order to transfer all of the nested reports to the client as well. This works because the process framework automatically appends reports together when they are called in the same thread.
    For example, the Process component defines a process runnable on the server when saving multiple team areas. Each team area is potentially saved according to a different process so they must be saved in separate operations. But by using a process runnable, all of these operations are grouped together at runtime (in a single transaction) and in the client UI (Team Advisor view).
    The implementation of a server-side process runnable might look something like this:
       public class MyItemsSaveRunnable extends ProcessRunnable {
          private MyItem[] itemsToSave;
          private MyItem[] saved;
          private MyService service;
    
          public MyItemsSaveRunnable(MyItem[] itemsToSave, MyService service) {
             this.itemsToSave = itemsToSave;
             this.service = service;
          }
          public IOperationReport run(IProgressMonitor monitor) {
             saved = new MyItem[itemsToSave.length];
             for (int i = 0; i < itemsToSave.length; i++) {
                // Invoke component logic which saves an item using an operation
                saved[i] = service.internalSaveItem(item);
             }
             return null; // server-side runnables don't return anything
          }
          public MyItem[] getSavedItems() {
             return saved;
          }
       }
    
    The component service would then execute this runnable:
       public IItemsResponse saveItems(final MyItem[] items) throws TeamRepositoryException {
          IProcessServerService processService = getService(IProcessServerService.class);
          MyItemsSaveRunnable runnable = new MyItemsSaveRunnable(items, this);
          IOperationReport report = processService.execute(runnable, "Save My Items");
          MyItem[] saved = runnable.getSavedItems();
    
          IItemsResponse response = ProcessCommon.createItemsResponse();
          response.setOperationReport(report);
          reponse.setClientItems(saved);
          return response;
       }
    

    Defining Operations on the Client

    • The component defines an operation configuration point:
       
          
       
    
    • Please see ProcessExtensionSchemas to learn about how to define a schema.
    • The component wraps its operation into an AdvisableOperation and passes it to the client-side team process for a certain team or project area. Usually, the operation affects an item that is associated with an area. However, the component decides which area to use.
    • When the operation involves the call of a process-enabled server-side service method, your implementation of the advisable operation's run method should return the server side generated operation report.
    • The server-side team process will throw a TeamOperationCanceledException in the event that the operation is canceled by process. This exception is currently a subclass ofTeamRepositoryException which carries an IOperationReport. If an AdvisableOperation calls a service method in run() and catches TeamRepositoryException (this is generally not recommended), the implementation should rethrow the exception if it is a TeamOperationCanceledException.
    The implementation of a client-side operation might look something like this:
       public class MySaveOperation extends AdvisableOperation {
          private MyItem itemToSave;
          private MyItem saved;
          private MyService service;
          public MySaveOperation(MyItem itemToSave, IProcessArea processArea, MyService service) {
             super("com.ibm.example.client.mySaveOperation", itemToSave, processArea);
             this.itemToSave = itemToSave;
             this.service = service;
          }
          public IOperationReport run(IBehaviorConfigurationconfiguration, IProgressMonitor monitor) throws TeamRepositoryException {
             IItemsResponse serviceResponse = service.saveItem(itemToSave, monitor); // invoke the service method
             saved = (MyItem) response.getFirstClientItem;
             return response.getOperationReport(); // Return the nested server-side report.
          }
          public MyItem getSavedItem() {
             return saved;
          }
       }
    
    The component's client library would then invoke this operation:
       public MyItem saveItem(MyItem itemToSave, IProgressMonitor monitor) throws TeamRepositoryException {
          IProcessArea processArea = findProcessArea(itemToSave); // custom component logic
          MyService myService = (MyService) clientLibraryContext.getServiceInterface(IProcessService.class);
          IProcessClientService processService = repository.getClientLibrary(IProcessClientService.class);
          IClientProcess clientProcess = processService.getClientProcess(processArea, monitor);
    
          MySaveOperation operation = MySaveOperation(itemToSave, processArea, myService);
          clientProcess.adviseAndExecute(operation);
          return operation.getSavedItem();
       }
    
    Server-side Only Operations (Process Runnables)
    If a component wishes to define a process-enabled operation on the server which in not invoked by a corresponding process-enabled operation on the client, a ProcessRunnable can be defined on the client which returns the server-side report to the process framework. By using a process runnable which returns the server-side report, a server-side only operation can be displayed to the end user by the process framework.
    Process runnables are simply instantiated at runtime and passed to the process framework. They are not declared via an extension point, so they don't show up in the process specification. Process runnables do not allow for advisors, participants, or permission checking; they are just executed by the framework.
    The implementation of a client-side process runnable might look something like:
       public class MyItemSaveRunnable extends ProcessRunnable {
          private MyItem itemToSave;
          private MyItem saved;
          private MyService service;
    
          public MyItemSaveRunnable(MyItem itemToSave, MyService service) {
             this.itemToSave = itemToSave;
             this.service = service;
          }
          public IOperationReport run(IProgressMonitor monitor) throws TeamRepositoryException {
             IItemsResponse response = service.saveItem(item, monitor);
             saved = (MyItem) response.getFirstClientItem();
             // Return the operation report from the server to the process framework.
             return response.getOperationReport();
          }
          public MyItem getSavedItem() {
             return savedItem;
          }
       }
    
    The component's client library would then execute this process runnable:
       public MyItem saveItem(MyItem item, IProgressMonitor monitor) throws TeamRepositoryException {
          MyService service = clientLibraryContext.getServiceInterface(MyService.class);
          IProcessClientService processClient = (IProcessClientService) clientLibraryContext.getTeamRepository().getClientLibrary(IProcessClientService.class);
    
          MyItemSaveRunnable runnable = new MyItemSaveRunnable(item, service);
          processClient.execute(runnable, monitor);
          return runnable.getSavedItem();
       }
    

    Operation Actions (Process Permissions)

    Operations can declare a set of actions which they may perform. A team can then configure their process to selectively grant permission to perform those actions. At runtime, an operation can report which actions it will perform and process can allow/disallow the operation based on the applicable permissions.
    An operation's available actions are declared in the client or server extension. For example:
       
          
             
                
                
             
          
       
    
    The team would then configure the permitted actions:
       [...]
       
          
             
                 
                   
                 
             
          
       
       [...]
    
    Here, the process uses the special keyword "any" to specify that all "Modify" actions are allowed.
    An operation can report any path in its declared actions at runtime. In this example, the "Save Example Item" operation could return the following values as actions:
      "Modify"
      "Modify/Description"
      "Modify/Name"
    
    When process is asked to execute an operation, it asks it for the actions it will perform. These actions are then compared against the permissions which apply to the current logged in user. As long as the permitted action paths match the actions to be performed, process will execute the operation. Otherwise, the operation will be blocked and reported in the Team Advisor view.
    Secondary Actions (Multi-Area Operations)
    We say that an advisable operation is run relative to a process area and it can return a set of actions for the purpose of checking permissions. However, sometimes an operation needs to check permissions relative to more than just one process area and this is supported by allowing to specify "secondary" areas and actions.
    This is important, for example, for an operation which moves an item from the context of one team area to another. In order to enforce a notion of ownership which is enforced by process permissions, such an operation would specify the source area as a secondary process area and return an appropriate action for this area, such as "remove".
    Secondary areas are consulted only for permissions. Advisors and participants configured for secondary areas are not invoked.
    An operation which moved an item from one team area to another and enforced permissions relative to both areas might look something like:
       public class MyItemMoveOperation extends AdvisableOperation {
          IProcessArea sourceArea;
          
          public MyItemMoveOperation(MyItem itemToMove, IProcessArea targetArea, IProcessArea sourceArea) {
             // Use targetArea as the operation's primary area
             super("com.example.moveItem", itemToMove, targetArea);
             this.sourceArea = sourceArea;
          }
          public IOperationReport run(...) {
              [...]
          }
          public String[] getActions() {
             // Return actions for the operation's process area (targetArea)
             return new String[] { "add" };
          }
          public IProcessArea[] getSecondaryAreas() {
             return new IProcessArea[] { sourceArea };
          }
          public String[] getActions(IProcessArea secondaryArea) {
             if (secondaryArea.sameItemId(sourceArea)) {
                return new String[] { "remove" };
             }
             return super.getActions(secondaryArea);
          }
       }
    

    Process Data Validation (Configuration Source)

    For operations which run on the client and server, the process framework provides a mechanism to validate that clients are running up-to-date process.
    When a client-side operation is run, we pass in the IBehaviorConfiguration which configures the operation. This object carries an "operation configuration info" object which contains information about exactly which process configuration was used (see IBehaviorConfiguration#getOperationConfigurationInfo()). The client-side operation can pass this IOperationConfigurationInfo over the wire in its service method.
    On the server, we have API which takes one of these configuration info objects and validates that the configuration which was run on the client in sync with the current repository contents (IServerProcess#validateSource(IOperationConfigurationInfo)). If validation fails, an exception is thrown.
    Back on the client, process catches this exception from the client-side operation, updates the client's process data, and re-runs the operation (if the operation supports this). Tying into this mechanism provides a seamless experience for the end user.

    Configuration Data

    A component can open up for configuration data on the server and on the client. Configuration data, independent of where it has been declared, can always be accessed on both the client and the server without limitation. Configuration data can only be defined in the project area and is global in nature. Configuration data should be used sparingly, only in situations where the data in question is really part of a project's process. In particular, components are warned against using configuration data for settings which should really be user preferences or which should be persisted as part of their component model and configured in their own editors.

    Configuration Data on the Server

    • The component defines a configuration data configuration-point (the element name "staticConfigurationData" is a holdover which will be changed to "configurationData" eventually):
       
          
       
    
    • Please see ProcessExtensionSchemas to learn about how to define a schema.
    • The component retrieves the configuration data from the server-side team process for the project area.
       IProcessArea processArea = findProcessArea(parameter);
       IProcessServerService service = (IProcessServerService) getService(IProcessServerService.class);
       IServerProcess serverProcess = service.getServerProcess(processArea);
       IProcessConfigurationData data = serverProcess.getProjectConfigurationData("com.ibm.team.process.example.elementPreferences");
       if (data != null) {
          IProcessConfigurationElement[] elements = data.getElements();
          for (int i = 0; i < elements.length; i++) {
             IProcessConfigurationElement element = elements[i];
             ...
          }
       }
    

    Configuration Data on the Client

    • The component defines a static configuration data configuration-point:
       
          
       
    
    • Please see ProcessExtensionSchemas to learn about how to define a schema.
    • The component retrieves the configuration data from the client-side team process for the project area.
       IProcessArea processArea = findProcessArea(parameter);
       IProcessClientService processService = (IProcessClientService) repository.getClientLibrary(IProcessClientService.class);
       IClientProcess clientProcess = processService.getClientProcess(processArea, new SubProgressMontior(monitor, 1));
       IProcessConfiguration data = clientProcess.getProjectConfigurationData("com.ibm.team.process.example.itemTypes", new SubProgressMontior(monitor, 1));
       if (data != null) {
          IProcessConfigurationElement[] elements = data.getElements();
          for (int i = 0; i < elements.length; i++) {
             IProcessConfigurationElement element = elements[i];
             ...
          }
       }
    

    Events

    In order for a component's server part to allow process reaction to its change events, the component must define an event configuration point. The event's identifier corresponds to the value of IChangeEvent#getCategory()
    The process server-side component installs a scheduling task on the server which queries for new change events at a regular interval and dispatches them to the event handlers which have been configured by the team.

    Associate Items with a Process Area

    All of the scenarios above have forced the component to retrieve a client or server-side process relative to a process area. Usually, the process area is determined based on the items affected by a particular operation and those items' association to a team area.
    A component defines the way in which its items are associated with a process area. The typical way to do this is by adding a field to the item which references a process area.

    Extending the Choices of Process

    In order to extend the choices of process the following plug-ins are required:
    • On the client
      • com.ibm.team.process.common
      • com.ibm.team.process.client
      • com.ibm.team.process.ide.ui
    • On the server
      • com.ibm.team.process.commmon
      • com.ibm.team.process.service

    Adding New Operation Advisors

    Operation advisors are run before an operation is invoked to decide whether or not the operation should be executed. Advisors check conditions and report problems via the collector they are given at runtime. If an advisor reports a serious problem with an operation, the operation will not be executed (though subsequent advisors will still be checked).
    Advisors may not make modifications to data which is persisted in the repository. If an advisor were to modify the data in the repository, its changes could invalidate the checks made by previous advisors which would potentially cause a team's desired preconditions to not be correctly enforced. Clients wishing to participate in operations by modifying data should implement a participant instead.
    Client-side advisors support the notion of being optionally overrulable. If a team specifies that users can overrule an advisor, users have the freedom to ignore a particular advisor if they wish it. The support for overruling advisors is handled completely by the process framework. Advisor implementors do not need to do anything to support it. Note that at this time, onlyclient-side advisors support overruling.
    Operation advisors can be provided for the client and the server side via the com.ibm.team.process.client.operationAdvisors and com.ibm.team.process.service.operationAdvisors extension points, respectively.
    In order to provide a new advisor available in process definitions and process settings a component must:
    • Implement a new advisor by implementing com.ibm.team.process.common.advice.runtime.IOperationAdvisor.
    • Provide an extension to the operation advisor extension point to declare the new advisor
    • Optionally, a component may provide a schema which describes custom syntax for configuring the advisor. See ProcessExtensionSchemas for details.
    
      
        
          This advisor requires that everything is great before something can be modified.
        
      
    
    
    If a server-side advisor does not make reference to any services, providing an implementation of this interface via an extension declaration like the example above is sufficient. However, there are two additional requirements for server-side implementors who wish to access services:
    • The implementation of this interface must also extend com.ibm.team.repository.service.AbstractService.
    • The extension declaration of such an advisor must include an extensionService element which declares all of the services which the advisor requires.
    The following example shows a definition of a server-side advisor which requires the repository item service and the process server service:
    
      
        
          This advisor requires that everything is great before something can be modified.
        
        
          
            
            
          
        
      
    
    

    Adding New Operation Participants

    Operation participants run after an operation is invoked and may make modifications to the repository. In an operation fails (for example, because it is blocked by an advisor or if an exception occurs), its participants will not be invoked. On the server, participants are run in the same transaction as the operation in which they are participating.
    If an participant throws an exception or reports a serious problem, subsequent participants will not be run. On the server, this will cause the entire operation transaction to be rolled back.
    Operation participants can be provided for the client and the server side via the com.ibm.team.process.client.operationParticipants and com.ibm.team.process.service.operationParticipants extension points, respectively.
    In order to provide a new participant which teams can configure for an operation a component must:
    • Implement a new participant by implementing com.ibm.team.process.common.advice.runtime.IOperationParticipant.
    • Provide an extension to the operation participant extension point to declare the new participant
    • Optionally, a component may provide a schema which describes custom syntax for configuring the participant. See ProcessExtensionSchemas for details.
    
      
        
          This participant creates a receipt whenever something is modified.
        
      
    
    
    If a server-side participant does not make reference to any services, providing an implementation of this interface via an extension declaration like the example above is sufficient. However, there are two additional requirements for server-side implementors who wish to access services:
    • The implementation of this interface must also extend com.ibm.team.repository.service.AbstractService.
    • The extension declaration of such a participant must include an extensionService element which declares all of the services which the participant requires.
    The following example shows a definition of a server-side participant which requires the repository item service and the process server service:
    
      
        
          This participant creates a receipt whenever something is modified.
        
        
          
            
            
          
        
      
    
    

    Adding New Event Handlers

    Event handlers can only be provided for the server side. In order to provide a new event handler which teams can configure for an event a component must:
    • Implement a new event handler by implementing the interface com.ibm.team.process.service.IChangeEventHandler.
    • Declare an extension to the event handler extension point to provide the new event handler.
    • Optionally, a component may provide a schema which describes custom syntax for configuring the handle. See ProcessExtensionSchemas for details.
       
          
       
    

    Hooking in to Content Assist in the Process Editors

    In addition to defining schema to describe the format of component specific data associated with a process related configuration point, component authors can register to provide completion proposals for attribute values when content assist is requested in the process editors.
    For example, if your schema defines a new element "foo" with an attribute "type" and you want to provide the user with a list of valid values for the "type" attribute when content assist is requested, this mechanism will allow you to do that.
    In order contribute your proposals, in one of your component's client-side plugins, you need to provide an extension to the com.ibm.team.process.ide.ui.attributeValueProposalProvidersextension point. Via this extension, you will indicate which source types (specifications and/or customization) you support and the attributes for which you intend to provide values. In addition, you must specify a class which implements com.ibm.team.process.ide.ui.IAttributeValueProposalProvider. This is the class which will be called to obtain the completion proposals. Please see the extension point description for additional details.
    The following is an example extension which provides attribute value proposals for an attribute named "fooType" which appears on elements named "foo" in the "http://com.ibm.team.process.ide.ui.tests" namespace. Proposals are provide for both specification and customization source types:
        
           
              
              
              
              
              
                 
                    
                    
                 
              
           
        
    
    The following is the code for the TestAttributeValueProvider class referenced by the extension.
    public class TestAttributeValueProvider implements IAttributeValueProposalProvider {
    
       public TestAttributeValueProvider() {
       }
    
       public IProcessCompletionProposal[] computeProposals(IProcessArea processArea, IProcessProposalContext context, IProgressMonitor monitor) {
          
          ArrayList proposals = new ArrayList();
          
          switch (context.getSourceType()) {
             case IProcessProposalContext.SPECIFICATION_SOURCE_TYPE:
                if (processArea instanceof IProjectArea) {
                   IProjectArea projectArea = (IProjectArea) processArea;
                   List teamAreas = projectArea.getTeamAreas();
                   
                   ITeamRepository repo = (ITeamRepository) projectArea.getOrigin();
                   IItemManager itemManager = repo.itemManager();
                   try {
                      List items = itemManager.fetchCompleteItems(teamAreas, IItemManager.DEFAULT, monitor);
                      for (Iterator iterator = items.iterator(); iterator.hasNext();) {
                         ITeamArea teamArea = (ITeamArea) iterator.next();
                         if (teamArea != null) {
                            proposals.add(ProcessCompletionProposalFactory.createProposal(context, teamArea.getName()));
                         }
                         
                      }
                   } catch (TeamRepositoryException e) {
                      // just ignore for this test / example provider...
                   }
                } else {
                   proposals.add(ProcessCompletionProposalFactory.createProposal(context, "A1"));
                   proposals.add(ProcessCompletionProposalFactory.createProposal(context, "B1"));
                   proposals.add(ProcessCompletionProposalFactory.createProposal(context, "C1"));
                }
                break;
             case IProcessProposalContext.CUSTOMIZATION_SOURCE_TYPE:
                proposals.add(ProcessCompletionProposalFactory.createProposal(context, "A2"));
                proposals.add(ProcessCompletionProposalFactory.createProposal(context, "B2"));
                proposals.add(ProcessCompletionProposalFactory.createProposal(context, "C2"));
                break;
          }
          
          return (IProcessCompletionProposal[]) proposals.toArray(new IProcessCompletionProposal[proposals.size()]);
       }
    }
    
    This particular provider provides a static list of proposals "A2", "B2", "C2" when invoked for the customization source type (e.g. when content assist is used in the Team Area editors 'customization' tab). When it is called for a specification source type and the process area provided is a project area (e.g. when content assist is used in the Project Area editor 'specification' tab) the proposals are the names of the team areas for the project area. When the provided process area is not a project area (i.e. content assist was invoked in the specification tab of a template editor), the proposals provided are "A1", "B1", "C1".
    While this provider only provides for a single attribute, through the use of the namespace, element, and attribute configuration elements, a single provider can indicate its ability to provide for multiple attributes spanning multiple elements and/or namespaces.

    Gotchas

    The following are specific situations that we have discovered can be confusing for people who haven't yet totally absorbed the Team Process mindset.
    • Operations may involve other operations and the two may involve different processes. For example:
      • SCM stream HEAD is associated with team area Foo
      • Workitem category UI is associated with team area Bar
      • Deliver code to HEAD
        • For the deliver operation, the advisors and participants configured in team area Foo will be run
        • One of the deliver participants modifies a workitem whose category is UI
          • For the workitem save operation, the advisors and participants configured in team area Bar will be run