I have a web API method which creates secrets on azure key vault and it works fine, I also have a delete method that deletes an entity and its associated secrets, however, this method is not deleting the key on azure key vault, but it's not throwing an exception either!
Here the helper methods:
public async Task OnCreateSecretAsync(string name, string value)
{
Message = "Your application description page.";
int retries = 0;
bool retry = false;
try
{
/* The below 4 lines of code shows you how to use AppAuthentication library to set secrets from your Key Vault*/
AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider();
KeyVaultClient keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
var result = await keyVaultClient.SetSecretAsync(ConfigurationManager.AppSettings["VaultUrl"].ToString(), name, value)
.ConfigureAwait(false);
SecretIdentifier = result.Id;
/* The below do while logic is to handle throttling errors thrown by Azure Key Vault. It shows how to do exponential backoff which is the recommended client side throttling*/
do
{
long waitTime = Math.Min(GetWaitTime(retries), 2000000);
result = await keyVaultClient.SetSecretAsync(ConfigurationManager.AppSettings["VaultUrl"].ToString(), name, value)
.ConfigureAwait(false);
Message = result.Id;
retry = false;
}
while (retry && (retries++ < 10));
}
/// <exception cref="KeyVaultErrorException">
/// Thrown when the operation returned an invalid status code
/// </exception>
catch (KeyVaultErrorException keyVaultException)
{
Message = keyVaultException.Message;
if ((int)keyVaultException.Response.StatusCode == 429)
retry = true;
}
}
/// <summary>
/// Deletes secrets
/// </summary>
/// <param name="name">Secret</param>
/// <param name="value">Value</param>
/// <returns></returns>
public async Task OnDeleteSecretAsync(string name)
{
Message = "Your application description page.";
int retries = 0;
bool retry = false;
try
{
/* The below 4 lines of code shows you how to use AppAuthentication library to set secrets from your Key Vault*/
AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider();
KeyVaultClient keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
var result = await keyVaultClient.DeleteSecretAsync(ConfigurationManager.AppSettings["VaultUrl"].ToString(), name)
.ConfigureAwait(false);
SecretIdentifier = result.Id;
/* The below do while logic is to handle throttling errors thrown by Azure Key Vault. It shows how to do exponential backoff which is the recommended client side throttling*/
do
{
long waitTime = Math.Min(GetWaitTime(retries), 2000000);
result = await keyVaultClient.DeleteSecretAsync(ConfigurationManager.AppSettings["VaultUrl"].ToString(), name)
.ConfigureAwait(false);
Message = result.Id;
retry = false;
}
while (retry && (retries++ < 10));
}
/// <exception cref="KeyVaultErrorException">
/// Thrown when the operation returned an invalid status code
/// </exception>
catch (KeyVaultErrorException keyVaultException)
{
Message = keyVaultException.Message;
if ((int)keyVaultException.Response.StatusCode == 429)
retry = true;
}
}
And here the methods where I call them from:
public async Task<IHttpActionResult> AddGlobalDesignTenant([FromBody]GlobalDesignTenant globaldesigntenant)
{
var telemetry = new TelemetryClient();
try
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
string domainUrl = globaldesigntenant.TestSiteCollectionUrl;
string tenantName = domainUrl.Split('.')[0].Remove(0, 8);
globaldesigntenant.TenantName = tenantName;
var globalDesignTenantStore = CosmosStoreHolder.Instance.CosmosStoreGlobalDesignTenant;
byte[] data = Convert.FromBase64String(globaldesigntenant.base64CertFile);
var cert = new X509Certificate2(
data,
globaldesigntenant.CertificatePassword,
X509KeyStorageFlags.Exportable |
X509KeyStorageFlags.MachineKeySet |
X509KeyStorageFlags.PersistKeySet);
try
{
using (var cc = new AuthenticationManager().GetAzureADAppOnlyAuthenticatedContext(globaldesigntenant.TestSiteCollectionUrl,
globaldesigntenant.Applicationid,
globaldesigntenant.TenantName + ".onmicrosoft.com",
cert, AzureEnvironment.Production))
{
cc.Load(cc.Web, p => p.Title);
cc.ExecuteQuery();
Console.WriteLine(cc.Web.Title);
}
}
catch (Exception ex)
{
return BadRequest("Cant authenticate with those credentials");
}
KeyVaultHelper keyVaultHelperPFX = new KeyVaultHelper();
await keyVaultHelperPFX.OnCreateSecretAsync("GlobalDesignTenantPFXFileBAse64"+ tenantName, globaldesigntenant.base64CertFile);
globaldesigntenant.SecretIdentifierBase64PFXFile = keyVaultHelperPFX.SecretIdentifier;
KeyVaultHelper keyVaultHelperPassword = new KeyVaultHelper();
await keyVaultHelperPassword.OnCreateSecretAsync("GlobalDesignTenantCertPassword" + tenantName, globaldesigntenant.CertificatePassword);
globaldesigntenant.SecretIdentifieCertificatePassword = keyVaultHelperPassword.SecretIdentifier;
globaldesigntenant.CertificatePassword = string.Empty;
globaldesigntenant.base64CertFile = string.Empty;
var added = await globalDesignTenantStore.AddAsync(globaldesigntenant);
return Ok(added);
}
catch (Exception ex)
{
string guid = Guid.NewGuid().ToString();
var dt = new Dictionary<string, string>
{
{ "Error Lulo: ", guid }
};
telemetry.TrackException(ex, dt);
return BadRequest("Error Lulo: " + guid);
}
}
public async Task<IHttpActionResult> DeleteGlobalDesignTenant(string id)
{
var telemetry = new TelemetryClient();
try
{
var globalDesignTenantStore = CosmosStoreHolder.Instance.CosmosStoreGlobalDesignTenant;
var globalDesignTenant = await globalDesignTenantStore.FindAsync(id, "globaldesigntenants");
KeyVaultHelper keyVaultHelperPFX = new KeyVaultHelper();
await keyVaultHelperPFX.OnDeleteSecretAsync("GlobalDesignTenantPFXFileBAse64" + globalDesignTenant.TenantName);
KeyVaultHelper keyVaultHelperPassword = new KeyVaultHelper();
await keyVaultHelperPassword.OnDeleteSecretAsync("GlobalDesignTenantCertPassword" + globalDesignTenant.TenantName);
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var result = await globalDesignTenantStore.RemoveAsync(globalDesignTenant);
return Ok(result);
}
catch (Exception ex)
{
string guid = Guid.NewGuid().ToString();
var dt = new Dictionary<string, string>
{
{ "Error Lulo: ", guid }
};
telemetry.TrackException(ex, dt);
return BadRequest("Error Lulo: " + guid);
}
}
Based on my test, await keyVaultClient.DeleteSecretAsync(ConfigurationManager.AppSettings["VaultUrl"].ToString(), name) will delete the secret with specified name.
So, please set a break-point at the delete calling. Then run your application to see if it hits, and check if the parameters were expected values.
Related
I have used the aws-samples example named aws-cognito-dot-net-desktop-app in C# and Android:
aws-cognito-dot-net-desktop-app
It works very well and correctly registers the user in Cognito.
To register a user, do the following:
bool success = await helper.SignUpUser(etUserName.Text, etPasswordUser.Text, etEmailUser.Text, etPhoneUser.Text);
That way the user is created, but a code needs to be entered that is sent to the user's email. The code entry is as follows:
CognitoHelper cognitoHelper = new CognitoHelper();
return await cognitoHelper.VerifyAccessCode(userName, codeSentToMail);
and the user registers without problems, that is to say, it works correctly:
Now I want to delete any user created, for which I am creating a task as follows:
internal async Task<bool> DeleteUser(string username)
{
try
{
AmazonCognitoIdentityProviderClient provider =
new Amazon.CognitoIdentityProvider.AmazonCognitoIdentityProviderClient(new Amazon.Runtime.AnonymousAWSCredentials(), RegionEndpoint.USEast1);
DeleteUserPoolRequest request = new DeleteUserPoolRequest();
request.UserPoolId = username;
DeleteUserPoolResponse deleteUserPoolClientResponse = await provider.DeleteUserPoolAsync(request);
return true;
}
catch (Exception ex)
{
Console.WriteLine(ex);
return false;
}
}
When executing DeleteUserPoolRequest, an exception is thrown indicating an error of type Amazon.Runtime.ErrorType.Unknown
Any idea what I'm doing wrong?
Any comments or suggestions are welcome.
public static async Task<bool> DeleteUserFromAws(string emailId)
{
try
{
AmazonCognitoIdentityProviderClient cognito =
new AmazonCognitoIdentityProviderClient(awsAccessKeyId, awsSecretAccessKey, Region1);
CognitoUserPool cognitoUserPool = new CognitoUserPool(poolId, appClienId, cognito);
AdminGetUserRequest adminGetUserRequest = new AdminGetUserRequest();
adminGetUserRequest.Username = emailId;
adminGetUserRequest.UserPoolId = poolId;
AdminGetUserResponse adminGetUserResponse = await cognito.AdminGetUserAsync(adminGetUserRequest);
var getUserNameByEmaliID = adminGetUserResponse.Username;
AmazonCognitoIdentityProviderClient provider =
new AmazonCognitoIdentityProviderClient(awsAccessKeyId, awsSecretAccessKey, Region1);
AdminDeleteUserRequest request = new AdminDeleteUserRequest();
CancellationToken cancellationToken = default;
request.Username = getUserNameByEmaliID;
request.UserPoolId = poolId;
await provider.AdminDeleteUserAsync(request,cancellationToken);
return true;
}
catch (Exception ex)
{
Logger.log(ex, (Int32)Category.Fatal, (Int32)Priority.High);
throw;
}
}
I have to go through all team drives, folders, and files and the code I have works perfectly fine:
/// <summary>
/// Get All files inside a folder
/// </summary>
/// <param name="service"></param>
/// <param name="folderId"></param>
/// <param name="td"></param>
/// <returns></returns>
private static async Task<Google.Apis.Drive.v3.Data.FileList> GetAllFilesInsideFolder(DriveService service, string folderId, TeamDrive td)
{
string FolderId = folderId;
// Define parameters of request.
FilesResource.ListRequest listRequest = service.Files.List();
listRequest.Corpora = "drive";
listRequest.SupportsAllDrives = true;
listRequest.DriveId = td.Id;
listRequest.PageSize = 100;
listRequest.IncludeItemsFromAllDrives = true;
listRequest.Q = "'" + FolderId + "' in parents and trashed=false";
listRequest.Fields = "nextPageToken, files(*)";
// List files.
Google.Apis.Drive.v3.Data.FileList files = await listRequest.ExecuteAsync();
return files;
}
/// <summary>
/// Gets all folders from an specific team drive
/// </summary>
/// <param name="service"></param>
/// <param name="td"></param>
/// <returns></returns>
private static async Task<Google.Apis.Drive.v3.Data.FileList> GetAllFoldersFromTeamDriveAsync(DriveService service, TeamDrive td)
{
try
{
var request = service.Files.List();
request.Corpora = "drive";
request.SupportsAllDrives = true;
request.DriveId = td.Id;
request.PageSize = 100;
request.IncludeItemsFromAllDrives = true;
request.Q = "mimeType = 'application/vnd.google-apps.folder'";
var response = await request.ExecuteAsync();
return response;
}
catch (Exception ex )
{
Console.WriteLine("GetAllFoldersFromTeamDriveAsync Error: " + ex.Message);
throw;
}
}
/// <summary>
/// Gets all teamdrives
/// </summary>
/// <param name="service"></param>
/// <returns></returns>
private static async Task<Google.Apis.Drive.v3.Data.TeamDriveList> GetAllTeamDrivesAsync(DriveService service)
{
try
{
var request = service.Teamdrives.List();
request.PageSize = 100;
var response = await request.ExecuteAsync();
return response;
}
catch (Exception ex)
{
Console.WriteLine("GetAllTeamDrivesAsync Error" + ex.Message);
throw;
}
}
Main method:
public async Task RunFix()
{
UserCredential credential;
Directory.CreateDirectory(StorageLocation);
var DataStore = new FileDataStore(StorageLocation);
using var stream = new FileStream(CredentialsString, FileMode.Open, FileAccess.Read);
// Please give consent to the Auth/drive scope
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
Username,
CancellationToken.None,
DataStore).Result;
try
{
var service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
var clientbillCycleGoogleDriveFilesDEV = new TableClient("...");
// Get All team drives
var allTeamDrives = await GetAllTeamDrivesAsync(service);
// We will use a CSV to copy the unmapped files
var csvUnmappedBillCycleFiles = new StringBuilder();
//Iterate over all Team Drives I have access to:
foreach (TeamDrive td in allTeamDrives.TeamDrives)
{
if (td.Name == "XXX")
{
Console.WriteLine("Team Drive: " + td.Name);
Stopwatch sAllFilesInsideFolder = Stopwatch.StartNew();
// Get All Folders inside this team drive
var allFolders = await GetAllFoldersFromTeamDriveAsync(service, td);
foreach (Google.Apis.Drive.v3.Data.File file in allFolders.Files)
{
Console.WriteLine("--Folder-- " + file.Name);
if (file.Name.StartsWith("xyz"))
{
//some business logic
foreach (Google.Apis.Drive.v3.Data.File googlefile in allFilesInsideFolder.Files)
{
//some business logic
}
}
}
}
}
System.IO.File.WriteAllText("csvUnmappedBillCycleFiles.csv", csvUnmappedBillCycleFiles.ToString());
}
catch (Exception ex)
{
Console.WriteLine("Error" + ex.Message);
}
}
The problem is that I cant set PageSize to something above 100.
How can I change this code to actually to go through everything?
Assuming that you are using drives list and files list. Which is just a guess since you haven't included the code GetAllTeamDrivesAsync? GetAllFoldersFromTeamDriveAsync.
You can set the page size to max 1000 on your file.list method.
var request = service.Files.List();
request.PageSize = 1000;
But thats you are still going to need to paginate over the page. I recommend using the pageStreamer. It will loop over each of the rows for you.
var request = service.Files.List();
request.PageSize = 1000;
var pageStreamer =
new Google.Apis.Requests.PageStreamer<Google.Apis.Drive.v3.Data.File, FilesResource.ListRequest,
Google.Apis.Drive.v3.Data.FileList, string>(
(req, token) => request.PageToken = token,
response => response.NextPageToken,
response => response.Files);
// data storage
var all = new Google.Apis.Drive.v3.Data.FileList();
all.Files = new List<Google.Apis.Drive.v3.Data.File>();
// fetching data and adding it to storage
foreach (var result in await pageStreamer.FetchAllAsync(request, CancellationToken.None))
{
all.Files.Add(result);
}
I have a video up that explains how pagestreamer works How to use the nextpagetoken from the files list method in the Google Drive api v3.
You should be able to use pagestreamer with drives list as well.
I have a condition set to where if there's a cached token, it will use that or else it will either look for passed in credentials or prompt for credentials. Even after entering my credentials once via AcquireTokenInteractive() and running the program again, it still prompts for credentials. If I only have AcquireTokenSilent(), I get a reference error for the token variable because nothing is passed to it. It is either not caching my token or it is not fetching my cached token properly, but I'm not sure how to troubleshoot either. According to the MSDocs https://learn.microsoft.com/en-us/azure/active-directory/develop/msal-acquire-cache-tokens it should do the caching automatically.
For the time being, I commented out the AcquireTokenByUsernamePassword() for troubleshooting purposes.
static async Task<GraphServiceClient> Auth()
{
string[] scopes = new string[] { "user.read" };
string token = null;
IPublicClientApplication app;
app = PublicClientApplicationBuilder.Create(ConfigurationManager.AppSettings["clientId"])
.Build();
AuthenticationResult result = null;
var accounts = await app.GetAccountsAsync();
if (accounts.Any())
{
result = await app.AcquireTokenSilent(scopes, accounts.FirstOrDefault())
.ExecuteAsync();
}
else
{
try
{
///var securePassword = new SecureString();
///foreach (char c in "dummy") // you should fetch the password
/// securePassword.AppendChar(c); // keystroke by keystroke
/// result = await app.AcquireTokenByUsernamePassword(scopes,"joe#contoso.com",securePassword).ExecuteAsync();
}
catch (MsalException)
{
///
}
try
{
result = await app.AcquireTokenInteractive(scopes).ExecuteAsync();
}
catch (MsalException)
{
///
}
}
token = result.AccessToken;
// Use the token
GraphServiceClient graphClient = new GraphServiceClient(
"https://graph.microsoft.com/v1.0",
new DelegateAuthenticationProvider(
async (requestMessage) =>
{
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", token);
}));
return graphClient;
}
Yes, you are right. The SDK will do the caching automatically. I tested it by creating a console app:
class Program
{
static void Main(string[] args)
{
string flag = "Y";
IPublicClientApplication app = PublicClientApplicationBuilder.Create("60ef0838-f145-4f00-b7ba-a5af7f31cc3c").Build();
string[] scopes = new string[] { "api://4a673722-5437-4663-bba7-5f49372e06ba/Group.All","openid" };
do
{
List<IAccount> list = app.GetAccountsAsync().GetAwaiter().GetResult().ToList();
Console.WriteLine("Checking cache");
if (list.Count > 0)
{
Console.WriteLine($"Find {list.Count}");
list.ForEach(_ =>
{
Console.WriteLine($"Acquire a new token for {_.Username}");
AuthenticationResult result = app.AcquireTokenSilent(scopes, _).WithForceRefresh(true).WithAuthority("https://login.microsoftonline.com/e4c9ab4e-bd27-40d5-8459-230ba2a757fb/").ExecuteAsync().Result;
Console.WriteLine($"New token -> {result.AccessToken}");
});
}
else
{
Console.WriteLine("No cache");
try
{
var securePassword = new SecureString();
// Test AcquireTokenByUsernamePassword
foreach (char c in "**********") securePassword.AppendChar(c);
AuthenticationResult result = app.AcquireTokenByUsernamePassword(scopes, "jack#hanxia.onmicrosoft.com", securePassword).WithAuthority("https://login.microsoftonline.com/e4c9ab4e-bd27-40d5-8459-230ba2a757fb/").ExecuteAsync().GetAwaiter().GetResult();
// Test AcquireTokenInteractive
//AuthenticationResult result = app.AcquireTokenInteractive(scopes).WithAuthority("https://login.microsoftonline.com/e4c9ab4e-bd27-40d5-8459-230ba2a757fb/").ExecuteAsync().Result;
Console.WriteLine(result.Account.Username + " -> " + result.AccessToken);
}
catch (Exception e)
{
Console.Error.WriteLine(e.Message);
Console.Error.WriteLine(e.StackTrace);
}
}
Console.Write("Continue? Y/N:");
flag = Console.ReadLine();
} while (flag.Trim().ToUpper().Equals("Y"));
Console.ReadLine();
}
}
The result:
I'm building an app based on the Gmail API. I can see all messages from the current inbox, but I need to limit this to only messages which have an attachment. How can I do this?
This is my GoogleController.cs:
[HttpGet]
[Authorize]
public async Task<IActionResult> GetListEmail(string LabelId, string nameLabel)
{
string UserEmail = User.FindFirst(c => c.Type == ClaimTypes.Email).Value;
var service = GetService();
List<My_Message> listMessages = new List<My_Message>();
List<Message> result = new List<Message>();
var emailListRequest = service.Users.Messages.List(UserEmail);
emailListRequest.LabelIds = LabelId;
emailListRequest.IncludeSpamTrash = false;
emailListRequest.MaxResults = 1000;
var emailListResponse = await emailListRequest.ExecuteAsync();
if (emailListResponse != null && emailListResponse.Messages != null)
{
foreach (var email in emailListResponse.Messages)
{
var emailInfoRequest = service.Users.Messages.Get(UserEmail, email.Id);
var emailInfoResponse = await emailInfoRequest.ExecuteAsync();
if (emailInfoResponse != null)
{
My_Message message = new My_Message();
message.Id = listMessages.Count + 1;
message.EmailId = email.Id;
foreach (var mParts in emailInfoResponse.Payload.Headers)
{
if (mParts.Name == "Date")
message.Date_Received = mParts.Value;
else if (mParts.Name == "From")
message.From = mParts.Value;
else if (mParts.Name == "Subject")
message.Title = mParts.Value;
}
listMessages.Add(message);
}
}
}
ViewBag.Message = nameLabel;
return View("~/Views/Home/Index.cshtml", listMessages);
}
I think a simpler solution would be to query in the Users.messages.list endpoint without the need to create filters.
You can actually use the parameter q to make a query like you would in the GMail searchbox, if not familiar you can look at the whole list of operators.
In fact there is an example to make use of this query parameter in the documentation:
using Google.Apis.Gmail.v1;
using Google.Apis.Gmail.v1.Data;
using System.Collections.Generic;
// ...
public class MyClass {
// ...
/// <summary>
/// List all Messages of the user's mailbox matching the query.
/// </summary>
/// <param name="service">Gmail API service instance.</param>
/// <param name="userId">User's email address. The special value "me"
/// can be used to indicate the authenticated user.</param>
/// <param name="query">String used to filter Messages returned.</param>
public static List<Message> ListMessages(GmailService service, String userId, String query)
{
List<Message> result = new List<Message>();
UsersResource.MessagesResource.ListRequest request = service.Users.Messages.List(userId);
request.Q = query; // inform this with the right query
do
{
try
{
ListMessagesResponse response = request.Execute();
result.AddRange(response.Messages);
request.PageToken = response.NextPageToken;
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
}
} while (!String.IsNullOrEmpty(request.PageToken));
return result;
}
// ...
}
So for your case you just need to add the line
emailListRequest.Q = "has:attachment";
before executing the request, doing like this will not create a whole filter for your account, so maybe it's more convenient for your case.
use a filter with criteria like this => criteria.query="has:attachment"
see also here => https://developers.google.com/gmail/api/v1/reference/users/settings/filters#resource
For testing any filter you can use GMail:
image
I am trying to connect with c#.
Here is the class that submits hive queries successfully to my remote HDInsight cluster. what do i need to change here to connect to the local emulator
public class HadoopImporter : IImporter
{
public static readonly Logger log = LogManager.GetCurrentClassLogger();
public void Import(string _query)
{
try
{
log.Warn("Inside Hive submission method");
var store = new X509Store();
store.Open(OpenFlags.ReadOnly);
var cert =
store.Certificates.Cast<X509Certificate2>()
.First(item => item.Thumbprint == "MYCERTTUMBPRINT");
if (cert == null)
log.Error("no cert found");
log.Warn(cert.FriendlyName);
log.Warn("got the cert with thumbprint ", cert.Thumbprint.ToString())
;
log.Warn("trying to create credentials from cert");
var creds = new JobSubmissionCertificateCredential(new Guid("MYSUBSCRIPTIONID"),
cert, "MYSTORAGECONTAINER");
log.Warn("trying to connect with cert");
var jobClient = JobSubmissionClientFactory.Connect(creds);
log.Warn("Setting Hive job parameters");
var hiveJob = new HiveJobCreateParameters()
{
Query = _query,
StatusFolder = "/samplequeryoutput"
};
var jobResults = jobClient.CreateHiveJob(hiveJob);
log.Warn("Executing wait for jhive results");
WaitForJobCompletion(jobResults, jobClient);
using (var stream = jobClient.GetJobOutput(jobResults.JobId))
{
var reader = new StreamReader(stream);
var res = reader.ReadToEnd();
log.Warn("trying to get the job results " + res.ToString());
}
}
catch (Exception exp)
{
log.Error(exp);
}
}
private static void WaitForJobCompletion(JobCreationResults jobDetails, IJobSubmissionClient client)
{
var jobInProgress = client.GetJob(jobDetails.JobId);
while (jobInProgress.StatusCode != JobStatusCode.Completed && jobInProgress.StatusCode != JobStatusCode.Failed)
{
log.Warn("Inside the while loop waiting for hive job to complete");
jobInProgress = client.GetJob(jobInProgress.JobId);
Thread.Sleep(TimeSpan.FromSeconds(10));
}
log.Trace("HIVE Job has Imported " + jobDetails.JobId);
}
}
You should be able to connect to a local one-box using the REST implementation of the client.
You're looking for the WebHCatHttpClient interface. The code below runs a basic query against my local one-box.
var httpClient = new WebHCatHttpClient(new Uri("http://localhost:50111/"), "username", "password");
string outputDir = "basichivejob";
var task = httpClient.CreateHiveJob(#"select * from iris;", null, null, outputDir, null);
task.Wait();
var response = task.Result;
var output = response.Content.ReadAsAsync<JObject>();
output.Wait();
response.EnsureSuccessStatusCode();
string id = output.Result.GetValue("id").ToString();
httpClient.WaitForJobToCompleteAsync(id).Wait();
See the SDK docs for more info.