MS Dynamics 365 Online Plugin External Rest API access gives error - plugins

I am trying to access an external third party API from a Dynamics 365 Online plugin using the following code:
public void Execute(IServiceProvider serviceProvider)
{
//Extract the tracing service for use in plug-in debugging.
ITracingService tracingService =
(ITracingService)serviceProvider.GetService(typeof(ITracingService));
try
{
tracingService.Trace("Downloading the target URI: " + webAddress);
try
{
//<snippetWebClientPlugin2>
// Download the target URI using a Web client. Any .NET class that uses the
// HTTP or HTTPS protocols and a DNS lookup should work.
using (WebClient client = new WebClient())
{
byte[] responseBytes = client.DownloadData(webAddress);
string response = Encoding.UTF8.GetString(responseBytes);
//</snippetWebClientPlugin2>
tracingService.Trace(response);
// For demonstration purposes, throw an exception so that the response
// is shown in the trace dialog of the Microsoft Dynamics CRM user interface.
throw new InvalidPluginExecutionException("WebClientPlugin completed successfully.");
}
}
catch (WebException exception)
{
string str = string.Empty;
if (exception.Response != null)
{
using (StreamReader reader =
new StreamReader(exception.Response.GetResponseStream()))
{
str = reader.ReadToEnd();
}
exception.Response.Close();
}
if (exception.Status == WebExceptionStatus.Timeout)
{
throw new InvalidPluginExecutionException(
"The timeout elapsed while attempting to issue the request.", exception);
}
throw new InvalidPluginExecutionException(String.Format(CultureInfo.InvariantCulture,
"A Web exception occurred while attempting to issue the request. {0}: {1}",
exception.Message, str), exception);
}
}
catch (Exception e)
{
tracingService.Trace("Exception: {0}", e.ToString());
throw;
}
}
}
But I am getting the error:
Request for the permission of type 'System.Security.Permissions.SecurityPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.'
I have checked MS documentation but nothing suggests why I am unable to do this. I know about sandboxed plugins but according to MS I should be able to do this using their own sample code.

This is expected in CRM Online, as this is SaaS and you're in a shared tenant in cloud. You can do either webhook or Azure service hub to trigger external endpoint with CRM context for processing. Read more
And if you've got CRM Online, then the normal solution is to offload the processing to an environment that you have more control over. The most common option is to offload the processing to Azure, using the Azure Service Bus or Azure Event Hub. The alternative, new to CRM 9, is to send the data to a WebHook, which can be hosted wherever you like.

Related

Trying to connect XMPP server by Smack and getting error

I have got an requirement to connect XMPP server using Java API Smack and further make send message/receive message.
I tried with Smack API (4.1.8) and I am getting errors (find errors below).
Note: both host and port are opened.
Code:`public class Sender {
public static void main(String a[]) throws NoResponseException,XMPPException,
InterruptedException, SmackException, IOException
{
// Create the configuration for this new connection
XMPPTCPConnectionConfiguration.Builder configBuilder = XMPPTCPConnectionConfiguration.builder();
configBuilder.setUsernameAndPassword("user", "******");
configBuilder.setResource("work");
configBuilder.setServiceName("HOstname");
configBuilder.setSocketFactory(SSLSocketFactory.getDefault());
configBuilder.setSecurityMode(SecurityMode.required);
configBuilder.setCompressionEnabled(true);
configBuilder.setHost("thingsociety.im");
configBuilder.setDebuggerEnabled(true);
configBuilder.setPort(5222);
System.out.println("Connected1..............");
XMPPTCPConnection connection = new XMPPTCPConnection(configBuilder.build());
// Connect to the server
try {
System.out.println("Connected2..............");
connection.setPacketReplyTimeout(100000);
connection.connect();
System.out.println("Connected3..............");
// Log into the server
connection.isConnected();
connection.login();
System.out.println("Connected4..............");
}
catch (XMPPException | SmackException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println(e.getMessage());
}
}
}
Error: No response received within reply timeout. Timeout was 100000ms (~100s). Used filter: No filter used or filter was 'null'.
org.jivesoftware.smack.SmackException$NoResponseException: No response received within reply timeout. Timeout was 100000ms (~100s). Used filter: No filter used or filter was 'null'
So basicly something (local firewall or on your gateway) is blocking outgouing communications OR configBuilder.setServiceName("HOstname"); service name (aka XMPP Domain) is wrong, maybe mispelled - especialy capital O looks like misspell to me.
I have just probe thingsociety.im:5222 and it is open so most probably it is a firewall issue.
Another one could be unhandeld, low level error on server side.

Restlet Studio Error 422 when generating sample client and server

Hi I'm using the restlet studio to generate a client and server from your sample pet store API . Here are my steps:
Generate Java Server (JAX-RS)
Edit pom.xml to make a war file
mvn package
Deploy to jetty server as webapp
Verify it works by going to hitting the URL with a browser:
http://54.149.215.125:8080/v2/pet/findByTags
Response:
{"code":4,"type":"ok","message":"magic!"}
At this point I think it works, until I generate the client in Java
I change the endpoint from the webnik one to my webserver
Make a simple main method
public static void main(String[] args) {
try {
FindPetByTagsClientResource a = new FindPetByTagsClientResource();
Pet represent = a.represent();
} catch (Exception ex) {
Logger.getLogger(APIPetStore.class.getName()).log(Level.SEVERE, null, ex);
}
}
When I run it I get this:
run:
Starting the internal HTTP client
null
Unprocessable Entity (422) - The server understands the content type of the request entity and the syntax of the request entity is correct but was unable to process the contained instructions
at org.restlet.resource.Resource.toObject(Resource.java:893)
at org.restlet.engine.resource.ClientInvocationHandler.invoke(ClientInvocationHandler.java:326)
at com.sun.proxy.$Proxy5.represent(Unknown Source)
at net.apispark.webapi.client.FindPetByTagsClientResource.represent(FindPetByTagsClientResource.java:22)
at apipetstore.APIPetStore.main(APIPetStore.java:28)
Caused by: java.io.IOException: Unable to create the Object representation
at org.restlet.engine.converter.DefaultConverter.toObject(DefaultConverter.java:282)
at org.restlet.service.ConverterService.toObject(ConverterService.java:229)
at org.restlet.resource.Resource.toObject(Resource.java:889)
... 4 more
Caused by: java.lang.IllegalArgumentException: The serialized representation must have this media type: application/x-java-serialized-object or this one: application/x-java-serialized-object+xml
at org.restlet.representation.ObjectRepresentation.(ObjectRepresentation.java:221)
at org.restlet.representation.ObjectRepresentation.(ObjectRepresentation.java:123)
at org.restlet.representation.ObjectRepresentation.(ObjectRepresentation.java:104)
at org.restlet.engine.converter.DefaultConverter.toObject(DefaultConverter.java:279)
... 6 more
BUILD SUCCESSFUL (total time: 0 seconds)
Change the main method to this and it works:
public static void main(String[] args) {
try {
FindPetByTagsClientResource a = new FindPetByTagsClientResource();
a.getClientResource().get().write(System.out);
} catch (Exception ex) {
Logger.getLogger(APIPetStore.class.getName()).log(Level.SEVERE, null, ex);
}
}
Output:
Starting the internal HTTP client
{"code":4,"type":"ok","message":"magic!"}
Any ideas on how I can fix this?
In fact, the JAXRS server skeleton is really a server skeleton ;-) This means that it doesn't actually send back the right content according to the client. If you look at the server code, you always see this:
public Response findPetsByTags(#ApiParam(value = "Tags to filter by") #QueryParam("tags") List<String> tags)
throws NotFoundException {
// do some magic!
return Response.ok().entity(new ApiResponseMessage(ApiResponseMessage.OK, "magic!")).build();
}
It doesn't correspond to a list of pet objects...
On the client side, you got the error since you try to use annotated interfaces. They automatically try to use the internal converter of Restlet. It fails since it expects an object of type Pet and you received something with this structure: {"code":4,"type":"ok","message":"magic!"}.
In conclusion, you need to do some work to adapt the server skeleton to return the correct objects. Here is an hardcoded solution to make work your client SDK:
#GET
#Path("/findByTags")
#ApiOperation(value = "Finds Pets by tags", notes = "Finds Pets by tags", response = Pet.class, responseContainer = "List")
#ApiResponses(value = {
#ApiResponse(code = 400, message = "") })
public Response findPetsByTags(#ApiParam(value = "Tags to filter by") #QueryParam("tags") List<String> tags)
throws NotFoundException {
// do some magic!
Pet pet = new Pet();
pet.setId(10);
pet.setName("My pet");
pet.setStatus("status");
List<Tag> actualTags = new ArrayList<Tag>();
Tag tag1 = new Tag();
tag1.setId(1);
tag1.setName("tag1");
actualTags.add(tag1);
Tag tag2 = new Tag();
tag2.setId(2);
tag2.setName("tag2");
actualTags.add(tag2);
pet.setTags(actualTags);
return Response.ok().entity(pet).build();
}
I'll have a look if we can improve this for the server side. In fact, the Restlet Studio internally uses the swagger2 codegen tool chain to generate this server skeleton.
Hope it helps,
Thierry

Handle JDBC exception in BIRT API

I have a scheduler job which is based on a standalone RunAndRenderTask. The report design connects to a remote mysql database to fetch data. The scheduler generates a PDF and emails the report as attachment to a set of people. This works as long as the database is available.
But when the database is unavailable, then I can see the error in the logs, but the RunAndRenderTask still generates a PDF report which is blank and useless, and this gets emailed by the scheduler. I need to be able to catch this exception and instead email another set of people who can fix the DB issue. I tried various things but couldn't figure out how to do it.
In the code below, I expect the API to return an exception, and hence print "BirtException" or "Exception", but this code prints "Success" even when there is a JDBC exception.
Any help is appreciated.
Here's the code I have.
IReportEngine engine = null;
IRunAndRenderTask runAndRenderTask = null;
try {
EngineConfig config = new EngineConfig();
config.setEngineHome("birt-runtime-4_4_0/RuntimeEngine");
Platform.startup(config);
IReportEngineFactory factory = (IReportEngineFactory) Platform
.createFactoryObject(IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY);
engine = factory.createReportEngine(config);
IReportRunnable reportRunnable = engine.openReportDesign(DATA_PATH + "sample.rptdesign");
runAndRenderTask = engine.createRunAndRenderTask(reportRunnable);
PDFRenderOption option = new PDFRenderOption();
option.setOutputFileName(DATA_PATH + "output.pdf");
option.setOutputFormat("pdf");
runAndRenderTask.setRenderOption(option);
runAndRenderTask.run();
System.out.println("Success!");
} catch (BirtException e) {
System.out.println("BirtException");
e.printStackTrace();
} catch (Throwable e) {
System.out.println("Exception");
e.printStackTrace();
} finally {
if (runAndRenderTask != null) {
runAndRenderTask.close();
}
if (engine != null) {
engine.destroy();
}
Platform.shutdown();
RegistryProviderFactory.releaseDefault();
}
This is the exception stacktrace, which never gets propagated back by RunAndRenderTask.run()
INFO: Loaded JDBC driver class in class path: com.mysql.jdbc.Driver
Jun 26, 2014 9:26:43 PM org.eclipse.birt.data.engine.odaconsumer.ConnectionManager openConnection
SEVERE: Unable to open connection.
org.eclipse.birt.report.data.oda.jdbc.JDBCException: There is an error in get connection, Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server..
at org.eclipse.birt.report.data.oda.jdbc.JDBCDriverManager.doConnect(JDBCDriverManager.java:336)
at org.eclipse.birt.report.data.oda.jdbc.JDBCDriverManager.getConnection(JDBCDriverManager.java:235)
at org.eclipse.birt.report.data.oda.jdbc.Connection.connectByUrl(Connection.java:252)
at org.eclipse.birt.report.data.oda.jdbc.Connection.open(Connection.java:162)
at org.eclipse.datatools.connectivity.oda.consumer.helper.OdaConnection.open(OdaConnection.java:250)
at org.eclipse.birt.data.engine.odaconsumer.ConnectionManager.openConnection(ConnectionManager.java:165)
at org.eclipse.birt.data.engine.executor.DataSource.newConnection(DataSource.java:224)
at org.eclipse.birt.data.engine.executor.DataSource.open(DataSource.java:212)
at org.eclipse.birt.data.engine.impl.DataSourceRuntime.openOdiDataSource(DataSourceRuntime.java:217)
at org.eclipse.birt.data.engine.impl.QueryExecutor.openDataSource(QueryExecutor.java:435)
at org.eclipse.birt.data.engine.impl.QueryExecutor.prepareExecution(QueryExecutor.java:322)
at org.eclipse.birt.data.engine.impl.PreparedQuery.doPrepare(PreparedQuery.java:463)
at org.eclipse.birt.data.engine.impl.PreparedDataSourceQuery.produceQueryResults(PreparedDataSourceQuery.java:190)
at org.eclipse.birt.data.engine.impl.PreparedDataSourceQuery.execute(PreparedDataSourceQuery.java:178)
at org.eclipse.birt.data.engine.impl.PreparedOdaDSQuery.execute(PreparedOdaDSQuery.java:178)
at org.eclipse.birt.report.data.adapter.impl.DataRequestSessionImpl.execute(DataRequestSessionImpl.java:637)
at org.eclipse.birt.report.engine.data.dte.DteDataEngine.doExecuteQuery(DteDataEngine.java:152)
at org.eclipse.birt.report.engine.data.dte.AbstractDataEngine.execute(AbstractDataEngine.java:275)
at org.eclipse.birt.report.engine.executor.ExtendedGenerateExecutor.executeQueries(ExtendedGenerateExecutor.java:205)
at org.eclipse.birt.report.engine.executor.ExtendedGenerateExecutor.execute(ExtendedGenerateExecutor.java:65)
at org.eclipse.birt.report.engine.executor.ExtendedItemExecutor.execute(ExtendedItemExecutor.java:62)
at org.eclipse.birt.report.engine.internal.executor.dup.SuppressDuplicateItemExecutor.execute(SuppressDuplicateItemExecutor.java:43)
at org.eclipse.birt.report.engine.internal.executor.wrap.WrappedReportItemExecutor.execute(WrappedReportItemExecutor.java:46)
at org.eclipse.birt.report.engine.internal.executor.l18n.LocalizedReportItemExecutor.execute(LocalizedReportItemExecutor.java:34)
at org.eclipse.birt.report.engine.layout.html.HTMLBlockStackingLM.layoutNodes(HTMLBlockStackingLM.java:65)
at org.eclipse.birt.report.engine.layout.html.HTMLPageLM.layout(HTMLPageLM.java:92)
at org.eclipse.birt.report.engine.layout.html.HTMLReportLayoutEngine.layout(HTMLReportLayoutEngine.java:100)
at org.eclipse.birt.report.engine.api.impl.RunAndRenderTask.doRun(RunAndRenderTask.java:181)
at org.eclipse.birt.report.engine.api.impl.RunAndRenderTask.run(RunAndRenderTask.java:77)
at test.ReportTester.test(ReportTester.java:50)
at test.ReportTester.main(ReportTester.java:19)
In addition to catching BirtException, you should be aware that the way BIRT handles Javascript errors is - by default - browser-like. That is, BIRT tries to continue generating the report.
There are different ways to handle this for production-quality code (where task is a RunAndRenderTask or RunTask or RenderTask):
Use task.setErrorHandlingOption(CANCEL_ON_ERROR) (see BIRT docs). Personally, I have never tried this.
After task.run(...), but before task.close(), call task.getErrors(). If this list is not empty, your code should output these messages and throw an exception.
You need to add catch block that catches EngineException, not JDBC exception.
You can find javadocs at link.

How to check my jboss is started in JAVA?

ex) abc.war is deployed in Jboss.
I want to know that jboss is started or not... in already deployed java source(abc.war).
there is running a thread to check it out.
but I wondering how can I know my jboss is completelly started.
or How to know the end point which jboss is successfully started.
cos I have to execute some method after jboss is completelly on.
jboss5.0 + spring3.0 + jre1.6
EDIT: I just realized that you were aiming at JBoss 5. AFAIK, the below advice works only with JBoss 7.x. Please tell if it is still relevant to you. Otherwise I will delete the answer.
You can use the Jboss Management API for this. HEre is an example of how to access JBoss management using JBoss detyped management (jboss.dmr) library:
final ModelNode request = new ModelNode();
request.get(ClientConstants.OP).set("read-resource");
request.get("recursive").set(true);
request.get(ClientConstants.OP_ADDR).add("subsystem", "deployments");
ModelControllerClient client = null;
try {
client = ModelControllerClient.Factory.create(InetAddress.getByName(MANAGEMENT_HOST),
MANAGEMENT_PORT);
} catch (final UnknownHostException e) {
log.warn("unable to create ModelControllerClient on {}:{}, {}", new Object[] {
MANAGEMENT_HOST, MANAGEMENT_PORT, e });
return;
}
ModelNode response = null;
try {
response = client.execute(new OperationBuilder(request).build());
} catch (final IOException e) {
log.warn("unable to perform operation : {}, {}", request, e);
return;
}
log.info("request returned following results:");
final ModelNode resultNode = response.get(ClientConstants.RESULT);
for (final String key : resultNode.keys()) {
log.info("{} : {}", key, resultNode.get(key));
}
Perhaps JSR-88 would be of assistance, which JBoss supports and even provides example code to note its use?

UCMA 3.0 API Conferencing Error : Cannot join a different conference after receiving a conference invitation or conference escalation request

We have a UCMA 3.0 based application/bot that matches end users with experts. It migrates incoming one-one chat requests from end users into a multi user conference and then invites experts into the resulting multi user conference. The application itself continues to be a participant in the conference. At any given time, there may be several such conferences being brokered by our application but only one per end user. However, a single expert may be participating in more than one conference at the same time.
In our application logs we occasionally see the following exception.
Error in Conference Migration conf call # 63809878 ,Address :sip:xxxxxx#xxx.com;gruu;opaque=app:conf:focus:id:TQRREACE System.InvalidOperationException: Cannot join a different conference after receiving a conference invitation or conference escalation request.
at Microsoft.Rtc.Collaboration.ConferenceSession.VerifyAndGetConferenceAddress(String conferenceUri, String parameterName)
at Microsoft.Rtc.Collaboration.ConferenceSession.BeginJoinCommon(String conferenceUri, ConferenceJoinOptions options, AsyncCallback userCallback, Object state)
at Microsoft.Rtc.Collaboration.ConferenceSession.BeginJoin(String conferenceUri, ConferenceJoinOptions options, AsyncCallback userCallback, Object state)
at a(String A_0, String A_1, String A_2, Boolean A_3, Boolean A_4)
Below is the code snippet used to make conference. Previously this site was an OCS 2007 R2 Installation and was migrated to Lync 2010 Server.
Site is running in mixed mode. It occurs only on production server and we are not able to generate this exception on dev server, we
have tested it after generating more than 15 conferences simultaniously but no luck.
private void CreateAdHohConf(string user1Uri, string user2uri, string subject)
{
Exception exception = null;
// Create conference scheduling details for the conference.
ConferenceScheduleInformation scheduleInfo = new ConferenceScheduleInformation();
// Restrict the conference to invited users only.
scheduleInfo.AccessLevel = ConferenceAccessLevel.Everyone;
// Set a subject for the conference.
scheduleInfo.Subject = subject;
scheduleInfo.Description = subject;
scheduleInfo.ConferenceId = ConferenceServices.GenerateConferenceId();
scheduleInfo.ExpiryTime = System.DateTime.Now.AddHours(8);
scheduleInfo.IsPasscodeOptional = true;
scheduleInfo.PhoneAccessEnabled = false;
// Don't automatically assign a leader.
scheduleInfo.AutomaticLeaderAssignment = AutomaticLeaderAssignment.Everyone;
// Add the caller and recipient as participants.
scheduleInfo.Participants.Add(new ConferenceParticipantInformation("sip:" + user1Uri, ConferencingRole.Leader));
scheduleInfo.Participants.Add(new ConferenceParticipantInformation("sip:" + user2uri, ConferencingRole.Leader));
scheduleInfo.Mcus.Add(new ConferenceMcuInformation(McuType.ApplicationSharing));
scheduleInfo.Mcus.Add(new ConferenceMcuInformation(McuType.InstantMessaging));
scheduleInfo.Mcus.Add(new ConferenceMcuInformation(McuType.AudioVideo));
scheduleInfo.Mcus.Add(new ConferenceMcuInformation(McuType.Meeting));
//Scheduling conference
ConferenceServices objLocalConfSvc = lyncAgent.LocalEndpoint.ConferenceServices;
Conference confSession = null;
objLocalConfSvc.BeginScheduleConference(scheduleInfo,
result =>
{
try
{
confSession = objLocalConfSvc.EndScheduleConference(result);
}
catch (RealTimeException rtex)
{
exception = rtex;
}
catch (Exception ex)
{
exception = ex;
}
finally
{
_waitForConferenceScheduling.Set();
}
}, objLocalConfSvc);
_waitForConferenceScheduling.WaitOne();
//Begin Join conference
ConferenceSession objLocalConfSession=this.call.Conversation.ConferenceSession;
try
{
ConferenceJoinOptions joinOptions = new ConferenceJoinOptions() { CanManageLobby = false, JoinMode = JoinMode.Default };
objLocalConfSession.BeginJoin(new RealTimeAddress(confSession.ConferenceUri).Uri, joinOptions,
result => {
try
{
objLocalConfSession.EndJoin(result);
}
catch (Exception ex)
{
exception = ex;
}
finally
{
//Again, for sync. reasons.
_waitForConferenceJoin.Set();
}
}
, this.call.Conversation.ConferenceSession);
// Wait until join completes.new RealTimeAddress(this._conference.ConferenceUri).Uri,
_waitForConferenceJoin.WaitOne();
}
catch (InvalidOperationException ioex)
{
exception = ioex;
}
catch (Exception ex)
{
exception = ex;
}
//Begin Escalation
Conversation objLocalConv= this.call.Conversation;
try
{
objLocalConv.BeginEscalateToConference(
result =>
{
try
{
objLocalConv.EndEscalateToConference(result);
}
catch (Exception ex)
{
exception = ex;
}
finally
{
//Sync It
_waitForEscalation.Set();
}
}
, objLocalConv);
// Wait until escalation completes.
_waitForEscalation.WaitOne();
}
catch (InvalidOperationException ioex)
{
exception = ioex;
}
catch (Exception ex)
{
exception = ex;
}
finally
{
if (exception != null)
{
lyncAgent.Logger.Error( "Error in Conference Migration conf call # " + GetHashCode() + " , Address :" + confSession.ConferenceUri , exception);
}
}
}
Please suggest what could be the possible problem on priority basis.
Thanks in advance.
Does this method reside in an object where it is possible that it will be called by multiple sources at the same time?
If so, using what appears to be a class level variable like _waitForConferenceScheduling could be problematic. Thread A could end up accidentally letting Thread B proceed before Thread B's async action is actually completed. So Thread B could call .BeginEscalate before .EndJoin was called.
When I write UCMA code, I generally use nested callbacks to prevent this type of thing from happening.
Other than that, I'd recommend you run OCSLogger on your application server and the Lync Front End server to gather SIPStack, S3 and Collaboration logs. Looking at the actual SIP messages in detail will provide some clues.
You'd be looking for an INVITE to the conference and the response back to that INVITE.
We managed to detect the reason. It happens if any one in the participant list have already added any contact for meeting in conversation with our endpoint.