Can I read a notes.ini parameter from a different server? - lotus-domino

I wonder if I am able to open a server connection in an Agent running on server A to access the notes.ini of server B. I want to read check for a parameter in that notes.ini. Is that possible via coding?
I am aware of session.getEnvironment methods but they access the notes.ini of the server where the Agent is running on (or the Notes client).
Any ideas?
Used the solution from Egor:
/**
* checks for notes.ini value for
* #return
* #throws NotesException
*/
private boolean checkNoSessionInfo(String serverName) {
boolean result = false;
try {
String console = session.sendConsoleCommand(serverName, "show config *");
result = console.contains("LOG_DISABLE_SESSION_INFO=1");
} catch (NotesException e) {
oli.logErrorEx(e, "Could not check if server's user session info was disabled", OpenLogItem.SEVERITY_MEDIUM, null);
}
return result;
}
Works like a charm! :-)
Thank you all!

Try to add the Server A to Trusted Servers of Server B server document in names.nsf (and maybe few other fields on security tab). After I'd just use Session.sendConsoleCommand method (use command "show config *". See documentation for reference: https://www-01.ibm.com/support/knowledgecenter/SSVRGU_9.0.1/com.ibm.designer.domino.main.doc/H_SENDCONSOLECOMMAND_METHOD_SESSION_JAVA.html

There are couple of issues with this:
You would need a NotesSession object of server B on server A which is not possible.
Unfortunately you can not execute agent on server B from server A, it just does not work:
02.03.2016 10:51:05 Agent 'TestRunAgent' error: Cannot access foreign servers when running on a server)
Your best bet would be a HTTP call from server A to server B, this way the server B agent can return HTML with required property.
You can return simple HTML body by using print keyword, it conveniently prints to HTTP response.

In theory, I think it should be possible to do this by calling a web service, custom REST servlet or XAgent on server B. That would return the information you need.

Related

User destinations in a multi-server environment? (Spring WebSocket and RabbitMQ)

The documentation for Spring WebSockets states:
4.4.13. User Destinations
An application can send messages targeting a specific user, and Spring’s STOMP support recognizes destinations prefixed with "/user/" for this purpose. For example, a client might subscribe to the destination "/user/queue/position-updates". This destination will be handled by the UserDestinationMessageHandler and transformed into a destination unique to the user session, e.g. "/queue/position-updates-user123". This provides the convenience of subscribing to a generically named destination while at the same time ensuring no collisions with other users subscribing to the same destination so that each user can receive unique stock position updates.
Is this supposed to work in a multi-server environment with RabbitMQ as broker?
As far as I can tell, the queue name for a user is generated by appending the simpSessionId. When using the recommended client library stomp.js this results in the first user getting the queue name "/queue/position-updates-user0", the next gets "/queue/position-updates-user1" and so on.
This in turn means the first users to connect to different servers will subscribe to the same queue ("/queue/position-updates-user0").
The only reference to this I can find in the documentation is this:
In a multi-application server scenario a user destination may remain unresolved because the user is connected to a different server. In such cases you can configure a destination to broadcast unresolved messages to so that other servers have a chance to try. This can be done through the userDestinationBroadcast property of the MessageBrokerRegistry in Java config and the user-destination-broadcast attribute of the message-broker element in XML.
But this only makes the it possible to communicate with a user from a different server than the one where the web socket is established.
I feel I'm missing something? Is there anyway to configure Spring to be able to safely use MessagingTemplate.convertAndSendToUser(principal.getName(), destination, payload) in a multi-server environment?
If they need to be authenticated (I assume their credentials are stored in a database) you can always use their database unique user id to subscribe to.
What I do is when a user logs in they are automatically subscribed to two topics an account|system topic for system wide broadcasts and account|<userId> topic for specific broadcasts.
You could try something like notification|<userid> for each person to subscribe to then send messages to that topic and they will receive it.
Since user Ids are unique to each user you shouldn't have an issue within a clustered environment as long as each environment is hitting the same database information.
Here is my send method:
public static boolean send(Object msg, String topic) {
try {
String destination = topic;
String payload = toJson(msg); //jsonfiy the message
Message<byte[]> message = MessageBuilder.withPayload(payload.getBytes("UTF-8")).build();
template.send(destination, message);
return true;
} catch (Exception ex) {
logger.error(CommService.class.getName(), ex);
return false;
}
}
My destinations are preformatted so if i want to send a message to user with id of one the destinations looks something like /topic/account|1.
Ive created a ping pong controller that tests websockets for users who connect to see if their environment allows for websockets. I don't know if this will help you but this does work in my clustered environment.
/**
* Play ping pong between the client and server to see if web sockets work
* #param input the ping pong input
* #return the return data to check for connectivity
* #throws Exception exception
*/
#MessageMapping("/ping")
#SendToUser(value="/queue/pong", broadcast=false) // send only to the session that sent the request
public PingPong ping(PingPong input) throws Exception {
int receivedBytes = input.getData().length;
int pullBytes = input.getPull();
PingPong response = input;
if (pullBytes == 0) {
response.setData(new byte[0]);
} else if (pullBytes != receivedBytes) {
// create random byte array
byte[] data = randomService.nextBytes(pullBytes);
response.setData(data);
}
return response;
}

SSRS ReportViewer fails when using parameters

I'm using the ReportViewer control in VS2010.
In my local and development environments when I use:
ReportParameter[] toReportParameterList = new ReportParameter[1];
toReportParameterList[0] = new ReportParameter("intApplicationID", Session["APPLICATION_ID"]);
rvFinancialSummaryReport.ServerReport.SetParameters(toReportParameterList);
Everything works properly.
When I try to do the exact same thing in my Staging/Beta environment, I get an HTTP 401 not authorized error.
When I comment out those three lines, the report parameter section loads and I can get the report correctly when I type in the parameter.
Any idea why trying to pass parameters via the server report, I get an HTTP 401?
EDIT
I should probably add that I am sending credential information as such:
string tsUserNameDomain = ConfigurationManager.AppSettings["ReportUserName"].ToString();
string tsDomain = tsUserNameDomain.Substring(0, tsUserNameDomain.IndexOf("\\"));
string tsUsername = tsUserNameDomain.Substring(tsUserNameDomain.IndexOf("\\") + 1);
string tsPassword = ConfigurationManager.AppSettings["ReportPassword"].ToString();
ReportViewerCredentials toCredentials = new ReportViewerCredentials(tsUsername, tsPassword, tsDomain);
rvFinancialSummaryReport.ServerReport.ReportServerCredentials = toCredentials;
This works as long as there is no parameters set.
EDIT
Just to Reiterate... when I comment this line:
rvFinancialSummaryReport.ServerReport.SetParameters(toReportParameterList);
It works...
When I uncomment this line:
rvFinancialSummaryReport.ServerReport.SetParameters(toReportParameterList);
I get an HTTP 401: Unauthorized.
EDIT
Another detail... my SSRS server is HTTP, my IIS is HTTPS...
It would seem that the order of operations in this scenario is important.
After some extensive testing on a local server, I realized that after the parameter value was set, when I went to set the credential values the parameter array object on the server report was coming back as null.
I moved the instantiation of the credential object to the top of the page load, and now everything is working properly.

CloudFileShare CreateIfNotExistsAsync().Wait method throwing The remote server returned an error: (400) Bad Request

I am trying to use the Azure File Service preview as a mapped drive between my two instances of a cloud service and I came across the following blog post with some details:
http://blogs.msdn.com/b/windowsazurestorage/archive/2014/05/12/introducing-microsoft-azure-file-service.aspx?CommentPosted=true#commentmessage
I have signed up for the preview version of the storage account and created a new storage account and verified that the file endpoint is included. I then use the following code to attempt to create the share programmatically:
CloudStorageAccount account = CloudStorageAccount.Parse(System.Configuration.ConfigurationManager.AppSettings["SecondaryStorageConnectionString"].ToString());
CloudFileClient client = account.CreateCloudFileClient();
CloudFileShare share = client.GetShareReference("SCORM");
try
{
share.CreateIfNotExistsAsync().Wait();
}
catch (AggregateException e)
{
var test = e.Message;
var test1 = e.InnerException.Message;
}
On the CreateIfNotExistsAsync().Wait() method I am getting a Aggregate exception and when I look at the Inner details it just says The remote server returned an error: (400) Bad Request.
Your comment is the correct answer. Please refer to Naming and Referencing Shares, Directories, Files, and Metadata article for more information.

My SQL Server Can Only Handle 2 players?

I am developing a game using TCP. The clients send and listen the server using TCP. When the server receives a request, then it consults the database (SQL Server Express / Entity Framework) and sends a response back to client.
I'm trying to make a MMORPG, so I need to know all the players locations frequently, so I used a System.Timer to ask the server the location of the players around me.
The problem:
If I configure the timer to trigger for every 500ms a method that asks the server the currently players location, then I can open 2 instances of the client app, but it's laggy. If I configure to trigger for every 50ms, then when I open the second instance, the SQL Server throws this exception often:
"The connection was not closed. The connection's current state is open."
I mean, what the hell? I know I am requesting A LOT of things to the database in a short period, but how do real games deals with this?
Here is one code that throws the error when SQL Server seems to be overloaded (second line of the method):
private List<CharacterDTO> ListAround()
{
List<Character> characters = new List<Character>();
characters = ObjectSet.Character.AsNoTracking().Where(x => x.IsOnline).ToList();
return GetDto(characters);
}
Your real problem is ObjectSet is not Thread Safe. You should be creating a new database context inside ListAround and disposing it when you are done with it, not re-using the same context over and over again.
private List<CharacterDTO> ListAround()
{
List<Character> characters = new List<Character>();
using(var ObjectSet = new TheNameOfYourDataContextType())
{
characters = ObjectSet.Character.AsNoTracking().Where(x => x.IsOnline).ToList();
return GetDto(characters);
}
}
I resolved the problem changing the strategy. Now I don't update the players positions in real time to the database. Instead, I created a list (RAM memory) in the server, so I manage only this list. Eventually I will update the information to the database.

Can Flash be integrated with SQL?

Can Flash be used together with SQL? I have a Flash form and I need to connect it to SQL. If there is any example on the net about this topic. I can't find it.
You don't use ActionScript directly with an SQL database. Instead you make http requests from ActionScript to a server, specifying the correct parameters. A typical opensource setup, is a PHP script communicating with a MySQL DB, but you can use Java with Oracle, Ruby with CouchDB, .NET with SQL or any other possible configuration. The important point is that you must be able to call a server script and pass variables... typically a Restful setup.
Once your PHP script has been properly configured, you can use http POST or http GET to send values from ActionScript.
PHP:
<?php
$updateValue = $_POST["updateValue"];
$dbResult = updateDB( $updateValue ); //This should return the db response
echo( $dbResult );
?>
To call this script from ActionScript, you need to create a variables object.
var variables:URLVariables = new URLVariables();
variables.updateValue = "someResult";
The variable name .updateValue, must match the php variable exactly.
now create a URLRequest Object, specifying the location of your script. For this example the method must be set to POST. You add the variable above to the data setter of the request.
var request:URLRequest = new URLRequest( "yourScript.php" );
request.method = URLRequestMethod.POST;
request.data = variables;
Now create a URLLoader and add an event listener. Do not pass the request created above to the constructor, but to the load method.
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, onComplete );
loader.load( request );
The handler would look something like this.
private function onComplete( e:Event ) : void
{
trace( URLLoader( e.target ).data.toString() );
}
This example shows how to update and receive a response from a server / db combo. However, you can also query a DB through the script and parse the result. So in the PHP example above, you can output JSON, XML or even a piped string, and this can be consumed by ActionScript.
XML is a popular choice, as ActionScript's e4x support treats XML like a native object.
To treat the response above like an XML response, use the following in the onComplete handler.
private function onComplete( e:Event ) : void
{
var result:XML = XML( URLLoader( e.target ).data );
}
This will throw an error if your xml is poorly formed, so ensure the server script always prints out valid XML, even if there is a DB error.
The problem with this is giving someone a flash file that directly accesses SQL server is very insecure. Even if it's possible, which I have seen SOCKET classes out there to do so for MySQL (though never used it), allowing users to remotely connect to your DB is insecure as the user can sniff the login information.
In my opinion, the best way to do this is to create a Client/Server script. You can easily do this with PHP or ASP.net by using SendAndLoad to send the data you need to pass to SQL via POST fields. You can then send back the values in PHP with:
echo 'success='.+urlencode(data);
With this, flash can access the data via the success field.
I don't personally code flash but I work with a company who develops KIOSK applications for dozens of tradeshow companies, and my job is to store the data, return it to them. This is the method we use. You can make it even cleaner by using actual web services such as SOAP, but this method gets the job done if its just you using it.
You should look into Zend Amf or even the Zend Framework for server side communication with Flash. As far as I know Zend Amf is the fastest way to communicate with PHP ( therefore your database ) also you can pass & return complex Objects from the client to the server and vice versa.
Consider this , for instance. You have a bunch of data in your database , you implement functions in ZF whereas this data is formatted and set as a group of Value Objects. From Flash , you query ZF , Zf queries the database , retrieve & formats your data, return your Value Objects as a JSON string ( for instance ). In Flash, you retrieve you JSON string , decode it and assign your Value Objects to whatever relevant classes you have.
There are plenty of tutorials out there regarding Flash communication with the Zend Framework.
Here's an example:
http://gotoandlearn.com/play.php?id=90