API Calls,e.g. to Firebase https://fcm.googleapis.com/fcm/send worked before switching from <env>vm</env> appengine-web.xml to
env: flex app.yaml flexible.
When deploying with mvn appengine:deploy everything is fine, but when an API call gets fired, which worked before, i get the exception below:
Exception in thread "Thread-14" com.google.apphosting.api.ApiProxy$CallNotFoundException:
Can't make API call urlfetch.Fetch in a thread that is neither the original request thread nor a thread created by ThreadManager
at com.google.apphosting.api.ApiProxy$CallNotFoundException.foreignThread(ApiProxy.java:800)
at com.google.apphosting.api.ApiProxy.makeSyncCall(ApiProxy.java:112)
at com.google.appengine.api.urlfetch.URLFetchServiceImpl.fetch(URLFetchServiceImpl.java:40)
at com.google.api.client.extensions.appengine.http.UrlFetchRequest.execute(UrlFetchRequest.java:74)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:981)
at com.qweez.flexenv.service.GameCounterService.run(GameCounterService.java:80)
it crashes when calling request.execute() below:
import com.google.api.client.http.ByteArrayContent;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpResponse;
import java.io.IOException;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Logger;
// stuff
try {
HttpRequest request = HttpRequestUtil.getHttpRequestFactory().buildPostRequest(new GenericUrl(GlobalConfig.MESSAGING_SERVER_URL), ByteArrayContent.fromString("application/json", requestBody));
HttpResponse response = request.execute();
//logger.warning(LOG_TAG+" ++++++ response status=" + response.getContent());
} catch (IOException e) {
logger.warning(LOG_TAG+" sent messge to topic error: " + e.getMessage());
}
the helper class httpRequestUtil looks like this
import com.google.api.client.extensions.appengine.http.UrlFetchTransport;
import com.google.api.client.http.HttpHeaders;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import java.io.IOException;
public class HttpRequestUtil {
private static HttpTransport httpTransport;
private static HttpRequestFactory requestFactory;
static {
httpTransport = UrlFetchTransport.getDefaultInstance();
requestFactory = httpTransport.createRequestFactory(new HttpRequestInitializer() {
#Override
public void initialize(com.google.api.client.http.HttpRequest httpRequest) throws IOException {
HttpHeaders hh = new HttpHeaders();
hh.setAuthorization(GlobalConfig.SERVER_KEY);
hh.setContentType("application/json");
httpRequest.setHeaders(hh);
}
});
}
public static HttpRequestFactory getHttpRequestFactory(){
return requestFactory;
}
Is there something deprecated now?
Or what's the issue here now?
Any help very appreciated. Thanks!
Related
I'm new to the community. I built an e-commercce application with the Jhipster (Java + React Redux) Monolitica. I have the following problem: The application is configured to display a hashtag (#) in the URL for example ... http://localhost:9000/#/. I removed this parameter in React and everything was right. But when I upload the application with Gradle (./gradew) it works, http://localhost:9000/. But if you type directly into the browser http://localhost:9000/home/ I get ERROR 404, Page not found! -----> my application to check the problem (http://www.severobalanceboard.eco.br - OK), (http://www.severobalanceboard.eco.br/historia - ERROR 404)
_
I think this problme by Spring.
Resolved, for remove Hash tag # To URL, using Jhipster and React [Spring + ReactJs]. I use the link of #Gaël Marziou told me.
follows the modifications:
==React==
1 - com/mycompany/myapp/src/main/webapp/app/app.tsx
import { BrowserRouter as Router } from 'react-router-dom';
// import { HashRouter as Router } from 'react-router-dom';
2 - com/mycompany/myapp/src/main/webapp/index.html
<!-- <base href="./"/> -->
<base href="/"/>
3 - com/mycompany/myapp/webpack/webpack.prod.js
},
devServer: {
historyApiFallback: true, /*insert this line - only use for develop*/
stats: options.stats,
hot: true,
contentBase: './build/www',
proxy: [{
context: [
...
==JAVA==
4 - com/mycompany/myapp/src/main/java/br/com/MyApp/config/WebConfigurer.java
#Bean
public Html5RouteFilter html5RouteFilter() {
return new Html5RouteFilter();
}
5 - com/mycompany/myapp/src/main/java/br/com/MyApp/web/Html5RouteFilter.java
YOU NEED CREATE THIS FILE
package com.mycompany.myapp.web;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.regex.Pattern;
/**
* Filter that distinguishes between client routes and server routes when you don't use '#' in client routes.
*/
public class Html5RouteFilter extends OncePerRequestFilter {
private Logger log = LoggerFactory.getLogger(getClass());
// These are the URIs that should be processed server-side
private static final Pattern PATTERN = Pattern.compile("^/((api|content|i18n|management|swagger-ui|swagger-resources)/|error|h2-console|swagger-resources|favicon\\.ico|v2/api-docs).*");
#Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {
if (isServerRoute(request)) {
filterChain.doFilter(request, response);
} else {
RequestDispatcher rd = request.getRequestDispatcher("/");
rd.forward(request, response);
}
}
protected static boolean isServerRoute(HttpServletRequest request) {
if (request.getMethod().equals("GET")) {
String uri = request.getRequestURI();
if (uri.startsWith("/app")) {
return true;
}
return PATTERN.matcher(uri).matches();
}
return true;
}
}
===END==
now be happy
The following is a simple Google App Engine Standard servlet that displays a user’s Google e-mail address if the user is logged in. How can I invoke this programmatically (e.g. using curl or Java code) while providing Google credentials (e.g. for a user or service account). I think I need to obtain an OAuth2 token, but I could use some help coming up with a step-by-step process.
package com.example.appengine.java8;
import java.io.IOException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
#WebServlet(name = "HelloAppEngine", value = "/hello")
public class HelloAppEngine extends HttpServlet {
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
UserService userService = UserServiceFactory.getUserService();
User user = userService.getCurrentUser();
response.setContentType("text/plain");
PrintWriter out = response.getWriter();
if(user == null) {
out.print("not authenticated");
}
else {
out.print(user.getEmail());
}
}
}
Here is a live version of this servlet:
https://servlet-authentication-test.appspot.com/hello
You can use the following link to login with a Google account and then access the servlet while authenticated:
https://accounts.google.com/signin/v2/identifier?service=ah&passive=true&continue=https%3A%2F%2Fappengine.google.com%2F_ah%2Fconflogin%3Fcontinue%3Dhttps%3A%2F%2Fservlet-authentication-test.appspot.com%2Fhello&flowName=GlifWebSignIn&flowEntry=ServiceLogin
You can use GoogleAuthorizationCodeFlow from Google API Client Library to generate a callback request to Google to handle signing in to a Google account. For a detailed example you can take a look at this documentation or at GitHub for the source code.
Thankfully, Google announced the export logic from cloud Datastore. I would like to set up schedule-export in my platform. However, it's not Python, but Java. So I need to use cron.xml and Java logic to design this logic.
Is there any reference to design Datastore export logic (cloud_datastore_admin.py) in Java? Especially, I need to transform this part in Java
app = webapp2.WSGIApplication(
[
('/cloud-datastore-export', Export),
], debug=True)
https://cloud.google.com/datastore/docs/schedule-export
You can create the skeleton for App Egnine by following these instructions.
Once you have the skeleton, add something like this to handle export requests:
CloudDatastoreExport.java
package com.google.example.datastore;
import com.google.appengine.api.appidentity.AppIdentityService;
import com.google.appengine.api.appidentity.AppIdentityServiceFactory;
import com.google.apphosting.api.ApiProxy;
import com.google.common.io.CharStreams;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.logging.Logger;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;
#WebServlet(name = "CloudDatastoreExport", value = "/cloud-datastore-export")
public class CloudDatastoreExport extends HttpServlet {
private static final Logger log = Logger.getLogger(CloudDatastoreExport.class.getName());
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
// Verify outputURL parameter
String outputUrlPrefix = request.getParameter("output_url_prefix");
if (outputUrlPrefix == null || !outputUrlPrefix.matches("^gs://.*")) {
response.setStatus(HttpServletResponse.SC_CONFLICT);
response.setContentType("text/plain");
response.getWriter().println("Error: Must provide a valid output_url_prefix.");
} else {
// Get project ID
String projectId = ApiProxy.getCurrentEnvironment().getAppId();
// Remove partition information to get plain app ID
String appId = projectId.replaceFirst("(.*~)", "");
// Get access token
ArrayList<String> scopes = new ArrayList<String>();
scopes.add("https://www.googleapis.com/auth/datastore");
final AppIdentityService appIdentity = AppIdentityServiceFactory.getAppIdentityService();
final AppIdentityService.GetAccessTokenResult accessToken =
appIdentity.getAccessToken(scopes);
// Read export parameters
// If output prefix does not end with slash, add a timestamp
if (!outputUrlPrefix.substring(outputUrlPrefix.length() - 1).contentEquals("/")) {
String timeStamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
outputUrlPrefix = outputUrlPrefix + "/" + timeStamp + "/";
}
String[] namespaces = request.getParameterValues("namespace_id");
String[] kinds = request.getParameterValues("kind");
// Build export request
JSONObject exportRequest = new JSONObject();
exportRequest.put("output_url_prefix", outputUrlPrefix);
JSONObject entityFilter = new JSONObject();
if (kinds != null) {
JSONArray kindsJSON = new JSONArray(kinds);
entityFilter.put("kinds", kinds);
}
if (namespaces != null) {
JSONArray namespacesJSON = new JSONArray(namespaces);
entityFilter.put("namespaceIds", namespacesJSON);
}
exportRequest.put("entityFilter", entityFilter);
URL url = new URL("https://datastore.googleapis.com/v1/projects/" + appId + ":export");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.addRequestProperty("Content-Type", "application/json");
connection.addRequestProperty("Authorization", "Bearer " + accessToken.getAccessToken());
OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
exportRequest.write(writer);
writer.close();
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
JSONTokener exportResponseTokens = new JSONTokener(connection.getInputStream());
JSONObject exportResponse = new JSONObject(exportResponseTokens);
response.setContentType("text/plain");
response.getWriter().println("Export started:\n" + exportResponse.toString(4));
} else {
InputStream s = connection.getErrorStream();
InputStreamReader r = new InputStreamReader(s, StandardCharsets.UTF_8);
String errorMessage =
String.format(
"got error (%d) response %s from %s",
connection.getResponseCode(), CharStreams.toString(r), connection.toString());
log.warning(errorMessage);
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
response.setContentType("text/plain");
response.getWriter().println("Failed to initiate export.");
}
}
}
}
You can use the same cron.yaml from the docs:
cron:
- description: "Daily Cloud Datastore Export"
url: /cloud-datastore-export?namespace_id=&output_url_prefix=gs://BUCKET_NAME[/NAMESPACE_PATH]
target: cloud-datastore-admin
schedule: every 24 hours
Use gcloud to deploy the cron job:
gcloud app deploy cron.yaml
Make sure you complete this part to give GAE export and bucket permissions or else
you'll get permission denied errors:
https://cloud.google.com/datastore/docs/schedule-export#before_you_begin
The code snippet you showed is just a part of the typical GAE app skeleton specific for 1st generation standard environment python apps. You can easily recognize it in the main.py section of the python quickstart Hello World code review.
The code initializes the app variable (from the main python module, i.e. the main.py file) which is referenced in the app.yaml handler config as script: main.app.
The corresponding java app skeleton is significantly different, see the java quickstart Hello World code review. But no worries, you shouldn't need to specifically transform that code snippet, you just need to build your java app skeleton and focus on what the app handler actually does - making those POST requests to the datastore. Sorry I can't help more, but I'm not a java user.
What I really realized is that app.yaml is like Web.xml in java
and cloud-datastore-export is a servlet that communicates with gae to export data but I can't do more
I get "Error while updating 'end' in shadow node of type: BVLinearGradient" error when i run my react native app and the error seems to emanate from my MainApplication.java file here is my code:
package com.*;
import com.BV.LinearGradient.LinearGradientPackage;
import com.facebook.react.ReactPackage;
import com.horcrux.svg.SvgPackage;
import com.oblador.vectoricons.VectorIconsPackage;
import com.reactnativenavigation.NavigationApplication;
import com.wheelpicker.WheelPickerPackage;
import java.util.Arrays;
import java.util.List;
public class MainApplication extends NavigationApplication {
#Override
public boolean isDebug() {
// Make sure you are using BuildConfig from your own application
return BuildConfig.DEBUG;
}
#Override
public List<ReactPackage> createAdditionalReactPackages() {
// Add the packages you require here.
// No need to add RnnPackage and MainReactPackage
return Arrays.<ReactPackage>asList(
new WheelPickerPackage(),
new VectorIconsPackage(),
new SvgPackage(),
new LinearGradientPackage()
);
}
}
Please help me resolve this
This is a bug with the react-native-linear-gradient. The issue is in open status. For the time being, there are 2 solutions-
Replace start with startPoint and end with endPoint props for <LinearGradient/>
Downgrade react-native version to 0.50.3
The details for this issue is below:
https://github.com/react-native-community/react-native-linear-gradient/issues/246
I just started to play with MemCache in Google Apps Engine and every time I create CacheFactory I get this error :
net.sf.jsr107cache.CacheException:
Could not find class: 'com.google.appengine.api.memcache.jsr107cache.GCacheFactory'
at net.sf.jsr107cache.CacheManager.getCacheFactory(CacheManager.java:46)
I'm using Apps Engine SDK "1.5.0.1 - 2011-05-16" ( which is the latest ). I tested this in my local.
Anybody know how to fix this issue?
Here is my snippet of my code.
#SuppressWarnings("rawtypes")
Map props = new HashMap();
//props.put(GCacheFactory.EXPIRATION_DELTA, 3600);
try {
CacheFactory cacheFactory = CacheManager.getInstance().getCacheFactory();
cache = cacheFactory.createCache(props);
if(cache.containsKey("userAgent"))
{
userAgent = (String)cache.get("userAgent");
}else
{
cache.put("userAgent", userAgent+" from MEMCache");
}
} catch (CacheException e) {
e.printStackTrace();
}
This should be fixed in App Engine SDK 1.5.0.1.
Make sure you are importing:
import net.sf.jsr107cache.CacheException;
import net.sf.jsr107cache.CacheFactory;
import net.sf.jsr107cache.CacheManager;
I don't have any "Could not find class" error with the following sample code
package classnotfoundtest;
import net.sf.jsr107cache.CacheException;
import net.sf.jsr107cache.CacheFactory;
import net.sf.jsr107cache.CacheManager;
import java.io.IOException;
import javax.servlet.http.*;
#SuppressWarnings("serial")
public class ClassnotfoundtestServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
try {
CacheFactory cacheFactory = CacheManager.getInstance().getCacheFactory();
resp.setContentType("text/plain");
resp.getWriter().println("Hello, world");
} catch (CacheException e) {
e.printStackTrace(resp.getWriter());
}
}
}
Eclipse projects created with App Engine plugin 1.5.0 had the broken jsr107cache-1.1.jar added to their war/WEB-INF/lib directory.
Updating the SDK and plugin doesn't alter your projects, you'll need to fix that yourself.