I cant get a batch scanner to only scan for a specific row, when settings start and stop keys to the same thing I get no entry's back, when using an scanner I get this exception:
"java.lang.IllegalArgumentException: Start key must be less than end key in range (Test : [] 0 false, Test : [] 0 false)"...
I am writing in C# in Visual Studio 2010 and using Thrift (ver 0.9.1.1) and Accumulo's (ver 1.5.0) proxy.thrift code in the project.
Here is my code, everything "works" but I don't get any entries from client.nextK
class Program
{
static byte[] GetBytes(string str)
{
return Encoding.ASCII.GetBytes(str);
}
static string GetString(byte[] bytes)
{
return Encoding.ASCII.GetString(bytes);
}
static void Main(string[] args)
{
try
{
/** connect **/
TTransport transport = new TSocket("192.168.58.62", 42424);
transport = new TFramedTransport(transport);
TCompactProtocol protocol = new TCompactProtocol(transport);
transport.Open();
AccumuloProxy.Client client = new AccumuloProxy.Client(protocol);
Dictionary<string, string> passwd = new Dictionary<string,string>();
passwd.Add("password", "password");
var login = client.login("root", passwd);
/** connect end **/
/** Get all data from one "Row" **/
var bScanner = new BatchScanOptions();
Range range = new Range();
range.Start = new Key();
range.Start.Row = GetBytes("Test");
range.Stop = new Key();
range.Stop.Row = GetBytes("Test");
bScanner.Ranges = new List<Range>();
bScanner.Ranges.Add(range);
var scanId = client.createBatchScanner(login, "firstTable", bScanner);
var more = true;
while (more)
{
var scan = client.nextK(scanId, 10);
more = scan.More;
foreach (var entry in scan.Results)
{
Console.WriteLine("{0} {1}:{2} [{3}] {4}", GetString(entry.Key.Row), GetString(entry.Key.ColFamily), GetString(entry.Key.ColQualifier), GetString(entry.Key.ColVisibility), GetString(entry.Value));
}
}
client.closeScanner(scanId);
Console.WriteLine();
/** Get data end **/
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
The user manual for Accumulo 1.5, is showing this code snippet and that is the same as I'm doing (but in C#): (http://accumulo.apache.org/1.5/accumulo_user_manual.html#_basic_table)
Range r = new Range(userid, userid); // single row
Scanner s = conn.createScanner("userdata", auths);
s.setRange(r);
s.fetchColumnFamily(new Text("age"));
for(Entry<Key,Value> entry : s)
System.out.println(entry.getValue().toString());
The problem is likely your range. In the Java API, you can construct a Range for a single row, with:
Range r = new Range("myRow");
In the thrift Proxy API, you can only give Keys to the Range constructor, not just RowIDs (this is an option in the Java API, also, but it is the only option in the Proxy API). Keys represent a single entry, so scanning:
R1:CF1:CQ1:CV1 -> R1:CF1:CQ1:CV1
will only ever result a scan over that one exact entry (and possibly all versions of it, if you don't have the VersioningIterator configured for the table).
So, if you want to scan all entries in row "a", you don't scan like this:
"a":null:null:null(inclusive) -> "a":null:null:null(inclusive)
Rather, you scan like this for row == "a":
"a":null:null:null(inclusive) -> "a\0":null:null:null(exclusive)
Or this, for row startsWith "a":
"a":null:null:null(inclusive) -> "b":null:null:null(exclusive)
Have you already checked that possibility here?
https://issues.apache.org/jira/browse/ACCUMULO-1189
It's fixed in Accumulo 1.5, you use 1.4, so seems worth a look.
Related
I'm trying to hit the Coinspot REST API, but I'm getting an error returned. I'm having no trouble talking to Bittrex and Independent Reserve, but Coinspot is a bit different. This is my code:
protected override RESTClient RESTClient { get; } = new RESTClient(new NewtonsoftSerializationAdapter(), new Uri("https://www.coinspot.com.au/api"));
public class postdata
{
public string nonce { get; set; }
}
public string CalculateMD5Hash(string input)
{
//step 1, calculate MD5 hash from input
MD5 md5 = MD5.Create();
var inputBytes = Encoding.ASCII.GetBytes(input);
var hash = md5.ComputeHash(inputBytes);
// step 2, convert byte array to hex string
var sb = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sb.Append(hash[i].ToString("X2"));
}
return sb.ToString();
}
/// <summary>
/// Private IR Call: GetAccounts
/// </summary>
/// <returns></returns>
private async Task<List<AccountHolding>> Balances()
{
//https://github.com/geekpete/py-coinspot-api/blob/master/coinspot/coinspot.py
//var nonce = new Date().getTime();
//var postdata = postdata || { };
//postdata.nonce = nonce;
//var stringmessage = JSON.stringify(postdata);
//var signedMessage = new hmac("sha512", self.secret);
//signedMessage.update(stringmessage);
// 'sign': sign,
//'key': self.key
var nonce = APIHelpers.GetNonce();
var postdata = new postdata { nonce = nonce };
var json = JsonConvert.SerializeObject(postdata);
System.Diagnostics.Debug.WriteLine(json);
var sign = APIHelpers.GetHMACSHAHash(ApiSecret, json, APIHelpers.HMACSHAType.NineBit);
//Do we do this?
//The JavaScript samples seem to hash with MD5 afterwards for double encryption?
sign = CalculateMD5Hash(sign);
RESTClient.Headers.Clear();
RESTClient.Headers.Add("sign", sign);
RESTClient.Headers.Add("key", ApiKey);
try
{
var retVal = await RESTClient.PostAsync<string, postdata>(postdata, "/my/balances");
System.Diagnostics.Debug.WriteLine(retVal);
}
catch (Exception ex)
{
}
throw new NotImplementedException();
}
The doco is very scant! I'm stuck.
https://www.coinspot.com.au/api
I don't have the error handy right now, but it was a completely non-descript error with information about what went wrong. It was something like "invalid call". But, I know that it is accepted my posted data to some extent, because if I change the name of the property "nonce" to "noncey", I get a meaningful error back that says "no nonce".
Did you ever manage to get this API working. CoinSpot are not very supportive of this. I can only get 3 of the coins API working which isn't much help
I managed to get it working recently and put together a simple SDK in .NET
https://github.com/QuintinHumphreys/CoinspotAPI
tl:dr It's undocumented but you need to use port 443, I found it by digging through their node SDK.
I was having the same issue, getting the very non-descriptive {status: invalid} response, in my case using Elixir not C#. I got it to work by peeking into their node SDK - my details worked using their SDK so I knew it had to be something I wasn't doing properly (although their documentation is pretty shocking). They use port 443 and as soon as I set that it worked.
I tried 2 things, I'm 90% sure it was the port number but half way through my getting it to work I printed the sha512 sign created by their node sdk and compared it to the one I generating using Cryptex I saw that they were generating the same sha512 signature, but my one was in capital letters while the node one was in lowercase - this may or may not end up mattering but I did use String.downcase() on mine in the end.
Hey Guys i have a script written in c# that generates some encryption keys that i want to save into my database my code looks like this:
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Threading;
using Microsoft.WindowsAzure.MediaServices.Client;
using Microsoft.WindowsAzure.MediaServices.Client.ContentKeyAuthorization;
using Microsoft.WindowsAzure.MediaServices.Client.DynamicEncryption;
using Microsoft.WindowsAzure.MediaServices.Client.Widevine;
using Newtonsoft.Json;
namespace DeliverDRMLicenses
{
class Program
{
// Read values from the App.config file.
private static readonly string _mediaServicesAccountName =
ConfigurationManager.AppSettings["MediaServicesAccountName"];
private static readonly string _mediaServicesAccountKey =
ConfigurationManager.AppSettings["MediaServicesAccountKey"];
private static readonly Uri _sampleIssuer =
new Uri(ConfigurationManager.AppSettings["Issuer"]);
private static readonly Uri _sampleAudience =
new Uri(ConfigurationManager.AppSettings["Audience"]);
// Field for service context.
private static CloudMediaContext _context = null;
private static MediaServicesCredentials _cachedCredentials = null;
static void Main(string[] args)
{
// Create and cache the Media Services credentials in a static class variable.
_cachedCredentials = new MediaServicesCredentials(
_mediaServicesAccountName,
_mediaServicesAccountKey);
// Used the cached credentials to create CloudMediaContext.
_context = new CloudMediaContext(_cachedCredentials);
bool tokenRestriction = true;
string tokenTemplateString = null;
string drm_key_id = null;
IContentKey key = CreateCommonTypeContentKey();
// Print out the key ID and Key in base64 string format
drm_key_id = key.Id;
Console.WriteLine(" key:{0}",
key.Id, System.Convert.ToBase64String(key.GetClearKeyValue()));
Console.WriteLine(" key value:{1} ",
key.Id, System.Convert.ToBase64String(key.GetClearKeyValue()));
sbasedrmdataDataSetTableAdapters.sbase_drm_keysTableAdapter sbasedrmTableAdapter =
new sbasedrmdataDataSetTableAdapters.sbase_drm_keysTableAdapter();
sbasedrmTableAdapter.Insert(drm_key_id);
Console.WriteLine("Protection key: {0} ",
key.ProtectionKeyId, System.Convert.ToBase64String(key.GetClearKeyValue()));
Console.WriteLine("PlayReady URL: {0}",
key.GetKeyDeliveryUrl(ContentKeyDeliveryType.PlayReadyLicense));
Console.WriteLine("Widevin URL: {0}",
key.GetKeyDeliveryUrl(ContentKeyDeliveryType.Widevine));
if (tokenRestriction)
tokenTemplateString = AddTokenRestrictedAuthorizationPolicy(key);
else
AddOpenAuthorizationPolicy(key);
Console.WriteLine("Auth policy: {0}",
key.AuthorizationPolicyId);
Console.WriteLine();
Console.ReadLine();
Environment.Exit(0);
}
static public void AddOpenAuthorizationPolicy(IContentKey contentKey)
{
// Create ContentKeyAuthorizationPolicy with Open restrictions
// and create authorization policy
List<ContentKeyAuthorizationPolicyRestriction> restrictions =
new List<ContentKeyAuthorizationPolicyRestriction>
{
new ContentKeyAuthorizationPolicyRestriction
{
Name = "Open",
KeyRestrictionType = (int)ContentKeyRestrictionType.Open,
Requirements = null
}
};
// Configure PlayReady and Widevine license templates.
string PlayReadyLicenseTemplate = ConfigurePlayReadyLicenseTemplate();
string WidevineLicenseTemplate = ConfigureWidevineLicenseTemplate();
IContentKeyAuthorizationPolicyOption PlayReadyPolicy =
_context.ContentKeyAuthorizationPolicyOptions.Create("",
ContentKeyDeliveryType.PlayReadyLicense,
restrictions, PlayReadyLicenseTemplate);
IContentKeyAuthorizationPolicyOption WidevinePolicy =
_context.ContentKeyAuthorizationPolicyOptions.Create("",
ContentKeyDeliveryType.Widevine,
restrictions, WidevineLicenseTemplate);
IContentKeyAuthorizationPolicy contentKeyAuthorizationPolicy = _context.
ContentKeyAuthorizationPolicies.
CreateAsync("Deliver Common Content Key with no restrictions").
Result;
contentKeyAuthorizationPolicy.Options.Add(PlayReadyPolicy);
contentKeyAuthorizationPolicy.Options.Add(WidevinePolicy);
// Associate the content key authorization policy with the content key.
contentKey.AuthorizationPolicyId = contentKeyAuthorizationPolicy.Id;
contentKey = contentKey.UpdateAsync().Result;
}
public static string AddTokenRestrictedAuthorizationPolicy(IContentKey contentKey)
{
string tokenTemplateString = GenerateTokenRequirements();
List<ContentKeyAuthorizationPolicyRestriction> restrictions =
new List<ContentKeyAuthorizationPolicyRestriction>
{
new ContentKeyAuthorizationPolicyRestriction
{
Name = "Token Authorization Policy",
KeyRestrictionType = (int)ContentKeyRestrictionType.TokenRestricted,
Requirements = tokenTemplateString,
}
};
// Configure PlayReady and Widevine license templates.
string PlayReadyLicenseTemplate = ConfigurePlayReadyLicenseTemplate();
string WidevineLicenseTemplate = ConfigureWidevineLicenseTemplate();
IContentKeyAuthorizationPolicyOption PlayReadyPolicy =
_context.ContentKeyAuthorizationPolicyOptions.Create("Token option",
ContentKeyDeliveryType.PlayReadyLicense,
restrictions, PlayReadyLicenseTemplate);
IContentKeyAuthorizationPolicyOption WidevinePolicy =
_context.ContentKeyAuthorizationPolicyOptions.Create("Token option",
ContentKeyDeliveryType.Widevine,
restrictions, WidevineLicenseTemplate);
IContentKeyAuthorizationPolicy contentKeyAuthorizationPolicy = _context.
ContentKeyAuthorizationPolicies.
CreateAsync("Deliver Common Content Key with token restrictions").
Result;
contentKeyAuthorizationPolicy.Options.Add(PlayReadyPolicy);
contentKeyAuthorizationPolicy.Options.Add(WidevinePolicy);
// Associate the content key authorization policy with the content key
contentKey.AuthorizationPolicyId = contentKeyAuthorizationPolicy.Id;
contentKey = contentKey.UpdateAsync().Result;
return tokenTemplateString;
}
static private string GenerateTokenRequirements()
{
TokenRestrictionTemplate template = new TokenRestrictionTemplate(TokenType.SWT);
template.PrimaryVerificationKey = new SymmetricVerificationKey();
template.AlternateVerificationKeys.Add(new SymmetricVerificationKey());
template.Audience = _sampleAudience.ToString();
template.Issuer = _sampleIssuer.ToString();
template.RequiredClaims.Add(TokenClaim.ContentKeyIdentifierClaim);
return TokenRestrictionTemplateSerializer.Serialize(template);
}
static private string ConfigurePlayReadyLicenseTemplate()
{
// The following code configures PlayReady License Template using .NET classes
// and returns the XML string.
//The PlayReadyLicenseResponseTemplate class represents the template
//for the response sent back to the end user.
//It contains a field for a custom data string between the license server
//and the application (may be useful for custom app logic)
//as well as a list of one or more license templates.
PlayReadyLicenseResponseTemplate responseTemplate =
new PlayReadyLicenseResponseTemplate();
// The PlayReadyLicenseTemplate class represents a license template
// for creating PlayReady licenses
// to be returned to the end users.
// It contains the data on the content key in the license
// and any rights or restrictions to be
// enforced by the PlayReady DRM runtime when using the content key.
PlayReadyLicenseTemplate licenseTemplate = new PlayReadyLicenseTemplate();
// Configure whether the license is persistent
// (saved in persistent storage on the client)
// or non-persistent (only held in memory while the player is using the license).
licenseTemplate.LicenseType = PlayReadyLicenseType.Nonpersistent;
// AllowTestDevices controls whether test devices can use the license or not.
// If true, the MinimumSecurityLevel property of the license
// is set to 150. If false (the default),
// the MinimumSecurityLevel property of the license is set to 2000.
licenseTemplate.AllowTestDevices = true;
// You can also configure the Play Right in the PlayReady license by using the PlayReadyPlayRight class.
// It grants the user the ability to playback the content subject to the zero or more restrictions
// configured in the license and on the PlayRight itself (for playback specific policy).
// Much of the policy on the PlayRight has to do with output restrictions
// which control the types of outputs that the content can be played over and
// any restrictions that must be put in place when using a given output.
// For example, if the DigitalVideoOnlyContentRestriction is enabled,
//then the DRM runtime will only allow the video to be displayed over digital outputs
//(analog video outputs won’t be allowed to pass the content).
// IMPORTANT: These types of restrictions can be very powerful
// but can also affect the consumer experience.
// If the output protections are configured too restrictive,
// the content might be unplayable on some clients.
// For more information, see the PlayReady Compliance Rules document.
// For example:
//licenseTemplate.PlayRight.AgcAndColorStripeRestriction = new AgcAndColorStripeRestriction(1);
responseTemplate.LicenseTemplates.Add(licenseTemplate);
return MediaServicesLicenseTemplateSerializer.Serialize(responseTemplate);
}
private static string ConfigureWidevineLicenseTemplate()
{
var template = new WidevineMessage
{
allowed_track_types = AllowedTrackTypes.SD_HD,
content_key_specs = new[]
{
new ContentKeySpecs
{
required_output_protection =
new RequiredOutputProtection { hdcp = Hdcp.HDCP_NONE},
security_level = 1,
track_type = "SD"
}
},
policy_overrides = new
{
can_play = true,
can_persist = true,
can_renew = false
}
};
string configuration = JsonConvert.SerializeObject(template);
return configuration;
}
static public IContentKey CreateCommonTypeContentKey()
{
// Create envelope encryption content key
Guid keyId = Guid.NewGuid();
byte[] contentKey = GetRandomBuffer(16);
IContentKey key = _context.ContentKeys.Create(
keyId,
contentKey,
"ContentKey",
ContentKeyType.CommonEncryption);
return key;
}
static private byte[] GetRandomBuffer(int length)
{
var returnValue = new byte[length];
using (var rng =
new System.Security.Cryptography.RNGCryptoServiceProvider())
{
rng.GetBytes(returnValue);
}
return returnValue;
}
}
}
So the issue im having is when i try to run the program i get an error at this line
sbasedrmTableAdapter.Insert(drm_key_id);
and the error i receive is:
Error CS7036 There is no argument given that corresponds to the
required formal parameter 'drm_key' of
'sbase_drm_keysTableAdapter.Insert(string, string, string, string)'
How can i solve this error
It looks like you are trying to call a method that requires 4 strings as parameters with just one parameter. Try supplying the correct parameters to the method.
Your problem looks quite similar to: OOP inheritance and default constructor
I am working with C# for the first time and I am facing a strange issue.
I am building my own class for a plugin, but copied parts of the code from an existing class. Basically it's
var sanInput = Console.ReadLine();
alternativeNames = sanInput.Split(',');
sanList = new List<string>(alternativeNames);
but somehow this doesn't work. The debug console says System.Console.ReadLine returned jogi,philipp string, but sanInput keeps null as its value.
Even stranger is the fact, that the next step works "a bit". string.Split returned {string[2]} string[], so it returns an array of [jogi, philipp], but still sanInput, alternativeNamesand sanList stay as null.
How is it possible, that the second line works if sanInput has no value and how can I fix this problem? When I work with the existing class with the same code everything works as expected.
//EDIT:
Looks like a quite complicated issue. Here is the complete method:
public override void HandleMenuResponse(string response, List<Target> targets)
{
if (response == "r")
{
Console.WriteLine("Which hosts do you want to configure? Enter numbers separated by a comma.");
var hostsInput = Console.ReadLine();
int[] hosts = null;
string[] alternativeNames = null;
List<string> sanList = null;
hosts = hostsInput.Split(',').Select(int.Parse).ToArray();
Console.Write("Generating certificates for ");
foreach (int entry in hosts)
{
Console.Write(targets[entry - 1].Host + ", ");
}
Console.Write("\n \n");
foreach (int entry in hosts)
{
int entry2 = entry - 1;
if (Program.Options.San)
{
Console.WriteLine("Enter all Alternative Names for " + targets[entry2].Host + " seperated by a comma:");
// Copied from http://stackoverflow.com/a/16638000
int BufferSize = 16384;
Stream inputStream = Console.OpenStandardInput(BufferSize);
Console.SetIn(new StreamReader(inputStream, Console.InputEncoding, false, BufferSize));
var sanInput = Console.ReadLine();
alternativeNames = sanInput.Split(',');
sanList = new List<string>(alternativeNames);
targets[entry2].AlternativeNames.AddRange(sanList);
}
Auto(targets[entry - 1]);
}
}
if (response == "e")
{
string[] alternativeNames = null;
List<string> sanList = new List<string>();
if (Program.Options.San)
{
Console.WriteLine("Enter all Alternative Names seperated by a comma:");
// Copied from http://stackoverflow.com/a/16638000
int BufferSize = 16384;
Stream inputStream = Console.OpenStandardInput(BufferSize);
Console.SetIn(new StreamReader(inputStream, Console.InputEncoding, false, BufferSize));
var sanInput = Console.ReadLine();
alternativeNames = sanInput.Split(',');
}
if (alternativeNames != null)
{
sanList = new List<string>(alternativeNames);
}
foreach (var entry in targets)
{
Auto(entry);
}
}
}
I know the code isn't pretty and efficient. All in all it let's the user decide if he wants to use all detected hosts (response e) or only single ones (response r). But the mentioned problem occurs only in the second if-method. If I switch them it's again the latter one. So maybe the reason lies in the main program or in this BufferSize-Stuff? I don't know.
//EDIT 2: I think I found the problem: Somehow the integer BufferSize (shortly before the Console.Read()) is set to 0, so of course without any buffer it can't read the input. So the question remains: Why?
//EDIT 3: Okay, I'm done. It looks like I can't use the same name for the variables although they are in two different if-methods. I just named them sanInput2, alternativeNames2 etc. and now everything works.
try this, all of the variables are having values(you can use var also for all the variables):
var sanInput = Console.ReadLine();
string[] alternativeNames = sanInput.Split(',');
List<string> sanList = new List<string>(alternativeNames);
The problem you mention is, that debugging code in VS do assignements in two steps. First is to execute Console.ReadLine() (therefore you see Console.Readline returned message) and AFTER that is is assigned into sanInput. Same situation is after Split. Function is called, but not assigned yet.
My recommendation: use rather the step over instead of step inside. After time, you get used to this functionality and appreciate it.
In ServiceNow, I am able to get only a maximum of 250 records in a SOAP request. How to get all the records?
Web Reference Url = https://*****.service-now.com/rm_story.do?WSDL
Code:
var url = "https://*****.service-now.com/rm_story.do?SOAP";
var userName = *****;
var password = *****;
var proxy = new ServiceNow_rm_story
{
Url = url,
Credentials = new NetworkCredential(userName, password)
};
try
{
var objRecord = new Namespace.WebReference.getRecords
{
// filters..
};
var recordResults = proxy.getRecords(objRecord);
}
catch (Exception ex)
{
}
In recordResults, I am getting only 250 records. How to get all the records ?
Also see this stack overflow answer which provides info.
Get ServiceNow Records Powershell - More than 250
Note that returning a large number of records can affect performance of the response and it may be more efficient to process your query in batches using offsets (i.e., get 1-100, then 101-200, ...). This can be achieved by using a sort order and offset. The ServiceNow REST Table API actually returns link headers from Get requests providing you links for the first, next and last set of records making it easy to know the url to query the next batch of records.
See: http://wiki.servicenow.com/index.php?title=Table_API#Methods
and look under 'Response Header'.
Have u tried to pass/override __limit parameter?
Google / wiki / Users manual / Release notes are always helpful
In your code snippet in line where it says //filter you should define __limit (and potentially __first_row and __last_row as explained in the example bellow)
int Skip = 0;
int Take = 250;
while (true)
{
using (var soapClient = new ServiceNowLocations.ServiceNow_cmn_location())
{
var cred = new System.Net.NetworkCredential(_user, _pass);
soapClient.Credentials = cred;
soapClient.Url = _apiUrl + "cmn_location.do?SOAP";
var getParams = new ServiceNowLocations.getRecords()
{
__first_row = Skip.ToString(),
__last_row = (Skip + Take).ToString(),
__limit = Take.ToString()
};
var records = soapClient.getRecords(getParams);
if (records != null)
{
if (records.Count() == 0)
{
break;
}
Skip += records.Count();
if (records.Count() != Take)
{
// last batch or everything in first batch
break;
}
}
else
{
// service now web service endpoint not configured correctly
break;
}
}
}
I made an library that handles interacting with ServiceNow Rest API much easier
https://emersonbottero.github.io/ServiceNow.Core/
Trying to create a prototype application that will post a new Requirement to HPQC 11.
I've managed to get a solid connection but when I attempt to add the blank requirement I get an AccessViolationException.
TDConnectionClass td = HPQC_Connect(); //Open a connection
ReqFactory myReqFactory = (ReqFactory)td.ReqFactory; //Start up the Requirments Factory.
Req myReq = (Req)myReqFactory.AddItem(DBNull.Value); //Create a new blank requirement (AccessViolationException)
myReq.Name = "New Requirement"; //Populate Name
myReq.TypeId = "1"; // Populate Type: 0=Business, 1=Folder, 2=Functional, 3=Group, 4=Testing
myReq.ParentId = 0; // Populate Parent ID
myReq.Post(); // Submit
Any ideas? I'm fairly new to C# and coding in general, so it's probably best to assume I know nothing.
After some significant working through the isse the following code works correctly:
private void HPQC_Req_Create_Click()
{
TDConnection td = null;
try
{
td = new TDConnection();
td.InitConnectionEx("server");
td.Login(HPQCUIDTextbox.Text.ToString(), HPQCPassTextbox.Text.ToString());
Console.WriteLine(HPQCPassTextbox.Text.ToString());
td.Connect("DEFAULT", "Test_Automation_Playground");
bool check = td.LoggedIn;
if (check == true)
{
Console.WriteLine("Connected.");
HPQCStatus.Text = "Connected.";
}
ReqFactory myReqFactory = (ReqFactory)td.ReqFactory;
Req myReq = (Req)myReqFactory.AddItem(-1); //Error Here
myReq.Name = "New Requirement 1";
myReq.TypeId = "1"; // 0=Business, 1=Folder, 2=Functional, 3=group, 4=testing
myReq.ParentId = 0;
myReq.Post();
Console.WriteLine("Requirement Created.");
HPQCStatus.Text = "Requirement Created.";
try
{
td.Logout();
td.Disconnect();
td = null;
}
catch
{ }
}
catch (Exception ex)
{
Console.WriteLine("[Error] " + ex);
try
{
td.Logout();
td.Disconnect();
td = null;
}
catch
{ }
}
This code requires that the Server be patched to QC 11 Patch 9 (Build 11.0.0.7274) in order to work. Previous versions cause errors, most notably the error in the question.
Requirements in ALM are hierarchical, when creating requirement you need to create it under some existing requirement.
What you want to do is get a hold of the root requirement, it's Id should be either 0 or 1, you can check it in ALM UI.
And then get an instance of ReqFactory from a property on that Root requirement.
And then add your requirement to that factory.
Also, make sure you are working on STA and not MTA thread.