Assigning task to mutiple users in scrpted assignment of kaleo worlflow of liferay - workflow

I have created a workflow using kaleo workflow.In this i am trying to assign a task to multiple users,I used groovy script in scripted assignment tag for this.But its not working .when am putting two userid's in user object,first one gets replaced and second user got the approvel task.
also i used users arraylist for this,like roles in kaleo single approver scripted assignment definition.but no use.
How can i manage this.
This is my code.
roles=null;
Connection con = null;
Statement stmt = null;
ResultSet rs = null;
String secondid;
try
{
Class.forName(dbDriver);
con= (Connection) DriverManager.getConnection(dbUrl,dbUser,dbPwd);
stmt = con.createStatement();
rs = stmt.executeQuery("select ap1,ap2 from test where id = '"+userId+"'");
users=new ArrayList<User>();
while (rs.next())
{
println "approverid one"+rs.getInt(1);
println "approverid two"+rs.getInt(2);
user=UserLocalServiceUtil.getUser(Long.parseLong(rs.getString(1)));
user=UserLocalServiceUtil.getUser(Long.parseLong(rs.getString(2)));
users.add(user);
println "array list:"+users;
}
rs.close();
con.close();
}
catch(SQLException e)
{
e.printStackTrace();
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
}
]]>
</script>
<script-language>groovy</script-language>
</scripted-assignment>
when am adding two user id in user tag.also it indicate error in definition while uploading.

In short, use roles. In the control panel, you can specify roles and add users to them. Or, if you'd rather do it programmatically, (Though I would still create the role beforehand) something like this:
(And I'm assuming you can get or have an array of userIds
//Already created array of userIds like
// [10180,10191], etc.
roles=new ArrayList<Role>();
try {
Role r = RoleLocalServiceUtil.getRole(companyId, roleName);
if (r.getType()==RoleConstants.TYPE_REGULAR) {
UserLocalServiceUtil.addRoleUsers(r.getRoleId(), userIds);
} else {
UserGroupRoleLocalServiceUtil.addUserGroupRoles(userIds, groupId, r.getRoleId());
}
roles.add(r);
} catch (SystemException e) {
e.printStackTrace();
} catch (PortalException e) {
e.printStackTrace();
}
Just toss that or some approximation of that or a call to that in your scripted-assignment definition. If you need to, use UserLocalServiceUtil.unsetRoleUsers or something similar to clear out the old users from the role first.

Related

Connectjboss 4 with Firebird 3 via Jaybird 2.214-jdk1.6 [duplicate]

As soon as my code gets to my while(rs.next()) loop it produces the ResultSet is closed exception. What causes this exception and how can I correct for it?
EDIT: I notice in my code that I am nesting while(rs.next()) loop with another (rs2.next()), both result sets coming from the same DB, is this an issue?
Sounds like you executed another statement in the same connection before traversing the result set from the first statement. If you're nesting the processing of two result sets from the same database, you're doing something wrong. The combination of those sets should be done on the database side.
This could be caused by a number of reasons, including the driver you are using.
a) Some drivers do not allow nested statements. Depending if your driver supports JDBC 3.0 you should check the third parameter when creating the Statement object. For instance, I had the same problem with the JayBird driver to Firebird, but the code worked fine with the postgres driver. Then I added the third parameter to the createStatement method call and set it to ResultSet.HOLD_CURSORS_OVER_COMMIT, and the code started working fine for Firebird too.
static void testNestedRS() throws SQLException {
Connection con =null;
try {
// GET A CONNECTION
con = ConexionDesdeArchivo.obtenerConexion("examen-dest");
String sql1 = "select * from reportes_clasificacion";
Statement st1 = con.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY,
ResultSet.HOLD_CURSORS_OVER_COMMIT);
ResultSet rs1 = null;
try {
// EXECUTE THE FIRST QRY
rs1 = st1.executeQuery(sql1);
while (rs1.next()) {
// THIS LINE WILL BE PRINTED JUST ONCE ON
// SOME DRIVERS UNLESS YOU CREATE THE STATEMENT
// WITH 3 PARAMETERS USING
// ResultSet.HOLD_CURSORS_OVER_COMMIT
System.out.println("ST1 Row #: " + rs1.getRow());
String sql2 = "select * from reportes";
Statement st2 = con.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
// EXECUTE THE SECOND QRY. THIS CLOSES THE FIRST
// ResultSet ON SOME DRIVERS WITHOUT USING
// ResultSet.HOLD_CURSORS_OVER_COMMIT
st2.executeQuery(sql2);
st2.close();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
rs1.close();
st1.close();
}
} catch (SQLException e) {
} finally {
con.close();
}
}
b) There could be a bug in your code. Remember that you cannot reuse the Statement object, once you re-execute a query on the same statement object, all the opened resultsets associated with the statement are closed. Make sure you are not closing the statement.
Also, you can only have one result set open from each statement. So if you are iterating through two result sets at the same time, make sure they are executed on different statements. Opening a second result set on one statement will implicitly close the first.
http://java.sun.com/javase/6/docs/api/java/sql/Statement.html
The exception states that your result is closed. You should examine your code and look for all location where you issue a ResultSet.close() call. Also look for Statement.close() and Connection.close(). For sure, one of them gets called before rs.next() is called.
You may have closed either the Connection or Statement that made the ResultSet, which would lead to the ResultSet being closed as well.
Proper jdbc call should look something like:
try {
Connection conn;
Statement stmt;
ResultSet rs;
try {
conn = DriverManager.getConnection(myUrl,"","");
stmt = conn.createStatement();
rs = stmt.executeQuery(myQuery);
while ( rs.next() ) {
// process results
}
} catch (SqlException e) {
System.err.println("Got an exception! ");
System.err.println(e.getMessage());
} finally {
// you should release your resources here
if (rs != null) {
rs.close();
}
if (stmt != null) {
stmt.close();
}
if (conn != null) {
conn.close();
}
}
} catch (SqlException e) {
System.err.println("Got an exception! ");
System.err.println(e.getMessage());
}
you can close connection (or statement) only after you get result from result set. Safest way is to do it in finally block. However close() could also throe SqlException, hence the other try-catch block.
I got same error everything was correct only i was using same statement interface object to execute and update the database.
After separating i.e. using different objects of statement interface for updating and executing query i resolved this error. i.e. do get rid from this do not use same statement object for both updating and executing the query.
Check whether you have declared the method where this code is executing as static. If it is static there may be some other thread resetting the ResultSet.
make sure you have closed all your statments and resultsets before running rs.next. Finaly guarantees this
public boolean flowExists( Integer idStatusPrevious, Integer idStatus, Connection connection ) {
LogUtil.logRequestMethod();
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = connection.prepareStatement( Constants.SCRIPT_SELECT_FIND_FLOW_STATUS_BY_STATUS );
ps.setInt( 1, idStatusPrevious );
ps.setInt( 2, idStatus );
rs = ps.executeQuery();
Long count = 0L;
if ( rs != null ) {
while ( rs.next() ) {
count = rs.getLong( 1 );
break;
}
}
LogUtil.logSuccessMethod();
return count > 0L;
} catch ( Exception e ) {
String errorMsg = String
.format( Constants.ERROR_FINALIZED_METHOD, ( e.getMessage() != null ? e.getMessage() : "" ) );
LogUtil.logError( errorMsg, e );
throw new FatalException( errorMsg );
} finally {
rs.close();
ps.close();
}
A ResultSetClosedException could be thrown for two reasons.
1.) You have opened another connection to the database without closing all other connections.
2.) Your ResultSet may be returning no values. So when you try to access data from the ResultSet java will throw a ResultSetClosedException.
It happens also when using a ResultSet without being in a #Transactional method.
ScrollableResults results = getScrollableResults("select e from MyEntity e");
while (results.next()) {
...
}
results.close();
if MyEntity has eager relationships with other entities. the second time results.next() is invoked the ResultSet is closed exception is raised.
so if you use ScrollableResults on entities with eager relationships make sure your method is run transactionally.
"result set is closed" happened to me when using tag <collection> in MyBatis nested (one-to-many) xml <select> statement
A Spring solution could be to have a (Java) Spring #Service layer, where class/methods calling MyBatis select-collection statements are annotated with
#Transactional(propagation = Propagation.REQUIRED)
annotations being:
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
this solution does not require to set the following datasource properties (i.e., in JBoss EAP standalone*.xml):
<xa-datasource-property name="downgradeHoldCursorsUnderXa">**true**\</xa-datasource-property>
<xa-datasource-property name="resultSetHoldability">**1**</xa-datasource-property>

UA OPC Server data types

For the life of me I can't find out the answer to what I thought would have been a simple question - how to find the data typeof an OPC Node.
I'm writing a UA OPC library which involves creating a subscription and the monitoring/updating of tags within this subscription.
The request to write to a tag comes from an external application and consists of Subscription and tag ID together with an object value. The issue is that this object is invariably a string (don't ask), which needs to be converted to an appropriate data type for the tag. So, I need to find out what data type is associated with the tag. At the moment, the writing fails with a type mismatch exception.
Here's my update code:
//
// Extension methods
public bool Write<T>(long groupID, long tagID, T item)
{
var sub = FindSubscription(groupID);
try
{
if (sub != null)
{
var node = sub.MonitoredItems.FirstOrDefault(m => (long)m.Handle == tagID);
if (node != null)
{
bool result = false;
var nodesToWrite = BuildWriteValueCollection(node.DisplayName, Attributes.Value, item);
StatusCodeCollection results;
DiagnosticInfoCollection diag;
try
{
_session.Write(
requestHeader: null,
nodesToWrite: nodesToWrite,
results: out results,
diagnosticInfos: out diag);
result = CheckReturnValue(results[0]);
}
catch (Exception ex)
{
}
}
}
}
catch (Exception ex)
{
LogMessage(String.Format("Write GroupID {0}, Tag {1}, Value {2}", groupID, tagID, item.ToString()), ex);
}
return false;
}
I've searched for ages to find out how to determine the data type of the node, but without success. So, for a MonitoredItem, how would one go about finding the data type so that I can convert the string to a compatible type?
Thanks
Steve
Read the DataType attribute of the VariableNode in question.

Check whether insertions were successful (MongoDB C# driver)

Suppose "doc" is some document I want to insert into a MongoDB collection and "collection" is the collection I am inserting the document into.
I have something like the following:
try
{
WriteConcern wc = new WriteConcern();
wc.W = 1;
wc.Journal = true;
WriteConcernResult wcResult = collection.Insert(doc, wc);
if (!string.IsNullOrWhiteSpace(wcResult.ErrorMessage) || !wcResult.Ok)
{
return ErrorHandler(...);
}
else
{
return SuccessFunction(...);
}
}
catch (Exception e)
{
return e.Message;
}
Basically, if the insertion fails for any reason (other than hardware no longer working properly) I want to handle it (through the ErrorHandler function or the catch clause), while if it succeeds I want to call SuccessFunction.
My question: Is the above code sufficient for error checking purposes? In other words, will all failed insertions be caught, so that SuccessFunction is never called in those situations?
You don't even need to do any checking. collection.Insert will throw an exception if the write was not successful when you are using any write concern other than unacknowledged.
If you want to know if an error occured, you need to catch a WriteConcernException.

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.

Monotouch data sync - why does my code sometimes cause sqlite errors?

I have the following calls (actually a few more than this - it's the overall method that's in question here):
ThreadPool.QueueUserWorkItem(Database.Instance.RefreshEventData);
ThreadPool.QueueUserWorkItem(Database.Instance.RefreshLocationData);
ThreadPool.QueueUserWorkItem(Database.Instance.RefreshActData);
1st point is - is it OK to call methods that call WCF services like this? I tried daisy chaining them and it was a mess.
An example of one of the refresh methods being called above is (they all follow the same pattern, just call different services and populate different tables):
public void RefreshEventData (object state)
{
Console.WriteLine ("in RefreshEventData");
var eservices = new AppServicesClient (new BasicHttpBinding (), new EndpointAddress (this.ServciceUrl));
//default the delta to an old date so that if this is first run we get everything
var eventsLastUpdated = DateTime.Now.AddDays (-100);
try {
eventsLastUpdated = (from s in GuideStar.Data.Database.Main.Table<GuideStar.Data.Event> ()
orderby s.DateUpdated descending
select s).ToList ().FirstOrDefault ().DateUpdated;
} catch (Exception ex1) {
Console.WriteLine (ex1.Message);
}
try {
eservices.GetAuthorisedEventsWithExtendedDataAsync (this.User.Id, this.User.Password, eventsLastUpdated);
} catch (Exception ex) {
Console.WriteLine ("error updating events: " + ex.Message);
}
eservices.GetAuthorisedEventsWithExtendedDataCompleted += delegate(object sender, GetAuthorisedEventsWithExtendedDataCompletedEventArgs e) {
try {
List<Event> newEvents = e.Result.ToList ();
GuideStar.Data.Database.Main.EventsAdded = e.Result.Count ();
lock (GuideStar.Data.Database.Main) {
GuideStar.Data.Database.Main.Execute ("BEGIN");
foreach (var s in newEvents) {
GuideStar.Data.Database.Main.InsertOrUpdateEvent (new GuideStar.Data.Event {
Name = s.Name,
DateAdded = s.DateAdded,
DateUpdated = s.DateUpdated,
Deleted = s.Deleted,
StartDate = s.StartDate,
Id = s.Id,
Lat = s.Lat,
Long = s.Long
});
}
GuideStar.Data.Database.Main.Execute ("COMMIT");
LocationsCount = 0;
}
} catch (Exception ex) {
Console.WriteLine("error InsertOrUpdateEvent " + ex.Message);
} finally {
OnDatabaseUpdateStepCompleted (EventArgs.Empty);
}
};
}
OnDatabaseUpdateStepCompleted - just iterates an updateComplete counter when it's called and when it knows that all of the services have come back ok it removes the waiting spinner and the app carries on.
This works OK 1st time 'round - but then sometimes it doesn't with one of these: http://monobin.com/__m6c83107d
I think the 1st question is - is all this OK? I'm not used to using threading and locks so I am wandering into new ground for me. Is using QueueUserWorkItem like this ok? Should I even be using lock before doing the bulk insert/update? An example of which:
public void InsertOrUpdateEvent(Event festival){
try {
if (!festival.Deleted) {
Main.Insert(festival, "OR REPLACE");
}else{
Main.Delete<Event>(festival);
}
} catch (Exception ex) {
Console.WriteLine("InsertOrUpdateEvent failed: " + ex.Message);
}
}
Then the next question is - what am I doing wrong that is causing these sqlite issues?
w://
Sqlite is not thread safe.
If you want to access Sqlite from more than one thread, you must take a lock before you access any SQLite related structures.
Like this:
lock (db){
// Do your query or insert here
}
Sorry, no specific answers, but some thoughts:
Is SqlLite even threadsafe? I'm not sure - it may be that it's not (to the wrapper isn't). Can you lock on a more global object, so no two threads are inserting at the same time?
It's possible that the MT GC is getting a little overenthusiastic, and releasing your string before it's been used. Maybe keep a local reference to it around during the insert? I've had this happen with view controllers, where I had them in an array (tabcontrollers, specificially), but if I didn't keep an member variable around with the reference, they got GC'ed.
Could you get the data in a threaded manner, then queue everything up and insert them in a single thread? Atleast as a test anyway.