Adding a ProducerInterceptor - Kafka - apache-kafka

I am trying to intercept the messages before they get serialized, and I see that there is already a interface called ProducerInterceptor, that can be used in order to modify the records. After making a class which implements that interface and modifies the data, where do I need to put the new class, do I have to modify some files?

While creating the KafkaProducer object, pass it in the properties e.g.
Properties producerProps = new Properties();
producerProps.put(ProducerConfig.INTERCEPTOR_CLASSES_CONFIG, "fully qualified name of your interceptor class");
//... add other properties
KafkaProducer<String,String> kProd = new KafkaProducer<>(producerProps);

Related

How to create a library exposing named configured singletons generated at runtime with Dagger 2?

I'm considering migrating to Dagger 2 some libraries. This library expose a configurable client, each configuration can be named and later retrieved in a singleton fashion.
Let me show a pseudo-code of how the library works from the user perspective:
// initialization
ClientSDK clientA = new ClientSDK.Builder()
.configuration().attributes().here()
.apiKey("someString") // set api key / credentials
.build();
LibraryAuthenticationManager customAuthManager = new MyCustomAuthenticationManager();
ClientSDK clientB = new ClientSDK.Builder()
.configuration().attributes().here()
.apiKey("someStringElse")
.customAuthManager(customAuthManager) // override some default
.baseApiUrl("https://custom.domain.com/and/path") // override some default setting
.build();
ClientSDK.setSingleton("clientA", clientA);
ClientSDK.setSingleton("clientB", clientB);
And when I need an instance elsewhere:
// usage everywhere else
ClientSDK clientB = ClientSDK.singleton("clientB");
clientB.userManager(); // "singleton" using the configuration of clientB
clientB.subscriptionsManager(); // "singleton" using the configuration of clientB
clientB.currentCachedUser(); // for clientB
clientB.doSomething(); // action on this instance of the ClientSDK
ClientSDK instances are created by the user of the library and the ClientSDK statically keep a map of singletons associated to the name.
(The actual behavior of the SDK is slightly different: the naming is automatic and based on a mandatory configuration parameter.)
It's like I have lot of singleton classes with a single point of entry (the ClientSDK) but since I can have multiple configuration of the ClientSDK each with his own singletons instances this are not really singletons.
If I would try write a library like that with Dagger 2 I would do something like:
class ClientSDK {
#Inject SDKConfiguration configuration;
#Inject LibraryAuthenticationManager authManager;
...
}
The problem is that I need each instance of the ClientSDK to have its own configuration and authManager (and many other services) injected. And they need to be definable (the configuration) and overridable (the actual implementation) from the library user.
Can I do something like this with Dagger 2? How?
I've seen I can create custom Scopes but they are defined at compile time and the library user should be the one defining them.
(the library is an Android Library, but this shouldn't be relevant)
Thanks
It sounds like you should be creating stateful/configurable Module instances and then generating separate Components or Subcomponents for each ClientSDK you build.
public class ClientSDK {
#Inject SDKConfiguration configuration;
#Inject LibraryAuthenticationManager authManager;
// ...
public static class Builder {
// ...
public ClientSDK build() {
return DaggerClientSDKComponent.builder()
.configurationModule(new ConfigurationModule(
apiKey, customAuthManager, baseApiUrl)
.build()
.getClientSdk();
}
}
}
...where your ConfigurationModule is a #Module you write that takes all of those configuration parameters and makes them accessible through properly-qualified #Provides methods, your ClientSDKComponent is a #Component you define that refers to the ConfigurationModule (among others) and defines a #Component.Builder inner interface. The Builder is important because you're telling Dagger it can no longer use its modules statically, or through instances it creates itself: You have to call a constructor or otherwise procure an instance, which the Component can then consume to provide instances.
Dagger won't get into the business of saving your named singletons, but it doesn't need to: you can save them yourself in a static Map, or save the ClientSDKComponent instance as an entry point. For that matter, if you're comfortable letting go of some of the control of ClientSDK, you could even make ClientSDK itself the Component; however, I'd advise against it, because you'll have less control of the static methods you want, and will lose the opportunity to write arbitrary methods or throw exceptions as needed.
You don't have to worry yourself about scopes, unless you want to: Dagger 2 tracks scope lifetime via component instance lifetime, so scopes are very easy to add for clarity but are not strictly necessary if you're comfortable with "unscoped" objects. If you have an object graph of true singleton objects, you can also store that component as a conventional (static final field) singleton and generate your ClientSDKComponent as a subcomponent of that longer-lived component. If it's important to your build dependency graph, you can also phrase it the other way, and have your ClientSDKComponent as a standalone component that depends on another #Component.

EMF NotSerializableException

I build application in Java using EMF.
I use Java8 JDK.
All I need is persist instance of my model's class.
I run the code in debug mode on WildFly 10 server, remotely from Eclipse.
private String getXml(Audit audit) throws NeoflexException {
XMLResource res = new XMLResourceImpl();
res.getContents().add(audit);
StringWriter sw = new StringWriter();
try {
res.save(sw, null);
} catch (IOException e) {
throw new NeoflexException(e);
}
return sw.toString();
}
On serialization I get a NotSerializableException.
I see that generated Audit class isn't marked as Serializable.
I can not edit generated code, how ever, I also don't have option to mark this class in diagram as serializable.
As described here: https://www.eclipse.org/forums/index.php/t/261475/
I need to create an interface and derive it from serializable, but I don't have such option. See screenshot attached.
In general, EMF serializability is not bound to the ISerializable interface, but a containment hierarchy formed between the model elements. Furthermore, you should not make EMF interfaces extend the ISerializable inferface at all, as it is misleading (EMF model objects are not supposed to be serializable using the basic Java serialization).
Basically, the instances of your classes should for a containment tree: one object should be the root of the tree, and all other instances should be contained in it. Then you could save this entire containment hierarchy into a file by adding the model root into the resource.
Without knowing the concrete error message in the exception, my first tip would be to check whether the Audit element references some other model element, because if that element is referenced in a non-containment relation, than the serialization will fail.
To set a relation containment, edit your metamodel (Audit.ecore file) and set the property called containment true for the reference. However, you have to make sure that the containment subtree can be set up correctly: there is only a single model root element; all other elements can be reached by exactly one path of containment references from the model root. If an element is referenced by a cross-reference, it must also be included in the containment hierarchy in order for the EMF serialization (Resource.save) to work.
A further issue I see that you create the EMF Resource file manually, without any URI (that determines where you want to save your model) and without any resourceset (that is used to split your models into multiple files/resources with separate containment hierarchies).
In other words, you should create a ResourceSet instance, and use that to create your model Resource instances.
For more details, I suggest to check the basic and serialization specific tutorial at vogella.com.

How to catch events of a class in a class helper?

I want to create a helper for TCustomQuery, TQuery, TTable and so on... With a LastRecordPosition property, which I will get with OnBeforeScroll setting that property from RecNo.
How do I create that trigger in that helper class to catch the event without interfere in an user's OnBeforePost if he/she needs one?
I use FireDAC or ZeosLib for older versions.
To intercept the OnBeforeScroll event without interfering with the user's OnBeforeScroll event handler, you need to override each component's virtual DoBeforeScroll() method. However, a class helper cannot override any virtual methods of the class it is helping. So, you will have to instead either:
write new classes that are derived from each base component class you want to intercept (type TMyCustomQuery = class(TCustomQuery), etc), and then the user must use those new component classes in their code instead of the originals.
(XE and later only) use Delphi's TVirtualMethodInterceptor class to hook the virtual DoBeforeScroll() method of specific component object instances (not the classes themselves) without having to write any derived classes.
The alternative is to write a class, possibly a Generic class, that the user has to instantiate for each component object instance, and the class can then subclass its associated component (possibly with RTTI) to capture and replace the user's OnBeforeScroll event handler with its own, and then its event handler can call the user's event handler when needed.

Doctrine - mapping an entity from an external library

i'm using an external library (the awesome nicmart/Tree to build trees) that returns me an object that is the extension of the original object produced by the library
class originalObject
{
//some properties
// this is the object produced by the library
// i dont want to modify the external library so no mapping here
}
class myObject extends originalObject
{
//this is the entity i want to persist
// but it hasnt got any property ??
}
i want to persist myObject with Doctrine\MongoDB, therefore i need to map it.
i (obviously) dont want to modify the library itself so my question is:
where do i put the mapping ?
I thought i could override the properties (like i would do with methods) by re-declaring them and adding the mapping to the re-declaration, but they are not overriden but duplicated.
IMHO you can't do it this way. You'll have to modify originalObject (add annotations there) or you'll have to declare whole myObject and can't inherit origObj.

Unity Registration: Hooking up an interface to a pre-registered concrete class

I already have a concrete class registered in my unity container and I want to, later on, register an interface that hooks up to that class but uses the existing registration.
I can do this using the following code but it causes a resolve at registration time...
container.RegisterInstance<IMyClass>(container.Resolve<MyClass>());
Is it possible to hook the code up with all resolution done at the point the interface is resolved?
The trick is to use an InjectionFactory:
container.Register<IMyClass>(
new InjectionFactory(c => c.Resolve<MyClass>()));
It sounds like you want to create a factory type. Here, a Func delegate type is used to avoid the creation of a new custom factory type:
container.RegisterInstance<Func<IMyClass>>(() => container.Resolve<MyClass>());
Your other types can then take a dependency on this factory:
private IMyClass myClass;
public MyOtherType(Func<IMyClass> myClassFactory)
{
this.myClass = myClassFactory();
}
IUnityContainer container = new UnityContainer();
var onlyInstance = new MyClass();
container.RegisterInstance<IMyClass>(onlyInstance);
IMyClass resolved = container.Resolve<IMyClass>();
if (object.ReferenceEquals(onlyInstance, resolved))
{
Console.WriteLine("Equal");
}
This prints "Equal". This is the way I would register the instance in the first place.
In a comment above, you imply that you do not control the initial registration. That's the real issue. I would recommend going down one of the following paths (in order of preference, highest to lowest):
Create your own UnityContainer independent of the pre-registered one
Create a child container with CreateChildContainer
Use named (non-default) mappings