Hadoop DistributedCache caching files without absolute path? - apache

I am in the process of migrating to YARN and it seems the behavior of the DistributedCache changed.
Previously, I would add some files to the cache as follows:
for (String file : args) {
Path path = new Path(cache_root, file);
URI uri = new URI(path.toUri().toString());
DistributedCache.addCacheFile(uri, conf);
}
The path would typically look like
/some/path/to/my/file.txt
Which pre-exists on HDFS and would essentially end up in the DistributedCache as
/$DISTRO_CACHE/some/path/to/my/file.txt
I could symlink to it in my current working directory and use with DistributedCache.getLocalCacheFiles()
With YARN, it seems this file instead ends up in the cache as:
/$DISTRO_CACHE/file.txt
ie, the 'path' part of the file URI got dropped and only the filename remains.
How does with work with different absolute paths ending up with the same filename? Consider the following case:
DistributedCache.addCacheFile("some/path/to/file.txt", conf);
DistributedCache.addCacheFile("some/other/path/to/file.txt", conf);
Arguably someone could use fragments:
DistributedCache.addCacheFile("some/path/to/file.txt#file1", conf);
DistributedCache.addCacheFile("some/other/path/to/file.txt#file2", conf);
But this seems unnecessarily harder to manage. Imagine the scenario where those are command-line arguments, you somehow need to manage that those 2 filenames, although different absolute paths would definitely clash in the DistributedCache and therefore need to re-map these filenames to fragments and propagate as such to the rest of the program?
Is there an easier way to manage this?

Try to add files into Job
It's most likely how you're actually configuring the job and then accessing them in the Mapper.
When you're setting up the job you're going to do something like
job.addCacheFile(new Path("cache/file1.txt").toUri());
job.addCacheFile(new Path("cache/file2.txt").toUri());
Then in your mapper code the urls are going to be stored in an array which can be accessed like so.
URI file1Uri = context.getCacheFiles()[0];
URI file2Uri = context.getCacheFiles()[1];
Hope this could help you.

Related

Migrating from Microsoft.Azure.Storage.Blob to Azure.Storage.Blobs - directory concepts missing

These are great guides for migrating between the different versions of NuGet package:
https://github.com/Azure/azure-sdk-for-net/blob/Azure.Storage.Blobs_12.6.0/sdk/storage/Azure.Storage.Blobs/README.md
https://elcamino.cloud/articles/2020-03-30-azure-storage-blobs-net-sdk-v12-upgrade-guide-and-tips.html
However I am struggling to migrate the following concepts in my code:
// Return if a directory exists:
container.GetDirectoryReference(path).ListBlobs().Any();
where GetDirectoryReference is not understood and there appears to be no direct translation.
Also, the concept of a CloudBlobDirectory does not appear to have made it into Azure.Storage.Blobs e.g.
private static long GetDirectorySize(CloudBlobDirectory directoryBlob) {
long size = 0;
foreach (var blobItem in directoryBlob.ListBlobs()) {
if (blobItem is BlobClient)
size += ((BlobClient) blobItem).GetProperties().Value.ContentLength;
if (blobItem is CloudBlobDirectory)
size += GetDirectorySize((CloudBlobDirectory) blobItem);
}
return size;
}
where CloudBlobDirectory does not appear anywhere in the API.
There's no such thing as physical directories or folders in Azure Blob Storage. The directories you sometimes see are part of the blob (e.g. folder1/folder2/file1.txt). The List Blobs requests allows you to add a prefix and delimiter in a call, which are used by the Azure Portal and Azure Data Explorer to create a visualization of folders. As example prefix folder1/ and delimiter / would allow you to see the content as if folder1 was opened.
That's exactly what happens in your code. The GetDirectoryReference() adds a prefix. The ListBlobs() fires a request and Any() checks if any items return.
For V12 the command that'll allow you to do the same would be GetBlobsByHierarchy and its async version. In your particular case where you only want to know if any blobs exist in the directory a GetBlobs with prefix would also suffice.

vNext ConfigurationModel null reference-ing when picking up a config.json?

using Microsoft.Framework.ConfigurationModel;
---
public Startup(IHostingEnvironment env)
{
var config = new Configuration();
config.AddEnvironmentVariables();
config.AddJsonFile("config.json");
}
Using the above, with the config.json placed in the root directory under the project name, I get a null reference exception?
This is practically a brand new/empty solution, I've never had this issue before.
I've tried empty files, no file, the default generated contents, different file extension, all give the same error, leading me to think that it is looking outside what should be the root dir.
However, it also does the same when supplied with a direct filepath...
It also doesn't fail when adding env variables on the line above, so it's not likely to be an issue with the Configuration object itself.
Same behaviour across both dnx core/coreclr and full.
Turns out Microsoft.Framework.ConfigurationModel from beta4 was renamed to Microsoft.Framework.Configuration in beta 5/6
with the = new Configuration method being replaced with having to use a ConfigurationBuilder, specifying the app path with appEnv.ApplicationBasePath in it's constructor.
= new ConfigurationBuilder(appEnv.ApplicationBasePath)
See: https://github.com/aspnet/Announcements/issues/25

Get path of App_Data folder in the Seed method of EF migration configuration class

How do you get the path of the App_Data folder in the Seed method of the configuration class of code first migrations.
I want to read from a file I've put in the App_Data folder and the Seed method runs after the update-database command. HttpContext.Current.Server.MapPath obviously does not work because there is no HttpContext at that point.
I got it to work with something like:
string MyPath = AppDomain.CurrentDomain.BaseDirectory + "/../App_Data"
because AppDomain.CurrentDomain.BaseDirectory ends at the "/bin" directory.
Here is a quick-and-dirty way to get you started:
var myPath = AppDomain.CurrentDomain.BaseDirectory;
//to quickly show the path, either attach another debugger or just throw an exception
throw new Exception(myPath);
#Rusty Divine gave a good answer, however maybe you will find this is better for you:
System.IO.Path.Combine( System.Text.RegularExpressions.Regex.Replace(AppDomain.CurrentDomain.BaseDirectory, #"\\bin\\Debug$", String.Empty, System.Text.RegularExpressions.RegexOptions.IgnoreCase) , RELATIVE_PATH, "FILENAME.EXE");
For example:
System.IO.Path.Combine( System.Text.RegularExpressions.Regex.Replace(AppDomain.CurrentDomain.BaseDirectory, #"\\bin$", String.Empty, System.Text.RegularExpressions.RegexOptions.IgnoreCase) , "App_Data\\Init", "fileName.txt");
In that way (using Regx), we make sure the only replace could be is at the suffix (at the end) of the AppDomain.CurrentDomain.BaseDirectory String. If there is sub folders in the server path named: "\bin\Debug" they won't be replaced.
This solution is case insensitive, meaning "\BIN\debug" will also be replaced.
Moreover, you don't need to append the strings to one string.
System.IO.Path.Combine will do it for you.
For what it's worth... you need to do a string replace if you are going to use BaseDirectory in your unit test. But, this still has the problem that it uses the path of your unit test project so be weary of that if you are trying to point to files in another project. In this case you will have to hard code the path.
AppDomain.CurrentDomain.BaseDirectory.Replace("\\bin\\Debug","") + "\\App_Data";

Resolving relative paths outside the standard directories (applicationDirectory, desktopDirectory, etc)

I need to navigate to a file relative to my applicationDirectory, but as it says in the documentation:
No ".." reference that reaches the file system root or the application-persistent storage root passes that node; it is ignored.
But the crazy thing is that if I do something like
File.applicationDirectory.resolvePath("/home/myHome/");
I can get anywhere in the filesystem.
My question is:
is there a workaround to navigate from my applicationDirectory to a relative path like "../../my.cfg" ?? (I need to read a config file generated by a different application)
if you are trying to access root privileged folders - than you can not.
in other cases try do next "home/blah/blah/blah/../../my.cfg" and research once again http://help.adobe.com/en_US/AIR/1.5/jslr/flash/filesystem/File.html to save your time about navigation.
also you have another few ways: create a link to your file or run external bash/bat script.
I was previously using the little hack mentioned in Eugene's answer to copy from an absolute path:
var file = 'C:\Users\User1\Pictures\pic.png';
var newPath = air.File.applicationStorageDirectory.resolvePath('images/pic.png');
air.File.applicationDirectory.resolvePath('/../../../../../../../../../../' +
file).copyTo(newPath, true);
However, this is a much better way of doing it:
var file = 'C:\Users\User1\Pictures\pic.png';
var newPath = air.File.applicationStorageDirectory.resolvePath('images/pic.png');
new air.File(file).copyTo(newPath, true);

How to set image path for fckeditor?

I am using fckeditor for PHP. I have set an absolute path for image uploading. I can upload images, but I am unable to use images that were uploaded. Can anyone help me find my problem?
Here is the code I have changed in my config.php file:
// Path to user files relative to the document root.
$Config['UserFilesPath'] = '/userfiles/' ;
// Fill the following value it you prefer to specify the absolute path for the
// user files directory. Useful if you are using a virtual directory, symbolic
// link or alias. Examples: 'C:\\MySite\\userfiles\\' or '/root/mysite/userfiles/'.
// Attention: The above 'UserFilesPath' must point to the same directory.
$Config['UserFilesAbsolutePath'] = '/var/www/host/mysite//userfiles/' ;
I just solved this frustrating problem after a full day of searching on Google.
The solution is here. Look for:
Returning Full URLs
You can configure the File Browser to return full URLs to FCKeditor, like "http://www.example.com/userfiles/", instead of absolute URLs, like "/userfiles/". To do that, you must configure the connector, combining the UserFilesPath and UserFilesAbsolutePath settings:
UserFilesPath: include here the full URL for the user files directory. For example, set it to "http://www.example.com/userfiles/".
UserFilesAbsolutePath: include here the server path to reach the above URL directory. For example, in a Windows environment, you could have something like "C:/inetpub/mysite/userfiles/", while on Linux, something like "/usr/me/public_html/mysite/userfiles/".
Just adjust the above settings to your installation values and the File Browser will start returning full URLs to the editor.
For your localhost :
$Config['UserFilesPath'] = 'http://localhost/mywebsite/userfiles/' ;
$Config['UserFilesAbsolutePath'] = 'C:\\wamp\www\\mywebsite\\userfiles\\' ;
and in order to get your images from there, use :
$path = 'http://localhost/mywebsite/userfiles/image/myimage.jpg';
Now, For your web server:
$Config['UserFilesPath'] = 'http://localhost/mywebsite/userfiles/' ; // if your webserver named localhost as mine
$Config['UserFilesAbsolutePath'] = '/var/www/vhosts/mywebsite.com/httpdocs/' ;
and the images path remains the same as above.
Check the permission of the folder
Full Subject: FCK editor 2.x: File/image/video upload in different folders for different applications using a single FCKeditor, by making $Config['UserFilesPath'] fully dynamic in a secure way
It can be done in many ways. I am explaining a process, which I applied as per my php applications' code structure. The same code structure/framework I followed for different applications, with each application as a sub-folder in my server. So, there is a logical need to use one single FCKeditor and configure it in some way, so that it work properly for all the applications. The content part of FCKeditor is ok. It can easily be reused by different applications or projects from a single FCKeditor component. But the problem arises with file upload, like image, video or any other document. To make it applicable for different project, the files must be uploaded in separe folders for different projects. And for that $Config['UserFilesPath'] must by configured with dynamic folder path, means different folder path for each project, but calling the the same FCKeditor component in the same location. I am explaning some differnt process together in a step-by-step way. Those worked for me fine with FCKeditor version 2.5.1 and VersionBuild 17566 and I hope they will work for others as well. If it does not work for other developrs, then may be they need to make some tweaks in those process as per their project code structure and folder write permission as well as per the FCKeditor version.
1) In fckeditor\editor\filemanager\connectors\phpconfig.php file
a) Go after global $Config ; and $Config['Enabled'] = false ;
i) There, if want a session dependent secure method: only for single site setting: i.e. one FCKeditor for each one project domain or subdomain, not one FCKeditor for multiple project then place this code:
if(!isset($_SESSION)){
session_start();
}
if(isset($_SESSION['SESSION_SERVER_RELATIVEPATH']) && $_SESSION['SESSION_SERVER_RELATIVEPATH']!="") {
$relative_path=$_SESSION['SESSION_SERVER_RELATIVEPATH'];
include_once($_SERVER['DOCUMENT_ROOT'].$relative_path."configurations/configuration.php");
}
N.B.: Here, $_SESSION['SESSION_SERVER_RELATIVEPATH']: relative folder path of the project corresponding to the webroot; should be like "/project/folder/path/" and set this session variable in a common file in your project where the session started. And there should be a configurations/configuration.php as the configuration file in your project. If it's name or path is different you have to place the corresponding path here instead of configurations/configuration.php
ii) If want to use a single FCKeditor component for different projects represented as different sub-folders and with a session dependent secure way (Assuming different session_name for different projects, to differentiate their sessions in a single server). But it will not work if projects represented as sub-domains or different domains, then have to use the session independent way (iii) provided bellow (though it is insecure). Place this code:
if(!isset($_SESSION)){
session_name($_REQUEST['param_project_to_fck']);
session_start();
}
if(isset($_SESSION['SESSION_SERVER_RELATIVEPATH']) && $_SESSION['SESSION_SERVER_RELATIVEPATH']!="") {
$relative_path=$_SESSION['SESSION_SERVER_RELATIVEPATH'];
include_once($_SERVER['DOCUMENT_ROOT'].$relative_path."configurations/configuration.php");
}
Please read N.B. at the end of previous point, i.e. point (i)
iii) If want to use a single FCKeditor component for different projects represented either different sub-folders as well as sub-domains or domains (though it is not fully secure). Place this code:
if(isset($_REQUEST['param_project_to_fck']) && $_REQUEST['param_project_to_fck']!=""){ //base64 encoded relative folder path of the project corresponding to the webroot; should be like "/project/folder/path/" before encoding
$relative_path=base64_decode($_REQUEST['param_project_to_fck']);
include_once($_SERVER['DOCUMENT_ROOT'].$relative_path."configurations/configuration.php");
}
Please read N.B. at the end of point (i)
b)Now after that for any case you selected, please find this code:
// Path to user files relative to the document root.
$Config['UserFilesPath'] = '/userfiles/' ;
and replace the following code:
if(isset($SERVER_RELATIVEPATH) && $SERVER_RELATIVEPATH==$relative_path) { //to make it relatively secure so that hackers can not create any upload folder automatcally in the server, using a direct link and can not upload files there
$Config['Enabled'] = true ;
$file_upload_relative_path=$SERVER_RELATIVEPATH;
}else{
$Config['Enabled'] = false ;
exit();
}
// Path to user files relative to the document root.
//$Config['UserFilesPath'] = '/userfiles/' ;
//$Config['UserFilesPath'] = $file_upload_relative_path.'userfiles/' ;
$Config['UserFilesPath'] = '/userfiles'.$file_upload_relative_path;
Here $SERVER_RELATIVEPATH is the relative path and it must be set in your project's configuration file included previously.
Here you can set the $Config['UserFilesPath'] with any other dynamic folder path using $file_upload_relative_path variable.In my bluehost linux server, as their was a folder user permission conflict between the project root folder (0755 permission) and the userfiles folder under it and subfolders under userfiles (should be 0777 as per FCKeditor coding), so it does not allow uploading files in those folders. So, I created a folder userfiles at the server webroot (beyond the project root folder), and set the permission to 0777 to it, use the code for the $config setting as :
$Config['UserFilesPath'] = '/userfiles'.$file_upload_relative_path;
But, if you have no problem with write permission in the project's subfolders in your case, then you can use the previous line (commented out in the previous code segment):
$Config['UserFilesPath'] = $file_upload_relative_path.'userfiles/' ;
Mind it, you mast comment out the existing $Config['UserFilesPath'] = '/userfiles/' ; in this file by either replacing or simply commenting out if it exist in other place of the file.
2) If you choose 1) (a) (ii) or (iii) method then open
(a) fckeditor\editor\filemanager\browser\default\browser.html file.
Search for this line: var sConnUrl = GetUrlParam( 'Connector' ) ;
Put these commands after that line:
var param_project_to_fck = GetUrlParam( 'param_project_to_fck' ) ;
Now, Search for this line: sUrl += '&CurrentFolder=' + encodeURIComponent( this.CurrentFolder ) ;
Put this command after that line:
sUrl += '&param_project_to_fck=' + param_project_to_fck ;
(b) Now, open ckeditor\editor\filemanager\browser\default\frmupload.html file.
Search for this line (it should be in the SetCurrentFolder() function):
sUrl += '&CurrentFolder=' + encodeURIComponent( folderPath ) ;
Put this command after that line:
sUrl += '&param_project_to_fck='+window.parent.param_project_to_fck;
3) Now where you want to show the FCKeditor in your project, you have to put those lines first in the corresponding php file/page:
include_once(Absolute/Folder/path/for/FCKeditor/."fckeditor/fckeditor.php") ;
$oFCKeditor = new FCKeditor(Field_name_for_editor_content_area) ;
$oFCKeditor->BasePath = http_full_path_for_FCKeditor_location.'fckeditor/' ;
$oFCKeditor->Height = 400;
$oFCKeditor->Width = 600;
$oFCKeditor->Value =Your_desired_content_to_show_in_editor;
$oFCKeditor->Create() ;
a) Now, if you choose 1) (a) (ii) or (iii) method then place the following code segment before that line: $oFCKeditor->Create() ;
$oFCKeditor->Config["LinkBrowserURL"] = ($oFCKeditor->BasePath)."editor/filemanager/browser/default/browser.html?Connector=../../connectors/php/connector.php&param_project_to_fck=".base64_encode($SERVER_RELATIVEPATH);
$oFCKeditor->Config["ImageBrowserURL"] = ($oFCKeditor->BasePath)."editor/filemanager/browser/default/browser.html?Type=Image&Connector=../../connectors/php/connector.php&param_project_to_fck=".base64_encode($SERVER_RELATIVEPATH);
$oFCKeditor->Config["FlashBrowserURL"] = ($oFCKeditor->BasePath)."editor/filemanager/browser/default/browser.html?Type=Flash&Connector=../../connectors/php/connector.php&param_project_to_fck=".base64_encode($SERVER_RELATIVEPATH);
b) if you chose 1) (a) (ii) method, then in the above code code segment, just replace all the texts: base64_encode($SERVER_RELATIVEPATH) with this one: base64_encode(session_name())
And you are done.
UserFilesPath: include here the full URL for the user files directory. For example, set it to "http://www.example.com/userfiles/".