Expose REST controller only during testing by using "test profile" - wildfly

For better testability of our application I'm adding a REST controller which allows setting certain states, e.g. http://localhost:8090/test-api/customer would allow creating a new customer in the application's database for further tests.
The class would basically look like this:
#RequestScoped
#Path("/test-api/customer")
public class TestController {
#POST
public void createCustomer() {}
}
Now I'd like this controller to be available only for testing, i.e. the production system should not expose this endpoint. Is there something like a "testing profile" or "testing annotation" like a Spring Boot profile I can add to this class to hide it from the production system?

Related

How can Spring Boot Admin send custom notifications for actuator metric change?

Spring Boot Admin provides notification feature only for status up or down of the application. I want to send email notification for some metric change in actuator endpoint. could you please guide me how can I configure this?
Simple notification for UP/DOWN of the application
#Configuration
public class NotifierConfiguration {
#Autowired
private Notifier notifier;
#Primary
#Bean(initMethod = "start", destroyMethod = "stop")
public RemindingNotifier remindingNotifier() {
RemindingNotifier notifier = new RemindingNotifier(notifier, repository);
notifier.setReminderPeriod(Duration.ofMinutes(10));
notifier.setCheckReminderInverval(Duration.ofSeconds(10));
return notifier;
}
}
This is for the UP?DOWN of the application. I want to configure in some metric of the actuator endpoint
I don't think there's an easy way to do that at the moment.
Notifications are sent by classes implementing the Notifier interface. These classes are consuming a Flux of InstanceEvent to produce these notifications. These events are triggered when there are changes on an instance info/status actuator endpoint, when an instance is registered/unregistered, etc. To create notifications for actuator metrics, you should therefore create a custom InstanceEvent (say InstanceMetricsChangedEvent) each time there's some changes on an instance metrics actuator endpoint. Maybe you can have a look at how InstanceInfoChangedEvent are triggered and see if it's possible to do something similar with your InstanceMetricsChangedEvent. Have a look at : InfoUpdater and InfoUpdateTrigger.

I want to expose my existing controller as a Restful service

I have an application where I'm registering a user so user will enter his data on JSP page and the data will be save into DB, the flow will be JSP->dispatcher->controller->Service->Dao.
Now in MemberController which is delegating the request to the Service, has a method register() which will take the MemberDto as a parameter now and return the Successfull msg to the success.jsp page. Sometihng like user registered successfully.
public String Register(MemberDto memberDto)
Now I want to expose this same method as RestFul service using Jersey for partners and also use this same method within my application as a normal MVC flow. How can I acheive this
So u want to use Jersey so import the jersey library to support JAX-RS.
#Path("/classlevelpath")
public class MyController {
#POST
#Produces(MediaType.APPLICATION-XML)
#Path("/register")
public String Register(MemberDto memberDto) {
}
}
Be careful JAX-RS (Jersey is an implementaion) and Spring REST annotations are different.
Annotate your rest class with #RestController. The best practice is to create another controller. By you can see this answer if you want to transform your existing controller: https://stackoverflow.com/questions/33062509/returning-view-from-spring-mvc-restcontroller

Set up default page and Dynamic Web Project, JAX-RS

I am trying to do a simple rest service sample with eclipse, galssfiash server, using jersey. I started project like webDynamic.I did servlet mapping with Application class.Without web.xml file:
#ApplicationPath("/rest/*")
public class ApplicationConfig extends Application{
public Set<Class<?>> getClasses(){
return new HashSet<Class<?>>(Arrays.asList(MyClass.class));
}
And for now everything work fine. Bath how do I set default page?
On sample, when someone or I putt in address bar of web explorer only project name like:
localhost:8080/name.of.the.project/. I wish to be presented first page like readme.xhtml where is explained rest service on sample. And if in url I add .../rest/ it will be returned by web service. How do I accomplish this. Or I can use web.xml for first page and can register sevlet with Application class?
Yes, if you are using the Applicationpath annotation, you don't need to specify servlet class in the web.xml again. You can use the web.xml to specify welcome page and still use your application class as is

Linking to an MVC Route from Web API inside an in-memory server

I'm having problems testing the generation of MVC Routes from inside Web API. The code works when hit manually, but fails under test as the in-memory instance of Web API is unaware of the MVC routes and I can't figure out how to add them.
Here's an example project on github illustrating the problem, but I'll include some relevant code here.
I'm using an in-memory HTTP Server to host the Web API for integration testing:
private HttpConfiguration _config;
private HttpServer _server;
private HttpMessageInvoker _client;
[TestInitialize]
public void TestInitialize()
{
_config = new HttpConfiguration();
WebApiConfig.Register(_config);
_server = new HttpServer(_config);
_client = new HttpMessageInvoker(_server);
}
In my Web API Controller I'm trying to return links via the out-of-the-box default routes, both Web API and Mvc:
[HttpGet]
[Route("MvcRoute")]
public string MvcRoute()
{
return Url.Link("Default", new {Controller = "Other", Action = "Index"});
}
[HttpGet]
[Route("ApiRoute")]
public string ApiRoute()
{
return Url.Link("DefaultApi", new {Controller = "Example", Id = "MvcRoute"});
}
A test for the ApiRoute passes, but this test for the MvcRoute fails with the error message "A route named 'Default' could not be found in the route collection.":
[TestMethod]
public void ShouldReturnMvcRoute()
{
using (var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/api/example/mvcroute"))
{
using (var response = _client.SendAsync(request, CancellationToken.None).Result)
{
var responseContent = response.Content.ReadAsStringAsync().Result;
Assert.AreEqual("\"http://localhost/Other\"", responseContent);
}
}
}
So how can I make the in-memory server aware of MVC's routes? Or if that's the wrong question to ask, how can I run automated tests on a build server (i.e., no IIS) that hit Web API routes that generate links to MVC routes?
In-memory scenario is only supported in Web API. When hosted on a real server like IIS, Web API registers its routes onto the route table provided by System.Web.Routing.RouteCollection...Since MVC also registers its routes into this same route table, when generating links from Web API to MVC, the routes are indeed there...
Note that Web API came later than MVC and one of the design goals of it was to run outside IIS host (like it can be run on Selfhost too) and not have dependency on System.Web...In your about example, you are instantiating HttpConfiguration which means that you are having a different route collection where as in the real app WebApiConfig.Register would be passed in GlobalConfiguration instance...

Architecture for stateful MVVM application with self contained client-server code and IoC container

I have an application which has multiple screens and talks to a WCF web service. I am using SimpleInjector for my favourite IoC container, and Caliburn Micro for MMVM with WPF.
I have a separate class implementation of ITransportClient that controls the connection to the web service and sends and receives messages.
The application has the following states:
Start up and initialisation of the application.
Display the login form.
Login form performs connection to chat server with ITransportClient.Login(username, password).
If login successful show a new MainWindow view, if failed prompt user for credentials again.
When logged in, MainWindow controls messages sent and received to the WCF service.
When connection is lost with the server (notified by ITransportClientCallback.OnTransportDisconnected), or when the user clicks logout, the Login form is displayed again.
With the technology I have available and this being my first MVVM project I have the following architectural and design questions:
What design pattern should I use to control showing a separate log in screen, then the main screen when connected, and revert back to the login screen when the connection has been lost?
Who should control the connection state of the chat application and where would this code sit? Would this state sit in the bootstrapper class?
Could I have the ITransportClient registered as a persistence instance scope, and have multiple forms control when required by injecting in to the ViewModel that required it (i.e. both the login form and the main window form)?
The ITransportClient interface is below:
public interface ITransportClientCallback
{
string OnReceivedMessage();
void OnTransportDisconnected();
}
// transport interface that client calls
public interface ITransportClient
{
bool SendLogin(string username, string password);
void SendLogout();
void SendMessage();
void RegisterCallback(ITransportClientCallback applicationHostCallback);
}
Along with the Caliburn.Micro bootstrapper code using SimpleInjector:
public class SimpleInjectorBootstrapper : Caliburn.Micro.Bootstrapper
{
private Container container;
protected override void Configure()
{
this.container = new Container();
this.container.Register<IWindowManager, WindowManager>();
this.container.Register<IEventAggregator, EventAggregator>();
this.container.Register<IAppViewModel, AppViewModel>();
this.container.RegisterSingle<ITransportClient, Transport.WCF.TransportClient>();
}
protected override object GetInstance(Type serviceType, string key)
{
return this.container.GetInstance(serviceType);
}
protected override IEnumerable<object> GetAllInstances(Type serviceType)
{
return this.container.GetAllInstances(serviceType);
}
protected override void OnStartup(object sender, System.Windows.StartupEventArgs e)
{
base.OnStartup(sender, e);
var appViewModel = this.container.GetInstance<IAppViewModel>();
var windowManager = this.container.GetInstance<IWindowManager>();
windowManager.ShowWindow(appViewModel);
}
}
What design pattern should I use to control showing a separate log in
screen, then the main screen when connected, and revert back to the
login screen when the connection has been lost?
In alot of cases, MVVM project is accompanied with a "mediator" or "messenger". All View Models can interact between each other through this mechanism by subscribing and publishing messages. All VMs would subscribe to "UserLoggedOutMessage" and do the necessary response (i.e. change its visual state to readonly, or not show anything at all). A separate bootstrapper can also "redirect" the user to the login screen.
Who should control the connection state of the chat application and
where would this code sit? Would this state sit in the bootstrapper
class?
One approach is to have an abstraction for the state of the app - this is equivalent to the HTTPContext.Current variable in asp.net. You could have a Session object which has a CurrentState read-only property with corresponding Login(), Logout(), SendMessage() methods which acts as a state machine. All View Model would then subscribe to the events as soon as the state of the app changes - again through the Mediator. The Session object can be a static variable on the bootstrapper, or a singleton injected to all VMs via the IoC.
Could I have the ITransportClient registered as a persistence instance
scope, and have multiple forms control when required by injecting in
to the ViewModel that required it (i.e. both the login form and the
main window form)?
that's definitely the idea. in most MVVM project, you would want to have a single instance of the dependencies injected to the VMs. This allow for more efficient memory use and also allow a clean object oriented model (as opposed to a procedural immutable transaction scripts).
Having said that, if this was an attempt to check for the "application state" I would change the level of the abstraction to something higher e.g. IApplicationStateMachine or IUserSession. This way if you want to ever support multiple user in one application instance, you could in theory have multiple instances of the IUserSession objects.