Trying to use adminp.DeleteReplicas followed by adminp.ApproveReplicaDeletion gives error "Invalid Approval Request note" - lotus-domino

I am trying delete a database and any associated replicas using LotusScript adminp calls. This is basically the code:
Dim session As New NotesSession
Dim adminp As NotesAdministrationProcess
Set adminp = session.CreateAdministrationProcess("Software_Server")
noteid$ = adminp.DeleteReplicas("Software_Server", "Guys1")
If noteid$ <> "" Then
Call adminp.ApproveReplicaDeletion(noteid$) 'This is where the error is thrown
End If
The first adminp call is successful and returns a noteid, and if I look in the admin requests database can see the document. The next call to ApproveReplicateDeletion results in the error "Invalid Approval Request note"
The documentation doesn't contain any examples for the adminp approve methods. I have a feeling that maybe the second request cannot be called until much later when adminp has processed the first request?
Also related question, do I only have to make this request on a single server and it will remove replicas on all other servers, or do I need to make this request for each server?

So this is a bit more complicated than the help gives any indication of, and might explain why I couldn't find any examples on the internet on how to do it. So the Workflow for using AdminP is as Follows:
Create the request to get the noteID for the initial noteid of the DeleteReplicas request. The returned noteID is not the one that is used to approve the delete replica request. noteid$ = adminp.DeleteReplicas("Software_Server", "Guys1")
This creates a document in the admin.nsf db for the initial request, but the approval docs don't yet exist, for the server to create those, the adminp process must run.
So in the code send a Console command to the Server "tell adminp process now"
Sleep the agent for a few seconds to give adminp time to process the request (this will also fire off any other waiting adminp requests unfortunately)
Now new documents will have been created in the admin database, that are awaiting approval by an admin. These documents contain the noteids that should be sent the approvereplicadeletion
To get them, first lookup the notes document by the noteID in the admin db obtained in step 1
Using that noteid for the document, get the field value ProxyOriginatingRequestUNID from the document.
using this UNID value, perform a getalldocumentsbykey on the view ($AllRequestsbyOriginatingUNID)
if the returned document has a ProxyAction field with a value of "82", this is an approval request document. This documents noteid can be passed to approveReplicaDeletion to have adminp remove the database next time it processes requests.
You can either send a console command to process adminp again, or just wait for the database deletions etc. to happen next time around.

Related

How to execute API update password in jMeter Load test

I'm a newbie with jMeter. I would to ask opinion and guide from forum to point me to right direction. I've have been tasked to do Load test on API Update Password. I have try several approach I can think off plus with the info from internet, but failed to have successful execution.
Below is my most successful approach but still failed after 3-5 minutes execution.
Test Plan
CSV Data Set Config - (Default setting, contain 500 member id's)
Thread Group (Setting: 100vu/100s, Loop: Infinite, Duration: 1 hour)
Counter1 (Old Password) example: abc001
Counter2 (New Password) example: abc002
Http Request (Get Token) {
Old Password
Member Id } --> Send token to next http request
Http Request (Update Password) {
Old Password
New Password
Confirm New Password }
The both Counter have increment of 1 and checked for Track counter independently for each user.
Based on my logic, it should be able to handle the execution as below.
Member1 (abc001,abc002) > Member1 (abc002,abc003) > Member1 (abc003,abc004) > etc
But in reality if failed. I also have try using JSR223 for counter, but still failed. Please help me by pointing me to correct direction how to execute this. I hope anyone can help! Thanks
In its current form your question doesn't make a lot of sense, it's unclear to me what is expected behaviour, what is the actual one, how exactly your test is failing and so on.
Try running it with Debug Sampler added so you would see the JMeter Variables with their respective values.
If it doesn't help - come up with a minimal test plan which shows the issue you're having using i.e. Dummy Sampler and indicate what's wrong and how it should behave according to your expectations.

How to pass UserName & Password in IBMMQ Client Message using .NET or C++ Program

I am writing a .NET Console application, our goal is keep a message on the queue and read the message. the message header should contain User Name & Password. I try to pass the Message with below code it is not working.
hashTable.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_CLIENT);
hashTable.Add(MQC.HOST_NAME_PROPERTY, strServerName);
hashTable.Add(MQC.CHANNEL_PROPERTY, strChannelName);
hashTable.Add(MQC.PORT_PROPERTY, 1414);
hashTable.Add(MQC.USER_ID_PROPERTY, "XXXXXX");
hashTable.Add(MQC.PASSWORD_PROPERTY, "XXXXXX");
hashTable.Add(MQC.USE_MQCSP_AUTHENTICATION_PROPERTY, true);
queueManager = new MQQueueManager(strQueueManagerName,hashTable);
queue = queueManager.AccessQueue(requestQueue, MQC.MQOO_OUTPUT + MQC.MQOO_FAIL_IF_QUIESCING);
requestMessage = new MQMessage();
requestMessage.WriteString(StrAPICMessage);
requestMessage.Format = MQC.MQFMT_STRING;
requestMessage.MessageType = MQC.MQMT_REQUEST;
requestMessage.Report = MQC.MQRO_COPY_MSG_ID_TO_CORREL_ID;
requestMessage.ReplyToQueueName = responseQueue;
requestMessage.ReplyToQueueManagerName = strQueueManagerName;
queuePutMessageOptions = new MQPutMessageOptions();
queue.Put(requestMessage, queuePutMessageOptions);
In the Message Descriptor it is taking the default value mentioned MQ Server. it is not takeing my UserName "XXXXX"
I have tried using the CSICS Bridge header also unable to send the message with my application Service account + Password.
help me on this scenario.
See "MQCSP authentication mode" here: https://www.ibm.com/docs/en/ibm-mq/latest?topic=authentication-connection-java-client
It says:
In this mode, the client-side user ID is sent as well as the user ID and password to be authenticated, so you are able to use ADOPTCTX(NO). The user ID and password are available to a server-connection security exit in the MQCSP structure that is provided in the MQCXP structure.
"client-side user ID" means the UserId that the application is running under. Therefore, if you are authenticating with a different UserId than the one that the application is running under.
Therefore, you (or your MQAdmin) will need to change ADOPTCTX to YES.
Your program works fine for me, when I fill in the correct values for my qmgr connection.
Except for one change I made: instead of TRANSPORT_MQSERIES_CLIENT I used TRANSPORT_MQSERIES_MANAGED. That keeps everything in the managed .Net space.
Without that change, I was actually getting MQRC_UNSUPPORTED_FUNCTION during the connection which typically means either some kind of mismatch between versions of interfaces, or it couldn't find the C dll that underpins the unmanaged environment. And I wasn't going to take time to dig into that further.
Running amqsbcg against the output queue, I see
UserIdentifier : 'mqguest '
which is the id I had set in the USER_ID_PROPERTY.

Counting the number of response codes in JMeter 4.0

I run some load tests (all endpoints) and we do have a known issue in our code: if multiple POST requests are sent in the same time we do get a duplicate error based on a timestamp field in our database.
All I want to do is to count timeouts (based on the message received "Service is not available. Request timeout") in a variable and accept this as a normal behavior (don't fail the tests).
For now I've added a Response Assertion for this (in order to keep the tests running) but I cannot tell if or how many timeout actually happen.
How can I count this?
Thank you
I would recommend doing this as follows:
Add JSR223 Listener to your Test Plan
Put the following code into "Script" area:
if (prev.getResponseDataAsString().contains('Service is not available. Request timeout')) {
prev.setSampleLabel('False negative')
}
That's it, if sampler will contain Service is not available. Request timeout in the response body - JMeter will change its title to False negative.
You can even mark it as passed by adding prev.setSuccessful(false) line to your script. See Apache Groovy - Why and How You Should Use It article fore more information on what else you can do with Groovy in JMeter tests
If you just need to find out the count based on the response message then you can save the performance results in a csv file using simple data writer (configure for csv only) and then filter csv based on the response message to get the required count. Or you can use Display only "errors" option to get all the errors and then filter out based on the expected error message.
If you need to find out at the runtime then you can use aggregate report listener and use "Errors" checkbox to get the count of failure but this will include other failures also.
But, if you need to get the count at the run time to use it later then it is a different case. I am assuming that it is not the case.
Thanks,

RESTful API - Ignore invalid PUT request?

I build a simple API for a bookmark manager, where the URL of record should only be stored once. Record 001 with www.example.com already exists beside record 002 with www.stuff.com.
If I update record 002 with the url www.example.com, should I ignore the complete request and send back an error message or is it better to update all valid parts and just send an errror message, that says, that the url/bookmark already exists?
With a PUT, the expectation is that the entire operation will succeed or fail:
The PUT method requests that the state of the target resource be
created or replaced with the state defined by the representation
enclosed in the request message payload. A successful PUT of a given
representation would suggest that a subsequent GET on that same
target resource will result in an equivalent representation being
sent in a 200 (OK) response.
https://www.rfc-editor.org/rfc/rfc7231#section-4.3.4
You should send an error for an invalid PUT (since the URL already exists and cannot be in two records at the same time) and not apply any of the other updates.
For partial updates you might consider a PATCH, but in this case I don't think you would go this direction since:
If the entire patch document
cannot be successfully applied, then the server MUST NOT apply any of
the changes.
https://www.rfc-editor.org/rfc/rfc5789

ActiveRecord (Rails 3.0.1): API Can't Handle Too Many Requests?

I have an API that services a web-based plugin for processing email. The API is responsible for two things:
Creating SessionIDs so the plugin can setup a dynamic link; and
Once an email is sent, for receiving that SessionID, the email recipients and subject line, to store the information into a new session.
Imagine the scenario where the plugin sends a request to the API:
PUT http://server.com/api/email/update/<SessionID> -d "to=<address1,address2>&subject=<subject>"
In testing this works fine: the data is saved normally. However, the plugin can't help but send that request several times a second, bombarding my server with identical requests. The result is that I get my EmailSession object saving multiple copies of the recipients.
In terms of my database schema, I have an EmailSession model, which has_many EmailRecipients.
Here's the relevant part of the update method in my API's controller:
#email_session = EmailSession.find_or_create_by_session_id(:session_id => params[:id], :user_id => #user.id)
if opts[:params][:cm_to].blank? == false
self.email_recipients.destroy_all
unless opts[:params][:cm_to].blank?
opts[:params][:cm_to].strip.split(",").each do |t|
self.email_recipients << EmailRecipient.create(:recipient_email => t)
end
end
end
Admittedly, the "find_or_create" dynamic method is new to me, and I wonder if there's something about that screwing up the works.
The symptoms I'm seeing include:
ActiveRecord errors complaining about attempts to save a non-unique key into the database (I have an index on the SessionId)
Duplicate recipients ending up in the EmailRecipients collection
In the case of multiple users employing the plugin, I get recipients from other emails ending up in the wrong email session collections.
I've attempted to employ delayed_job to attempt to serialize these requests somehow. I haven't had much luck with it thanks to various bugs in the current release. But I'm wondering if there's a more fundamental problem with my approach to this solution? Any help would be appreciated.
I'm still not sure I understand what you're doing, but here's my advice.
First off I don't think you are using find_or_create_by properly. This method has slightly confusing semantics (which is why 3.2 introduces some clearer alternatives) but as it stands it isn't using the user_id to find the record (although it is setting user_id if a record is created). I don't think this is what you wanted. Instead use find_or_create_by_session_id_and_user_id
This can still raise a duplicate key error since in between find_or_create checking and it creating the record there is time for someone else to create the record. If you weren't doing anything other than creating email session rows the  rescuing this duplicate key error and then retrying should take of that: on the retry you'll find the row that blocked your insert.
However when you then go on to add recipients you still have a potential issue because 2 things could be trying to remove recipients and add them to the same email session at the same time. This might be a good usecase for pessimistic locking. 
begin
EmailSession.transaction do
session = EmailSession.lock(true).find_or_create_by_bla_bla(...)
# use the session object here, add recipients etc.
end
rescue ActiveRecord::StatementInvalid => e
end
What is happening here is that when the email session is retrieved from the db, the row is locked (even if it doesn't exist yet - effectively you can lock the gap where the record would go). This means that anyone else wanting to add recipients or do any other manipulation has to wait for the lock to be released. Locks last as long as the transaction in which they occur lasts  so all your work should happen in here (even if in the second part you are not actually changing the email session object any more).
You may end up with deadlocks - I don't know what else is going on in your app but you should be prepared for them if you are using transactions. That's what the rescue block is for: if the error message looks like a deadlock then you should probably retry some limited number of times.
Locks are (at least on MySQL) row level locks: as long as you have an index on session_id,user_id then just because one of your instance has one email session object locked doesn't stop another instance from using another one.