I'm using restlet in a proof-of-concept as follows:
final Component component = new Component();
component.getServers().add(Protocol.HTTP, 8182);
final Router router = new Router(component.getContext().createChildContext());
router.attachDefault(HttpListener.class);
component.start();
This should give me a URL path of http://localhost:8182/*. However, I just get 404 errors when trying to GET from this URL:
http://localhost:8182/ -> 404
http://localhost:8182/xyz -> 404
Restlet isn't routing any requests to my HttpListener class.
My HttpListener class:
public class HttpListener extends ServerResource {
public static void main(String[] args) throws Exception {
final Component component = new Component();
component.getServers().add(Protocol.HTTP, 8182);
final Router router = new Router(component.getContext().createChildContext());
router.attachDefault(HttpListener.class);
component.start();
}
#Get()
public Representation getDBName() {
String body = "hello, world";
Representation representation = new StringRepresentation(body, MediaType.APPLICATION_JSON);
representation.setCharacterSet(CharacterSet.UTF_8);
return representation;
}
}
I had to attach the route as follows:
public static void main(String[] args) throws Exception {
final Router router = new Router();
router.attachDefault(HttpListener.class);
Application myApp = new Application() {
#Override
public org.restlet.Restlet createInboundRoot() {
router.setContext(getContext());
return router;
};
};
Component component = new Component();
component.getDefaultHost().attach("/", myApp);
new Server(Protocol.HTTP, 8182, component).start();
}
Thanks to https://stackoverflow.com/a/13165900/1033422 for this answer.
Related
I am writing a Windows service using Topshelf that should start a self hosted webapi project and a FIX service based on quickfix/n. Please consider the shortened code below, which works so far.
However there is one problem - there are now two container instances living in my application. My guts tell me this is a bad idea, especially because I am loading MyBigModule two times. Also because one of my controllers require the same component than the one using quickfix.
// Assembly A referencing B
public class Program
{
public static void Main(string[] args)
{
var builder = new ContainerBuilder();
buider.RegisterModule<MyBigModule>();
var container = builder.Build();
_ = HostFactory.Run(c =>
{
c.UseAutofacContainer(container);
c.Service<IMyServiceManager>(svc =>
{
svc.ConstructUsingAutofacContainer();
// ...
}
// ...
});
}
}
// Assembly B
public class Startup
{
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
var builder = new ContainerBuilder();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly())
var container = builder.Build();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
// ...
app.UseAutofacMiddleware(container);
app.UseAutofacWebApi(config);
app.UseWebApi(config);
}
}
// Assembly B
public class WebHost : IWebHost
{
// ...
public void Start()
{
WebApp.Start<Startup>("someUrl");
}
}
// Assembly B
public class MyBigModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.Register<WebHost>.As<IWebHost>();
// ...
}
}
My first approach was to pass an Action<IAppBuilder> to the WebHost constructor, that is created within Main(). Something like this:
public class Program
{
public static void Main(string[] args)
{
var builder = new ContainerBuilder();
builder.RegisterModule<MyBigModule>();
var container = builder.Build();
var webhost = new WebHost("someUrl", app =>
{
var config = new HttpConfiguration();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
// ....
});
builder.RegisterInstance(webost);
// ...
}
}
However I would have to build my container first and then add another registration later. Which doesn't follow the recommendation that a container should be considered immutable. Another alternativ would be to pass the container instance down to my WebHosts Startup class.
It seems that I need to have a registration of my container inside the container itself. How would I do that? Maybe there is a better approach? I hope it's clear what I am struggling with.
I am pretty sure there must be a better way to wire up webapi's resolver. Any ideas and feedback is very appreciated.
I solved it in the meantime, thanks to this post. We can inject an instance of ILifetimeScope to the constructor without having to register anything.
// Assembly A referencing B
public class Program
{
public static void Main(string[] args)
{
var builder = new ContainerBuilder();
buider.RegisterModule<MyBigModule>();
var container = builder.Build();
_ = HostFactory.Run(c =>
{
c.UseAutofacContainer(container);
c.Service<IMyServiceManager>(svc =>
{
svc.ConstructUsingAutofacContainer();
// ...
}
// ...
});
}
}
// Assembly B
public class WebHost : IWebHost
{
private readoly ILifetimeScope scope
public WebHost(ILifetimeScope scope)
{
this.scope = scope;
}
public void Start()
{
WebApp.Start("someUri", app => {
var config = new HttpConfiguration
{
DependencyResolver = new AutofacWebApiDependencyResolver(this.scope)
};
// ...
});
}
}
// Assembly B
public class MyBigModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.Register<WebHost>.As<IWebHost>();
// ...
}
}
Hi I'm new on RestLet this is a simple example that I want to post a Json representation but after running the client I have error which is mentioned in the below.please help me in this regard.Thank you so much.
The resource :
import org.json.JSONException;
import org.json.JSONObject;
import org.restlet.ext.json.JsonRepresentation;
import org.restlet.resource.Post;
import org.restlet.resource.ServerResource;
import org.restlet.data.Status;
public class DepResource extends ServerResource{
String jsonString="";
#Post
public void acceptJsonRepresentation(JsonRepresentation entity) {
JSONObject json = null;
try {
json = entity.getJsonObject();
// business logic and persistence
String jsonPost=json.toString();
System.out.println(jsonPost);
} catch (JSONException e) {
setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
return;
}
}
}
The client has Error in line 44
import java.io.IOException;
import java.net.InetAddress;
import org.json.JSONException;
import org.json.JSONObject;
import org.restlet.data.CharacterSet;
import org.restlet.data.Method;
import org.restlet.ext.json.JsonRepresentation;
import org.restlet.resource.ClientResource;
public class Client {
public static void main(String[] args) throws JSONException, IOException {
/**##POST Prepration##**/
JSONObject jsonObjectGraph = new JSONObject();
jsonObjectGraph.put("Traffic", 100);
jsonObjectGraph.put("Disksize", 20);
String str=jsonObjectGraph.toString();
JsonRepresentation JRRepDep = new JsonRepresentation(str);
JRRepDep.setCharacterSet(CharacterSet.UTF_8);
System.out.println("with jsonrepresentation: "+JRRepDep.getText());
// TODO Auto-generated method stub
/**********POST**************/
String baseURL1 = "http://" + InetAddress.getLocalHost().getHostAddress() + ":" + "8181";
// Specifying the URL for the resource
String resourceName = "/files";
String ApplicationServerName = baseURL1 + resourceName;
System.out.println("URI at client: " +ApplicationServerName);
// Specifying the REST client and post to REST server
ClientResource restletClient = new ClientResource(ApplicationServerName);
System.out.println(ApplicationServerName);
restletClient.setMethod(Method.POST);
System.out.println("dovomi");
restletClient.post(JRRepDep);
System.out.println("After post");
// Checking the status of the post request
if (restletClient.getStatus().isSuccess())
{
System.out.println("POST Request success.");
restletClient.release();
}
}
}
The server is running without any error
import java.net.InetAddress;
import org.restlet.Application;
import org.restlet.Restlet;
import org.restlet.Server;
import org.restlet.data.Protocol;
import org.restlet.routing.Router;
public class DepServer extends Application {
private static String ipAddress;
private static int port;
public static String getURI()
{
return "http://" + ipAddress + ":" + port;
}
public static void main(String[] args) {
try {
ipAddress = InetAddress.getLocalHost().getHostAddress();
port = 8181;
Server server = new Server(Protocol.HTTP, ipAddress, port);
server.setNext(new DepServer());
server.start();
System.out.print("Server is running");
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public Restlet createInboundRoot() {
String baseURL = "http://" + ipAddress + ":" + port;
// Create a router restlet.
Router router = new Router(getContext());
// Attach the resources to the router.
router.attach(baseURL + "/files", DepResource.class);
// Return the root router
return router;
}
}
Error:
Jul 20, 2019 2:00:03 PM org.restlet.engine.http.connector.HttpClientHelper start
INFO: Starting the default HTTP client
Exception in thread "main" Internal Server Error (500) - Internal Server Error
at org.restlet.resource.ClientResource.handle(ClientResource.java:870)
at org.restlet.resource.ClientResource.post(ClientResource.java:1209)
at Client.main(Client.java:44)
The question is quite unclear, but if you're asking how to return a JsonRepresentation then you must not return a void but rather a JsonRepresentation see:
public class DepResource extends ServerResource {
String jsonString="{}";
#Post
public JsonRepresentation acceptJsonRepresentation(JsonRepresentation entity) {
// do stuff and return a JsonRepresentation object
Representation representation = new JsonRepresentation(jsonString);
return representation;
}
}
I am trying to add logging to my application using ClientHttpRequestInterceptor.My interceptor is not being called.
Not sure what is going wrong here -
Here is my code -
#Component
#Slf4j
public final class RestTemplateInterceptor implements ClientHttpRequestInterceptor {
protected static final LoggingAspect aspect = new LoggingAspect();
private final RequestContext requestContext;
private boolean logResponseBody = true;
public RestTemplateInterceptor(RequestContext requestContext) {
this.requestContext = requestContext;
}
#Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution clientHttpRequestExecution) throws IOException {
populateHeader(request);
traceRequest(request, body);
ClientHttpResponse response = clientHttpRequestExecution.execute(request,body);
traceResponse(response);
return response;
}
private void populateHeader(HttpRequest request) {
final HttpHeaders headers = request.getHeaders();
// Propagate TAM headers
headers.add("iv-user", requestContext.getUser());
headers.add("MessageId", requestContext.getMessageId());
headers.add("CorrelationId", requestContext.getConversationId());
headers.add("BusinessId", requestContext.getBusinessId());
headers.add("ApplicationName", requestContext.getSourceSystem());
headers.add("iv-groups", requestContext.getGroups());
headers.add("MessageDateTime", requestContext.getSourceTimestamp());
}
...................
Here is my config file
#Configuration
public class RestTemplateConfig {
/**
* initialise restTemplate
*
* #param restTemplateInterceptor autowired in RestTemplateInterceptor
* #return
*/
#Bean
public RestTemplate restTemplate(ClientHttpRequestInterceptor restTemplateInterceptor, ObjectMapper objectMapper) {
RestTemplate restTemplate = new RestTemplate(new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory()));
List<ClientHttpRequestInterceptor> interceptors = restTemplate.getInterceptors();
if (CollectionUtils.isEmpty(interceptors)) {
interceptors = new ArrayList<>();
}
interceptors.add(restTemplateInterceptor);
restTemplate.setInterceptors(interceptors);
return restTemplate;
}
}
Here is my WebMVC file
#Configuration
public class WebMvcConfig implements WebMvcConfigurer {
#Bean
public WebMvcConfigurer webAuthentication() {
return new WebMvcConfigurer() {
#Override
public void addInterceptors(InterceptorRegistry registry) {
//registry.addInterceptor(myInterceptor());
registry.addInterceptor(new MVCLoggingInterceptor()).addPathPatterns("/api/**");
registry.addInterceptor(new WebAuthentication()).addPathPatterns("/api/**/");
}
};
}
}
Here is my application file
#EnableAsync
#EnableScheduling
#SpringBootApplication(exclude = { SecurityAutoConfiguration.class })
public class XManagementApplication {
public static void main(String[] args) {
SpringApplication.run(XManagementApplication.class, args);
}
}
Can anybody tell why my interceptor class is not called when I try to call any API
Any help would be appreciate?
I don't really understand why you want to instantiate your RestTemplateInterceptor as a Bean. Why not simply instantiate your interceptor inside the method RestTemplateConfig.restTemplate() ?
#Configuration
public class RestTemplateConfig {
#Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate(new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory()));
List<ClientHttpRequestInterceptor> interceptors = restTemplate.getInterceptors();
if (CollectionUtils.isEmpty(interceptors)) {
interceptors = new ArrayList<>();
}
interceptors.add(new RestTemplateInterceptor());
restTemplate.setInterceptors(interceptors);
return restTemplate;
}
}
Btw, why do you need to pass RequestContext to the constructor of your interceptor ?
I have two web api.
One publish a message when specific controller be call (work)
One subscribe to receive message. (not work)
Here is config for both web api :
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddRawRabbit();
var builder = new ContainerBuilder();
builder.RegisterRawRabbit("guest:guest#localhost:15672/");
var container = builder.Build();
}
In web api 1, here is action that publish a message :
[Route("api/[controller]")]
public class ValuesController : Controller
{
// GET api/values
[HttpGet]
public IEnumerable<string> Get()
{
EventMessage message = new EventMessage() ;
var client = BusClientFactory.CreateDefault();
message = new EventMessage() { id = new Guid(), createDate = DateTime.Now };
client.PublishAsync<EventMessage>(message);
Console.WriteLine($"message create {message.ToString()}");
return new string[] { "value1", "value2",};
}
}
And in web api 2, I dont know how to receive that message,
here is the way that i try but it not work
public class Listener
{
public static void Start()
{
var client = BusClientFactory.CreateDefault());
client.SubscribeAsync<EventMessage>(async (msg, context) => Console.WriteLine($"Recieved:{msg.createDate.ToString()}.");
}
}
public class Program
{
public static void Main(string[] args)
{
//not working
Listener.Start();
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
In this project, im using Rawrabbit, any library with the same scenario will be ok. Thanks
Update: i fix this code, it work
I have a REST handler servlet defined as follows (this works perfectly):
//REST handler context
ServletContextHandler restHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
restHandler.setContextPath("/");
// Jersey REST handling servlet
ServletHolder jerseyServlet = restHandler.addServlet(org.glassfish.jersey.servlet.ServletContainer.class, "/*");
jerseyServlet.setInitOrder(0);
// Tell Jersey which REST service class to load....
jerseyServlet.setInitParameter("jersey.config.server.provider.classnames", RestHandler.class.getCanonicalName());
I now want to add a authentication filter, which I do as:
FilterHolder authFilter = restHandler.addFilter(AuthFilter.class, "/",
EnumSet.of( DispatcherType.ASYNC,
DispatcherType.ERROR,
DispatcherType.FORWARD,
DispatcherType.INCLUDE,
DispatcherType.REQUEST));
if (authFilter == null) {
dlog.debug("Failed to load authentication filter");
};
All good so far, however, the filter does not fire on incoming REST. Calls still go through. The AuthFilter is straight from sample code:
public class AuthFilter implements javax.servlet.Filter {
private static final Logger dlog = Dlog.get();
public static final String AUTHENTICATION_HEADER = "Authorization";
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filter)
throws IOException, ServletException {
dlog.entry(request, response, filter);
if (request instanceof HttpServletRequest) {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String authCredentials = httpServletRequest.getHeader(AUTHENTICATION_HEADER);
AuthService authenticationService = new AuthService();
boolean authenticationStatus = authenticationService.authenticate(authCredentials);
if (authenticationStatus) {
filter.doFilter(request, response);
} else {
if (response instanceof HttpServletResponse) {
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
httpServletResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
}
}
}
dlog.exit();
}
#Override
public void destroy() {
}
#Override
public void init(FilterConfig arg0) throws ServletException {
}
}
I use handler collection as I also have a resource handler to serve static web pages besides the REST calls.
HandlerCollection handlerList = new HandlerCollection();
handlerList.setHandlers(new Handler[] { resourceHandler,
restHandler,
new DefaultHandler(),
requestLogHandler });
What else I need to do? I have scanned through number of related posts and come up empty. Thanks in advance.