Setting value of Row/Partition Key based on other propert - azure

Is there a way I can override getter of RowKey property for TableEntity ?

I would assume that it is possible to use the new keyword to override the getter as such:
public class Person : TableEntity
{
public Person(string name, string surname)
:base(surname, name)
{
}
public new string PartitionKey
{
get { return "OhLala" + base.PartitionKey; }
}
public new string RowKey
{
get { return "ohMama" + base.RowKey; }
}
}

Here is the snippet to implement the ITableEntity interface
public class TestEntity : ITableEntity
{
private string _rowKey;
public TestEntity()
{
this.Properties = new Dictionary<string, EntityProperty>();
}
private IDictionary<string, EntityProperty> Properties { get; set; }
public void ReadEntity(IDictionary<string, EntityProperty> properties, Microsoft.WindowsAzure.Storage.OperationContext operationContext)
{
this.Properties = properties;
}
public IDictionary<string, EntityProperty> WriteEntity(Microsoft.WindowsAzure.Storage.OperationContext operationContext)
{
return this.Properties;
}
}

Related

Model mapper mapping Map<String,Object> to class which extends another generic class not working for list field

I am trying to create my custom configuration object from Map using model mapper. Everything gets mapped properly excepts the fields property which is coming fro Generic super class.
My target object is
public class ADParserConfig extends CustomParserConfig<ADParserConfigField> {
private String pattern;
public String getPattern() {
return pattern;
}
public void setPattern(String pattern) {
this.pattern = pattern;
}
}
This extends generic class CustomParserConfig
public class CustomParserConfig<T extends CustomParserConfigField> {
protected List<T> fields;
protected String timeStampField;
public List<T> getFields() {
return fields;
}
public void setFields(List<T> fields) {
this.fields = fields;
}
public String getTimeStampField() {
return timeStampField;
}
public void setTimeStampField(String timeStampField) {
this.timeStampField = timeStampField;
}
}
Where CustomParserConfigField is
public class CustomParserConfigField {
protected String name;
protected Integer index;
protected String type;
protected String format;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getIndex() {
return index;
}
public void setIndex(Integer index) {
this.index = index;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getFormat() {
return format;
}
public void setFormat(String format) {
this.format = format;
}
}
I am trying to map Map using below function
ADParserConfig adParserConfig = getConfig(map,ADParserConfig.class);
public <T extends CustomParserConfig> T getConfig(Map<String,Object> configObject, Class<T> classType){
ModelMapper modelMapper = new ModelMapper();
return modelMapper.map(configObject,classType);
}
Everything excepts fields gets mapped properly for the below map.
{fields=[{name=timeStamp, type=timestamp, format=dd/mm/yyyy HH:MM:SS a}, {name=logName, type=string}], pattern=(?<timeStamp>\d{2}\/\d{2}\/\d{4}\s\d{2}:\d{2}:\d{2}\s[AMPMampm]{2})?\s(LogName=(?<logName>[\w\s\W]+))?\sSourceName=(?<sourceName>[\w\s\W]+)\sEventCode=(?<eventCode>[0-9]*), timeStampField=timestamp}
Please help. Why is issue happens only for fields object ? Do I need to specify something else in mapper configurations ?
It looks like a bug and it had been fixed by #370

JAVA/JAXB : Marshal/UnMarshal using attributes in the xml or class members

I have XML as follows
<request type="1">
<request-header/>
<request-details>
<!-- Some more tags -->
</request-details>
</request>
For mapping this XML I have class structure as follows :
public class Request1
{
private RequestDetail_1;
//other members
}
public class Request2
{
private RequestDetail_2;
//other members
}
public class RequestDetail_1
{
//members
}
public class RequestDetail_2
{
//Members
}
What I want to do is ... If attribute type is 1 then I need to create object of type Request_1 , if type is 2 then object type will be Request_2 and so on.
I have gone through this link for reference but still couldn't figure out a way to do this. I want to use pure JAXB and not MOXY or any other such frame works... :( .
Partial code :
#XmlJavaTypeAdapter(RequestAdaptor.class)
#XmlRootElement(name="request")
public class AuthRequest extends Request
{
private AuthRequestDetails requestDetails;
public RequestDetails getRequestDetails()
{
return requestDetails;
}
#Override
public void setRequestDetails(RequestDetails requestDetails)
{
this.requestDetails = (AuthRequestDetails)requestDetails;
}
}
#XmlAccessorType(XmlAccessType.FIELD)
public class AuthRequestDetails extends RequestDetails
{
#XmlElement(name="user-name")
private String userName;
#XmlElement(name="password")
private String password;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
#XmlAccessorType(XmlAccessType.FIELD)
#XmlJavaTypeAdapter(RequestAdaptor.class)
public abstract class Request
{
#XmlAttribute
protected String type;
#XmlElement(name="request-header")
protected RequestHeader requestHeader;
public RequestHeader getRequestHeader()
{
return requestHeader;
}
public void setRequestHeader(RequestHeader requestHeader)
{
this.requestHeader = requestHeader;
}
public String getType()
{
return type;
}
public void setType(String type)
{
this.type = type;
}
public abstract void setRequestDetails(RequestDetails requestDetails);
public abstract RequestDetails getRequestDetails();
}
public class RequestAdaptor extends XmlAdapter<RequestDTO, Request>
{
#Override
public RequestDTO marshal(Request v) throws Exception
{
System.out.println("marshal");
RequestDTO lRequestDTO= new RequestDTO();
lRequestDTO.setRequestHeader(v.getRequestHeader());
lRequestDTO.setType(v.getType());
if(v.getType().equals("5"))
{
AuthRequest lRequest = (AuthRequest)v;
}
else
{
PingRequest lRequest = (PingRequest)v;
}
return lRequestDTO;
}
#Override
public Request unmarshal(RequestDTO v) throws Exception
{
System.out.println("unmarshal");
if(v.getType().equals("5"))
{
AuthRequest lRequest = new AuthRequest();
lRequest.setRequestHeader(v.getRequestHeader());
lRequest.setType(v.getType());
return lRequest;
}
else
{
PingRequest lRequest = new PingRequest();
lRequest.setRequestHeader(v.getRequestHeader());
lRequest.setType(v.getType());
return lRequest;
}
}
}
#XmlAccessorType(XmlAccessType.FIELD)
public class RequestDTO
{
#XmlAttribute
protected String type;
#XmlElement(name="request-header")
private RequestHeader requestHeader;
#XmlElement(name="request-details")
private RequestDetails requestDetails;
public RequestHeader getRequestHeader()
{
return requestHeader;
}
public void setRequestHeader(RequestHeader requestHeader)
{
this.requestHeader = requestHeader;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public RequestDetails getRequestDetails() {
return requestDetails;
}
public void setRequestDetails(RequestDetails requestDetails) {
this.requestDetails = requestDetails;
}
}
#XmlAccessorType(XmlAccessType.FIELD)
public class RequestHeader
{
#XmlElement(name="name")
String Name;
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
}
First thing is : Marshal and Unmarshal of Adaptor is not getting called. I am stuck at this point.
You can use a StAX XmlStreamReader to parse the XML. Then advance it to the root element. When it's at the root element event check the value of the type attribute. Use this value to determine which Class you should pass to the unmarshal method that takes a Class and XmlStreamReader to get the result you are looking for.

Azure Table Storage Entity Row/Primary Key as Attribute for existing properties

I already have entity migrated from EntityFramework.
I'm don't want override some propeties and Convert it to string
public class User : TableEntity, ITableStorageEntity<int, Guid>
{
[RowKey]
public Guid ID { get; set; }
[PartitionKey]
public int LanguageID { get; set; }
It's possible ? I don't want override ReadEntity/WriteEntity.
Since your class is already based on TableEntity, you might want to try to override/replace the row key and partition key property of TableEntity using the 'new' keyword instead.
public class User : TableEntity
{
[IgnoreProperty]
public Guid ID { get; set; }
[IgnoreProperty]
public int LanguageID { get; set; }
public new string PartitionKey { get { return ID.ToString(); } set { ID = Guid.Parse(value); } }
public new string RowKey { get { return LanguageID.ToString(); } set { LanguageID = int.Parse(value); } }
}
I am not a big fan of 'new' modifier. In my opinion it is non-OOP approach.
I will suggest following
public class ConsumerApplicationEntity : TableEntity
{
public ConsumerApplicationEntity(string applicationKey, string applicationSecret)
: base(applicationKey, applicationSecret)
{
}
[IgnoreProperty]
public string ApplicationKey
{
get
{
return this.PartitionKey;
}
set
{
this.PartitionKey = value;
}
}
[IgnoreProperty]
public string ApplicationSecret
{
get
{
return this.RowKey;
}
set
{
this.RowKey = value;
}
}
}

ServiceStack empty metadata

Seeing a strange problem, getting empty metata pages for xml,json and jvs.
Using the following command line app. How does one debug these issues?
namespace ConsoleApplication2
{
public struct NativeUser
{
public int login;
public string group;
public string name;
}
[DataContract]
public class User
{
private NativeUser _native;
public User() { }
public User(NativeUser native)
{
_native = native;
}
public static implicit operator NativeUser(User user)
{
return user._native;
}
public static implicit operator User(NativeUser native)
{
return new User(native);
}
// ReSharper disable InconsistentNaming
[DataMember]
public int login
{
get { return _native.login; }
set { _native.login = value; }
}
[DataMember]
public string group
{
get { return _native.group; }
set { _native.group = value; }
}
[DataMember]
public string name
{
get { return _native.name; }
set { _native.name = value; }
}
}
[Description("GET account, all or by list of groups or by list of logins")]
[Route("/accounts/{groups}", "GET")]
[Route("/accounts/{logins}", "GET")]
[Route("/accounts/", "GET")]
public class Accounts : IReturn<User[]>
{
public string[] groups { set; get; }
public int[] logins { set; get; }
public Accounts() { }
public Accounts(params int[] logins)
{
this.logins = logins;
}
public Accounts(params string[] groups)
{
this.groups = groups;
}
}
public class Host : AppHostHttpListenerBase
{
public Host() : base("Test",
typeof(Accounts).Assembly)
{
}
public override void Configure(Funq.Container container)
{
}
}
public class Servce : IService
{
public object Get(Accounts request)
{
return new List<User>(){new User(new NativeUser())};
}
}
class Program
{
static void Main(string[] args)
{
var host = new Host();
host.Init();
host.Start("http://+:12345/");
global::System.Console.ReadLine();
}
}
}
Nm, found the bug :
public class Accounts : IReturn<User[]>
needs to be
public class Accounts : IReturn<List<User>>
Another very note worthy thing: All DTO's and objects being passed back and fourth in the DTO's require an empty constructor in order for the metata data to be properly generated.
Not sure if this is by design or a bug

How can I set the RowKey to a new value with a sequence

I have the following class:
public class Note : TableServiceEntity
{
public Note( )
{
}
public Note(string pK)
{
PartitionKey = pK,
RowKey = Seq.GetSequence().ToString();
}
public string Description { get; set; }
}
What I need is to set the RowKey to the value generated by the sequence. Can anyone explain how to do this with a constructor? What I get is a syntax error: Virtual member call in constructor.
public static class Seq
{
static int index;
public static int GetSequence()
{
return index++;
}
}
public class Note : TableServiceEntity
{
public Note(string partitionKey, string rowKey)
: base(partitionKey, Seq.GetSequence().ToString()) { }
}

Resources