Programmatically create users (application server)
I am trying to programmatically create new application server users in RTC. Currently, a user can log into the url https://localhost:9443/jazz and Click User Management and add users by hand. I need to create hundreds of users which is cumbersome. I am playing with the RTC server to see if I can programmatically create new users.
As a start, any http server accepts either GET or POST messages. It is possible to use java.net technique, to open a connection (URLConnection) with the http server and manipulate the server to serve the request. I have had success with many commercial websites.
In context of RTC E,g. When I create a user by hand a url like this is autogenerated in the JavaScript and POST message is sent, so the server can process the request.
https://9.34.120.71:9443/jazz/service/com.ibm.team.repository.service.internal.IAdminRestService/contributor?emailAddress=st3&itemId=new&jsonLicenses=%7B%22add%22%3A%20%5B%22com.ibm.team.rtc.developer%22%5D%2C%20%22remove%22%3A%20%5B%5D%7D&jsonRoles=%5B%22JazzAdmins%22%2C%20%22JazzUsers%22%5D&name=st3&userId=st3
I wrote a plain java client to handle this via SSL (IBM JSSE Provider com.ibm.jsse) since now https:// is being provided with RTC. I created a client keystore file from the server keystore file and imported server keys/certificates. I am not getting any errors, but neither am I seeing any results. Nothing particular in the tomcat logs. I can post the code on request. I was looking if this is the way to go. Any alternative ideas..? Thanks for your time.
As a start, any http server accepts either GET or POST messages. It is possible to use java.net technique, to open a connection (URLConnection) with the http server and manipulate the server to serve the request. I have had success with many commercial websites.
In context of RTC E,g. When I create a user by hand a url like this is autogenerated in the JavaScript and POST message is sent, so the server can process the request.
https://9.34.120.71:9443/jazz/service/com.ibm.team.repository.service.internal.IAdminRestService/contributor?emailAddress=st3&itemId=new&jsonLicenses=%7B%22add%22%3A%20%5B%22com.ibm.team.rtc.developer%22%5D%2C%20%22remove%22%3A%20%5B%5D%7D&jsonRoles=%5B%22JazzAdmins%22%2C%20%22JazzUsers%22%5D&name=st3&userId=st3
I wrote a plain java client to handle this via SSL (IBM JSSE Provider com.ibm.jsse) since now https:// is being provided with RTC. I created a client keystore file from the server keystore file and imported server keys/certificates. I am not getting any errors, but neither am I seeing any results. Nothing particular in the tomcat logs. I can post the code on request. I was looking if this is the way to go. Any alternative ideas..? Thanks for your time.
23 answers
RTC suggests the use of repotools rather than Java API:
"We do a provide the ability to import users through the -createUsers command in repotools. The link to the documentation for that command is http://publib.boulder.ibm.com/infocenter/clmhelp/v3r0/topic/com.ibm.jazz.install.doc/topics/r_repotools_createusers.html"
"We do a provide the ability to import users through the -createUsers command in repotools. The link to the documentation for that command is http://publib.boulder.ibm.com/infocenter/clmhelp/v3r0/topic/com.ibm.jazz.install.doc/topics/r_repotools_createusers.html"
warade wrote:
Another attempt.
TeamRepository repo = (TeamRepository)repository;
ITeamRestServiceClient restClient = repo.getRepositoryRestService();
Location loc =
Location.serviceLocation(repo.getRepositoryURI(),com.ibm.team.repository.service.internal.ILicenseAdminRestService.class,"assignLicense","userId=test10&licenseId=com.ibm.team.rtc.developer");
final IRestClientConnection connection =
restClient.getConnection(loc);
connection.addRequestHeader(HttpUtil.ACCEPT,
MediaType.TEXT.toString());
connection.addRequestHeader(HttpUtil.ACCEPT_CHARSET,
CharsetEncoding.UTF8.toString());
repo.getRepositoryRestService() returns the RepositoryRestService, a
very specific REST service that you're binding your location to. The
javadoc for ITeamRestServiceClient.getConnection(...) says this:
/**
* Returns a server communications connection for the location
specified
* by <code>loc</code>. Note that regardless of what server or service
* is specified in <code>loc</code>, the server that this service
client is bound to
* is the server and service that this client connection is bound to.
*
A particular service binding trumps the location's service binding. The
way to do what you're doing is something like this...
licenseRestService =
(ITeamRestServiceClient)repo.getServiceInterface(ILicenseAdminService.class);
....which may not be accessible to you, scope-wise.
However, let me suggest that you're probably on a bad path - depending
upon how the ILicenseAdminService is declared as a service, this still
may not bind correctly at run-time.
Dan Kogan's suggestion of using a tool like "curl", or even a JUnit that
uses java.net.HttpUrlConnection might be a better way to go. Because
your server is using SSL (and probably form-based auth), you'll need
some help dealing with authentication and certificates. Take a look at
the FormBasedAuth class in repository.client, and if you have the tests
source, the FeedServiceTests (readFeed()) which uses this mechanism.
--
Todd Lainhart
Jazz Repository/Foundation Team
In the tests source bundle FeedServiceTests.class is available in team_core_client_tests.jar can't find .java file.
Sorry found .java file. Too quick to post message :)
warade wrote:
Another attempt.
TeamRepository repo = (TeamRepository)repository;
ITeamRestServiceClient restClient = repo.getRepositoryRestService();
Location loc =
Location.serviceLocation(repo.getRepositoryURI(),com.ibm.team.repository.service.internal.ILicenseAdminRestService.class,"assignLicense","userId=test10&licenseId=com.ibm.team.rtc.developer");
final IRestClientConnection connection =
restClient.getConnection(loc);
connection.addRequestHeader(HttpUtil.ACCEPT,
MediaType.TEXT.toString());
connection.addRequestHeader(HttpUtil.ACCEPT_CHARSET,
CharsetEncoding.UTF8.toString());
repo.getRepositoryRestService() returns the RepositoryRestService, a
very specific REST service that you're binding your location to. The
javadoc for ITeamRestServiceClient.getConnection(...) says this:
/**
* Returns a server communications connection for the location
specified
* by <code>loc</code>. Note that regardless of what server or service
* is specified in <code>loc</code>, the server that this service
client is bound to
* is the server and service that this client connection is bound to.
*
A particular service binding trumps the location's service binding. The
way to do what you're doing is something like this...
licenseRestService =
(ITeamRestServiceClient)repo.getServiceInterface(ILicenseAdminService.class);
....which may not be accessible to you, scope-wise.
However, let me suggest that you're probably on a bad path - depending
upon how the ILicenseAdminService is declared as a service, this still
may not bind correctly at run-time.
Dan Kogan's suggestion of using a tool like "curl", or even a JUnit that
uses java.net.HttpUrlConnection might be a better way to go. Because
your server is using SSL (and probably form-based auth), you'll need
some help dealing with authentication and certificates. Take a look at
the FormBasedAuth class in repository.client, and if you have the tests
source, the FeedServiceTests (readFeed()) which uses this mechanism.
--
Todd Lainhart
Jazz Repository/Foundation Team
In the tests source bundle FeedServiceTests.class is available in team_core_client_tests.jar can't find .java file.
warade wrote:
repo.getRepositoryRestService() returns the RepositoryRestService, a
very specific REST service that you're binding your location to. The
javadoc for ITeamRestServiceClient.getConnection(...) says this:
/**
* Returns a server communications connection for the location
specified
* by <code>loc</code>. Note that regardless of what server or service
* is specified in <code>loc</code>, the server that this service
client is bound to
* is the server and service that this client connection is bound to.
*
A particular service binding trumps the location's service binding. The
way to do what you're doing is something like this...
licenseRestService =
(ITeamRestServiceClient)repo.getServiceInterface(ILicenseAdminService.class);
....which may not be accessible to you, scope-wise.
However, let me suggest that you're probably on a bad path - depending
upon how the ILicenseAdminService is declared as a service, this still
may not bind correctly at run-time.
Dan Kogan's suggestion of using a tool like "curl", or even a JUnit that
uses java.net.HttpUrlConnection might be a better way to go. Because
your server is using SSL (and probably form-based auth), you'll need
some help dealing with authentication and certificates. Take a look at
the FormBasedAuth class in repository.client, and if you have the tests
source, the FeedServiceTests (readFeed()) which uses this mechanism.
--
Todd Lainhart
Jazz Repository/Foundation Team
Another attempt.
TeamRepository repo = (TeamRepository)repository;
ITeamRestServiceClient restClient = repo.getRepositoryRestService();
Location loc =
Location.serviceLocation(repo.getRepositoryURI(),com.ibm.team.repository.service.internal.ILicenseAdminRestService.class,"assignLicense","userId=test10&licenseId=com.ibm.team.rtc.developer");
final IRestClientConnection connection =
restClient.getConnection(loc);
connection.addRequestHeader(HttpUtil.ACCEPT,
MediaType.TEXT.toString());
connection.addRequestHeader(HttpUtil.ACCEPT_CHARSET,
CharsetEncoding.UTF8.toString());
repo.getRepositoryRestService() returns the RepositoryRestService, a
very specific REST service that you're binding your location to. The
javadoc for ITeamRestServiceClient.getConnection(...) says this:
/**
* Returns a server communications connection for the location
specified
* by <code>loc</code>. Note that regardless of what server or service
* is specified in <code>loc</code>, the server that this service
client is bound to
* is the server and service that this client connection is bound to.
*
A particular service binding trumps the location's service binding. The
way to do what you're doing is something like this...
licenseRestService =
(ITeamRestServiceClient)repo.getServiceInterface(ILicenseAdminService.class);
....which may not be accessible to you, scope-wise.
However, let me suggest that you're probably on a bad path - depending
upon how the ILicenseAdminService is declared as a service, this still
may not bind correctly at run-time.
Dan Kogan's suggestion of using a tool like "curl", or even a JUnit that
uses java.net.HttpUrlConnection might be a better way to go. Because
your server is using SSL (and probably form-based auth), you'll need
some help dealing with authentication and certificates. Take a look at
the FormBasedAuth class in repository.client, and if you have the tests
source, the FeedServiceTests (readFeed()) which uses this mechanism.
--
Todd Lainhart
Jazz Repository/Foundation Team
Another attempt.
TeamRepository repo = (TeamRepository)repository;
ITeamRestServiceClient restClient = repo.getRepositoryRestService();
Location loc = Location.serviceLocation(repo.getRepositoryURI(),com.ibm.team.repository.service.internal.ILicenseAdminRestService.class,"assignLicense","userId=test10&licenseId=com.ibm.team.rtc.developer");
final IRestClientConnection connection = restClient.getConnection(loc);
connection.addRequestHeader(HttpUtil.ACCEPT, MediaType.TEXT.toString());
connection.addRequestHeader(HttpUtil.ACCEPT_CHARSET, CharsetEncoding.UTF8.toString());
............
response = connection.doPost(bais, licbytes.length, "text/json;charset=UTF-8");
..........
CRJAZ0054I Error retrieving the resource identified by "com.ibm.team.repository.service.internal.ILicenseAdminRestService": CRJAZ0103I The request for URL "/jazz/service/com.ibm.team.repository.common.internal.IRepositoryRestService/assignLicense?userId=test10&licenseId=com.ibm.team.rtc.developer" was denied with a Not Implemented status.
I debugged and step through, to find that for some reason the class loader is unable to find the class ILicenseAdminRestService even though the jar is in the workspace and also in the path. What is forcing the Location.serviceLocation to think that the service requested is IRepositoryRestService and not ILicenseAdminRestService.
Any other ideas..
TeamRepository repo = (TeamRepository)repository;
ITeamRestServiceClient restClient = repo.getRepositoryRestService();
Location loc = Location.serviceLocation(repo.getRepositoryURI(),com.ibm.team.repository.service.internal.ILicenseAdminRestService.class,"assignLicense","userId=test10&licenseId=com.ibm.team.rtc.developer");
final IRestClientConnection connection = restClient.getConnection(loc);
connection.addRequestHeader(HttpUtil.ACCEPT, MediaType.TEXT.toString());
connection.addRequestHeader(HttpUtil.ACCEPT_CHARSET, CharsetEncoding.UTF8.toString());
............
response = connection.doPost(bais, licbytes.length, "text/json;charset=UTF-8");
..........
CRJAZ0054I Error retrieving the resource identified by "com.ibm.team.repository.service.internal.ILicenseAdminRestService": CRJAZ0103I The request for URL "/jazz/service/com.ibm.team.repository.common.internal.IRepositoryRestService/assignLicense?userId=test10&licenseId=com.ibm.team.rtc.developer" was denied with a Not Implemented status.
I debugged and step through, to find that for some reason the class loader is unable to find the class ILicenseAdminRestService even though the jar is in the workspace and also in the path. What is forcing the Location.serviceLocation to think that the service requested is IRepositoryRestService and not ILicenseAdminRestService.
Any other ideas..
I also tried https sniffer program to manually send POST requests but I got connection refused error. Not sure if it is a problem with the sniffer program, but I didn't want to spend too much time debugging that. Atleast I am able to create users worst I would have to browse through them, select license and save which is little better.
It's pretty hard to execute a POST directly from a standard browser. If
you tried to go to that URL in a normal way it would execute a GET
rather than a POST request. You can use something like the
TeamRestServiceClient to execute the POST request from Java code.
-
Matt Lavin
Jazz Server Team
On Wed, 2008-11-05 at 15:47 +0000, warade wrote:
From the browser when I tried
https://localhost:9443/jazz/service/com.ibm.team.repository.service.internal.ILicenseAdminRestService/assignLicense?userId=test12&licenseId=com.ibm.team.rtc.developer
HTTP Status 400 - CRJAZ1175I Unable to get method info from service
call.
--------------------------------------------------------------------------------
type Status report
message CRJAZ1175I Unable to get method info from service call.
description The request sent by the client was syntactically incorrect
(CRJAZ1175I Unable to get method info from service call.).
It's pretty hard to execute a POST directly from a standard browser. If
you tried to go to that URL in a normal way it would execute a GET
rather than a POST request. You can use something like the
TeamRestServiceClient to execute the POST request from Java code.
-
Matt Lavin
Jazz Server Team
On Wed, 2008-11-05 at 15:47 +0000, warade wrote:
you tried to go to that URL in a normal way it would execute a GET
rather than a POST request. You can use something like the
TeamRestServiceClient to execute the POST request from Java code.
-
Matt Lavin
Jazz Server Team
On Wed, 2008-11-05 at 15:47 +0000, warade wrote:
From the browser when I tried
https://localhost:9443/jazz/service/com.ibm.team.repository.service.internal.ILicenseAdminRestService/assignLicense?userId=test12&licenseId=com.ibm.team.rtc.developer
HTTP Status 400 - CRJAZ1175I Unable to get method info from service
call.
--------------------------------------------------------------------------------
type Status report
message CRJAZ1175I Unable to get method info from service call.
description The request sent by the client was syntactically incorrect
(CRJAZ1175I Unable to get method info from service call.).
page 1of 1 pagesof 2 pagesof 3 pages