I am setting up the Backend code of a chat messaging system for an app my group is creating using WebSockets. My goal is for our app to be able to send and receive messages in a public group chat, and also specifically Direct Message (DM) specific people with an # symbol, in front of the recipient's username.
I managed to get the public group messaging component working perfectly fine. However, I am running into an issue with the DM functionality. Let's say for example a person named "test" wrote a message to someone named "teacher" and here was what they typed: "#teacher testMessage". Ideally, I would want the program to send the message "testMessage" to "teacher" only. However, every time I would test the program using Postman, I would end up with the following error:
java.lang.NullPointerException: Cannot invoke "javax.websocket.Session.getBasicRemote()" because the return value of "java.util.Map.get(Object)" is null
From my understanding, the error means that the variable type the method is supposed to receive (in this case a String), is not what it is actually getting.
Here is the code below:
private static Map < Session, String > sessionUsernameMap = new Hashtable<>();
private static Map < String, Session > usernameSessionMap = new Hashtable<>();
#OnMessage
public void onMessage(Session session, String message) throws IOException { //The message is the the entire thing that the person types (ex: #teacher testMessage)
logger.info("Message Received: " + message); //String message = #teacher testMessage
String username = sessionUsernameMap.get(session); //String username = "test" This is the username of the person who wrote the message
if (message.startsWith("#")) {
String destUsername = message.split(" ")[0].substring(1); //destUsername = "teacher"
String realMessage = message.substring(message.lastIndexOf(" ") + 1); //realMessage = "testMessage"
sendMessageToParticularUser(destUsername, "[DM] " + username + ": " + realMessage); //puts in "teacher" for destUsername and "testMessage" for realMessage
sendMessageToParticularUser(username, "[DM] " + username + ": " + message);
}
else {
broadcast(username + ": " + message);
}
msgRepo.save(new Message(username, message));
}
private void sendMessageToParticularUser(String username, String message) {
System.out.println(message);
try {
usernameSessionMap.get(username).getBasicRemote().sendText(message); //PROBLEM RIGHT HERE WITH .get(username)
} catch (IOException e) {
logger.info("Exception: " + e.getMessage().toString());
e.printStackTrace();
}
}
I have been working on this issue for a few hours now with no luck. I would very much appreciate any help or input on this. Thank you.
Google warns us about PlaceID changes and suggests;
Place IDs may change due to large-scale updates on the Google Maps database. In such cases, a place may receive a new place ID, and the old ID returns a NOT_FOUND response.
You can refresh Place IDs free of charge, by making a Place Details request, specifying only the ID field in the fields parameter.
Unfortunately, there is no sample code for Java/Kotlin on their website except a link to their web services
String placeID ="Some place ID";
List<Place.Field> placeFields = Arrays.asList(
Place.Field.ID,
);
// Construct a request object, passing the place ID and fields array.
FetchPlaceRequest request = FetchPlaceRequest.builder(placeID, placeFields).build();
placesClient.fetchPlace(request).addOnSuccessListener((response) -> {
Place place = response.getPlace();
if (!placeID.equals(place.getId())) {
//update your old placeID
}
}).addOnFailureListener((exception) -> {
if (exception instanceof ApiException) {
//Place removed.
}
});
Is this a porper way to update a placeIDs with Java?
I've tested my databases and found a case where the update occurs. The below code contains both a renewed placeID, removed placeID, and still valid palceID so that one can test.
ArrayList<String> placeIDsList = new ArrayList<>();
placeIDsList.add("ChIJTaKjynxesBQREvi1CU5QUFg");
placeIDsList.add("EjhDdW1odXJpeWV0IE1haGFsbGVzaSwgVXp1biBTay4sIEV6aW5lL8OHYW5ha2thbGUsIFR1cmtleSIuKiwKFAoSCakQkmN8XrAUEVkLpNK_F4IJEhQKEgmFzKyYe16wFBGSjU7F2ooIIg");
placeIDsList.add("hIJy9YVxdxpsBQRq0-xUVJdZQ8");
// Specify the fields to return (in this example all fields are returned).
List<Place.Field> placeFields = Arrays.asList(Place.Field.ID);
for (String plc : placeIDsList ) {
// Construct a request object, passing the place ID and fields array.
FetchPlaceRequest request = FetchPlaceRequest.builder(plc, placeFields).build();
Log.e(TAG,"request for place with ID = " + plc);
placesClient.fetchPlace(request).addOnSuccessListener((response) -> {
Place place = response.getPlace();
if (!plc.equals(place.getId())) {
Log.e(TAG,"placeID renewed");
Log.e(TAG,"placeID old = " + plc);
Log.e(TAG,"placeID new = " + place.getId());
} else {
Log.e(TAG, "Place found: " + place.getId());
}
}).addOnFailureListener((exception) -> {
if (exception instanceof ApiException) {
ApiException apiException = (ApiException) exception;
int statusCode = apiException.getStatusCode();
// Handle error with given status code.
Log.e(TAG, "Place with ID "+plc+" not found");
Log.e(TAG, "Exception message is :" + exception.getMessage());
Log.e(TAG, "Status code = " + statusCode);
}
});
}
The output is
E/MapsActivity: request for place with ID = ChIJTaKjynxesBQREvi1CU5QUFg
E/MapsActivity: request for place with ID = jhDdW1odXJpeWV0IE1haGFsbGVzaSwgVXp1biBTay4sIEV6aW5lL8OHYW5ha2thbGUsIFR1cmtleSIuKiwKFAoSCakQkmN8XrAUEVkLpNK_F4IJEhQKEgmFzKyYe16wFBGSjU7F2ooIIg
E/MapsActivity: request for place with ID = hIJy9YVxdxpsBQRq0-xUVJdZQ8
E/MapsActivity: placeID renewed
E/MapsActivity: placeID old = EjhDdW1odXJpeWV0IE1haGFsbGVzaSwgVXp1biBTay4sIEV6aW5lL8OHYW5ha2thbGUsIFR1cmtleSIuKiwKFAoSCakQkmN8XrAUEVkLpNK_F4IJEhQKEgmFzKyYe16wFBGSjU7F2ooIIg
E/MapsActivity: placeID new = Ei5DdW1odXJpeWV0LCBVenVuIFNrLiwgRXppbmUvw4dhbmFra2FsZSwgVHVya2V5Ii4qLAoUChIJqRCSY3xesBQRWQuk0r8XggkSFAoSCYXMrJh7XrAUEZKNTsXaiggi
E/MapsActivity: Place with ID hIJy9YVxdxpsBQRq0-xUVJdZQ8 not found
E/MapsActivity: Exception message is :9012: INVALID_REQUEST
E/MapsActivity: Status code = 9012
E/MapsActivity: Place found: ChIJTaKjynxesBQREvi1CU5QUFg
And it seems that the status code 9102 is for place not found.
I am trying to create work item in RTC through java application using the jazz api's.
My connection to the repository is successful. Now i need to set all the required fields through java code in order to save/run the workitem. Really dont know how to set those values in below codes.
String repositoryURI= args[0];
String userId= args[1];
String password= args[2];
String projectAreaName= args[3];
String typeIdentifier= args[4];
String summary= args[5];
String categoryName= args[6];
ITeamRepository teamRepository= TeamPlatform.getTeamRepositoryService().getTeamRepository(repositoryURI);
teamRepository.registerLoginHandler(new LoginHandler(userId, password));
teamRepository.login(null);
IProcessClientService processClient= (IProcessClientService) teamRepository.getClientLibrary(IProcessClientService.class);
IAuditableClient auditableClient= (IAuditableClient) teamRepository.getClientLibrary(IAuditableClient.class);
IWorkItemClient workItemClient= (IWorkItemClient) teamRepository.getClientLibrary(IWorkItemClient.class);
URI uri= URI.create(projectAreaName.replaceAll(" ", "%20"));
IProjectAreaHandle projectArea= (IProjectAreaHandle) processClient.findProcessArea(uri, null, null);
//IProjectAreaHandle projectArea = teamArea.getProjectArea();
if (projectArea == null) {
System.out.println("Project area not found.");
return false;
}
//IWorkItemType workItemType = service.findWorkItemType(projectArea, "defect", monitor);
IWorkItemType workItemType= workItemClient.findWorkItemType((IProjectAreaHandle) projectArea, typeIdentifier, null);
// findWorkItemType(projectArea, typeIdentifier, null);
if (workItemType == null) {
System.out.println("Work item type not found.");
return false;
}
System.out.println("Category not found.: " + categoryName );
List path= Arrays.asList(categoryName.split("/"));
System.out.println("Category not found.: " + path );
ICategoryHandle category= workItemClient.findCategoryByNamePath((IProjectAreaHandle) projectArea, path, null);
//ICategoryHandle category=
if (category == null) {
System.out.println("Category not found.: " + category );
return false;
}
WorkItemInitialization operation= new WorkItemInitialization(summary, category);
IWorkItemHandle handle= operation.run(workItemType, null);
IWorkItem workItem= auditableClient.resolveAuditable(handle, IWorkItem.FULL_PROFILE, null);
System.out.println("Created work item " + workItem.getId() + ".");
teamRepository.logout();
While running the codes i am receiving the below errors. Because of mandatory fields are not assigned. Can any one help me to pass the attribute values (Contact Phone) from java to jazz.
ERROR received:
Severity: ERROR
Summary: Attribute 'Contact Phone #' not set
Description: The 'Contact Phone #' attribute needs to be set (work item <09:13:03>).
Problem
I want to see if user "john" is in group "Calltaker". I can't seem to get the syntax right on my search filter to check for a specific user in a specific group. I can list all users in a group to verify the desired user is there.
Questions
What is the right syntax for a ldap search filter to determine if a specific user is in a specific group(in Tivoli Access Manager)?
What should I check on the returned LDAPEntry object given by that search string to see that the user is, or isn't, in the group?
Info
john is defined in "cn=users,dc=ldap,dc=net"
Calltaker is defined in "cn=groups,dc=ldap,dc=net"
I'm querying against TAM's ldap, from java
Using the searchfilter to be "cn=Calltaker" I can print out the search results such that calling nextEntry.toString contains the list of users. See Example 1 below
Here's a few searchfilters I've tried that don't work (aka searchResults.next() throws an error):
(&(objectclass=groupOfUniqueName)(uniquemember=uid="+ username + ",cn=groups,dc=ldap,dc=net))
(&(objectclass=groupOfUniqueName)(uniquemember=uid="+ username + ",cn=users,dc=ldap,dc=net))
(uniquemember=uid="+ username + ",cn=users,dc=ldap,dc=net)
Example 1) only search group, using searchFilter="cn=Calltaker", verify it contains users:
System.out.println(nextEntry.toString()); //added newlines for readability
nextEntry:
LDAPEntry:
cn=Calltaker,cn=groups,dc=ldap,dc=net;
LDAPAttributeSet:
LDAPAttribute: {type='objectclass', values='groupOfUniqueNames','top'}
LDAPAttribute: {type='uniquemember',
values=
'uid=placeholder,cn=users,dc=ldap,dc=net',
'secAuthority=default',
'uid=john,cn=users,dc=ldap,dc=net',
'uid=sally,cn=users,dc=ldap,dc=net', ....etc
Code:
public boolean isUserInGroup(username){
boolean userInGroup = false;
String loginDN = "uid=" + admin_username + "," + "cn=users,dc=ldap,dc=net";
String searchBase = "cn=groups,dc=ldap,dc=net";
int searchScope = LDAPConnection.SCOPE_SUB;
searchFilter = "(&(objectclass=ePerson)(uniquemember=uid="+ username + ",cn=users,dc=ldap,dc=net))";
//Connect
LDAPConnection lc = connect(hosts);
lc.bind(LDAPConnection.LDAP_V3, loginDN, admin_password.getBytes("UTF8"));
lc.getAuthenticationDN();
LDAPSearchResults searchResults = lc.search(searchBase,
searchScope,
searchFilter,
null, // return all attributes
false); // return attrs and values
while (searchResults.hasMore()) {
LDAPEntry nextEntry = null;
try {
nextEntry = searchResults.next();
} catch (LDAPException e) {
// Exception is thrown, go for next entry
if (e.getResultCode() == LDAPException.LDAP_TIMEOUT || e.getResultCode() == LDAPException.CONNECT_ERROR)
break;
else
continue;
}
//TODO some check to verify nextEntry shows the user in the group
userInGroup = true;
LDAPAttributeSet attributeSet = nextEntry.getAttributeSet();
Iterator<LDAPAttribute> allAttributes = attributeSet.iterator();
while (allAttributes.hasNext()) {
LDAPAttribute attribute = (LDAPAttribute) allAttributes.next();
String attributeName = attribute.getName();
System.out.println("found attribute '" + attributeName + "' with value '" + attribute.getStringValue() + "'");
}
}
lc.disconnect();
return userInGroup;
}
** EDIT **
Implemented answer from EJP, changed searchBase to include group
Code that works:
private static final String admin_username = "foo";
private static final String[] hosts = new String[]{"foohost.net"};
public boolean isUserInGroup(String username, String group){
boolean userInGroup = false;
String loginDN = "uid=" + admin_username + "," + "cn=users,dc=ldap,dc=net";
String searchBase = "cn=" + group + "," + "cn=groups,dc=ldap,dc=net";
int searchScope = LDAPConnection.SCOPE_SUB;
searchFilter = "(&(objectclass=groupOfUniqueNames)(uniquemember=uid="+ username + ",cn=users,dc=ldap,dc=net))";
//Connect
LDAPConnection lc = connect(hosts);
lc.bind(LDAPConnection.LDAP_V3, loginDN, admin_password.getBytes("UTF8"));
lc.getAuthenticationDN();
LDAPSearchResults searchResults = lc.search(searchBase,
searchScope,
searchFilter,
null, // return all attributes
false); // return attrs and values
while (searchResults.hasMore()) {
LDAPEntry nextEntry = null;
try {
nextEntry = searchResults.next();
} catch (LDAPException e) {
// Exception is thrown, go for next entry
if (e.getResultCode() == LDAPException.LDAP_TIMEOUT || e.getResultCode() == LDAPException.CONNECT_ERROR)
break;
else
continue;
}
//A result was found, therefore the user is in the group
userInGroup = true;
}
lc.disconnect();
return userInGroup;
}
What is the right syntax for a ldap search filter to determine if a specific user is in a specific group(in Tivoli Access Manager)?
Either of the filters you used, but the objectClass to search on is groupofUniqueNames (plural).
What should I check on the returned LDAPEntry object given by that search string to see that the user is, or isn't, in the group?
Nothing. He will be, otherwise the group won't be returned in the search. All you need to do is check that the search result is non-empty.
Here's a few searchfilters I've tried that don't work (aka searchResults.next() throws an error):
Throws what error?
(&(objectclass=groupOfUniqueName)(uniquemember=uid="+ username + ",cn=groups,dc=ldap,dc=net))
Nothing wrong with this except for groupOfUniqueName. You should use search filter arguments like {0} rather than building them into the search string.
(&(objectclass=groupOfUniqueName)(uniquemember=uid="+ username + ",cn=users,dc=ldap,dc=net))
This one will search the cn=users subtree for a group. It won't work unless you have groups under cn=users, which doesn't seem likely.
(uniquemember=uid="+ username + ",cn=users,dc=ldap,dc=net)
This will select non-groups. You don't want that: you need the objectClass part.
I am trying to get my followers and following list via Twitter 4J.
I pass the configuration builder from the main method as a parameter to the method.
Here is the code:
try {
Twitter twitter = new TwitterFactory().getInstance();
long cursor = -1;
IDs ids;
System.out.println("Listing following ids.");
do {
if (0 < args.length) {
ids = twitter.getFriendsIDs(args[0], cursor);
} else {
ids = twitter.getFriendsIDs(cursor);
}
for (long id : ids.getIDs()) {
System.out.println(id);
}
} while ((cursor = ids.getNextCursor()) != 0);
System.exit(0);
} catch (TwitterException te) {
te.printStackTrace();
System.out.println("Failed to get friends' ids: " + te.getMessage());
System.exit(-1);
}
So far this only returns IDS but it does not return the screen name of the followers. Does anyone have any idea? I am working in Java and printing to the terminal.
Thanks.
String twitterScreenName = twitter.getScreenName();
PagableResponseList<User> statuse = twitter.getFollowersList(twitterScreenName, -1);
for (User follower : statuse) {
System.out.println(follower.getName());
}