Error While Fetching Data from Corda Custom Tables - corda

How to fetch data from corda Custom tables?
my sample code is as follows :-
Api layer -- getIous() method
{
Field attributeValue=IOUSchemaV1.PersistentIOU.class.getDeclaredField("value");
CriteriaExpression currencyIndex = Builder.equal(attributeValue, "12");
QueryCriteria.VaultCustomQueryCriteria criteria = new
QueryCriteria.VaultCustomQueryCriteria(currencyIndex);
vaultStates = services.vaultQueryByCriteria(criteria,IOUState.class);
}
In ExamplePlugin I added below code for schema registration
public class ExamplePlugin extends CordaPluginRegistry implements
WebServerPluginRegistry
{
#NotNull
#Override
public Set<MappedSchema> getRequiredSchemas()
{
Set<MappedSchema> requiredSchemas = new HashSet<>();
requiredSchemas.add(new IOUSchemaV1());
return requiredSchemas;
}
}
My Schema classes are ---
public final class IOUSchema {
}
#CordaSerializable
public class IOUSchemaV1 extends MappedSchema
{
public IOUSchemaV1() {
super(IOUSchema.class, 1, ImmutableList.of(PersistentIOU.class));
}
#Entity
#Table(name = "iou_states")
public static class PersistentIOU extends PersistentState {
#Column(name = "sender_name") private final String senderName;
#Column(name = "recipient_name") private final String recipientName;
#Column(name = "value") private final int value;
public PersistentIOU(String senderName, String recipientName, int value) {
this.senderName = senderName;
this.recipientName = recipientName;
this.value = value;
}
public String getSenderName() {
return senderName;
}
public String getRecipientName() {
return recipientName;
}
public int getValue() {
return value;
}
}
}
my state has :-
public class IOUState implements LinearState, QueryableState
{
--- some code goes here and below methods as well.---
#Override
public PersistentState generateMappedObject(MappedSchema schema) {
if (schema instanceof IOUSchemaV1) {
return new IOUSchemaV1.PersistentIOU(
this.sender.getName().toString(),
this.recipient.getName().toString(),
this.iou.getValue());
} else {
throw new IllegalArgumentException("Unrecognised schema $schema");
}
}
#Override
public Iterable<MappedSchema> supportedSchemas() {
return ImmutableList.of(new IOUSchemaV1());
}
}
But all the time i am getting below exception.
Caused by: net.corda.core.node.services.VaultQueryException:
Please register the entity 'com.example.schema.IOUSchemaV1' class in your CorDapp's CordaPluginRegistry configuration (requiredSchemas attribute)
and ensure you have declared (in supportedSchemas()) and mapped (in generateMappedObject())
the schema in the associated contract state's QueryableState interface implementation.
Can anyone please help to resolve this.

Try deleting implements WebServerPluginRegistry from your plugin declaration.

Related

How to apply Command Design pattern with Dependency Injection using Generic Class?

i want to apply command Design pattern with dependency Injection in the following situation: i have three types of reports in my system (SubscriptionReport, SalesReport, SpechialistReport) so i created one interface IReportService
public interface IReportService<T> where T: class
{
public Task<GenericResponse<List<T>>> GetReport(string searchKey, DateTime from, DateTime to);
}
and to apply OCP i have implemented the GetReport function tree times for (SubscriptionReport, SalesReport, SpechialistReport)
public class SpechialistReportService : IReportService<SpechialistReportDTO>
{
public Task<GenericResponse<List<SpechialistReportDTO>>> Report(string searchKey, DateTime from, DateTime to)
{
throw new NotImplementedException(); // to be implemented later
}
}
public class SubscriptionReportService : IReportService<SubscriptionReportDTO>
{
public Task<GenericResponse<List<SubscriptionReportDTO>>> Report(string searchKey, DateTime from, DateTime to)
{
throw new NotImplementedException(); // to be implemented later
}
}
public class SalesReportService : IReportService<SalesReportDTO>
{
public Task<GenericResponse<List<SalesReportDTO>>> Report(string searchKey, DateTime from, DateTime to)
{
throw new NotImplementedException(); // to be implemented later
}
}
after that i have added the dependency
services.AddScoped(typeof(IReportService<SpechialistReportDTO>), typeof(SpechialistReportService));
services.AddScoped(typeof(IReportService<SubscriptionReportDTO>), typeof(SubscriptionReportService));
services.AddScoped(typeof(IReportService<SalesReportDTO>), typeof(SalesReportService));
the problem is in calling the dependency in the controller constructor
private readonly IEnumerable<IReportService> _reportService; // Should be IReportService<dont know what class should i specify here>
public ReportController(IReportService<T> reportService)
{
this._reportService = reportService;
}
Any help would be appreciated thanks in advance,
Okay i solved this problem by removing the Generic and adding marker interface to the DTOs classes
public interface ReportRoot
{
}
public class SubscriptionReportDTO : ReportRoot
{
// Some data here
}
public class SalesReportDTO: ReportRoot
{
// Some data here
}
In ReportService Interface
public interface IReportService
{
public Task<GenericResponse<List<ReportRoot>>> Report();
}
public class SubscriptionReportService : IReportService {
public async Task<GenericResponse<List<ReportRoot>>> Report()
{
List<ReportRoot> subscriptionReportDTO = new List<ReportRoot>();
SubscriptionReportDTO test = new SubscriptionReportDTO();
test.SalesTax = "1000";
subscriptionReportDTO.Add(test);
return new GenericResponse<List<ReportRoot>>("1", subscriptionReportDTO.Count, "Success", subscriptionReportDTO);
}
}
public class SalesReportService : IReportService {
public async Task<GenericResponse<List<ReportRoot>>> Report()
{
List<ReportRoot> salesReportDTO = new List<ReportRoot>();
SalesReportDTO test = new SalesReportDTO ();
test.SalesTax = "1000";
salesReportDTO .Add(test);
return new GenericResponse<List<ReportRoot>>("1", salesReportDTO.Count, "Success", salesReportDTO );
}
}
In controller
private readonly IEnumerable<IReportService> _reportService;
public ReportController(IEnumerable<IReportService> reportService)
{
this._reportService = reportService;
}

RestController JSON Response object format

I am using Spring Boot to return data from a Repository. I would like to format my JSON so that it plays nicely with ExtJS' ajax handling. Essentially I would like to include properties to handle success/failure, count, and errorMsg along with a List of data from the repository.
I have tried by creating a ResponseDTO object that I'm returning from my Rest Controller.
#RestController
public class AdminController {
private static final Logger logger = LogManager.getLogger(AdminController.class);
#Autowired
private UserService userService;
#Autowired
private SecurityService securityService;
#Autowired
private UserValidator userValidator;
#GetMapping("/searchUsers")
public ResponseDTO searchUsers(String name, String active) {
int activeFlag;
List<User> users;
ResponseDTO resp;
if(active.equals("true")) {
activeFlag = 1;
} else activeFlag=0;
if(StringUtils.isEmpty(name)) {
users= userService.findAllUsers(activeFlag);
} else {
users= userService.findByUsernameActive(name, activeFlag);
}
return new ResponseDTO(users, true);
}
}
Here's my DTO that I use in the controller:
public class ResponseDTO {
private boolean success;
private int count = 0;
private List<?> values;
public boolean getSuccess() {
return this.success;
}
public void setState(boolean st) {
this.success=st;
}
public int getCount() {
return this.count;
}
public void setCount(int cnt) {
this.count=cnt;
}
public List<?>getValues() {
return this.values;
}
public void setValues(List<?> vals) {
this.values = vals;
}
public ResponseDTO(List<?> items, boolean state) {
this.success = state;
values = items;
this.count = items.size();
}
}
Here's what the JSON I get back looks like:
{
"ResponseDTO": {
"success":true,
"count":2,
"values":[{obj1 } , { obj2}]
}
}
what I would like to get is something more like:
{
"success" : true,
"count" : 2,
"values" [{obj1},{obj2}]
}
I'm using Spring Boot and Jackson annotations. I have used an annotation to ignore individual fields in the objects in the results array, but I can't find a way to unwrap the ResponseDTO object to not include the class name.
When you serialize ResponseDTO POJO, you should not get 'ResponseDTO' in the response by default. Because, the root wrap feature is disabled by default. See the doc here. If you have the below code, please remove it.
mapper.enable(SerializationFeature.WRAP_ROOT_VALUE);

Custom #Id class for Spring Data Redis

I am trying to convert / serialize the #Id field (which is not a string) of the model class but keep getting this error. The custom ID class just concatenates two values with a colon, e.g. aaaa:2345.
org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [MyIdClass] to type [byte[]]
This is my model class.
#RedisHash("alert")
public class MyClass implements Serializable
{
public static class MyIdClass
{
public String userId;
public Long sessionExpiry;
public MyIdClass()
{
}
public MyIdClass(String id, Long ex)
{
userId = id;
sessionExpiry = ex;
}
}
public static class MyIdClassSerializer implements RedisSerializer<MyIdClass>
{
#Nullable
#Override
public byte[] serialize(#Nullable MyIdClass uid) throws SerializationException
{
return String.format("%s:%d", uid.userId, uid.sessionExpiry).getBytes();
}
#Nullable
#Override
public MyIdClass deserialize(#Nullable byte[] bytes) throws SerializationException
{
String[] t = new String(bytes).split(":");
return new MyIdClass(t[0], Long.parseLong(t[1]));
}
}
#Component
#ReadingConverter
public static class MyIdClassReader implements Converter<byte[], MyIdClass>
{
#Nullable
#Override
public MyIdClass convert(byte[] source)
{
String[] t = new String(source).split(":");
return new MyIdClass(t[0], Long.parseLong(t[1]));
}
}
#Component
#WritingConverter
public static class MyIdClassWriter implements Converter<MyIdClass, byte[]>
{
#Nullable
#Override
public byte[] convert(MyIdClass uid)
{
return String.format("%s:%d", uid.userId, uid.sessionExpiry).getBytes();
}
}
/**
* User ID
* Key := 'alert:' userId ':' sessionExpiry
*/
#Id
public MyIdClass id;
public String value;
}
Here's how I'm configuring the RedisTemplate.
#Bean("redisTemplateActivityAlert")
public RedisTemplate<ActivityAlert.UserIdExpiry, ActivityAlert> redisTemplateActivityAlert()
{
RedisTemplate<ActivityAlert.UserIdExpiry, ActivityAlert> template = new RedisTemplate<>();
template.setConnectionFactory(jedisConnectionFactory());
template.setKeySerializer(new ActivityAlert.UserIdExpirySerializer());
template.setHashKeySerializer(new ActivityAlert.UserIdExpirySerializer());
return template;
}
I've read other posts about configuring ConversionService or TypeConverter but haven't gone far with them.
add this Bean to your RedisConfiguration :
#Bean
public RedisCustomConversions redisCustomConversions(MyIdClassReader myIdClassReader , MyIdClassWriter myIdClassWriter ) {
return new RedisCustomConversions(Arrays.asList(myIdClassWriter,myIdClassReader));
}

How to use Jackson to deserialise list in java?

My Java Class is
public class User {
private List<UserInfo> userInfoList;
public class UserInfo {
private String id;
}
}
Let's assume it has getter, setter method.
json is
{"userInfoList" : [{"id":"a", "id":"b"}]}
I tried to deserialize it like below.
objectMapper.readValue(json, User.class);
But it throws error.
Can not construct instance of User$UserInfoList: no suitable constructor found
How to deserialize it?
I think you should make UserInfo static. Jackson cannot construct the UserInfo class.
I tried with that change and it works for me :
public class User {
private List<UserInfo> userInfoList;
public static class UserInfo {
private String id;
public UserInfo() {
super();
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
public List<UserInfo> getUserInfoList() {
return userInfoList;
}
public void setUserInfoList(List<UserInfo> userInfoList) {
this.userInfoList = userInfoList;
}
}
And :
public class App {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
User.UserInfo ui1 = new User.UserInfo();
ui1.setId("a");
User.UserInfo ui2 = new User.UserInfo();
ui2.setId("b");
List<User.UserInfo> userInfoList = new ArrayList<User.UserInfo>();
userInfoList.add(ui1);
userInfoList.add(ui2);
User user = new User();
user.setUserInfoList(userInfoList);
System.out.println(mapper.writeValueAsString(user));
user = mapper.readValue(mapper.writeValueAsString(user), User.class);
}
}

Unit Test issues with Entity FrameWork (nullable values)

im trying to implement a uniTest for my application so when i tried to get User by ID value in my application it's work fine, but when i tried to do the same scenario from my unit test class i always get nullable result even if the ID value is correct :
Class AccountController : ApiController
{
private UserService _UserService = null;
public AccountController()
{
_UserService = new UserService();
}
[AllowAnonymous]
[Route("test")]
public IHttpActionResult test()
{
var user = _UserService.getUserById(1); //user --> not null;
}
}
but when i tried a UnitTest Script
[TestClass]
public class userServiceTest
{
private UserService _UserService = null;
public userServiceTest()
{
_UserService = new UserService();
}
[TestMethod]
public void checkUserCase1()
{
var user = _UserService.getUserById(1); //user is null value !!!;
}
}
User Service :
public class UserService
{
private GenericRepository<User> _UserRepository = null;
public UserService()
{
_UserRepository = new GenericRepository<User>();
}
public User getUserById(int id)
{
return _UserRepository.Find(x => x.Id == id).FirstOrDefault();
}
}
The Generic Repository
public class GenericRepository<T> : IGenericRepository<T> where T : class
{
private MyDbContext db = null;
private DbSet<T> table = null;
public IEnumerable<T> Find(Expression<Func<T, bool>> predicate)
{
return table.Where(predicate);
}
}
IGeneric :
public interface IGenericRepository<T> where T : class
{
IEnumerable<T> SelectAll();
T SelectByID(object id);
void Insert(T obj);
void Update(T obj);
void Delete(object id);
void Save();
IEnumerable<T> Find(Expression<Func<T, bool>> predicate);
}
My DB Context :
public class MyDbContext : DbContext
{
public MyDbContext()
: base("AuthWebApiDb")
{
Database.SetInitializer<MyDbContext>(new MyDbInitializer());
}
public DbSet<User> Users { get; set; }
}
I have Two Project : One is the simple project, the second is the Unit Test
Check if EF is innstalled in your UnitTest project.
Put the connection string in the app.config file in the unitest project.
Thank's #Stewart_T

Resources