I'm doing a Dynamics CRM integration from a Java application and I've followed the example from the CRM training kit and managed successfully to connect and create accounts and contacts.
Now I'm having some problems with adding some more fields in the account creation and when connecting a contact with an account.
For instance I cannot create accounts with "address1_freighttermscode" that is a picklist.
My code is the following:
private static OrganizationServiceStub.Guid createAccount(OrganizationServiceStub serviceStub, String[] args) {
try {
OrganizationServiceStub.Create entry = new OrganizationServiceStub.Create();
OrganizationServiceStub.Entity newEntryInfo = new OrganizationServiceStub.Entity();
OrganizationServiceStub.AttributeCollection collection = new OrganizationServiceStub.AttributeCollection();
if (! (args[0].equals("null") )) {
OrganizationServiceStub.KeyValuePairOfstringanyType values = new OrganizationServiceStub.KeyValuePairOfstringanyType();
values.setKey("name");
values.setValue(args[0]);
collection.addKeyValuePairOfstringanyType(values);
}
if (! (args[13].equals("null"))){
OrganizationServiceStub.KeyValuePairOfstringanyType incoterm = new OrganizationServiceStub.KeyValuePairOfstringanyType();
incoterm.setKey("address1_freighttermscode");
incoterm.setValue(args[13]);
collection.addKeyValuePairOfstringanyType(incoterm);
}
newEntryInfo.setAttributes(collection);
newEntryInfo.setLogicalName("account");
entry.setEntity(newEntryInfo);
OrganizationServiceStub.CreateResponse createResponse = serviceStub.create(entry);
OrganizationServiceStub.Guid createResultGuid = createResponse.getCreateResult();
System.out.println("New Account GUID: " + createResultGuid.getGuid());
return createResultGuid;
} catch (IOrganizationService_Create_OrganizationServiceFaultFault_FaultMessage e) {
logger.error(e.getMessage());
} catch (RemoteException e) {
logger.error(e.getMessage());
}
return null;
}
When it executes, I get this error
[ERROR] Incorrect attribute value type System.String
Does anyone have examples on how to handle picklists or lookups?
To connect the contact with the account I'm filling the fields parentcustomerid and parentcustomeridtype with the GUID from the account and with "account", but the contact does not get associated with the account.
To set a picklist value you must use an OptionSet and for a lookup you must use an EntityReference. See the SDK's C# documentation, should work the same way using the Axis generated Java code.
incoterm.setKey("address1_freighttermscode")
//assuming the arg is an integer value that matches a picklist value for the attribute
OptionSetValue freight = new OptionSetValue();
freight.Value = args[13];
incoterm.setValue(freight);
collection.addKeyValuePairOfstringanyType(incoterm);
I haven't worked with Java for over a decade (and never towards an MS creation like Dynamics) so it might be way off from what you like. :)
You could use the REST web service and call directly to CRM creating your instances. As far I know, that's platform independent and should work as long as you can connect to the exposed service OrganizationData.
Related
I'm using smack-android:4.1.4 to connect to xmpp server, and I use this code to connect to a multi user chat room on that server:
MultiUserChatManager mucManager = MultiUserChatManager.getInstanceFor(connection);
MultiUserChat muc = mucManager.getMultiUserChat(roomName);
muc.join(nickName,password,discussionHistory,timeout);
In this room if I'm an owner then I can kick or ban a user, to ban a user:
muc.banUser(userJID, reason);
and I can get the banned users list in this room:
List<Affiliate> bannedList = muc.getOutcasts();
QUESTION 1: how can I unban a user from the previous list?
the problem is I couldn't find any function like:
//muc.unbanUser(String userJID); // there's nothing close to this
I read the whole documentation but came to nothing, so what am I missing here?
I can get the jid of any banned user through the outcasts list:
String jid = outcast.getJid(); // where outcast is of type Affiliate
but no function to use this jid to unban the user.
Question 2: this question is related to rooms but not to the banned list issue, in some rooms I get the following exception:
PacketParserUtils? Failed to parse extension packet in Presence packet. Attributes: from=roomName#conference.myXmppServer/someUserNickName id=null
org.jivesoftware.smack.SmackException: Caps elment with missing attributes. Attributes: hash=null version=1.0.0.84 node=http://www.google.com/xmpp/client/caps
at org.jivesoftware.smackx.caps.provider.CapsExtensionProvider.parse(CapsExtensionProvider.java:54)
at org.jivesoftware.smackx.caps.provider.CapsExtensionProvider.parse(CapsExtensionProvider.java:28)
at org.jivesoftware.smack.provider.Provider.parse(Provider.java:35)
at org.jivesoftware.smack.util.PacketParserUtils.parseExtensionElement(PacketParserUtils.java:929)
at org.jivesoftware.smack.util.PacketParserUtils.addExtensionElement(PacketParserUtils.java:1060)
at org.jivesoftware.smack.util.PacketParserUtils.parsePresence(PacketParserUtils.java:583)
at org.jivesoftware.smack.util.PacketParserUtils.parseStanza(PacketParserUtils.java:155)
at org.jivesoftware.smack.AbstractXMPPConnection.parseAndProcessStanza(AbstractXMPPConnection.java:956)
at org.jivesoftware.smack.tcp.XMPPTCPConnection.access$500(XMPPTCPConnection.java:140)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:989)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$300(XMPPTCPConnection.java:944)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:959)
at java.lang.Thread.run(Thread.java:856)
and it refers to some code inside the smack library classes, so it's not some uncaught exception inside my code,
what is the cause of this exception? and isn't there a way to handle such unparsed data?
I'm using ParsingExceptionCallback in other part of my application:
connection.setParsingExceptionCallback( parsingExceptionCallback );
but this function is not called for this case, is there any similar functions for MultiUserChat class ?
maybe making a user member will remove the jid from banned list? because according to xmpp a jid can not be in more than one list... how ever there are five lists in xmpp, one for owners,admins,members, none and banned.
at the following website
http://xmpp.org/extensions/xep-0045.html
read
4.1 General Terms
5.2.1 Privileges
optional read
Admin Use Cases
i'm using ejabberd server with smack-android-4.1.9 library and below code work perfect for me.
//remove the user from Group of ejabberd.
//revoke the Ownership,Admin and membership from group of ejabberd.
public void removeUser(String room_jid,RosterVO removeUserRosterVo,boolean isAdmin){
MultiUserChatManager multichatmanager = MultiUserChatManager.getInstanceFor(connection);
MultiUserChat chatRoom = multichatmanager.getMultiUserChat(room_jid);
try {
if (isAdmin) {
chatRoom.revokeOwnership(removeUserRosterVo.getJid());
chatRoom.revokeAdmin(removeUserRosterVo.getJid());
chatRoom.revokeMembership(removeUserRosterVo.getJid());
} else {
chatRoom.revokeMembership(removeUserRosterVo.getJid());
}
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
} catch (XMPPException.XMPPErrorException e) {
e.printStackTrace();
} catch (SmackException.NoResponseException e) {
e.printStackTrace();
}
}
I'm implementing a client to a web service (and the guys maintaining the web service have been a litte unresponsive..) I've used axis and WSDL2Java to generate java classes and I can call their login-method on their authentication-service ok, and get a sessionId back (eg z4zojhiqkw40lj55kgtn1oya). However, it seems that i cannot use this sessionId as a parameter anywhere. Even a call to their hasSession()-method directly after login returned false. I managed to solve this by setting setMaintainSession(true) on the Locator-object for this service. But the problem is, that this first service, the Authentication-service, is only used for authentification. If I then call setMaintainSession(true) on eg ProductServiceLocator, and call some method on it, I will get an error because of unauthenticated session. I have to find a way to share the session between the services on the client side.
Looking on their php code example-it seeems like they are storing the session in a cookie. How can I mimic this behaviour in my java client?
php-code:
$authentication = new SoapClient ( "https://webservices.24sevenoffice.com/authenticate/authenticate.asmx?wsdl", $options );
// log into 24SevenOffice if we don't have any active session. No point doing this more than once.
$login = true;
if (!empty($_SESSION['ASP.NET_SessionId'])){
$authentication->__setCookie("ASP.NET_SessionId", $_SESSION['ASP.NET_SessionId']);
try{
$login = !($authentication->HasSession()->HasSessionResult);
}
catch ( SoapFault $fault ) {
$login = true;
}
}
if( $login ){
$result = ($temp = $authentication->Login($params));
// set the session id for next time we call this page
$_SESSION['ASP.NET_SessionId'] = $result->LoginResult;
// each seperate webservice need the cookie set
$authentication->__setCookie("ASP.NET_SessionId", $_SESSION['ASP.NET_SessionId']);
// throw an error if the login is unsuccessful
if($authentication->HasSession()->HasSessionResult == false)
throw new SoapFault("0", "Invalid credential information.");
}
My code is the following:
AuthenticateLocator al = new AuthenticateLocator();
al.setMaintainSession(true);
Credential c = new Credential(CredentialType.Community,username,password,guid);
AuthenticateSoap s = al.getAuthenticateSoap();
String sessionId = s.login(c);
System.out.println("Session id was: "+sessionId);
System.out.println("Has Session: "+s.hasSession()); //Hooray, now works after setMaintainSession(true)
//And now trying to call another Service
CompanyServiceLocator cl = new CompanyServiceLocator();
cl.setMaintainSession(true);
CompanyServiceSoap css = cl.getCompanyServiceSoap();
css.getCountryList(); //FAILS!
So what can I do to make this work?
Hooray, I finally solved it myself :-D
Thanx a lot to the excellent article at http://www.nsftools.com/stubby/ApacheAxisClientTips.htm
I had to do the following with my code to make it work:
CompanyServiceLocator cl = new CompanyServiceLocator();
cl.setMaintainSession(true);
CompanyServiceSoap css = cl.getCompanyServiceSoap();
((Stub)css)._setProperty(HTTPConstants.HEADER_COOKIE, "ASP.NET_SessionId="+sessionId); //New line that does the magic
css.getCountryList(); //SUCCESS :-D
Operating in the high-level abstraction of the autogenerated classes, it was unknown to me that casting the service classes to Stub would expose more methods and properties that could be set. Good to know for later I guess :-)
I am creating a Java web app to manage meetings between a set of students and teachers. All of them already use Outlook to manage their email and personal calendar.
I would like to know if it's even possible to build the schedule feature of my web app using Exchange, Office365 or Sharepoint Team Calendar via REST service in order to check the availability and create a meeting for a student and one of the teachers available:
SharePoint 2013 REST service
So far, the most promising mechanism I have found is Microsoft Sharepoint Server's calendar, which collaborative features makes possible to create a meeting and check availability for a list of users. The downside is that it does not support one to one meetings but for the entire team (as far I have found).
My second option would be to require everyone in the group (students and teachers of the department) to make public their personal calendar so the web app be able to check the availability of both student and teacher and send a meeting request. The obvious problem is the privacy/security concern derived from this approach.
My last option (and by far the less favourite because it feels like re-inventing the wheel) is to build a proprietary calendar within the web app and send iCal requests to each person. The obvious problem with this approach is synchronisation between the two separated calendars.
In addition, this feature must be a pretty common need so there should be tons of blogs explaining how to take advantage of Exchange/Sharepoint/Office365 to implement it (other platforms are not considered since my employer's infrastructure is based on Microsoft). However, whether it is so obvious that nobody talks about it or I have not searched in the right place. Any advice to point me in the right direction?
Exchange natively shows user calendar availability exposed in EWS (Exchange Web Services), your network administrator must configure Exchange server enabling EWS.
But guess what... Office 365 (as I know) have EWS services enabled, due exchange is part of office 365 offer.
As EWS are normal Web services you should create a "service stub" or proxy in whatever you use in java to create services references mapping wsdl files.
Exchanged EWS is my preferred solution.
Hope this helps.
This is the reference page, this link show how to use the service references from C# to make the right API calls.
http://msdn.microsoft.com/en-us/library/exchange/aa494212(v=exchg.140).aspx
static void GetUserAvailability(ExchangeServiceBinding esb)
{
// Identify the time to compare free/busy information.
Duration duration = new Duration();
duration.StartTime = DateTime.Now;
duration.EndTime = DateTime.Now.AddHours(4);
// Identify the options for comparing free/busy information.
FreeBusyViewOptionsType fbViewOptions = new FreeBusyViewOptionsType();
fbViewOptions.TimeWindow = duration;
fbViewOptions.RequestedView = FreeBusyViewType.MergedOnly;
fbViewOptions.RequestedViewSpecified = true;
fbViewOptions.MergedFreeBusyIntervalInMinutes = 35;
fbViewOptions.MergedFreeBusyIntervalInMinutesSpecified = true;
MailboxData[] mailboxes = new MailboxData[1];
mailboxes[0] = new MailboxData();
// Identify the user mailbox to review for free/busy data.
EmailAddress emailAddress = new EmailAddress();
emailAddress.Address = "tplate#contoso.com";
emailAddress.Name = String.Empty;
mailboxes[0].Email = emailAddress;
mailboxes[0].ExcludeConflicts = false;
// Make the request.
GetUserAvailabilityRequestType request = new GetUserAvailabilityRequestType();
// Set the time zone of the request.
request.TimeZone = new SerializableTimeZone();
request.TimeZone.Bias = 480;
request.TimeZone.StandardTime = new SerializableTimeZoneTime();
request.TimeZone.StandardTime.Bias = 0;
request.TimeZone.StandardTime.DayOfWeek = DayOfWeekType.Sunday.ToString();
request.TimeZone.StandardTime.DayOrder = 1;
request.TimeZone.StandardTime.Month = 11;
request.TimeZone.StandardTime.Time = "02:00:00";
request.TimeZone.DaylightTime = new SerializableTimeZoneTime();
request.TimeZone.DaylightTime.Bias = -60;
request.TimeZone.DaylightTime.DayOfWeek = DayOfWeekType.Sunday.ToString();
request.TimeZone.DaylightTime.DayOrder = 2;
request.TimeZone.DaylightTime.Month = 3;
request.TimeZone.DaylightTime.Time = "02:00:00";
// Add the mailboxes to the request.
request.MailboxDataArray = mailboxes;
// Add the view options to the request.
request.FreeBusyViewOptions = fbViewOptions;
try
{
// Send the request and get the response.
GetUserAvailabilityResponseType response = esb.GetUserAvailability(request);
// Access free/busy information.
if (response.FreeBusyResponseArray.Length < 1)
{
throw new Exception("No free/busy response data available.");
}
else
{
foreach (FreeBusyResponseType fbrt in response.FreeBusyResponseArray)
{
if (fbrt.ResponseMessage.ResponseClass == ResponseClassType.Error)
{
Console.WriteLine(string.Format("Error: {0}", fbrt.ResponseMessage.MessageText));
}
else
{
// Show the free/busy stream.
FreeBusyView fbv = fbrt.FreeBusyView;
Console.WriteLine(string.Format("Merged free/busy data: {0}", fbv.MergedFreeBusy));
}
}
}
}
catch (Exception e)
{
// Perform error processing.
Console.WriteLine(e.Message);
Console.ReadLine();
}
}
I'm looking for the simplest way of programmatically logging in into Analytics and get data. Google documentation writes and gives examples for Oauth 2.0 which involves a user manually logging into with his google account, and then being redirected to my site with authorization. But this is not what I want to achieve - I'm building an automatic tool that needs to have user/pass or any other authorization key to be hard-coded and then log in without any user involvement (this is a periodic reporting tool).
I already found something about API KEY, but I can't find any example how to do that, or how to to that with Google java libraries.
I would be very grateful for pointing me into right direction. Also this may be valuable clue for others how to do it the simplest way - and I think logging should be simple.
I had the same problem and I took me about 1h to find this in the v3 documentation:
Service Accounts
Useful for automated/offline/scheduled access to Google Analytics data for your own account. For example, to build a live dashboard of your own Google Analytics data and share it with other users.
There are a few steps you need to follow to configure service accounts to work with Google Analytics:
Register a project in the APIs Console.
In the Google APIs Console, under the API Access pane, create a client ID with the Application Type set to Service Account.
Sign-in to Google Analytics and navigate to the Admin section.
Select the account for which you want the application to have access to.
Add the email address, from the Client ID created in the APIs Console from step #2, as a user of the selected Google Analytics account.
Follow the instructions for Service Accounts to access Google Analytics data.
Read more here:
https://developers.google.com/analytics/devguides/reporting/core/v3/gdataAuthorization
Puh, I guess the API is so big Google is having trouble documenting it an easy way =)
Then I looked at the code in the plus-serviceaccount-cmdline-sample and analytics-cmdline-sample. This is a very basic version implemented in a Playframework2 java app that
prints to System.out as the examples above:
private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
private static final JsonFactory JSON_FACTORY = new JacksonFactory();
public static Result index() {
GoogleCredential credential = null;
try {
credential = new GoogleCredential.Builder().setTransport(HTTP_TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId("2363XXXXXXX#developer.gserviceaccount.com")
.setServiceAccountScopes(Arrays.asList(AnalyticsScopes.ANALYTICS_READONLY))
.setServiceAccountPrivateKeyFromP12File(new File("/your/path/to/privatekey/privatekey.p12"))
.build();
} catch (GeneralSecurityException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// Set up and return Google Analytics API client.
Analytics analytics = new Analytics.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential).setApplicationName(
"Google-Analytics-Hello-Analytics-API-Sample").build();
String profileId = "";
try {
profileId = getFirstProfileId(analytics);
} catch (IOException e) {
e.printStackTrace();
}
GaData gaData = null;
try {
gaData = executeDataQuery(analytics, profileId);
} catch (IOException e) {
e.printStackTrace();
}
printGaData(gaData);
return ok(index.render("Your new application is ready."));
}
private static String getFirstProfileId(Analytics analytics) throws IOException {
String profileId = null;
// Query accounts collection.
Accounts accounts = analytics.management().accounts().list().execute();
if (accounts.getItems().isEmpty()) {
System.err.println("No accounts found");
} else {
String firstAccountId = accounts.getItems().get(0).getId();
// Query webproperties collection.
Webproperties webproperties =
analytics.management().webproperties().list(firstAccountId).execute();
if (webproperties.getItems().isEmpty()) {
System.err.println("No Webproperties found");
} else {
String firstWebpropertyId = webproperties.getItems().get(0).getId();
// Query profiles collection.
Profiles profiles =
analytics.management().profiles().list(firstAccountId, firstWebpropertyId).execute();
if (profiles.getItems().isEmpty()) {
System.err.println("No profiles found");
} else {
profileId = profiles.getItems().get(0).getId();
}
}
}
return profileId;
}
/**
* Returns the top 25 organic search keywords and traffic source by visits. The Core Reporting API
* is used to retrieve this data.
*
* #param analytics the analytics service object used to access the API.
* #param profileId the profile ID from which to retrieve data.
* #return the response from the API.
* #throws IOException tf an API error occured.
*/
private static GaData executeDataQuery(Analytics analytics, String profileId) throws IOException {
return analytics.data().ga().get("ga:" + profileId, // Table Id. ga: + profile id.
"2012-01-01", // Start date.
"2012-01-14", // End date.
"ga:visits") // Metrics.
.setDimensions("ga:source,ga:keyword")
.setSort("-ga:visits,ga:source")
.setFilters("ga:medium==organic")
.setMaxResults(25)
.execute();
}
/**
* Prints the output from the Core Reporting API. The profile name is printed along with each
* column name and all the data in the rows.
*
* #param results data returned from the Core Reporting API.
*/
private static void printGaData(GaData results) {
System.out.println("printing results for profile: " + results.getProfileInfo().getProfileName());
if (results.getRows() == null || results.getRows().isEmpty()) {
System.out.println("No results Found.");
} else {
// Print column headers.
for (GaData.ColumnHeaders header : results.getColumnHeaders()) {
System.out.printf("%30s", header.getName());
}
System.out.println();
// Print actual data.
for (List<String> row : results.getRows()) {
for (String column : row) {
System.out.printf("%30s", column);
}
System.out.println();
}
System.out.println();
}
}
Hope this helps!
I solved it finally with the 2.4 version of Core Reporting - there's autorization with your gmail user/pass, just as simple as it should be - I wonder why there's no example how to do this in new 3.0 version.
Core reporting 2.4: http://code.google.com/intl/pl-PL/apis/analytics/docs/gdata/v2/gdataJava.html
I attempted to follow the example provided and it does not compile. I don't know if this is 3.0 vs 2.4 and if so, is there a way that the example code can be made to work -- proper choice of jars or what.
One problem with the example is that the argument to setServiceAccountScopes is no longer a string but a Collections.singleton(AnalyticsScopes.Analytics.READ_ONLY).
Also important to using the example is proper configuration of the Service Account.
As an answer to another question I wrote a code example in Java which works for me.
See:
https://stackoverflow.com/a/24043488/1391050
I want to use a custom authentication module conforming to JSR 196 in GlassFish 3. The interface javax.security.auth.message.ServerAuth has the method:
AuthStatus validateRequest(
MessageInfo messageInfo,
javax.security.auth.Subject clientSubject,
javax.security.auth.Subject serviceSubject
)
AuthStatus can be one of several constants like FAILURE or SUCCESS.
The question is: How can I get the roles from a "role datebase" with JSR 196?
Example: The server receives a request with a SSO token (CAS token for example), checks whether the token is valid, populates the remote user object with roles fetches from a database via JDBC or from REST service via http.
Is the role fetching in the scope of JSR 196? How could that be implemented?
Do I have to use JSR 196 together with JSR 115 to use custom authentication and a custom role source?
This is a code example from my JSR-196OpenID Implementation.
The method set the roles stored in a String Array for the current CallerPrincipal:
private boolean setCallerPrincipal(String caller, Subject clientSubject) {
boolean rvalue = true;
boolean assignGroups = true;
// create CallerPrincipalCallback
CallerPrincipalCallback cPCB = new CallerPrincipalCallback(
clientSubject, caller);
if (cPCB.getName() == null && cPCB.getPrincipal() == null) {
assignGroups = false;
}
try {
handler.handle((assignGroups ? new Callback[] {
cPCB,
new GroupPrincipalCallback(cPCB.getSubject(),
assignedGroups) } : new Callback[] { cPCB }));
logInfo(DEBUG_JMAC, "jmac.caller_principal:" + cPCB.getName() + " "
+ cPCB.getPrincipal());
} catch (Exception e) {
// should not happen
logger.log(Level.WARNING, "jmac.failed_to_set_caller", e);
rvalue = false;
}
return rvalue;
}
I call this method during the validateRequest() method.
You can see the complete code here:
http://code.google.com/p/openid4java-jsr196/source/browse/trunk/src/main/java/org/imixs/openid/openid4java/OpenID4JavaAuthModule.java
Also this page will be helpfull :
http://code.google.com/p/openid4java-jsr196/
Here's how I map users to roles:
I have 3 roles in my web.xml and also I have 3 role-to-group mappings in my sun-web.xml which map those roles several groups. Then I have a database with table Users that has a column called "group". That group corresponds to the group that is mapped to a role. I also use JSR 196-based custom auth module with OpenID. So basically whenever a user is logged in their group is read from the db and then my app assigns them the corresponding role. This is all done using the standard declarative security model of J2EE.
For my custom auth module I use a library called AuthenticRoast which makes things quite a bit simpler.
Here's also a related post...
Hope this helps.