How to add context to cache load() for Guava LoadingCache? - guava

I want to add AWS XRay segment context to the cache loading mechanism, the problem is that the method load that we override to use LoadingCache from Guava, has fixed parameters so I cannot pass any XRay segment info.
I didn't try anything yet.
#AllArgsConstructor
public class InfoAsyncCacheLoader extends CacheLoader<String, String> {
#Override
public InfoModel load(String string) {
// TODO: create subsegment for ddb loading with context of parent segment passed in:
return item;
}

Related

How to be notified when CachedModeledFramework is initialized

I am using Apache Curator's CachedModeledFramework to try to cache all of the child nodes in a path. I want to be notified when the cache is loaded. If children exist, I do get the NODE_ADDED events from the listener, but I can't find any way to get notified when it is fully cached, even if no children exist yet. I can't use readThrough or readThroughAsZNode because the ZPath is not resolved.
Also, the modeledClient.cached() line produces a "CuratorCache does not support custom ExecutorService" warning even though I am not passing in an executor (same warning shows up if I do pass an executor).
private static final ModelSpec<Monitor> monitorSpec = ModelSpec.builder(ZPath.parseWithIds("/monitors/{id}"), JacksonModelSerializer.build(Monitor.class)).build();
private CachedModeledFramework<Monitor> cached;
public void init() {
AsyncCuratorFramework async = AsyncCuratorFramework.wrap(CuratorMgr.getClient());
ModeledFramework<Monitor> modeledClient = ModeledFramework.wrap(async, monitorSpec);
cached = modeledClient.cached();
cached.start();
cached.listenable().addListener((type, path, stat, model) -> {
logger.info("LISTENER {} {}", type, path);
});
}
Edit
I found the answer. The ModeledCacheListener has an initialized method I can override.
cached.listenable().addListener(new ModeledCacheListener<Monitor>() {
#Override
public void accept(ModeledCacheListener.Type type, ZPath path, Stat stat, Monitor model) {
logger.info("LISTENER {} {}", type, path);
}
#Override
public void initialized() {
ModeledCacheListener.super.initialized();
logger.info("INITIALIZED");
}
});
Edited the initial post with the answer of overriding the initialized method of ModeledCacheListener

How do I pass an Activity via MethodChannel in Flutter?

I'm making a Flutter app that needs to call a third party library (jar file provided).
The Java documentation for the third-party API object is created by calling something
public class MainActivity extends Activity {
private ThirdPartyAPI mAPI;
private ThirdPartyAPICallbacks mCallbacks = new ThirdPartyAPICallbacks(){
#Override
public void Connected() {
}
};
protected void onCreate(Bundle savedInstanceState) {
mAPI = new ThirdPartyAPI(this, mCallbacks); // how do we do the equivalent in Flutter?
}
}
How do I do this in Flutter?
I tried MethodChannel, but I don't know what to pass as the Activity instance to the ThirdPartyAPI constructor.
MethodChannel doesn't and will never allow to send something like an Activity.
The only types allowed are the following from the official DOCS:
If you really need to send something to Flutter, you'd need to create a method on Flutter which will call Java/Kotlin side, then get anything important you need from that 3rd party API/Library/Etc and send that info back to Flutter using a MethodChannel.
You don't transfer to Activity across the method channel. It only ever exists at the Java end. Instead it gets 'attached' to the Java end of the channel.
When creating a plugin (this is probably preferred as you can re-use it in different projects), make sure the plugin class also implements ActivityAware. Create stub implementation for the four methods required, in particular onAttachedToActivity.
For example:
public class ThirdPartyApiPlugin implements FlutterPlugin, ActivityAware {
#Override
public void onAttachedToActivity(ActivityPluginBinding binding) {
Activity activity = binding.getActivity();
mAPI = new ThirdPartyAPI(activity, mCallbacks);
}
If not using a plugin, modify the MainActivity class as described here.
public class MainActivity extends FlutterActivity {
private static final String CHANNEL = "someChannelName";
#Override
public void configureFlutterEngine(#NonNull FlutterEngine flutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
mAPI = new ThirdPartyAPI(this, mCallbacks);
new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL)
.setMethodCallHandler(
(call, result) -> {
// Note: this method is invoked on the main thread.
// TODO
}
);
}
}

Dagger 1 to 2 migration - Members injection methods may only return the injected type or void

Im trying to migrate our current system from dagger 1 to 2 and I been stuck for half a day on this. I don't think I'm understanding this well.
Here is my module:
public class BaseModule {
private final Context context;
private final SharedPreferences rawSharedPreferences;
public BaseModule(
Context context,
#Named("RawPreferences") SharedPreferences rawSharedPreferences
) {
this.context = context;
this.rawSharedPreferences = rawSharedPreferences;
}
#Provides
#Singleton
public Context provideContext() {
return context;
}
#Provides
#Singleton
public DevicePlatform provideDevicePlatform(AndroidDevicePlatform devicePlatform) {
return devicePlatform;
}
#Provides
#Named("RawPreferences")
#Singleton
public SharedPreferences provideRawSharedPreferences() {
return rawSharedPreferences;
}
#Provides
#Named("RawPreferencesStore")
#Singleton
public SharedPreferencesStore provideRawSharedPreferencesStore(
#Named("RawPreferences") SharedPreferences sharedPreferences) {
return new AndroidSharedPreferencesStore(sharedPreferences);
}
And my component:
#Singleton
#Component(
modules = {BaseModule.class}
)
public interface BaseComponent {
void inject (DefaultClientController defaultClientController);
void inject (StatisticsProvider statisticsProvider);
Context provideContext();
AndroidDevicePlatform provideDevicePlatform(AndroidDevicePlatform devicePlatform);
SharedPreferences provideRawSharedPreferences();
SharedPreferencesStore provideRawSharedPreferencesStore(
#Named("RawPreferences") SharedPreferences sharedPreferences);
}
I keep getting this error in provideRawSharedPreferencesStore when I run it:
Error:(168, 28) error: Members injection methods may only return the injected type or void.
I dont understand why. Can someone please help me out. Thanks!
A component can contain 3 types of methods:
inject something into some object, which is the error you see. Those methods usually return void, but you can just return the same object, if you try to have something like a builder.
MyInjectedObject inject(MyInjectedObject object); // or
void inject(MyInjectedObject object);
Subcomponents, for which you would include the needed modules as parameters (if they require initialization)
MySubcomponent plus(MyModuleA module);
and basically just "getters" or correctly called provision methods to expose objects, to manually get them from the component, and to your subcomponents
MyExposedThing getMything();
Which one of those is this?
// the line you get your error:
SharedPreferencesStore provideRawSharedPreferencesStore(
#Named("RawPreferences") SharedPreferences sharedPreferences);
You are already providing the SharedPreferencesStore from your module. There you also declare its dependency on RawPreferences: SharedPreferences. You do not have to do this again in your component.
It seems you just try to make the SharedPreferencesStore accessible, as described in 3.. If you just depend on it within the same scope / component, you could just remove the whole component. If you need the getter, you should just remove the parameter. Your Module knows how to create it.
SharedPreferencesStore provideRawSharedPreferencesStore(); // should work.

Print data received by REST call when using #Resource in Grails

Following along with groovies docs on REST, i've setup a model like so:
import grails.rest.*
#Resource(uri='/books')
class Book {
String title
static constraints = {
title blank:false
}
}
I'd print out the parameters I receive when creating and saving. Is there away to override these methods created by the #Resource(uri='/books') annotation? Or handle the annotation a closure or something to do this?
I think you may have 2 choices if you wish to have a default RESTful interface and modify it somewhat for your needs.
Use the $ grails generate-controller [Domain Class Name] command that will generate the appropriate controller and change the generated file as needed.
Create a Book controller and extend the RestfulController; then override the default methods with the #Override annotation, print/log the params, and then call the matching super method.
import grails.rest.RestfulController
class BookController extends RestfulController {
static responseFormats = ['json', 'xml']
BookController() {
super(Book)
}
#Override
def save() {
println params
super.save params
}
#Override
def update() {
println params
super.update params
}
}

Using HeaderResponseContainer: No FilteringHeaderResponse is present in the request cycle

I'm trying to add a custom HeaderResponseContainer in my wicket application. The tutorial looks quite simple (see Positioning of contributions), but when I add these lines and run the application I alwas get an IllegalStateException:
java.lang.IllegalStateException: No FilteringHeaderResponse is present in the request cycle. This may mean that you have not decorated the header response with a FilteringHeaderResponse. Simply calling the FilteringHeaderResponse constructor sets itself on the request cycle
at org.apache.wicket.markup.head.filter.FilteringHeaderResponse.get(FilteringHeaderResponse.java:165)
at org.apache.wicket.markup.head.filter.HeaderResponseContainer.onComponentTagBody(HeaderResponseContainer.java:64)
at org.apache.wicket.markup.html.panel.DefaultMarkupSourcingStrategy.onComponentTagBody(DefaultMarkupSourcingStrategy.java:71)
...
Yes, I already saw the note about FilteringHeaderResponse. But I am not sure where I should call the constructor. I already tried to add it in renderHead before calling response.render but I still get the same exception:
public void renderHead(IHeaderResponse response) {
super.renderHead(response);
FilteringHeaderResponse resp = new FilteringHeaderResponse(response);
resp.render(new FilteredHeaderItem(..., "myKey"));
}
You can create a decorator that wraps responses in a FilteringHeaderResponse:
public final class FilteringHeaderResponseDecorator implements IHeaderResponseDecorator {
#Override
public IHeaderResponse decorate(IHeaderResponse response) {
return new FilteringHeaderResponse(response);
}
}
And that set it during application initialization:
Override
public void init() {
super.init();
setHeaderResponseDecorator(new FilteringHeaderResponseDecorator());
}
I just ran into this same problem and found that the Wicket In Action tutorial leaves out the part about setting up a custom IHeaderResponseDecorator in your main Wicket Application init. The Wicket guide has a more thorough example:
Apache Wicket User Guide - Put JavaScript inside page body
You need something like this in your wicket Application:
#Override
public void init()
{
setHeaderResponseDecorator(new JavaScriptToBucketResponseDecorator("myKey"));
}
/**
* Decorates an original IHeaderResponse and renders all javascript items
* (JavaScriptHeaderItem), to a specific container in the page.
*/
static class JavaScriptToBucketResponseDecorator implements IHeaderResponseDecorator
{
private String bucketName;
public JavaScriptToBucketResponseDecorator(String bucketName) {
this.bucketName = bucketName;
}
#Override
public IHeaderResponse decorate(IHeaderResponse response) {
return new JavaScriptFilteredIntoFooterHeaderResponse(response, bucketName);
}
}