How to get uwsgi to work with internal routing - uwsgi

Hi I'm trying to to get uwsgi to serve static files and untimately to try adding ".js" if the file was not found before defaulting to the python app.
I already compiled the pcre support into my uwsgi but still cannot get it to work.
As a first step I tried to set up a simple example. I created a file settings.ini:
[uwsgi]
route = ^/hi rewrite:/hello.html
route = ^/logo static:/icon.svg
route = ^/huhu static:/hello.html
and run
uwsgi --ini settings.ini --http=127.0.0.1:8000 --check-static static --wsgi-file app.py
The content of app.py is not relevant but I post it for completeness:
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return [b"went to python app"]
If I put files in a subfolder static (e.g. static/hello.html) then they are served correctly, also app.py is called when I navigate to anything that is neither found in the static folder nor matches anything in settings.ini.
However, if I navigate to http://127.0.0.1:8000/hi it goes to the app. I would expect to be served hello.html.
And if I navigate to http://127.0.0.1:8000/huhu I get The connection was reset error on the browser.
I also tried adding plugins = router_static or plugins = router_rewrite to settings.ini with no success.

Related

pyhdfs.HdfsIOException: Failed to find datanode, suggest to check cluster health. excludeDatanodes=null

I am trying to run hadoop using docker provided here:
https://github.com/big-data-europe/docker-hadoop
I use the following command:
docker-compose up -d
to up the service and am able to access it and browse file system using: localhost:9870. Problem rises whenever I try to use pyhdfs to put file on HDFS. Here is my sample code:
hdfs_client = HdfsClient(hosts = 'localhost:9870')
# Determine the output_hdfs_path
output_hdfs_path = 'path/to/test/dir'
# Does the output path exist? If not then create it
if not hdfs_client.exists(output_hdfs_path):
hdfs_client.mkdirs(output_hdfs_path)
hdfs_client.create(output_hdfs_path + 'data.json', data = 'This is test.', overwrite = True)
If test directory does not exist on HDFS, the code is able to successfully create it but when it gets to the .create part it throws the following exception:
pyhdfs.HdfsIOException: Failed to find datanode, suggest to check cluster health. excludeDatanodes=null
What surprises me is that my code is able to create the empty directory but fails to put the file on HDFS. My docker-compose.yml file is exactly the same as the one provided in the github repo. The only change I've made is in the hadoop.env file where I change:
CORE_CONF_fs_defaultFS=hdfs://namenode:9000
to
CORE_CONF_fs_defaultFS=hdfs://localhost:9000
I have seen this other post on sof and tried the following command:
hdfs dfs -mkdir hdfs:///demofolder
which works fine in my case. Any help is much appreciated.
I would keep the default CORE_CONF_fs_defaultFS=hdfs://namenode:9000 setting.
Works fine for me after adding a forward slash to the paths
import pyhdfs
fs = pyhdfs.HdfsClient(hosts="namenode")
output_hdfs_path = '/path/to/test/dir'
if not fs.exists(output_hdfs_path):
fs.mkdirs(output_hdfs_path)
fs.create(output_hdfs_path + '/data.json', data = 'This is test.')
# check that it's present
list(fs.walk(output_hdfs_path))
[('/path/to/test/dir', [], ['data.json'])]

CraftCMS exception on first install (HTTP 503 – ServiceUnavailableHttpException)

I'm trying to install CraftCMS for the first time, and appear to have gone through all the steps on the installation guide - https://docs.craftcms.com/v3/installation.html#step-1-download-craft - yet I'm getting an Exception.
HTTP 503 – Service Unavailable – craft\web\ServiceUnavailableHttpException
Here is the line (509 in /var/www/craft/vendor/craftcms/cms/src/web/Application.php) that's throwing the exception:
// Should they be accessing the installer?
if (!$isInstalled) {
if (!$isCpRequest) {
throw new ServiceUnavailableHttpException();
}
Below is the call stack:
craft\web\ServiceUnavailableHttpException in /var/www/craft/vendor/craftcms/cms/src/web/Application.php:509
Stack trace:
#0 /var/www/craft/vendor/craftcms/cms/src/web/Application.php(184): craft\web\Application->_processInstallRequest(Object(craft\web\Request))
#1 /var/www/craft/vendor/yiisoft/yii2/base/Application.php(386): craft\web\Application->handleRequest(Object(craft\web\Request))
#2 /var/www/craft/web/index.php(21): yii\base\Application->run()
#3 {main}
I'm using v3.0.24 as far as I can see:
- Installing craftcms/cms (3.0.24): Downloading (100%)
As I haven't even got started with the CMS, I don't really know what more info to give - or where to go from here. The .env file has been copied, there really is no more instruction to do anything. Any ideas?
UPDATE
I've identified this section here (in /vendor/yiisoft/yii2/db/mysql/Schema.php) is returning an empty array:
protected function findTableNames($schema = '')
{
$sql = 'SHOW TABLES';
if ($schema !== '') {
$sql .= ' FROM ' . $this->quoteSimpleTableName($schema);
}
return $this->db->createCommand($sql)->queryColumn();
}
The table have been setup, I can see them in the MySQL console. My .env db config settings seem totally fine too.
Try the following steps for install craft3 by the terminal.
create a virtual host that point to the web directory of the project setup.
composer create-project craftcms/craft
./craft setup/security-key
./craft setup
After completing the above steps, provide the permission of storage, config, web, Modules, template folder.
Admin URL: http:///index.php/admin
For those creating a fresh install using Craft CMS Nitro and its nitro create command, don't forget to run the the Setup Wizard as a final step, as described in Step 6: Run the Setup Wizard, from the Craft Docs.
This will populate the database with Craft's tables and what not and should address the 503 error.

Docker: Can't read class path resource from spring boot application

Reading a classpath resource as,
try {
final ClassPathResource classPathResource = new ClassPathResource(format("location%sGeoLite2-City.mmdb", File.separator));
final File database = classPathResource.getFile();
dbReader = new DatabaseReader.Builder(database).build();
} catch (Exception e) {
System.out.println("Exception: " + e);
}
I've packaged this with docker using following Dockerfile,
FROM java:8
ADD build/libs/*.jar App.jar
CMD java -jar App.jar
But while running this application as docker run -p 8080:8080 app-image I can hit the application endpoint and from application logs I can see it fails to read this file (following is from logs),
Exception: java.io.FileNotFoundException: class path resource [location/GeoLite2-City.mmdb] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/App.jar!/BOOT-INF/classes!/location/GeoLite2-City.mmdb
Would appreciate any comment, Things to know before you comment,
**- Running on windows 10, intellij 2018.2, jdk 8
- Can run application successfully with intellij as well as command line
- File exists in jar (I did extract jar and checked )
**
Since you are using springboot you can try to use the following annotation for loading your classpath resource. Worked for me because I had the same exception. Be aware that the directory "location" must be under the src/main/resources folder:
#Value("classpath:/location/GeoLite2-City.mmdb")
private Resource geoLiteCity;
Without springboot you could try:
try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream("/location/GeoLite2-City.mmdb")) {
... //convert to file and other stuff
}
Also the answers before were correct as the use of "/" is not good at all and File.separator would be the best choice.
It is not a good approach to use slashes.
Always use File Seperators as they work irrespective of System OS.
Change
(location\\GeoLite2-City.mmdb)
to
("location"+ File.separator +"GeoLite2-City.mmdb")
Refer this for more.
https://www.journaldev.com/851/java-file-separator-separatorchar-pathseparator-pathseparatorchar
Difference between File.separator and slash in paths
Had the same issue, the file worked when running the Spring boot app but was not working in Docker. My issue got resolved by using ClassPathResource for the resource and reading the resource as stream using InputStreamReader.
Resource resource = new ClassPathResource("test-xyz.json");
InputStream inputStream = null;
try {
inputStream = resource.getInputStream();
Reader reader = new InputStreamReader(inputStream, "UTF-8");
....

Docker, ENOENT: no such file or directory

I have a Storage constant that is used in a file called listingController.js
const storage = Storage({
keyFilename: "../key/keyname.json"
});
Everything works fine when I'm not using Docker but after I create a Docker image and deploy it on server I get the following error:
ENOENT: no such file or directory, open '/key/keyname.json'
at wrapError (/app/node_modules/gcs-resumable-upload/build/src/index.js:17:12)
at /app/node_modules/gcs-resumable-upload/build/src/index.js:235:19
at getToken (/app/node_modules/google-auto-auth/index.js:27:9)
at getAuthClient (/app/node_modules/google-auto-auth/index.js:233:9)
at <anonymous>
Here I see a problem that the '..' is ignored in front of the path which is why I think that file is not found.
Here is my project structure:
src
--- key
----- keyname.json
----- firebasekeyfilename.json
--- controller
----- listingController.js
----- firebaseController.js
I have tried all different combinations of file names and paths but I cannot get it to find that file.
Does anyone have a clue why this is happening?
In my firebaseController I have the following reference to a similar file in the same folder and it works fine.
var serviceAccount = require("../key/firebasekeyfilename");
The only difference is that the path is inside require() and I guess that requires a different path.
Been stuck with this for a couple of days now, any pointers would be appreciated, thank!

symfony/yaml backed symfony/config not parsing environment variables

I have recreated a simple example in this tiny github repo. I am attempting to use symfony/dependency-injection to configure monolog/monolog to write logs to php://stderr. I am using a yaml file called services.yml to configure dependency injection.
This all works fine if my yml file looks like this:
parameters:
log.file: 'php://stderr'
log.level: 'DEBUG'
services:
stream_handler:
class: \Monolog\Handler\StreamHandler
arguments:
- '%log.file%'
- '%log.level%'
log:
class: \Monolog\Logger
arguments: [ 'default', ['#stream_handler'] ]
However, my goal is to read the path of the log files and the log level from environment variables, $APP_LOG and LOG_LEVEL respectively. According to The symphony documentations on external paramaters the correct way to do that in the services.yml file is like this:
parameters:
log.file: '%env(APP_LOG)%'
log.level: '%env(LOGGING_LEVEL)%'
In my sample app I verified PHP can read these environment variables with the following:
echo "Hello World!\n\n";
echo 'APP_LOG=' . (getenv('APP_LOG') ?? '__NULL__') . "\n";
echo 'LOG_LEVEL=' . (getenv('LOG_LEVEL') ?? '__NULL__') . "\n";
Which writes the following to the browser when I use my original services.yml with hard coded values.:
Hello World!
APP_LOG=php://stderr
LOG_LEVEL=debug
However, if I use the %env(VAR_NAME)% syntax in services.yml, I get the following error:
Fatal error: Uncaught UnexpectedValueException: The stream or file "env_PATH_a61e1e48db268605210ee2286597d6fb" could not be opened: failed to open stream: Permission denied in /var/www/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php:107 Stack trace: #0 /var/www/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php(37): Monolog\Handler\StreamHandler->write(Array) #1 /var/www/vendor/monolog/monolog/src/Monolog/Logger.php(337): Monolog\Handler\AbstractProcessingHandler->handle(Array) #2 /var/www/vendor/monolog/monolog/src/Monolog/Logger.php(532): Monolog\Logger->addRecord(100, 'Initialized dep...', Array) #3 /var/www/html/index.php(17): Monolog\Logger->debug('Initialized dep...') #4 {main} thrown in /var/www/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php on line 107
What am I doing wrong?
Ok you need a few things here. First of all you need version 3.3 of Symfony, which is still in beta. 3.2 was the released version when I encountered this. Second you need to "compile" the environment variables.
Edit your composer.json with the following values and run composer update. You might need to update other dependencies. You can substitute ^3.3 with dev-master.
"symfony/config": "^3.3",
"symfony/console": "^3.3",
"symfony/dependency-injection": "^3.3",
"symfony/yaml": "^3.3",
You will likely have to do this for symfony/__WHATEVER__ if you have other symfony components.
Now in you're code after you load your yaml configuration into your dependency container you compile it.
So after you're lines here (perhaps in bin/console):
$container = new ContainerBuilder();
$loader = new YamlFileLoader($container, new FileLocator(__DIR__ . DIRECTORY_SEPARATOR . '..'));
$loader->load('services.yml');
Do this:
$container->compile(true);
Your IDE's intellisense might tell you compile takes no parameters. That's ok. That's because compile() grabs its args indirectly via func_get_arg().
public function compile(/*$resolveEnvPlaceholders = false*/)
{
if (1 <= func_num_args()) {
$resolveEnvPlaceholders = func_get_arg(0);
} else {
. . .
}
References
Github issue where this was discussed
Pull request to add compile(true)
Using this command after loading your services.yaml file should help.
$containerBuilder->compile(true);
given your files gets also validated by the checks for proper configurations which this method also does. The parameter is $resolveEnvPlaceholders which makes environmental variables accessible to the yaml services configuration.

Resources