Can't read from datastore - java

Creating the entity and setting the property
package pack.exp;
import java.io.IOException;
import javax.servlet.http.*;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
#SuppressWarnings("serial")
public class IkaiLanServlet extends HttpServlet
{
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws...
{
Entity alice = new Entity("Person", "Alice");
alice.setProperty("gender", "female");
alice.setProperty("age", 20);
Key bobKey = KeyFactory.createKey("Person", "Bob");
Entity bob = new Entity(bobKey);
bob.setProperty("gender", "male");
bob.setProperty("age", "23");
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
datastore.put(alice);
datastore.put(bob);
resp.setContentType("text/plain");
resp.getWriter().println("Bye Bye");
}
}
In the same package creating another servlet
package pack.exp;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
public class Read extends HttpServlet
{
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws...
{
// TODO Auto-generated method stub
super.doGet(req, resp);
Key bobKey = KeyFactory.createKey("Person", "Bob");
Key aliceKey = KeyFactory.createKey("Person", "Alice");
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Entity alice, bob;
try {
alice = datastore.get(aliceKey);
bob = datastore.get(bobKey);
Long aliceAge = (Long) alice.getProperty("age");
Long bobAge = (Long) bob.getProperty("age");
System.out.println("Alice’s age: " + aliceAge);
System.out.println("Bob’s age: " + bobAge);
}
catch (EntityNotFoundException e)
{
// Alice or Bob doesn't exist!
}
}
}
When I am deploying the app the output is "Bye Bye". Why it is not reading the entity.
Please help me i am new to google app engine datastore..

When you go to whatever URL you have mapped to IkaiLanServlet, it will respond with "Bye Bye" because you called resp.getWriter().println("Bye Bye"). To read the entity, change
System.out.println("Alice’s age: " + aliceAge);
System.out.println("Bob’s age: " + bobAge);
to
resp.setContentType("text/plain");
resp.getWriter().println("Alice’s age: " + aliceAge);
resp.getWriter().println("Bob’s age: " + bobAge);
According to the docs (https://developers.google.com/appengine/docs/java/#Java_Logging):
Everything the servlet writes to the standard output stream (System.out) and standard error stream (System.err) is captured by App Engine and recorded in the application logs. Lines written to the standard output stream are logged at the "INFO" level, and lines written to the standard error stream are logged at the "WARNING" level.
To see the output in your browser, you must use resp.
Also, be sure that you visit the URL's for IkaiLanServlet and then Read, in that order, to ensure the entities are in the datastore.

Related

JavaEE and Firebase admin sdk - setValueAsync not pushing data to realtime firebase

Am using firebase admin sdk and JavaEE on intellij built on gradle and glassfish server.
am trying to push a value to realtime database, but sadly am unable to do so. I've been searching online for weeks now and gotten nothing. I also followed some solutions in stackoverflow answers like : Firebase Java Admin SDK don't work but nothing works for me.
I've read a lot of reasons why such a problem would occur with firebase admin sdk but i have no solutions.
here's my code:
package sample;
package sample;
import com.google.api.core.ApiFuture;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseToken;
import com.google.firebase.auth.UserRecord;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import sample.model.FireBaseAuth;
import sample.model.FireBaseUtils;
import sample.model.Owner;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
#WebServlet("/success")
public class SuccessServlet extends HttpServlet {
public void init() throws ServletException {
super.init();
FireBaseUtils.initilizeFirebase();
}
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
String email = request.getParameter("email");
String password = request.getParameter("pass");
//System.out.println(name);
try{
//a hashmap for the number of shopsOwned
HashMap<String, String> shopsOwned = new HashMap<>();
shopsOwned.put("shopName" , "shopName");
//get the database instance and the database reference
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("Business");
DatabaseReference ownersRef = ref.child("Owners"); //further get the reference to the owners node
//create a new owner with the values of the new user, using the Owner class
Owner newOwner = new Owner("userRecord2.getUid()", "userRecord2.getDisplayName()",
"userRecord2.getPhoneNumber()", "userRecord2.getEmail()", shopsOwned);
//create a hashmap of the users, in this case, just one user
Map<String, Owner> users = new HashMap<>();
users.put("userRecord2getPhoneNumber", newOwner); //add the new owner to the hashmap
System.out.println("this is the user :" + newOwner.getFull_name());
//push the new owner hashmap to the database reference
ApiFuture<Void> future = ownersRef.push().setValueAsync(users);
//Object o = future.get(8, TimeUnit.SECONDS);
System.out.println(future.isDone());
//System.out.println(future.isDone());
request.getRequestDispatcher("success.jsp").forward(request, response);
}catch(Exception e){e.printStackTrace();}
}
#Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
doGet(request, response);
}
}
any ideas will be appreciated.
Edit : I dont get any errors whatsoever, the webapp runs normally but the realtime db at firebase isn't updated
You need to wait until the future is complete, before the request thread is returned. Otherwise there's no guarantee that the update is completed, and any errors are silently discarded. So try something like the following:
ApiFuture<Void> future = ownersRef.push().setValueAsync(users);
future.get();
request.getRequestDispatcher("success.jsp").forward(request, response);
Writing to Firestore (like interaction with most cloud APIs) happens asynchronously, and on a different thread. When you call future.isDone(), the operation isn't done yet.
You'll want to add a callback that gets called when the operation has completed:
ApiFuture<Void> future = ownersRef.push().setValueAsync(users);
future.addCallback(future, new ApiFutureCallback<String>() {
#Override
public void onSuccess(String result) {
System.out.println("Operation completed with result: " + result);
System.out.println(future.isDone());
request.getRequestDispatcher("success.jsp").forward(request, response);
}
#Override
public void onFailure(Throwable t) {
System.err.println("Operation failed with error: " + t);
}
Also see:
Firebase: Asynchronous Operations with Admin Java SDK

How to set response header for digital asset in AEM CQ6.1?

I have a request that if a user directly accesses a .pdf asset(for example, http://localhost:4505/content/dam/company/us/en/962059.pdf) from AEM CQ 6.1, I need to send a custom http respone header. This is what I wrote. This is only works if I open a .html page. But it doesn't work if I open a .pdf in browser. So what did I do wrong?
Thanks
package com.mycompany.wcm.filter;
import org.apache.felix.scr.annotations.*;
import org.apache.felix.scr.annotations.sling.SlingFilter;
import org.apache.felix.scr.annotations.sling.SlingFilterScope;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.*;
import org.apache.sling.api.scripting.SlingBindings;
import org.apache.sling.api.scripting.SlingScriptHelper;
import org.apache.sling.runmode.RunMode;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jcr.Session;
import javax.servlet.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
#SlingFilter(
label = "Sample Filter",
description = "Sample Description",
metatype = true,
generateComponent = true, // True if you want to leverage activate/deactivate
generateService = true,
order = -501, // The smaller the number, the earlier in the Filter chain (can go negative);
scope = SlingFilterScope.REQUEST)
#Properties({
#Property(
label = "Vendor",
name = "service.vendor",
value = "SampleVendor",
propertyPrivate = true
)
})
public class AssetFilter implements Filter {
#Override
public void init(FilterConfig filterConfig) throws ServletException {
}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
final SlingHttpServletRequest slingRequest = (SlingHttpServletRequest) request;
final SlingHttpServletResponse slingResponse = (SlingHttpServletResponse) response;
slingResponse.setHeader("myheader1","no-cache");
slingResponse.setHeader("myheader2","no-store");
chain.doFilter(request, response);
}
#Override
public void destroy() {
}
}
Just a update, initialy I thought the problem only happens to .pdf file, but this also happens to image file. So I created a regular JSP web application, and this code is working for regular web app. Is there something funny on AEM side?

RemoteApi calls from servlet not loading in local app engine app

I'am trying this example https://cloud.google.com/appengine/docs/java/tools/remoteapi
Everything works fine if I run script as java application, but when I do it as servlet it always loads forever and doesn't throw any errors. Also works fine on localhost. Also I noticed it happens when query is made, when I comment it out (datastore.put), servlet loads instantly.
import java.io.IOException;
import javax.servlet.http.*;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.tools.remoteapi.RemoteApiInstaller;
import com.google.appengine.tools.remoteapi.RemoteApiOptions;
#SuppressWarnings("serial")
public class Gae_java_Servlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
RemoteApiOptions options = new RemoteApiOptions()
.server("java-dot-project.appspot.com", 443)
.useApplicationDefaultCredential();
RemoteApiInstaller installer = new RemoteApiInstaller();
installer.install(options);
try {
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
System.out.println("Key of new entity is " +
datastore.put(new Entity("Hello Remote API!")));
} finally {
installer.uninstall();
}
}
}
I figured it out, needed to use RemoteApiOptions().useServiceAccountCredential("service email", "p12key") instead of useApplicationDefaultCredential()

Iteration error showing while using google app engine

I am encountering the following issue:
I am trying to grab the users that are within x [miles/km] from the user’s cell
phone. I am using the datastore api for google app engine, I cant figure out
what is the problem. The issue is that when i fetch the record using the
itiration – an error appears telling me i cant use diffeant properties in the
combination filter.
package com.linkedlive.business;
import java.io.IOException;
import java.util.Iterator;
import javax.servlet.http.*;
import org.json.JSONArray;
import org.json.JSONObject;
import com.biomedica.server.geolocation.GeoLocation;
import com.biomedica.server.searchtools.SearchForGeolocEntitiy;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.KeyFactory;
#SuppressWarnings("serial")
public class Venue extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
this.doPost(req, resp);
}
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
DatastoreService datastore =
DatastoreServiceFactory.getDatastoreService();
String cmd=req.getParameter("cmd");
if(cmd.equals("venuenearby"))
{
GeoLocation geo=new GeoLocation();
SearchForGeolocEntitiy search=new
SearchForGeolocEntitiy("accounts");// this is a class that i created to set the
query filters see bellow
// get request parameters
float lat=Float.valueOf(req.getParameter("lat"));
float lng=Float.valueOf(req.getParameter("lng"));
float rad=Float.valueOf(req.getParameter("rad"));
// calculate the distance
Iterable<Entity>
ent=search.GetJSONForEntitiyNearByUsingBounds(lat,
lng,geo.getGeoLocationBounds(lat, lng, rad) );
Iterator<Entity> i=ent.iterator();
JSONObject json=new JSONObject();
JSONArray injson=new JSONArray();
json.put("result", "venuenearby");
while(i.hasNext())
{
try {
JSONObject j=new JSONObject();
Entity t=i.next();
j.put("key",
KeyFactory.keyToString(t.getKey()));
j.put("userid",
t.getProperty("userid"));
j.put("filepath",
t.getProperty("filepath"));
injson.put(j);
} catch (NullPointerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
json.put("body",injson);
resp.getWriter().write(json.toString());
}
}
}
///////////////////////////////////////////////////////////////////////////////
////////////////////
////////////////////////// SearchForGeolocEntitiy
////////////////////////////////////
package com.biomedica.server.searchtools;
import java.lang.reflect.Array;
import java.util.Arrays;
import com.biomedica.server.geolocation.GeoLocation;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.CompositeFilterOperator;
import com.google.appengine.api.datastore.Query.Filter;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.api.datastore.Query.FilterPredicate;
import com.google.appengine.api.datastore.Query.CompositeFilter;
public class SearchForGeolocEntitiy {
private String EntitiyName;
private Query q;
public SearchForGeolocEntitiy(String name)
{
EntitiyName=name;
q=new Query(name);
}
public Iterable<Entity> GetJSONForEntitiyNearBy(double lang,double
lat,double rad,int max_result)
{
DatastoreService datastore =
DatastoreServiceFactory.getDatastoreService();
// decleeraing filter object
Filter filter_min_lngt=new
FilterPredicate("lng", FilterOperator.GREATER_THAN, lang-rad);
Filter filter_max_lngt=new
FilterPredicate("lng", FilterOperator.LESS_THAN, lang+rad);
Filter filter_min_lat=new
FilterPredicate("lat", FilterOperator.GREATER_THAN, lat-rad);
Filter filter_max_lat=new
FilterPredicate("lat", FilterOperator.LESS_THAN, lat+rad);
Filter filter_lng=new
CompositeFilter(CompositeFilterOperator.AND,Arrays.asList(filter_min_lngt,filte
r_max_lngt));
Filter filter_lat=new
CompositeFilter(CompositeFilterOperator.AND,Arrays.asList(filter_min_lat,filter
_max_lat));
Filter filter=new
CompositeFilter(CompositeFilterOperator.AND,Arrays.asList(filter_lng,filter_lat
));
q.setFilter(filter);
PreparedQuery pq = datastore.prepare(q);
return pq.asIterable();
}
public Iterable<Entity> GetJSONForEntitiyNearByUsingSSID(String
EntityName,String entityID,String SSID)
{
DatastoreService datastore =
DatastoreServiceFactory.getDatastoreService();
// decleeraing filter object
Filter filter_entityID=new FilterPredicate(EntityName,
FilterOperator.EQUAL, entityID);
Filter filter_min_lngt=new
FilterPredicate("lng", FilterOperator.EQUAL, SSID);
Filter filter=new
CompositeFilter(CompositeFilterOperator.AND,Arrays.asList(filter_entityID,filte
r_min_lngt));
q.setFilter(filter);
PreparedQuery pq = datastore.prepare(q);
return pq.asIterable();
}
public Iterable<Entity> GetJSONForEntitiyNearByUsingBounds(float
lng,float lat,GeoLocation.GeoLocationBoundry bound)
{
DatastoreService datastore =
DatastoreServiceFactory.getDatastoreService();
Filter filter_min_lngt=new FilterPredicate("lng",
FilterOperator.LESS_THAN, bound.lng1);
Filter filter_max_lngt=new FilterPredicate("lng",
FilterOperator.LESS_THAN, bound.lng2);
Filter filter_min_lat=new FilterPredicate("lat",
FilterOperator.GREATER_THAN, bound.lat1);
Filter filter_max_lat=new FilterPredicate("lat",
FilterOperator.LESS_THAN, bound.lat2);
Filter filter_lng=new
CompositeFilter(CompositeFilterOperator.AND,Arrays.asList(filter_min_lngt,filte
r_max_lngt));
Filter filter_lat=new
CompositeFilter(CompositeFilterOperator.AND,Arrays.asList(filter_min_lat,filter
_max_lat));
Filter filter=new
CompositeFilter(CompositeFilterOperator.AND,Arrays.asList(filter_lng,filter_lat
));
q.setFilter(filter);
PreparedQuery pq = datastore.prepare(q);
return pq.asIterable();
}
}
You're hitting a limitation of the datastore. Inequality filters can only be on one property.
https://developers.google.com/appengine/docs/java/datastore/queries#Restrictions_on_Queries
The easiest way around this is to use the Search API. Otherwise, you need to build your own geohashing like mechanism to search within a range without using multiple inequality filters.

User (session) count in cluster

Is there a good way to get the logged in user count in a Java web application that is running in a cluster?
I wrote a simple HttpSessionListener with a static field, but I suppose this doesn't work in cluster. I can see there is a Spring Security solution, but I read in some forums that this is still not ok in cluster.
The product in which I have to implement this user count is trying to be application server independent, currently we support Tomcat, Weblogic and JBoss. At the moment I need a solution for Weblogic 10.3 clusters.
You can maintain the counter in database which will work in cluster env.
A simple tutorial to demonstrate how to determine active users / sessions in a Java Web Application.
package com.hubberspot.javaee.listener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
#WebListener
public class OnlineUsersCounter implements HttpSessionListener {
private static int numberOfUsersOnline;
public OnlineUsersCounter() {
numberOfUsersOnline = 0;
}
public static int getNumberOfUsersOnline() {
return numberOfUsersOnline;
}
public void sessionCreated(HttpSessionEvent event) {
System.out.println("Session created by Id : " + event.getSession().getId());
synchronized (this) {
numberOfUsersOnline++;
}
}
public void sessionDestroyed(HttpSessionEvent event) {
System.out.println("Session destroyed by Id : " + event.getSession().getId());
synchronized (this) {
numberOfUsersOnline--;
}
}
}
Running the below servlet on three different browsers will provide output as : (see fig below)
package com.hubberspot.javaee;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.hubberspot.javaee.listener.OnlineUsersCounter;
// #WebServlet annotation has a initParams field which takes
// in initialization parameters for a servlet.
// #WebInitParam annotation takes in a name and value for the
// initialization parameters for the current Servlet.
#WebServlet(name = "HelloWorldServlet" , urlPatterns = { "/HelloWorldServlet" }
, initParams = { #WebInitParam(name = "user" , value = "Jonty") })
public class HelloWorldServlet extends HttpServlet {
protected void doGet(
HttpServletRequest request,
HttpServletResponse response
) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
// sessionCreated method gets executed
HttpSession session = request.getSession();
session.setMaxInactiveInterval(60);
try {
out.println("<html>");
out.println("<body>");
out.println("<h2>Number of Users Online : "
+ OnlineUsersCounter.getNumberOfUsersOnline()
+ "</h2>");
out.println("</body>");
out.println("</html>");
} finally {
out.close();
}
}
}
Output of the program :
Eclipse Browser ->
Firefox Browser ->
Internet Explorer Browser ->
Console Output ->
For more: http://www.hubberspot.com/2013/09/how-to-determine-active-users-sessions.html

Categories