How to unregister Apptentive in Android? - apptentive

I need to disable Apptentive from showing its feedback dialogs because it is interfering with my UI tests. I could not find any method to unregister or disable it.
I tried setting random app key like this, but apptentive is using the cached API key.
#BeforeClass
public static void beforeClass() {
Apptentive.register(CustomApp.getInstance(), "");
}

You can't unregister Apptentive after it has been registered, but there are a few ways to keep it from showing up when you run your UI tests.
Use a special build variant for your UI tests. Then, in Application.onCreate(), wrap the call to Apptentive.register() in a check against the build config flavor
#Override
onCreate() {
if (!BuildConfig.FLAVOR.equals("<YOUR_UI_TEST_FLAVOR>")) {
Apptentive.register(...);
}
}
You can set a piece of Custom Person Data like Apptentive.addCustomPersonData("ui_test", true). Then, use that in your Interaction "Who" criteria so that the Interaciton can't show as long as this flag is true.

Related

Extending DialogService in Prism

On the Prism Library website there is a few notes about Simplify your Application Dialog APIs.
https://prismlibrary.com/docs/wpf/dialog-service.html
Let's say I have a Solution with multiple projects, MainProject, Modules.Module1, CoreProject. So creating this DialogServiceExtensions class in my Core project.
public static class DialogServiceExtensions
{
public static void ShowNotification(this IDialogService dialogService, string message, Action<IDialogResult> callBack)
{
dialogService.ShowDialog(nameof(NotificationDialog), new DialogParameters($"message={message}"), callBack, "notificationWindow");
}
}
I also put NotificationDialog and NotificationDialogViewModel in my Core project
I can call it at any project/module, but the question is how can I tell prism that NotificationDialog ViewModel is NotificationDialogViewModel.
Where should I register the dialog, to be able to use thru the hole solution? In my MainProject App.xaml.cs like usual?
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterDialog<NotificationDialog, NotificationDialogViewModel>();
}
Where should I register the dialog, to be able to use thru the hole solution? In my MainProject App.xaml.cs like usual?
If the app wants to show a dialog, you have to do this, as modules are essentially optional (they can be swapped out after deployment or they don't need to exist).
If a module wants to show a dialog (and not the app), you can decide whether it's part of your app's interface to its modules (then put the registration in the app) or not (then put it in the module, each module that uses it, that is, registrations may override each other).

Static Analysis tool to catch self-invocation bypassing Spring cache #Cacheable method

I understand that this is because of the way proxies are created for handling caching, transaction related functionality in Spring. And the way to fix it is use AspectJ but I donot want to take that route cause it has its own problems. Can I detect self-invocation using any static analyis tools?
#Cacheable(value = "defaultCache", key = "#id")
public Person findPerson(int id) {
return getSession().getPerson(id);
}
public List<Person> findPersons(int[] ids) {
List<Person> list = new ArrayList<Person>();
for (int id : ids) {
list.add(findPerson(id));
}
return list;
}
If it would be sufficient for you to detect internal calls, you could use native AspectJ instead of Spring AOP for that and then throw runtime exceptions or log warnings every time this happens. That is not static analysis, but better than nothing. On the other hand, if you use native AspectJ, you are not limited to Spring proxies anyway and the aspects would work for self-invocation too.
Anyway, here is what an aspect would look like, including an MCVE showing how it works. I did it outside of Spring, which is why I am using a surrogate #Component annotation for demo purposes.
Update: Sorry for targeting #Component classes instead of #Cacheable classes/methods, but basically the same general approach I am showing here would work in your specific case, too, if you simply adjust the pointcut a bit.
Component annotation:
package de.scrum_master.app;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
#Retention(RUNTIME)
#Target(TYPE)
public #interface Component {}
Sample classes (components and non-components):
This component is to be called by other components should not lead to exceptions/warnings:
package de.scrum_master.app;
#Component
public class AnotherComponent {
public void doSomething() {
System.out.println("Doing something in another component");
}
}
This class is not a #Component, so the aspect should ignore self-invocation inside it:
package de.scrum_master.app;
public class NotAComponent {
public void doSomething() {
System.out.println("Doing something in non-component");
new AnotherComponent().doSomething();
internallyCalled("foo");
}
public int internallyCalled(String text ) {
return 11;
}
}
This class is a #Component. The aspect should flag internallyCalled("foo"), but not new AnotherComponent().doSomething().
package de.scrum_master.app;
#Component
public class AComponent {
public void doSomething() {
System.out.println("Doing something in component");
new AnotherComponent().doSomething();
internallyCalled("foo");
}
public int internallyCalled(String text ) {
return 11;
}
}
Driver application:
Please note that I am creating component instances throughout this sample code with new instead of requesting beans from the application context, like I would do in Spring. But you can ignore that, it is just an example.
package de.scrum_master.app;
public class Application {
public static void main(String[] args) {
new NotAComponent().doSomething();
new AComponent().doSomething();
}
}
Console log when running without aspect:
Doing something in non-component
Doing something in another component
Doing something in component
Doing something in another component
Now with the aspect, instead of the last message we would expect an exception or a logged warning. Here is how to do that:
Aspect:
Sorry for using native AspectJ syntax here. Of course, you could also use annotation-based syntax.
package de.scrum_master.aspect;
import de.scrum_master.app.*;
public aspect SelfInvocationInterceptor {
Object around(Object caller, Object callee) :
#within(Component) &&
call(* (#Component *).*(..)) &&
this(caller) &&
target(callee)
{
if (caller == callee)
throw new RuntimeException(
"Self-invocation in component detected from " + thisEnclosingJoinPointStaticPart.getSignature() +
" to "+ thisJoinPointStaticPart.getSignature()
);
return proceed(caller, callee);
}
}
Console log when running with aspect:
Doing something in non-component
Doing something in another component
Doing something in component
Doing something in another component
Exception in thread "main" java.lang.RuntimeException: Self-invocation in component detected from void de.scrum_master.app.AComponent.doSomething() to int de.scrum_master.app.AComponent.internallyCalled(String)
at de.scrum_master.app.AComponent.internallyCalled_aroundBody3$advice(AComponent.java:8)
at de.scrum_master.app.AComponent.doSomething(AComponent.java:8)
at de.scrum_master.app.Application.main(Application.java:6)
I think, you can use this solution and maybe rather log warnings instead of throwing exceptions in order to softly guide your co-workers to inspect and improve their AOP-dependent Spring components. Sometimes maybe they do not wish self-invocation to trigger an aspect anyway, it depends on the situation. You could run the Spring application in full AspectJ mode and then, after evaluating the logs, switch back to Spring AOP. But maybe it would be simpler to just use native AspectJ to begin with and avoid the self-invocation problem altogether.
Update: In AspectJ you can also make the compiler throw warnings or errors if certain conditions are met. In this case you could only statically determine calls from components to other components, but without differentiating between self-invocation and calls on other methods from other components. So this does not help you here.
Please also notice that this solution is limited to classes annotated by #Component. If your Spring bean is instantiated in other ways, e.g. via XML configuration or #Bean factory method, this simple aspect does not work. But it could easily be extended by checking if the intercepted class is a proxy instance and only then decide to flag self-invocations. Then unfortunately, you would have to weave the aspect code into all of your application classes because the check can only happen during runtime.
I could explain many more things, such as using self-injection and call internal methods on the injected proxy instance instead of via this.internallyCalled(..). Then the self-invocation problem would be solved too and this approach also works in Spring AOP.
Can I detect self-invocation using any static analysis tools?
In theory you can, but be aware of Rice's theorem. Any such tool would sometimes give false alarms.
You could develop such a tool using abstract interpretation techniques. You may need more than a year of work.
You could subcontract the development of such tools to e.g. the Frama-C team. Then email me to basile.starynkevitch#cea.fr

serenity-bdd with cucumber feature hooks

I am using Serenity-BDD with cucumber and I would like to run certain things only once per feature file. It looks like cucumber doesn't support this at the moment. I was wondering if serenity has some workaround for this.
I've also tried to use the JUnit #BeforeClass, #AfterClass hooks in the test suite class but the 2 annotations require static methods and I cannot access the serenity page objects methods at that time (there is no instance injected at that point in time).
You could try setting up a static global flag which will make sure that the before method will runs only once.
Setup the feature file with a tag.
#RunOnce
Feature: Run Once
Use the following hook in your stepdefinition.
private static boolean onceFlag = true;
#Before(value="#RunOnce")
public void beforeOnce(){
if(onceFlag) {
onceFlag = false;
//Your code to write once per feature file
}
}
You could try to implement net.thucydides.core.steps.StepListener interface and connect it via SPI. I described this in answer in this post

Turn off Hystrix functionality

I am integrating Hystrix in an application. That application is already in production and we will be testing out hystrix integration work in sandbox before we will push it to production.
My question is that is there any way to turn on/off hystrix functionality using some configuration setting?
There is no single setting for this. You'll need to set multiple parameters to disable Hystrix.
See https://github.com/Netflix/Hystrix/wiki/Configuration for the configuration options:
hystrix.command.default.execution.isolation.strategy=SEMAPHORE
hystrix.command.default.execution.isolation.semaphore.maxConcurrentRequests=100000 # basically 'unlimited'
hystrix.command.default.execution.timeout.enabled=false
hystrix.command.default.circuitBreaker.enabled=false
hystrix.command.default.fallback.enabled=false
Please double check your version of Hystrix for the available parameters.
This is all what you need:
# Disable Circuit Breaker (Hystrix)
spring:
cloud:
circuit:
breaker:
enabled: false
hystrix:
command:
default:
circuitBreaker:
enabled: false
As ahus1 said, there is no single way to disable Hystrix entirely. To disable it in our application, we decided it was cleanest and safest to put a HystrixCommand in a wrapper class, and that wrapper class only exposed the parts of the HystrixCommand that we used (in our case, the execute() method). When constructing the wrapper class, we pass it a Callable that contains the code we want executed, and if Hystrix is disabled (according to our own config value), we simply call that Callable without ever creating a HystrixCommand. This avoids executing any Hystrix code whatsoever and makes it easier to say that Hystrix isn't affecting our application at all when it's disabled.
There are a couple of ways to achieve this-
Doing this for your every group including default. Although this will not disable hystrix(it will only keep the circuit closed all the time) but you will achieve the same result-
hystrix.command.{group-key}.circuitBreaker.forceClosed=false
If you are using java, you can create an around advice over #HystrixCommand annotation and bypass hystrix execution based upon a flag.
Java Code for #2-
#Pointcut("#annotation(com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand)")
public void hystrixCommandAnnotationPointcut() {
}
#Around("hystrixCommandAnnotationPointcut()")
public Object methodsAnnotatedWithHystrixCommand(final ProceedingJoinPoint joinPoint) throws Throwable {
Object result = null;
Method method = AopUtils.getMethodFromTarget(joinPoint);
if ((System.getProperty(enable.hystrix).equals("true")) {
result = joinPoint.proceed();
} else {
result = method.invoke(joinPoint.getTarget(), joinPoint.getArgs());
}
return result;
}
If your Project is spring Managed you can comment the bean definition of hystrixAspect in applicationContext.xml
Comment the following line
bean id="hystrixAspect"class="com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect"/>
This will remove Hystrix from your project.
I ran into this situation where I wanted to completely turnoff Hystrix using a single property (We use IBM uDeploy to manage dynamic properties). We are using javanica library built on top of Hystrix
Create a Configuration class which creates the HystrixCommandAspect
#Configuration
public class HystrixConfiguration{
#Bean(name = "hystrixCommandAspect")
#Conditional(HystrixEnableCondition.class)
public HystrixCommandAspect hystrixCommandAspect(){
return new HystrixCommandAspect()}
}
2. And the conditional class would be enabled based on a system property.
public class HystrixEnableCondition implements Condition{
#Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata){
return
"YES".equalsIgnoreCase(
context.getEnvironment().getProperty("circuitBreaker.enabled")) ||
"YES".equalsIgnoreCase(
System.getProperty("circuitBreaker.enabled"));
}
}
setting
hystrix.command.default.execution.isolation.strategy=SEMAPHORE
is enough.
Additionally you may or should disable also the timeout threads
with hystrix.command.default.execution.timeout.enabled=false

Wicket - Inter-session communication or Create new Request(Cycle) manually

I have some wicket panel store in a static Hashmap from different sessions, i want to do some like if some panel notifies the map, then the map notifies all other panel.
for example:
public class PanelMap{
private static Map<Long, List<MyPanel>> map = new HashMap<Long, List<MyPanel>>();
public static void subscribe(Long id, MyPanel panel){
if (!map.containsKey(id)){
map.put(id, new ArrayList<MyPanel>());
}
map.get(id).add(panel);
}
}
public static void notify(Long id, String notification){
if (map.containsKey(id)){
List<MyPanel> panels = map.get(id);
for(MyPanel panel : panels){
panel.newNotification(notification);
}
}
}
}
In Panel, newNotification(String notification) i want to send request to server and refresh my panel in browser.
public void String newNotification(String notification){
// do some business logic depends on notification
onMyRequest();
}
i've made some search among wicket behavior source files and about i found in AbstractDefaultAjaxBehavior i tried to make my own onRequest method inside my wicket panel as follows
private void onMyRequest(){
AjaxRequestTarget target = ((WebApplication)getApplication()).newAjaxRequestTarget(getPage());
target.add( _some_wicket_components_ );
RequestCycle.get().scheduleRequestHandlerAfterCurrent(target);
}
but all i did is some Ajax error in Wicket Ajax Debug about
Wicket.Ajax.Call.processComponent: Component with id _containerdiv_ was not found while trying to perform markup update.
ERROR: Cannot find element with id: _someComponentIdOnPanel_
(those components are exist)
How could i send my own request to server (or how can i get valid AjaxRequestTarget to update my components? )
Update: I need inter-session communication.
To update panels on different user's sessions, you obviously can't use the current AjaxRequestTarget as this in a way represents a single communication between the server and the requesting user of which another user's Browser has no way of knowing. (Very very basically spoken)
You could either use an AjaxSelfUpdatingTimerBehavior to poll for updates. This would generate new AjaxRequestTarget for every user at regular intervals that you can use to attach changed panels to. It's a very basic and simple implementation that will most likely impact your systems performance and generate quite some traffic.
The other way would be to use something like Atmosphere, which is supported by Wicket-Atmosphere (quickstart can be found here) and has some examples over at the wicket-library.com, but that's all I know about this.
Use Wicket event bus system. Have a look to the "Wicket events infrastructure" chapter of the free Wicket guide.
First you need to create one class to encapsulate the notification and the AjaxRequestTarget and pass them using the events infrastructure.
private class Notification {
private String message;
private AjaxRequestTarget target;
... constructor, getters, setters...
}
Then the panels that want to recive the event have to override onEvent method, something like this:
public void onEvent(IEvent<?> event) {
if (event.getPayload() instanceof Notification) {
Notification notification = (Notification) event.getPayload();
... do whatever you want before updating the panel ...
// Update the panel
notification.getTarget().add(this);
}
}
All the components will recive all the events that are send using Wicket events infrastructure. So you can send the event from any other panel using one method like this
protected void sendMessage(String message, AjaxRequestTarget target) {
send(getSession(), Broadcast.BREADTH, new Notification(message, target));
}
Remember that if you want to update the components using AJAX, you need to set setOutputMarkupId(true). And if it's a component that can be hidden and you want to make it visible using AJAX, then you need to set setOutputMarkupPlaceholderTag(true).

Resources