Spring Boot2 Undertow Same Site - HttpHandler Customization - Help wanted - httphandler

I ran across this url which suggests that an Http Handler can be added(Example is in Spring 1.x). https://lists.jboss.org/pipermail/undertow-dev/2017-March/001938.html
I have tried adding the following code - it does not appear to be called unless I add a listener. Unfortunately, Spring appears to have already added a listener. What would like to do is updates Spring's listener with my Http Handler. I am just not sure how to do it.
Any help is very much appreciated.
#Component
#Slf4j
public class LibCoreEmbeddedServletCustomerizer implements WebServerFactoryCustomizer<UndertowServletWebServerFactory> {
#Value("${same.site.string}")
private String sameSiteString;
#Value("${server.port}")
private int serverPort;
#Value("${server.address}")
private String serverAddress;
#Override
public void customize(UndertowServletWebServerFactory factory) {
factory.addBuilderCustomizers(new UndertowBuilderCustomizer() {
#Override
public void customize(Undertow.Builder builder) {
log.debug("LibCoreEmbeddedServletCustomerizer::customize");
UndertowBuilderCustomizer customizer = new UndertowBuilderCustomizer() {
#Override
public void customize(Undertow.Builder builder) {
builder.
//addHttpListener(serverPort, serverAddress)
setHandler(new HttpHandler() {
#Override
public void handleRequest(HttpServerExchange httpServerExchange) throws Exception {
Map<String, Cookie> cookies = httpServerExchange.getResponseCookies();
log.debug(Encode.log(String.format("UndertowServletWebServerFactory handleRequest sameSiteString=%s", sameSiteString)));
for (Cookie cookie:cookies.values()) {
log.debug(Encode.log(String.format("UndertowServletWebServerFactory handleRequest cookie=%s", cookie)));
cookie.setSameSiteMode(sameSiteString);
}
}
});
}
};
factory.addBuilderCustomizers(customizer);
}
});
}
}

Try this:
SameSiteHandler goes through all of response cookies and moves SameSite information from Comment To SameSiteMode property.
import io.undertow.server.HttpHandler;
import io.undertow.server.HttpServerExchange;
import io.undertow.server.handlers.Cookie;
import lombok.RequiredArgsConstructor;
#RequiredArgsConstructor
public class SameSiteHandler implements HttpHandler {
private final HttpHandler nextHttpHandler;
#Override
public void handleRequest(HttpServerExchange httpHandlerExchange) throws Exception {
httpHandlerExchange.addResponseCommitListener(exchange -> {
var cookies = exchange.getResponseCookies();
if (cookies != null) {
cookies.forEach((name, cookie) -> fix(cookie)));
}
});
nextHttpHandler.handleRequest(httpHandlerExchange);
}
/** Moves SameSite value from Comment to SameSiteMode */
private void fix(Cookie cookie) {
if (cookie == null) {
return;
}
var comment = cookie.getComment();
cookie.setComment(null);
cookie.setSameSiteMode(comment);
}
}
Register SameSiteHandler
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Configuration;
#Configuration
public class SameSiteHandlerConfig implements WebServerFactoryCustomizer<UndertowServletWebServerFactory> {
#Override
public void customize(UndertowServletWebServerFactory factory) {
factory.addDeploymentInfoCustomizers(deploymentInfo ->
deploymentInfo.addInitialHandlerChainWrapper(SameSiteHandler::new));
}
}

Related

How do I get IEventBroker injected into an e4 OSGI service component

I am trying to get IEventBroker injected into my code to send out notifications.
Everything else works but eventBroker never gets injected. I do not get any compile time errors.
It just comes up null when the code is executed.
I've trimmed the code because it wouldn't let me submit it.
Thanks for any help in advance!
package com.test.services.internal;
imports ...
#Component
public class EnvironmentServiceImpl implements IEnvironmentService {
#Inject
private IEventBroker eventBroker;
private EntityManagerFactory entityManagerFactory;
private EntityManager entityManager;
#Activate
#SuppressWarnings("unchecked")
protected void activateComponent() {
getAll(environments -> {
if (environments.isEmpty()) {
List<Environment> initialModel = getMockEnvironments();
initialModel.forEach(this::save);
}
});
}
#Deactivate
protected void deactivateComponent() {
}
#Override
public void getAll(Consumer<List<Environment>> taskConsumer) {
eventBroker.post(EnvironmentEventConstants.TOPIC_ENVIRONMENT_LOADED,
createEventData(EnvironmentEventConstants.TOPIC_ENVIRONMENT_LOADED, updateEnvironment.getId()));
}
private Map<String, String> createEventData(String topic, String environmentId) {
}
}

Mocking a method inside my test class

Android Studio 2.3
I have the following method I want to test inside my model class:
public class RecipeListModelImp implements RecipeListModelContract {
private Subscription subscription;
private RecipesAPI recipesAPI;
private RecipeSchedulers recipeSchedulers;
#Inject
public RecipeListModelImp(#NonNull RecipesAPI recipesAPI, #NonNull RecipeSchedulers recipeSchedulers) {
this.recipesAPI = Preconditions.checkNotNull(recipesAPI);
this.recipeSchedulers = Preconditions.checkNotNull(recipeSchedulers);
}
#Override
public void getRecipesFromAPI(final RecipeGetAllListener recipeGetAllListener) {
subscription = recipesAPI.getAllRecipes()
.subscribeOn(recipeSchedulers.getBackgroundScheduler())
.observeOn(recipeSchedulers.getUIScheduler())
.subscribe(new Subscriber<List<Recipe>>() {
#Override
public void onCompleted() {
}
#Override
public void onError(Throwable e) {
recipeGetAllListener.onRecipeGetAllFailure(e.getMessage());
}
#Override
public void onNext(List<Recipe> recipe) {
recipeGetAllListener.onRecipeGetAllSuccess(recipe);
}
});
}
#Override
public void shutdown() {
if(subscription != null && !subscription.isUnsubscribed()) {
subscription.unsubscribe();
}
}
}
Inside my test class I am testing like this:
public class RecipeListModelImpTest {
#Mock Subscription subscription;
#Mock RecipesAPI recipesAPI;
#Mock RecipeListModelContract.RecipeGetAllListener recipeGetAllListener;
#Mock List<Recipe> recipes;
#Inject RecipeSchedulers recipeSchedulers;
private RecipeListModelContract recipeListModel;
#Before
public void setup() {
TestBusbyComponent testBusbyComponent = DaggerTestBusbyComponent.builder()
.mockRecipeSchedulersModule(new MockRecipeSchedulersModule())
.build();
testBusbyComponent.inject(RecipeListModelImpTest.this);
MockitoAnnotations.initMocks(RecipeListModelImpTest.this);
recipeListModel = new RecipeListModelImp(recipesAPI, recipeSchedulers);
}
#Test(expected = NullPointerException.class)
public void testShouldThrowExceptionOnNullParameter() {
recipeListModel = new RecipeListModelImp(null, null);
}
#Test
public void testRecipeListModelShouldNotBeNull() {
assertNotNull(recipeListModel);
}
#Test
public void testShouldGetRecipesFromAPI() {
when(recipesAPI.getAllRecipes()).thenReturn(Observable.just(recipes));
recipeListModel.getRecipesFromAPI(recipeGetAllListener);
verify(recipesAPI, times(1)).getAllRecipes();
verify(recipeGetAllListener, times(1)).onRecipeGetAllSuccess(recipes);
verify(recipeGetAllListener, never()).onRecipeGetAllFailure(anyString());
}
#Test
public void testShouldFailToGetRecipesFromAPI() {
when(recipesAPI.getAllRecipes())
.thenReturn(Observable.<List<Recipe>>error(
new Throwable(new RuntimeException("Failed to get recipes"))));
recipeListModel.getRecipesFromAPI(recipeGetAllListener);
verify(recipesAPI, times(1)).getAllRecipes();
verify(recipeGetAllListener, times(1)).onRecipeGetAllFailure(anyString());
verify(recipeGetAllListener, never()).onRecipeGetAllSuccess(recipes);
}
#Test
public void testShouldShutdown() {
when(subscription.isUnsubscribed()).thenReturn(false);
final Field subscriptionField;
try {
subscriptionField = recipeListModel.getClass().getDeclaredField("subscription");
subscriptionField.setAccessible(true);
subscriptionField.set(recipeListModel, subscription);
} catch(NoSuchFieldException e) {
e.printStackTrace();
}
catch(IllegalAccessException e) {
e.printStackTrace();
}
recipeListModel.shutdown();
verify(subscription, times(1)).unsubscribe();
}
}
However, the problem is the Subscription in my model class is always null so will never enter the if blook. Is there any way to test this with using Mockito or spys?
Many thanks for any suggestions,
You should for testing recipeListModel class, where you have shutdown() method , set mock into this class.
If you don't have set method for subscription in recipeListModel , or constructor param.... ),you can set mock object with reflection like :
#Test
public void testShouldShutdown() {
Subscription subscription = mock(Subscription.class);
when(subscription.isUnsubscribed()).thenReturn(false);
Field subscriptionField = recipeListModel.getClass().getDeclaredField("subscription");
subscriptionField.setAccessible(true);
subscriptionField.set(recipeListModel, subscriptionMock);
recipeListModel.shutdown();
verify(subscription, times(1)).unsubscribe();
}
after your update :
if you can't change way of creation , you should mock it like (full way of creation) , i don't know your api , so it's just idea:
Subscription subscription = mock(Subscription.class);
when(subscription.isUnsubscribed()).thenReturn(false);
// preparation mock for create Subscription
//for recipesAPI.getAllRecipes()
Object mockFor_getAllRecipes = mock(....);
when(recipesAPI.getAllRecipes()).thenReturn(mockFor_getAllRecipes );
//for subscribeOn(recipeSchedulers.getBackgroundScheduler())
Object mockFor_subscribeOn = mock();
when(mockFor_getAllRecipes.subscribeOn(any())).thenReturn(mockFor_subscribeOn);
//for .observeOn(recipeSchedulers.getUIScheduler())
Object mockFor_observeOn = mock();
when(mockFor_subscribeOn .observeOn(any())).thenReturn(observeOn);
// for .subscribe
when(observeOn.subscribe(any()).thenReturn(subscription);

HazelCast max-idle-seconds :evict listener is not working

hazelcast configuration for the map is
<map name="test">
<max-idle-seconds>120</max-idle-seconds>
<entry-listeners>
<entry-listener include-value="true" local="false">com.test.listener.SessionListener</entry-listener>
</entry-listeners>
</map>
I have a listener configured for the evict action.
Listener is not able to catch the evict action consistently .
Hazelcast Version : 3.6.5
Listener Class Implemetation:
public class SessionListener implements EntryListener<String, Object> {
#Override
public void entryEvicted(EntryEvent<String, Object> evictData) {
try {
Session sessionObjValue = (Session) evictData.getOldValue();
String sessionId = sessionObjValue.getSessionId();
String userName = sessionObjValue.getUsername();
JSONObject inputJSON = new JSONObject();
inputJSON.put(Constants.SESSIONID, sessionId);
inputJSON.put(Constants.USER_NAME, userName);
//Operations to be performed based on the JSON Value
} catch (Exception exception) {
LOGGER.logDebug(Constants.ERROR, methodName, exception.toString());
}
}
Below are the recommendations:
Include Eviction policy configurations in your map config. Right now eviction is happening only based on max-idle-seconds.
Implement all the methods from EntryListener interface which inturn extends other interfaces.
Implement EntryExpiredListener listener also, to catch the expiry events explicitly though evict event also will be called during expiry.
Sample code:
public class MapEntryListernerTest implements EntryListener, EntryExpiredListener {
#Override
public void entryAdded(EntryEvent event) {
}
#Override
public void entryEvicted(EntryEvent event) {
}
#Override
public void entryRemoved(EntryEvent event) {
}
#Override
public void entryUpdated(EntryEvent event) {
}
#Override
public void mapCleared(MapEvent event) {
}
#Override
public void mapEvicted(MapEvent event) {
}
#Override
public void entryExpired(EntryEvent event) {
}
}

NServiceBus Configuration with Custom Container

I am trying to re-use the service registrations in an assembly that I use through a few services in my solution. I follow the example listed from the NServiceBus website to implement the solution. When following that, unless I add the IWantCustomInitialization interface, my Init method (and IoC container implementation) appears not to function. When I have that interface implemented, I get exceptions (listed in SO questions here and here). I can't seem to get it to work that there are no exceptions AND the dependencies in my MessageHandler are being populated properly. Here is my current EndpointConfig implementation.
[EndpointSLA("00:00:30")]
public class EndpointConfig : IConfigureThisEndpoint, AsA_Server, UsingTransport<Msmq>, INeedInitialization {
public void Init() {
Configure.With().ObjectBuilderAdapter();
}
}
public class ObjectBuilderAdapter : IContainer {
readonly IDependencyInjector injector;
public ObjectBuilderAdapter(IDependencyInjectionBuilder dependencyInjectionBuilder) {
injector = dependencyInjectionBuilder.Create(); //This method does all the common service registrations that I am trying to re-use
//injector.RegisterType<ExtractIncomingPrincipal, PrincipalExtractor>();
}
public void Dispose() {
injector.Dispose();
}
public object Build(Type typeToBuild) {
return injector.Resolve(typeToBuild);
}
public IContainer BuildChildContainer() {
return new ObjectBuilderAdapter(new DependencyInjectorBuilder());
}
public IEnumerable<object> BuildAll(Type typeToBuild) {
return injector.ResolveAll(typeToBuild);
}
public void Configure(Type component, DependencyLifecycle dependencyLifecycle) {
injector.RegisterType(component);
}
public void Configure<T>(Func<T> component, DependencyLifecycle dependencyLifecycle) {
injector.RegisterType(component);
}
public void ConfigureProperty(Type component, string property, object value) {
if (injector is AutofacDependencyInjector) {
((AutofacDependencyInjector)injector).ConfigureProperty(component, property, value);
} else {
Debug.WriteLine("Configuring {0} for property {1} but we don't handle this scenario.", component.Name, property);
}
}
public void RegisterSingleton(Type lookupType, object instance) {
injector.RegisterInstance(lookupType, instance);
}
public bool HasComponent(Type componentType) {
return injector.IsRegistered(componentType);
}
public void Release(object instance) { }
}
public static class Extensions {
public static Configure ObjectBuilderAdapter(this Configure config) {
ConfigureCommon.With(config, new ObjectBuilderAdapter(new DependencyInjectorBuilder()));
return config;
}
}
Note: When I use the INeedInitialization interface, I get the ComponentNotRegisteredException when it's looking for IStartableBus.
When you are trying to swap the built in container, then you need to implement IWantCustomInitialization in the same class that implements IConfigureThisEndpoint.
You can use your own container and register all your types in there and tell NSB to use that container.
For example:
public class EndpointConfig : IConfigureThisEndpoint, AsA_Server, IWantCustomInitialization
{
public void Init()
{
var container = new ContainerBuilder().Build();
Configure.With()
.AutofacBuilder(container);
}
}

Ninject, passing constructor argument to the kernel

Here is my problem:
I want to pass in one of the values to the constructor every time I request an instance form the kernel. I written some code below to illustrate the problem. The test is not failing so I guess that this works, but it does look pretty ugly. Is there a better, cleaner way to accomplish this with Ninject? Or should I rethink my design? All suggestions are appreciated.
[TestFixture]
public class Sandbox
{
[Test]
public void Run_Forrest_Run()
{
using (var kernel = new StandardKernel(new Module()))
{
var connection = new Connection(Guid.NewGuid().ToString());
var downloader = kernel.Get<IDownloader>(new IParameter[] { new Parameter("connection", connection, false) });
Assert.That(downloader.Connection.Info, Is.EqualTo(connection.Info));
}
}
public class Downloader : IDownloader
{
public Downloader(Connection connection, ILogger logger)
{
Connection = connection;
Logger = logger;
}
public Connection Connection { get; private set; }
public void Download()
{
Logger.Log("Downloading...");
}
public ILogger Logger { get; private set; }
}
public interface IDownloader
{
Connection Connection { get; }
void Download();
}
public class ConsoleLogger : ILogger
{
public void Log(string message)
{
Console.Out.WriteLine(message);
}
}
public interface ILogger
{
void Log(string message);
}
public class Connection
{
public Connection(string info)
{
Info = info;
}
public string Info { get; private set; }
}
public class Module : NinjectModule
{
public override void Load()
{
Bind<ILogger>().To<ConsoleLogger>();
Bind<IDownloader>().To<Downloader>()
.WithConstructorArgument("connection", context =>
{
var p = context.Parameters.First(x => x.Name == "connection");
return p.GetValue(context, null);
});
}
}
}
If you always want to specify the Connection when resolving a IDownloader then I think the ConstructorArgument (which is a IParameter) is what you are looking for:
[Test]
public void Run_Forrest_Run()
{
using (var kernel = new StandardKernel(new Module()))
{
var connection = new Connection(Guid.NewGuid().ToString());
var downloader = kernel.Get<IDownloader>(new [] {
new ConstructorArgument("connection", connection) });
Assert.That(downloader.Connection.Info, Is.EqualTo(connection.Info));
}
}
public class Module : NinjectModule
{
public override void Load()
{
Bind<ILogger>().To<ConsoleLogger>();
Bind<IDownloader>().To<Downloader>();
}
}

Resources