I am checking 'n' number of servers every minute, if any servers are down a mail is triggered to an user with the server name that is down. The issue I am facing is that if more than one server is down I am getting only one server name that is down. How to get the name of all servers that are down.
obj = dataAccess.getServers(); //getting the status and links of all servers
MailServer sender = new MailServer(From,Password);
List<String> downserver = new ArrayList();
for (Map<String, String> objs : obj) { //Iterating for each server
serverstatus = objs.get("status");
if (serverstatus.equals("DOWN")) {
servername = objs.get("name");
statusserver=objs.get("status");
}
downserver.add(servername);
if(!(servername.equals(null))){
sender.sendMail("Server Status",downserver.get(i),From,To)
}
Without checking for reasonability of your code or trying to improve anything, your code should look a little more like the following to (at least) come close to what you are trying:
servers = dataAccess.getServers();
MailServer sender = new MailServer(From,Password);
List<String> downservers = new ArrayList();
for (Map<String, String> server : servers) {
serverstatus = server.get("status");
servername = server.get("name");
if (serverstatus.equals("DOWN") && servername != null) {
downservers.add(servername);
}
}
StringBuilder sb = new StringBuilder();
String sep = "";
for (server : downservers) {
sb.Append(sep).Append(server);
sep = ", ";
}
sender.sendMail("Server Status", sb.ToString(), From, To);
or short with one iteration:
MailServer sender = new MailServer(From,Password);
StringBuilder sb = new StringBuilder();
String sep = "";
for (Map<String, String> server : dataAccess.getServers()) {
String servername = server.get("name");
if (server.get("status").equals("DOWN") && servername != null) {
sb.Append(sep).Append(servername);
sep = ", ";
}
}
sender.sendMail("Server Status", sb.ToString(), From, To);
If you want to do null check on a string, you should not do servername.equals(null), if servername is null, it throws a NullPointerException. You can use if (servername != null).
You can also use the variable servername instead of downserver.get(i) in sendMail method.
Check if you are getting NullPointerException or some other exception.
Related
I am attempting to enumerate all the groups in our Active Directory from Java. There are quite a lot, so I get a SizeLimitExceededException after 1000 results. I am attempting to use PagedResultsControl, with my code very closely modelled on all the examples out on the web, and it sort-of-works, in that it no longer throws the SizeLimitExceededException, and returns a number of results matching the specified page size (provided that isn't greater than 1000).
However, the next step is to get the cookie from the response and use it to get the next page, and my issue is that there is no PagedResultsResponseControl in the context after the call to search(). In fact getResponseControls() returns null.
I have searched extensively and can't seem to find anyone else reporting this issue, and I'm pretty much stuck here. So what am I doing wrong? Why don't I get a PagedResultsResponseControl?
Our domain is running on Windows Server 2016 and I have reduced my code down to the following test case:
public class PagingTest {
public static void main(String[] args) throws Exception {
Hashtable<String, String> env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.SECURITY_PRINCIPAL, "username");
env.put(Context.SECURITY_CREDENTIALS, "password");
env.put(Context.PROVIDER_URL, "ldap://campus.uni.ac.uk/DC=campus,DC=uni,DC=ac,DC=uk");
LdapContext adContext = new InitialLdapContext(env, null);
// Set up search controls.
SearchControls searchControl = new SearchControls();
searchControl.setSearchScope(SearchControls.SUBTREE_SCOPE);
String[] attributesToFetch = {"cn"};
searchControl.setReturningAttributes(attributesToFetch);
// Set up a paged search.
final int pageSize = 500;
byte[] cookie = null;
adContext.setRequestControls(new Control[]{
new PagedResultsControl(pageSize, Control.CRITICAL)
});
// Do the search.
int count = 0;
boolean finished = false;
while (!finished) {
NamingEnumeration<SearchResult> records
= adContext.search("OU=Groups", "objectClass=group", searchControl);
// Examine the page's results control response and act accordingly.
Control[] controls = adContext.getResponseControls();
if (controls != null) {
for (int i = 0; i < controls.length; ++i) {
if (controls[i] instanceof PagedResultsResponseControl) {
PagedResultsResponseControl prrc =
(PagedResultsResponseControl) controls[i];
cookie = prrc.getCookie();
if (cookie == null) {
finished = true;
}
}
}
} else {
cookie = null;
finished = true;
}
// Process the page of results.
while (records != null && records.hasMore()) {
SearchResult sr = records.next();
Attributes attribs = sr.getAttributes();
BasicAttribute ba = (BasicAttribute) attribs.get("cn");
String cn = (String) ba.get();
System.out.println(cn);
++count;
}
// Re-activate paged results with the new cookie.
adContext.setRequestControls(new Control[]{
new PagedResultsControl(pageSize, cookie, Control.CRITICAL)
});
}
System.out.println("Found " + count + " groups");
}
}
Maybe your ldap server does not support paging query, you can use ldapsearch command like this:
ldapsearch -H ldap://xxxx:389 -x -D "uid=zhangsan,ou=employee,dc=test,dc=com" -W -b "" -s base -a always "(objectClass=*)" "supportedControl"
If the return values contain 1.2.840.113556.1.4.319, it shows your ldap server supports paging query.
I would like to get all the keys from Redis cluster using Jedis with the following code snippet:
public void testRedis() {
String key = "*";
ScanParams scanParams = new ScanParams().count(1000).match("{*}");
String cur = SCAN_POINTER_START;
do {
ScanResult<String> scanResult = getRedisCluster().scan(cur, scanParams);
scanResult.getResult().stream().forEach(System.out::println);
cur = scanResult.getStringCursor();
} while (!cur.equals(SCAN_POINTER_START));
}
My problem is that it doesn't return any result with this solution. Even if I specify the matching pattern for an existing key it's still not working.
I tried to get specific keys with get command it returns value without any error, so the connection seems good.
Any suggestion?
(One of my clue is that match parameter waiting for "curly-brackets" so I had to add there, but I haven't seen using this like that on internet anywhere.)
You can get all keys of a cluster by getting keys from each node and unifying them.
getClusterNodes() method will come in handy which returns a map of all cluster nodes.
Here is an implementation using SCAN, similar to your attempt:
public void testRedis() {
ScanParams scanParams = new ScanParams().count(1000);
Set<String> allKeys = new HashSet<>();
getRedisCluster().getClusterNodes().values().forEach((pool) -> {
String cur = ScanParams.SCAN_POINTER_START;
do {
try (Jedis jedis = pool.getResource()) {
ScanResult<String> scanResult = jedis.scan(cur, scanParams);
allKeys.addAll(scanResult.getResult());
cur = scanResult.getStringCursor();
}
} while (!cur.equals(ScanParams.SCAN_POINTER_START));
});
allKeys.stream().forEach(System.out::println);
}
Update: You can check conditions to stop iteration right after getting at least 1000 keys.
public void testRedis() {
ScanParams scanParams = new ScanParams().count(1000);
Set<String> allKeys = new HashSet<>();
for (JedisPool pool : getRedisCluster().getClusterNodes().values()) {
String cur = ScanParams.SCAN_POINTER_START;
do {
try (Jedis jedis = pool.getResource()) {
ScanResult<String> scanResult = jedis.scan(cur, scanParams);
allKeys.addAll(scanResult.getResult());
cur = scanResult.getStringCursor();
}
if (allKeys.size() >= 1000) break;
} while (!cur.equals(ScanParams.SCAN_POINTER_START));
if (allKeys.size() >= 1000) break;
}
allKeys.stream().forEach(System.out::println);
}
The pattern from the match method should be "*" instead of "{*}"
I followed this: Reading email from gmail is not working and I am able to fetch all email messages. However, when I use search parameters, I always get 0 results. This is what I tried:
Date d1 = new DateTime(date.getTime()).toLocalDate().toDate();
Date d2 = new DateTime(date.getTime()).plusDays(-30).toLocalDate().toDate();
SearchTerm olderThan = new ReceivedDateTerm(ComparisonTerm.LT, d1);
SearchTerm newerThan = new ReceivedDateTerm(ComparisonTerm.GT, d2);
SearchTerm andTerm = new AndTerm(olderThan, newerThan);
Message[] messages = emailFolder.search(andTerm);
If I change the last line to
Message[] messages = emailFolder.getMessages();
everything works fine and I get all emails. There are emails in my inbox received in the last 30 days. Is there something wrong with my search logic?
You are missing below line of code, you have to override match method and put condition there
// creates a search criterion
SearchTerm searchCondition = new SearchTerm() {
#Override
public boolean match(Message message) {
try {
if (message.getSubject().contains(keyword)) {
return true;
}
} catch (MessagingException ex) {
ex.printStackTrace();
}
return false;
}
};
// performs search through the folder
Message[] foundMessages = folderInbox.search(searchCondition);
for (int i = 0; i < foundMessages.length; i++) {
Message message = foundMessages[i];
String subject = message.getSubject();
System.out.println("Found message #" + i + ": " + subject);
}
EDIT :-
SearchTerm andTerm = null;
andTerm = new AndTerm(andTerm, olderThan); //concat the search terms
andTerm = new AndTerm(andTerm, newerThan );
Message messages[] = folderInbox.search(andTerm); //search on the imap server
EDIT 1 :-
for (Message message : messages) {
if (message.getSentDate().after(olderThan) && message.getSentDate().before(newerThan))
{
//do whatever you want with your filtered by period message
}
}
I have this arraylist;
ArrayList<String> list = new ArrayList<String>();
I have populate this arraylist from some DB queries and i must send this list as e-mail.
public void sendMail(ArrayList carriers) throws Exception {
Email email = new SimpleEmail();
email.setHostName("mail.test.com.tr");
email.setSmtpPort(587);
email.setAuthentication("testuser#mail.test.com.tr","testuserpass");
email.setSSLOnConnect(false);
email.setFrom("testuser#mail.test.com.tr");
email.setSubject("Test Information List");
email.setMsg("Last 1 hour Information;\n"+carriers);
email.addTo("test#mail.test.com.tr");
email.send();
System.out.println("email sended succesfully.");
}
When i call this sendMail(list); method mail came to my mailbox succesfully. But all strings in this list showing side by side in message body normally. I want all strings align vertically.Let me explain;
Now;
trying1, trying2, trying3
Desired format;
trying1
trying2
trying3
How can i handle it?
--SOLVED--
StringBuilder b = new StringBuilder();
for(Object carrier : carriers)
b.append(carrier).append("\n");
String carriersString = b.toString();
Above lines added to sendMail() method, beginning of code. And below lines editing to;
email.setMsg("Last 1 hour Information;\n"+carriersString);
Thanks to #Icewind
You have to manually concatenate the strings to your desired format. The default toString() method will concatenate the values by a comma.
Something like this:
StringBuilder b = new StringBuilder();
for(String carrier : carriers)
b.append(carrier).append("\n");
String carriersString = b.toString();
or with StringUtils in apache commons (http://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/StringUtils.html):
String carriersString = StringUtils.join(carriers, "\n");
...snip...
email.setMsg("Last 1 hour Information;\n"+carriersString);
I have verified that the entity I am looking for is in the datastore. I have verified that the list I pass as a method parameter contains this entity. I am trying to find all objects that have their 'userGmail' contained in the list of strings I pass.
Here is my code
#SuppressWarnings("unchecked")
#ApiMethod(name = "findFriendsByEmailList")
public CollectionResponse<ZeppaUser> findFriendsByEmailList(
#Named("emailsList") List<String> emailsList, User user)
throws OAuthRequestException {
if (user == null) {
throw new OAuthRequestException(
"Null User Authorization Exception, findFriendsByEmailList");
}
PersistenceManager mgr = null;
List<ZeppaUser> execute = null;
Query query = null;
try {
mgr = getPersistenceManager();
query = mgr.newQuery(ZeppaUser.class);
query.declareParameters("java.util.List emailListParam");
query.setFilter("emailListParam.contains( userGmail )");
execute = (List<ZeppaUser>) query.execute(emailsList);
query.closeAll();
} finally {
mgr.close();
}
return CollectionResponse.<ZeppaUser> builder().setItems(execute)
.build();
}
This is the stack trace I receive from it:
Something worth noting: I do not receive this error on lists I pass in that to not contain an element found in the datastore. Just when it does exist which leads me to believe that the Query has located the element but has not been closed or executed into a return parameter correctly. If it is preferable to return List that is more than ok. I have tried multiple variations of this with no success thus far. It is getting quite frustrating.
Ok so I found a way around it.
Lists cannot be passed into ApiEndpoints. That or I didn't figure out the correct way to do it and would LOVE an update on the proper way to do this.
Instead, in my client, I construct a String of emails seperated by a comma and send a string into the parameter as an 'encoded' string list then 'decode' it upon execution. Works well but seems hacky.
here are the methods I used. This is convenient though because it works with iOS as well.
public static String encodeListString(ArrayList<String> stringList){
StringBuilder stringbuilder = new StringBuilder();
stringbuilder.append(stringList.get(0));
if(stringList.size() > 1){
for( int i = 0; i < stringList.size(); i++){
stringbuilder.append(",");
stringbuilder.append(stringList.get(i));
}
}
return stringbuilder.toString();
}
public static List<String> decodeListString(String encodedString){
char[] characters = encodedString.toCharArray();
StringBuilder stringbuilder = new StringBuilder();
int position = 0;
ArrayList<String> stringList = new ArrayList<String>();
while(true){
try {
char character = characters[position];
if(character == ','){
String resultString = stringbuilder.toString();
stringList.add(resultString);
stringbuilder = new StringBuilder(); // clear it
} else {
stringbuilder.append(character);
}
position++;
} catch (ArrayIndexOutOfBoundsException aiex){
// List ended
String resultString = stringbuilder.toString();
if(!resultString.isEmpty())
stringList.add(resultString);
break;
}
}
return stringList;
}