This has been asked here but I will try to approach the question differently.
A quick review of Corda's code:
interface FungibleState<T : Any> : ContractState {
val amount: Amount<T>
}
FungibleAsset then extends FungibleState:
interface FungibleAsset<T : Any> : FungibleState<Issued<T>>, OwnableState {
override val amount: Amount<Issued<T>>
#get:SerializableCalculatedProperty
val exitKeys: Collection<PublicKey>
fun withNewOwnerAndAmount(newAmount: Amount<Issued<T>>, newOwner: AbstractParty): FungibleAsset<T>
}
If I use FungibleAsset in a Java CorDapp:
public class MyFungibleAsset implements FungibleAsset<Currency> {
#NotNull
#Override
public Amount<Issued<Currency>> getAmount() {
return null;
}
...}
it will raise 2 errors when I build the project (IntelliJ won't highlight any error during editing):
error: MyFungibleAsset is not abstract and does not override abstract method getAmount() in FungibleState
error: getAmount() in MyFungibleAsset cannot implement getAmount() in FungibleState
public Amount<Issued<Currency>> getAmount() {
^
return type Amount<Issued<Currency>> is not compatible with Amount<Issued<? extends Currency>>
where T is a type-variable:
T extends Object declared in interface FungibleState
I assume this has something to do with FungibleState's getAmount returning Amount<T> whereas FungibleAsset's getAmount returns Amount<Issued<T>> ? I don't get an error in kotlin.
Related
I'm working with a Symfony 3.4 (PHP 7.2, update to 7.4 soon) project. I have some classes who extends an abstract class and i would like all my classes got the same constant name (constant have value different in each class). I'm starting with a pattern like this :
abstract class AbstractClass
{
abstract public function getConstant(): string;
}
final class Foo extends AbstractClass
{
const MY_CONST = 'foo';
public function getConstant(): string
{
return self::MY_CONST;
}
}
final class Bar extends AbstractClass
{
const MY_CONST = 'bar';
public function getConstant(): string
{
return self::MY_CONST;
}
}
// echo $foo->getConstant() : 'foo'
// echo $bar->getConstant() : 'bar'
The goal: if a class who extends AbstractClass don't have MY_CONST, i want return an message error.
I have excluded theses solutions :
I can't add a constant in an interface (maybe in PHP 8 ?)
I can't use "abstract factory" pattern for a constant (in my code it runs with getConstant() method
I can't use a static property
The only way i have found is : implement an interface and tag the interface like explain in documentation. With compilerpass, helped with ReflexionClass, i will check if constant name exist, and if not: thrown an error or something like this.
So, i've edit like this :
final class Foo extends AbstractClass implements MyCustomInterface
{
// ...
}
final class Bar extends AbstractClass implements MyCustomInterface
{
// ...
}
The interface :
interface MyCustomInterface
{
}
Adding tag in AppKernel.php
protected function build(ContainerBuilder $container): void
{
$container
->registerForAutoconfiguration(MyCustomInterface::class)
->addTag('my_custom_tag');
}
And a compilerpass :
class MyCustomPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container): void
{
if (!$container->has(MyCustomInterface::class)) {
dump('No interface found');
return;
}
$definition = $container->findDefinition(MyCustomInterface::class);
$taggedServices = $container->findTaggedServiceIds('my_custom_tag');
dump($taggedServices);
}
}
The fun begin here...if i have only ONE class who implement the interface, $taggedServices find the service. BUT, if more than one class implements interface, no class are found...
I don't find where i am wrong. Do i need to implements AbstractClass instead of children classes ?
How can one enable validation using #Valid inside the following kafka consumer code ? I am using Spring Cloud Stream (Kafka Stream binder implementation), and there after my implemention is using functional model for example.
#Bean
public Consumer<KStream<String, #Valid Pojo>> process() {
return messages -> messages.foreach((k, v) -> process(v));
}
I tried the following but it didn't work....
#Bean
public DefaultMessageHandlerMethodFactory configureMessageHandlerMethodFactory(
DefaultMessageHandlerMethodFactory messageHandlerMethodFactory,
LocalValidatorFactoryBean validatorFactoryBean) {
messageHandlerMethodFactory.setValidator(validatorFactoryBean);
return messageHandlerMethodFactory;
}
This is simple in spring-kafka by implementing KafkaListenerConfigurer and setting LocalValidatorFactoryBean on KafkaListenerEndpointRegistrar
public class KafkaConfiguration implements KafkaListenerConfigurer {
#Override
public void configureKafkaListeners(KafkaListenerEndpointRegistrar registrar) {
registrar.setValidator(validatorFactoryBean);
}
.....
This is not supported in the functional model at the moment. Even for a non-functional scenario, this is non-trivial for types like KStream. The KafkaListenerConfigurer you mentioned above is for regular Kafka Support with a message channel binder. Your best options for Kafka Streams binder are either using some custom validation in the function itself before continuing with the processing or introducing a schema registry and then perform a schema validation before passing the record to the function.
You can follow the recommendation to create a bean that respects the functional interface of java, that is, it has only a public method, for example:
#Validated
#Component
public class Processor implements Consumer<KStream<String, Pojo>> {
#Override
public void accept(final #Valid #NotNull KStream<String, Pojo> stream) {
stream.foreach((k, v) -> process(v));
}
private void process(final Pojo v) {
}
}
So that generates an execution:
javax.validation.ConstraintDeclarationException: HV000151: A method
overriding another method must not reset the parameter constraint
configuration
It is not possible to overwrite the parameters of the accept method of the consumer functional interface so just remove the interface and leave the component like this:
#Validated
#Component
public class Processor {
public void accept(final #Valid #NotNull KStream<String, Pojo> stream) {
stream.foreach((k, v) -> process(v));
}
private void process(final Pojo v) {
}
}
The problem is that the spring cloud function will not recognize the bean for not extending one of the functional classes.
the workaround I got was:
#RequiredArgsConstructor
public abstract class ValidatedEventListener<T> implements Consumer<T> {
private final Validator validator;
#Override
public void accept(final T t) {
validate(t);
listen(t);
}
public abstract void listen(final T t);
public void validate(final Object event) {
var violations = validator.validate(event);
if (!violations.isEmpty()) throw new ConstraintViolationException(violations);
}
}
I'm using the Java template (token-template branch), tokens SDK version is 1.1-SNAPSHOT.
I'm extending FungibleToken class to add one extra attribute (PublicKey owningAccount) and I'm getting this error inside Intellij (as red underlines):
supportedSchemas() in QueryableState clashes with supportedSchemas() in FungibleState, attempting to use incompatible type
When I add the below function; the compile error is gone (Intellij no longer shows red underlines), but I get a different error on ./gradlew deployNodes:
#NotNull
#Override
public List<FungibleTokenSchemaV1> supportedSchemas() {
return super.supportedSchemas();
}
Build error:
> Task :contracts:compileJava FAILED
MyToken.java:33: error: supportedSchemas() in MyToken cannot implement supportedSchemas() in QueryableState
public List<FungibleTokenSchemaV1> supportedSchemas() {
^
return type List<FungibleTokenSchemaV1> is not compatible with Iterable<MappedSchema>
1 error
Even though List is Iterable and FungibleTokenSchemaV1 is MappedSchmea.
Full code of class:
public class MyToken extends FungibleToken {
private final PublicKey owningAccount;
public Shoken(Amount<IssuedTokenType> amount,
AbstractParty holder,
SecureHash tokenTypeJarHash,
PublicKey owningAccount) {
super(amount, holder, tokenTypeJarHash);
this.owningAccount = owningAccount;
}
public PublicKey getOwningAccount() {
return owningAccount;
}
#NotNull
#Override
public List<FungibleTokenSchemaV1> supportedSchemas() {
return super.supportedSchemas();
}
}
I would suggest you to use evolvableTokentype to issue tokens with evolvable attributes. The FungibleToken and NonFungibleToken objects are only the instruments that carries the issuance of the tokens. The underlying template of the token is what stores the information.
Feel free to look at our TokenSDK workshop at https://www.youtube.com/watch?v=IAViczRAEyU.
I used moq version 4.0.10827 to mock an Com object and when i upgrade to 4.2.1510.2205 i get an nonComVisibleBaseClass error when the test execute:
[Guid("0339CD56-9BA3-477D-801B-E5F73D37EABE")]
[TypeLibType(4160)]
public interface IDaemonCli
{
// methods & propperties ...
[DispId(1)]
void CloseLog();
....
}
[CoClass(typeof(DaemonCliClass))]
[Guid("0339CD56-9BA3-477D-801B-E5F73D37EABE")]
public interface DaemonCli : IDaemonCli
{
}
[ClassInterface(0)]
[Guid("D94FBC81-06EC-4EAA-B73F-794051487691")]
[TypeLibType(2)]
public class DaemonCliClass : IDaemonCli, DaemonCli
{
// ... definitions of all methods of the com obj
[DispId(1)]
public virtual void CloseLog();
....
}
The mock is created as this :
[TestClass]
[Serializable]
public abstract class Test : IDisposable
{
protected static Mock<DaemonCli> DaemonClientMock { get; private set; }
static Test()
{
Test.DaemonClientMock = new Mock<DaemonCli>();
// here are all the setup on the DaemonClientMock
}
}
The mock is injected in the tested code as this :
typeof(LoggedServiceBase).GetProperty(
PropertySupport.ExtractPropertyName(() => this.batchClassService.Logger),
BindingFlags.Public | BindingFlags.Instance)
.SetValue(this.batchClassService, Test.DaemonClientMock.Object, null);
The Exception is raised when the mock is used by the tested class:
freeMindCom.SetLog(this.Logger);
All was fine with the version of Castle used by the previous version of Moq (4.0.10.827), i don't know precisely which one it was.
Any help would be appreciated.
Thanks
Hi I am using a UOW and Repository pattern in my project and I have created the following code:
// Interfaces
public interface IUnitOfWork : IDisposable
{
IGenericRepository<Company> CompanyRepository { get; }
void Commit();
}
public interface IEFUOW_Company : IUnitOfWork
{
bool CreateCompanyForUser(RegisterModel model, string userName);
}
// Implementation
public class EFUOW_Company : EfUnitOfWork
{
public EFUOW_Company()
{
}
}
public class EfUnitOfWork : Disposable, IUnitOfWork
{
private DALDbContext _dataContext;
private EfGenericRepository<Company> _companyRepo;
public DbSet<Company> Companies { get; set; }
public EfUnitOfWork()
{
_companyRepo = null;
}
}
// Unity Registration
container.RegisterType<IUnitOfWork, EfUnitOfWork>(new HttpContextLifetimeManager<IUnitOfWork>());
.RegisterType<IEFUOW_Company, EFUOW_Company>(new HttpContextLifetimeManager<IEFUOW_Company>());
// Error Message # Compile
Error 105 The type 'DataAccessLayer.UnitOfWork.EFUOW_Company' cannot be used as type parameter 'TTo' in the generic type or method
'Microsoft.Practices.Unity.UnityContainerExtensions.RegisterType<TFrom,TTo>(Microsoft.Practices.Unity.IUnityContainer, Microsoft.Practices.Unity.L
ifetimeManager, params Microsoft.Practices.Unity.InjectionMember[])'. There is no implicit reference conversion from '
DataAccessLayer.UnitOfWork.EFUOW_Company' to 'DataAccessLayer.UnitOfWork.IEFUOW_Company'.
I cannot work out why it's complaining about the conversion as I am new to Unity and this is my first attempt at building this type of logic.
I want to be able to create different IUnitOfWork based interfaces/implementations so I can reuse code in the IUnitOfwork and it's Implementation EfUnitOfWork.
Thanks in advance
The class efuow_company does not implement iefuow_company interface.