/_ah/start is never called in Go on AppEngine - google-app-engine

When I deploy my Go application to GAE, the /_ah/start endpoint is never invoked. When I run the following code, the log does not contain the "STARTING" entry and / does not have the X set.
What am I missing?
server.go:
package main
import (
"net/http"
"google.golang.org/appengine"
"google.golang.org/appengine/log"
)
var X string
func init() {
http.HandleFunc("/_ah/start", start)
http.HandleFunc("/", meh)
}
func start(w http.ResponseWriter, r *http.Request) {
X = "!!!!!"
c := appengine.NewContext(r)
log.Infof(c, "STARTING")
}
func meh(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("The value is: " + X))
}
app.yaml:
application: my-app
version: 1
runtime: go
api_version: go1
handlers:
- url: /.*
secure: always
script: _go_app

app.yml with manual scaling.
application: my-app
version: 1
runtime: go
api_version: go1
handlers:
- url: /.*
secure: always
script: _go_app
instance_class: B8
manual_scaling:
instances: 5
https://cloud.google.com/appengine/docs/go/an-overview-of-app-engine#scaling_types_and_instance_classes

Related

I have issue JSONDecodeError at /profile

JSONDecodeError at /profile
Expecting value: line 1 column 1 (char 0)
Request Method: POST
Request URL: http://127.0.0.1:8000/profile
Django Version: 3.2.6
Exception Type: JSONDecodeError
Exception Value:
Expecting value: line 1 column 1 (char 0)
Exception Location: C:\Users\bismi\AppData\Local\Programs\Python\Python310\lib\json\decoder.py, line 355, in raw_decode
Python Executable: C:\Users\bismi\AppData\Local\Programs\Python\Python310\python.exe
Python Version: 3.10.6
Python Path:
['C:\Users\bismi\OneDrive\Desktop\connectyfi modftn\connectyfi',
'C:\Users\bismi\AppData\Local\Programs\Python\Python310\python310.zip',
'C:\Users\bismi\AppData\Local\Programs\Python\Python310\DLLs',
'C:\Users\bismi\AppData\Local\Programs\Python\Python310\lib',
'C:\Users\bismi\AppData\Local\Programs\Python\Python310',
'C:\Users\bismi\AppData\Local\Programs\Python\Python310\lib\site-packages']

Can I dynamically set the condition in an IoT Rule SQL?

in this section of yaml file, I need to update condition in sql statement.
for example, user can reset condition to equal 20 instead of 30.
NotifyTemperatureAlarm:
Type: 'AWS::Serverless::Function'
DependsOn: AlertSNSTopic
Properties:
CodeUri: src/notify_temperature_alarm/
Handler: app.lambda_handler
Runtime: python3.9
Architectures:
- x86_64
Events:
PutImageEvent:
Type: IoTRule
Properties:
Sql: Select * FROM 'device/temperature/alarms' where value > 30
Policies:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action: "sns:*"
Resource: "*"
Environment:
Variables:
alert_sns: !Ref AlertSNSTopic
make your condition in parameters section such as
Parameters:
TemperatureThreshold:
Type: Number
Default: '20'
then update NotifyTemperatureAlarm such as
NotifyTemperatureAlarm:
Type: 'AWS::Serverless::Function'
DependsOn: AlertSNSTopic
Properties:
CodeUri: src/notify_temperature_alarm/
Handler: app.lambda_handler
Runtime: python3.9
Architectures:
- x86_64
Events:
PutImageEvent:
Type: IoTRule
Properties:
Sql: !Sub "SELECT * FROM 'device/temperature/alarms' where value > ${TemperatureThreshold}"
Policies:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action: "sns:*"
Resource: "*"
Environment:
Variables:
alert_sns: !Ref AlertSNSTopic
to make TemperatureThreshold Adjustable, you can update it from cloudformation such as
client = boto3.client('cloudformation')
response = client.update_stack(
StackName = "your_stack_name",
UsePreviousTemplate = True,
Capabilities = ['CAPABILITY_IAM'],
Parameters=[
{
'ParameterKey': 'TemperatureThreshold',
'ParameterValue': str(new_threshold),
}
]
)

Trouble starting dgraph with TLS

I'm trying to start a dgraph server with TLS enabled, my server config file is defined as following:
# Folder in which to store exports.
export: export
# Fraction of dirty posting lists to commit every few seconds.
gentlecommit: 0.33
# RAFT ID that this server will use to join RAFT groups.
idx: 1
# Port to run server on. (default 8080)
port: 8080
# GRPC port to run server on. (default 9080)
grpc_port: 9080
# Port used by worker for internal communication.
workerport: 12345
# Estimated memory the process can take. Actual usage would be slightly more
memory_mb: 4096
# The ratio of queries to trace.
trace: 0.33
# Directory to store posting lists.
p: p
# Directory to store raft write-ahead logs.
w: w
# Debug mode for testing.
debugmode: true
# Address of dgraphzero
peer: localhost:8888
# Use TLS connections with clients.
tls.on: true
# CA Certs file path.
#tls.ca_certs: /Users/pauloferreira/Workspace/RagnarTech/Node/base_backend_njs/certificates/development/development-server-root-CA.pem
# Include System CA into CA Certs.
tls.use_system_ca: true
# Certificate file path.
tls.cert: /Users/pauloferreira/Workspace/RagnarTech/Node/base_backend_njs/certificates/development/development-server-root-CA.pem
# Certificate key file path.
tls.cert_key: /Users/pauloferreira/Workspace/RagnarTech/Node/base_backend_njs/certificates/development/development-server-root-CA.key
# Certificate key passphrase.
#tls.cert_key_passphrase string
# Enable TLS client authentication
#tls.client_auth string
# TLS max version. (default "TLS12")
#tls.max_version string
# TLS min version. (default "TLS11")
#tls.min_version string
As soon as I start dgraphzero and dgraph, if the configuration tls.on is equal true, this output is shown:
Setting up listener at: localhost:8888
Setting up listener at: localhost:8889
2017/10/19 16:09:36 main.go:163: Loading configuration from file: development.conf
2017/10/19 16:09:36 init.go:74: Picked flag from config: ["export" = export]
2017/10/19 16:09:36 init.go:74: Picked flag from config: ["grpc_port" = 9080]
2017/10/19 16:09:36 init.go:74: Picked flag from config: ["workerport" = 12345]
2017/10/19 16:09:36 init.go:74: Picked flag from config: ["p" = p]
2017/10/19 16:09:36 init.go:74: Picked flag from config: ["tls.ca_certs" = /Users/pauloferreira/Workspace/RagnarTech/Node/base_backend_njs/certificates/development/development-server-root-CA.pem]
2017/10/19 16:09:36 init.go:74: Picked flag from config: ["memory_mb" = 4096]
2017/10/19 16:09:36 init.go:74: Picked flag from config: ["peer" = localhost:8888]
2017/10/19 16:09:36 init.go:74: Picked flag from config: ["gentlecommit" = 0.33]
2017/10/19 16:09:36 init.go:74: Picked flag from config: ["idx" = 1]
2017/10/19 16:09:36 init.go:74: Picked flag from config: ["port" = 8080]
2017/10/19 16:09:36 init.go:74: Picked flag from config: ["trace" = 0.33]
2017/10/19 16:09:36 init.go:74: Picked flag from config: ["tls.on" = true]
2017/10/19 16:09:36 init.go:74: Picked flag from config: ["tls.cert" = /Users/pauloferreira/Workspace/RagnarTech/Node/base_backend_njs/certificates/development/development-server-root-CA.pem]
2017/10/19 16:09:36 init.go:74: Picked flag from config: ["w" = w]
2017/10/19 16:09:36 init.go:74: Picked flag from config: ["debugmode" = true]
2017/10/19 16:09:36 init.go:74: Picked flag from config: ["tls.use_system_ca" = true]
2017/10/19 16:09:36 init.go:74: Picked flag from config: ["tls.cert_key" = /Users/pauloferreira/Workspace/RagnarTech/Node/base_backend_njs/certificates/development/development-server-root-CA.key]
Dgraph version : v0.8.3
Commit SHA-1 : 40175d0
Commit timestamp : 2017-10-18 15:55:02 +1100
Branch : HEAD
2017/10/19 16:09:36 node.go:234: Found hardstate: {Term:2 Vote:1 Commit:4 XXX_unrecognized:[]}
2017/10/19 16:09:36 node.go:246: Group 0 found 4 entries
2017/10/19 16:09:36 raft.go:292: Restarting node for dgraphzero
2017/10/19 16:09:36 raft.go:567: INFO: 1 became follower at term 2
2017/10/19 16:09:36 raft.go:315: INFO: newRaft 1 [peers: [], term: 2, commit: 4, applied: 0, lastindex: 4, lastterm: 2]
Running Dgraph zero...
2017/10/19 16:09:36 open : no such file or directory
I can't find what is causing the error open : no such file or directory, anyone experienced this? I'm using MacOS 10.12.3 (16D32) and installed dgraph version v0.8.3 using the command curl https://get.dgraph.io -sSf | bash
Thanks in advance.
I think this is a bug (update: it actually was confirmed as a bug and was fixed).
I've tried running it on Ubuntu and I've got the same error with tls.on.
Next I found the semi-manual test suite for tls here.
Running it confirmed the error, tests required small adjustments (add --memory_mb 2048), but after that the same failure was reproduced.
To confirm it I also downloaded dgraph sources and checked what's going on under delve debugger:
1) The config file is parsed and parameters are saved into global vars
2) TLS-related parameters are used to create the tlsCfg
- Here we already can see the problem: not all the parameters are passed, for example, tlsKey and tlsKeyPath are missing
3) If we look deeper, into tls_helper.go, where the TLS actually configured, we can find that parameters from the config are
passed into the parseCertificate method
4) Here we use config.Key and config.KeyPassphrase, but they are empty
182: func GenerateTLSConfig(config TLSHelperConfig) (tlsCfg *tls.Config, reloadConfig func(), err error) {
183: wrapper := new(wrapperTLSConfig)
184: tlsCfg = new(tls.Config)
185: wrapper.config = tlsCfg
186:
=> 187: cert, err := parseCertificate(config.CertRequired, config.Cert, config.Key, config.KeyPassphrase)
188: if err != nil {
189: return nil, nil, err
190: }
191:
192: if cert != nil {
(dlv) p config.CertRequired
true
(dlv) p config.Cert
"/home/seb/web/dgraph-test/test2.crt"
(dlv) p config.Key
""
(dlv) p config.KeyPassphrase
Then it fails inside the parseCertificate when it tries to read the file with certificate key.
I posted the issue on github.

Runtime error when attempting to read *http.Response Body, having used urlfetch.Transport

App Engine does not allow use of DefaultClient, providing the urlfetch service instead. The following minimal example deploys and works pretty much as expected:
package app
import (
"fmt"
"net/http"
"appengine"
"appengine/urlfetch"
"code.google.com/p/goauth2/oauth"
)
func init () {
http.HandleFunc("/", home)
}
func home(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
config := &oauth.Config{
ClientId: "<redacted>",
ClientSecret: "<redacted>",
Scope: "email",
AuthURL: "https://www.facebook.com/dialog/oauth",
TokenURL: "https://graph.facebook.com/oauth/access_token",
RedirectURL: "http://example.com/",
}
code := r.FormValue("code")
if code == "" {
http.Redirect(w, r, config.AuthCodeURL("foo"), http.StatusFound)
}
t := &oauth.Transport{Config: config, Transport: &urlfetch.Transport{Context: c}}
tok, _ := t.Exchange(code)
graphResponse, _ := t.Client().Get("https://graph.facebook.com/me")
fmt.Fprintf(w, "<pre>%s<br />%s</pre>", tok, graphResponse)
}
With correct ClientId, ClientSecret and RedirectURL, this produces the following output (edited for brevity):
&{AAADTWGsQ5<snip>kMdjh5VKwZDZD 0001-01-01 00:00:00 +0000 UTC}
&{200 OK %!s(int=200) HTTP/1.1 %!s(int=1) %!s(int=1)
map[Connection:[keep-alive] Access-Control-Allow-Origin:[*]
<snip>
Content-Type:[text/javascript; charset=UTF-8]
Date:[Wed, 06 Feb 2013 12:06:45 GMT] X-Google-Cache-Control:[remote-fetch]
Cache-Control:[private, no-cache, no-store, must-revalidate] Pragma:[no-cache]
X-Fb-Rev:[729873] Via:[HTTP/1.1 GWA] Expires:[Sat, 01 Jan 2000 00:00:00 GMT]]
%!s(*urlfetch.bodyReader=&{[123 34 105 100 <big snip> 48 48 34 125] false false})
%!s(int64=306) [] %!s(bool=true) map[] %!s(*http.Request=&{GET 0xf840087230
HTTP/1.1 1 1 map[Authorization:[Bearer AAADTWGsQ5NsBAC4yT0x1shZAJAtODOIx0tZCb
TYTjxFC4esEqCjPDi3REMKHBUjZCX4FIKLO1UjMpJxhJZCfGFcOJlFu7UvehkMdjh5VKwZDZD]]
0 [] false graph.facebook.com map[] map[] })}
It certainly seems like I'm consistently getting an *http.Response back, so I would expect to be able to read from the response Body. However, any mention of Body--for example with:
defer graphResponse.Body.Close()
compiles, deploys, but results in the following runtime error:
panic: runtime error: invalid memory address or nil pointer dereference
runtime.panic go/src/pkg/runtime/proc.c:1442
runtime.panicstring go/src/pkg/runtime/runtime.c:128
runtime.sigpanic go/src/pkg/runtime/thread_linux.c:199
app.home app/app.go:33
net/http.HandlerFunc.ServeHTTP go/src/pkg/net/http/server.go:704
net/http.(*ServeMux).ServeHTTP go/src/pkg/net/http/server.go:942
appengine_internal.executeRequestSafely go/src/pkg/appengine_internal/api_prod.go:240
appengine_internal.(*server).HandleRequest go/src/pkg/appengine_internal/api_prod.go:190
reflect.Value.call go/src/pkg/reflect/value.go:526
reflect.Value.Call go/src/pkg/reflect/value.go:334
_ _.go:316
runtime.goexit go/src/pkg/runtime/proc.c:270
What am I missing? Is this because of the use of urlfetch rather than DefaultClient?
Okay, this was of course my own silly fault but I can see how others could fall into the same trap so here's the solution, prompted by Andrew Gerrand and Kyle Lemons in this google-appengine-go topic (thanks guys).
First of all, I wasn't handling requests to favicon.ico. That can be taken care of by following the instructions here and adding a section to app.yaml:
- url: /favicon\.ico
static_files: images/favicon.ico
upload: images/favicon\.ico
This fixed panics on favicon requests, but not panics on requests to '/'. Problem was, I'd assumed that an http.Redirect ends handler execution at that point. It doesn't. What was needed was either a return statement following the redirect, or an else clause:
code := r.FormValue("code")
if code == "" {
http.Redirect(w, r, config.AuthCodeURL("foo"), http.StatusFound)
} else {
t := &oauth.Transport{Config: config, Transport: &urlfetch.Transport{Context: c}}
tok, _ := t.Exchange(code)
fmt.Fprintf(w, "%s", tok.AccessToken)
// ...
}
I don't recommend ignoring the error of course but this deploys and runs as expected, producing a valid token.

'self' not defined, jinja2, appengine

Error:
self.response.out.write(template.render(template_values)) NameError:
name 'self' is not defined
pertains to lines marked # ERROR, with other notes:
#!/usr/bin/env python27
import cgi
import webapp2
import jinja2
import time
import datetime
import urllib
#import cgitb; cgitb.enable()
import os
from google.appengine.ext import db
from google.appengine.api import users
from google.appengine.api import memcache
jinja_environment = jinja2.Environment(autoescape=True,
loader=jinja2.FileSystemLoader(os.path.join(os.path.dirname(__file__), 'templates')))
class Visitor(db.Model): # I still need this with jinja2, yes?
name = db.StringProperty(required=1)
mood = db.StringProperty(choices=["good","bad","fair"])
date = db.DateTimeProperty(auto_now_add=True)
class MainPage(webapp2.RequestHandler):
def get(self): # ERROR HERE
visitor_query = Visitor.all().order('-date') #not sure about query...need to get curent visitor's submitted form values (name, mood). no log-in in app.
visitor = visitor_query.fetch(1)
template_values = {
'visitor': visitor,
'url': url, #not sure how this applies, just following tutorial
'url_linktext': url_linktext,
}
localtime = time.localtime(time.time())
mon = localtime[1] # MONTH
h = localtime[3] # HOUR
span = "morning" if h == range(5,14) else "afternoon" if h == range(17,7) else "evening"
if mon <= 3:
var1 = "winter"
# more variables in if/elif statement here...I call these variables from index.html...
# name = self.request.get("name") # not sure if I need to define these variables here using jinja2...tutorial does not define entity properties in example.
# name = name.capitalize()
# mood = self.request.get("mood")
template = jinja_environment.get_template('index.html')
self.response.out.write(template.render(template_values)) # ERROR HERE
class Process(webapp2.RequestHandler):
def post(self):
name = self.request.get("name")
name = name.capitalize()
mood = self.request.get("mood")
message = Visitor(name=name, mood=mood)
if users.get_current_user():
message.name = users.get_current_user() #not sure if I need users.get_current...no log-in required
message.mood = self.request.get("mood")
message.put()
self.redirect("/")
app = webapp2.WSGIApplication([('/', MainPage)],
debug=True)
app.yaml:
application: emot
version: 1
runtime: python27
api_version: 1
threadsafe: true
handlers:
#- url: /stylesheets/ # I read no static files allowed with jinja2...not sure how I'll handle CSS...
# static_dir: stylesheets
- url: /.*
script: main.app
libraries:
- name: jinja2
version: latest
index.yaml (all of this works without jinja2...)
indexes:
- kind: Visitor
ancestor: yes
properties:
- name: name
- name: mood
- name: date
direction: desc
Also, I have alternately copied (not cut) jinja2 folder from g00gle_appengine/lib directory to my app directory folder, including just copying the "jinja" folder (as similar method worked using gdata atom & src...) I have also installed python-jinja2, which is located at: /usr/share/doc/python-jinja2
My index.html is in directory "templates" in my app directory. Thanks in advance for getting me going.
From the code you've posted, it looks like the erroring line of code (and the preceding few) aren't indented far enough.
The get method should be aligned as follows:
def get(self): # ERROR HERE
visitor_query = Visitor.all().order('-date') #not sure about query...need to get curent visitor's submitted form values (name, mood). no log-in in app.
visitor = visitor_query.fetch(1)
template_values = {
'visitor': visitor,
'url': url, #not sure how this applies, just following tutorial
'url_linktext': url_linktext,
}
localtime = time.localtime(time.time())
mon = localtime[1] # MONTH
h = localtime[3] # HOUR
span = "morning" if h == range(5,14) else "afternoon" if h == range(17,7) else "evening"
if mon <= 3:
var1 = "winter"
# more variables in if/elif statement here...I call these variables from index.html...
# name = self.request.get("name") # not sure if I need to define these variables here using jinja2...tutorial does not define entity properties in example.
# name = name.capitalize()
# mood = self.request.get("mood")
template = jinja_environment.get_template('index.html')
self.response.out.write(template.render(template_values)) # ERROR HERE

Resources