How to configure WildFly Port for Vaadin Application - wildfly

i have a Vaadin 8 Application with 2 WebServlets. I want to make it possible to connect to the second Servlet with a specific Port.
#WebServlet(urlPatterns = "/*", name = "MainUIServlet", asyncSupported = true)
#VaadinServletConfiguration(ui = MainUI.class, productionMode = false)
public static class MainUIServlet extends VaadinServlet {
#WebServlet(value = {"/admin/*", "/VAADIN/*"}, name = "AdminUIServlet", asyncSupported = true)
#VaadinServletConfiguration(ui = AdminUI.class, productionMode = false)
public static class AdminUIServlet extends VaadinServlet {
These are the two servlets. I want to make it possible that when i type "example.application.com:1111" that it will connect to the "AdminUIServlet". But without the vhost config from the Apache. Is it possible to bind the Port to the Servlet?
When i use the 9990 Port i get access to the Wildfly Manager, exactly like that i want to get access to the specific servlet of my Application just with the Port 1111

Related

Resource not exported up in OSGi container

I'm trying to expose a REST service through OSGi (using Apache Felix). I'm using the osgi-jax-rs-connector to publish the resource. Here is the resource interface:
#Path("/bingo")
public interface BingoService {
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("/lottery")
List<Integer> getLottery();
}
The implementation uses DS annotation to obtain reference to a provided service in container:
#Component(
immediate = true,
service = BingoService.class,
properties = "jersey.properties")
public class Bingo implements BingoService {
#Reference
private RandomNumberGenerator rng;
#Activate
public void activateBingo() {
System.out.println("Bingo Service activated using " +
rng.getClass().getSimpleName());
}
#Override
public List<Integer> getLottery() {
List<Integer> result = new ArrayList<>();
for (int i = 5; i > 0; i--) {
result.add(rng.nextInt());
}
return result;
}
}
jersey.properties simply contains this line
service.exported.interfaces=*
When I deploy the bundle it starts and register the service correctly. But if I go to http://localhost:8181/services/bingo/lottery I get 404.
Could someone point me to the issue or give me some advice on where to look?
On reading the documentation for OSGi - JAX-RS Connector, it expects to find the annotations #Path or #Provider on the service instance object. You have placed them instead on an interface implemented by the component.
I'm not sure what the purpose of the BingoService interface is. This is not required for JAX-RS services. Normally you would register the resource class using its own type (e.g. service=Bingo.class) or simply java.lang.Object.

Problems while connecting to two MongoDBs via Spring

I'm trying to achieve to connect to two different MongoDBs with Spring (1.5.2. --> we included Spring in an internal Framework therefore it is not the latest version yet) and this already works partially but not fully. More precisely I found a strange behavior which I will describe below after showing my setup.
So this is what I done so far:
Project structure
backend
config
domain
customer
internal
repository
customer
internal
service
In configI have my Mongoconfigurations.
I created one base class which extends AbstractMongoConfiguration. This class holds fields for database, host etc. which are filled with the properties from a application.yml. It also holds a couple of methods for creating MongoClient and SimpleMongoDbFactory.
Furthermore there are two custom configuration classes. For each MongoDB one config. Both extend the base class.
Here is how they are coded:
Primary Connection
#Primary
#EntityScan(basePackages = "backend.domain.customer")
#Configuration
#EnableMongoRepositories(
basePackages = {"backend.repository.customer"},
mongoTemplateRef = "customerDataMongoTemplate")
#ConfigurationProperties(prefix = "customer.mongodb")
public class CustomerDataMongoConnection extends BaseMongoConfig{
public static final String TEMPLATE_NAME = "customerDataMongoTemplate";
#Override
#Bean(name = CustomerDataMongoConnection.TEMPLATE_NAME)
public MongoTemplate mongoTemplate() {
MongoClient client = getMongoClient(getAddress(),
getCredentials());
SimpleMongoDbFactory factory = getSimpleMongoDbFactory(client,
getDatabaseName());
return new MongoTemplate(factory);
}
}
The second configuration class looks pretty similar. Here it is:
#EntityScan(basePackages = "backend.domain.internal")
#Configuration
#EnableMongoRepositories(
basePackages = {"backend.repository.internal"}
mongoTemplateRef = InternalDataMongoConnection.TEMPLATE_NAME
)
#ConfigurationProperties(prefix = "internal.mongodb")
public class InternalDataMongoConnection extends BaseMongoConfig{
public static final String TEMPLATE_NAME = "internalDataMongoTemplate";
#Override
#Bean(name = InternalDataMongoConnection.TEMPLATE_NAME)
public MongoTemplate mongoTemplate() {
MongoClient client = getMongoClient(getAddress(), getCredentials());
SimpleMongoDbFactory factory = getSimpleMongoDbFactory(client,
getDatabaseName());
return new MongoTemplate(factory);
}
}
As you can see, I use EnableMongoRepositoriesto define which repository should use which connection.
My repositories are defined just like it is described in the Spring documentation.
However, here is one example which is located in package backend.repository.customer:
public interface ContactHistoryRepository extends MongoRepository<ContactHistoryEntity, String> {
public ContactHistoryEntity findById(String id);
}
The problem is that my backend always only uses the primary connection with this setup. Interestingly, when I remove the beanname for the MongoTemplate (just #Bean) the backend then uses the secondary connection (InternalMongoDataConnection). This is true for all defined repositories.
My question is, how can I achieve that my backend really take care of both connections? Probably I missed to set another parameter/configuration?
Since this is a pretty extensive post I apologise if I forgot something to mention. Please ask for missing information in the comments.
I found the answer.
In my package structure there was a empty configuration class (of my colleague) with the annotation #Configurationand #EnableMongoRepositories. This triggered the automatic wiring process of Stpring Data and therefore led to the problems I reported above.
I simply deleted the class and now it works as it should!

How do I configure Zuul routing for URL with Token?

I am working with a microservice architecture where a Zuul gateway contacts a Eureka server to discover published microservices. I want my zuul gateway to accept path in a particular format.
It received a URL call with a member id sent as a token. Because we want to avoid sending sensitive information in URLs, these expirable tokens would be parsed by Zuul, translated to a Social Security Number, for example, and the ssn would be sent in a header.
For example, a bank acct GET:
http://zuulgateway/member/11/account/
would map to
http://microservice/account
X-MEMBER-SSN: 1112223333
My plan is to set up a "pre" Zuul filter to parse out the member token "11" and use it to get the SSN, then add it to the header.
But I'm not sure how I configure this route or if it is even possible.
zuul.routes.account.path: /member/*/**
does not achieve it. Is there some other mechanism I can use?
There are a few forum posts on the Zuul github regarding this issue but none of the solutions were working for me. I couldn't figure out why and finally realized: the hot deployment into Zuul from my Spring Tool Suite was restarting the application, but not deploying the latest changes (perhaps this is an endorsement for JRebel in the end!). Once I realized this I started experimenting with stop/deploy/start coding until I got a solution working with ZuulFilter.
The solution involves a "pre" filter which rewrites the contextURL to remove the /member/\d+/ portion of the URL so that the context can be directly mapped to the
Here is some example code:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
#Component
public class SpecialFilter extends ZuulFilter {
private static final String REQUEST_URI_KEY = "requestURI";
private static final Pattern URL_PATTERN = Pattern.compile("^\\/?(\\d+)\\/(.+)$");
#Override
public boolean shouldFilter() {
return isMember(RequestContext.getCurrentContext());
}
private boolean isMember(RequestContext currentContext) {
String path = (String) currentContext.get(REQUEST_URI_KEY);
Matcher m = URL_PATTERN.matcher(path);
return m.matches();
}
#Override
public Object run() {
RequestContext context = RequestContext.getCurrentContext();
String originalRequestPath = (String) context.get(REQUEST_URI_KEY);
Matcher m = URL_PATTERN.matcher(originalRequestPath);
System.out.println("Parsing original "+originalRequestPath + " against " + URL_PATTERN.toString());
if(!m.matches()) {
System.err.println("Invalid URL");
return null;
}
String ssn = translateSSN(m.group(1));
String requestPath = m.group(2);
String modifiedRequestPath = "/" + requestPath;
context.put(REQUEST_URI_KEY, modifiedRequestPath);
//Add this header to the request
context.addZuulRequestHeader("X-SSN", ssn);
return null;
}
#Override
public String filterType() {
return "pre";
}
#Override
public int filterOrder() {
// Should proceed this filter
return FilterConstants.PRE_DECORATION_FILTER_ORDER + 1;
}
}

Spring Cloud Contract and Zuul

Using Spring Cloud Dalston, we have built a proxy service that, of course, uses Zuul. I am now trying to add Spring Cloud Contract tests to verify our proxy service works as expected from a contract adherence perspective. What is strange is that I can send a request and receive a 200 status code back, but the expected response body, content type header, etc. is empty, and my tests fail as a result.
Are there additional configurations not specified in the Spring Cloud Contract documentation necessary for testing services that use Zuul capabilities?
Here you have an example https://github.com/spring-cloud/spring-cloud-contract/issues/450
/**
* Abstraction of configuration to test contracts with external microservices which are using a zuul-gateway in between.
*
* When a provider of data only allows communication through a Zuul-Gateway, a special way to ensure valid contracts is needed.
* The Goal is to emulate the Zuul-Interception to be able to use the contracts stored within the providing service.
*
* F.e.: Consumer-Service consumes the Provider-Service, but the provider can not be called directly.
* The Consumer-Service calls an URL with a prefix consisting of the name of the gateway ("gateway") and name of the
* service (in this example "Provider-Service"). For example: http://gateway/provider/path/to/resource.
* The contract provided by Provider-Service holds only a part of the provided URL (here: "/path/to/resource").
* The resolution of "gateway" and "provider" is done within this class.
*/
#RunWith(SpringRunner.class)
#SpringBootTest(classes = EmbeddedZuulProxy.class,
properties = {"server.port: 8080",
"zuul.routes.provider.path: /provider/**",
"zuul.routes.provider.service-id: provider",
"zuul.routes.provider.url: http://localhost:9090/" //the url of the provider-stub is at port 9090
},
webEnvironment = WebEnvironment.DEFINED_PORT) //defined port is important! Ribbon points to zuul, which then points to the provider-stub
#AutoConfigureMockMvc
#AutoConfigureJsonTesters
//the stub runs on fixed port 9090, so that zuul can point to it
#AutoConfigureStubRunner(ids = "<group-id>:<artifact-id>:+:stubs:9090")
#DirtiesContext
public abstract class ZuulContractBase {
}
/**
* Configuration and Setup of an embedded Zuul-Gateway.
* This way it is possible to use contracts, stored in providing service
*/
#Configuration
#ComponentScan(basePackages = "<path.to.feign.client>") //autowiring feign client
#EnableAutoConfiguration
#EnableZuulProxy
#EnableFeignClients
#RibbonClient(name = "gateway", configuration = SimpleRibbonClientConfiguration.class)
class EmbeddedZuulProxy {
#Bean
RouteLocator routeLocator(DiscoveryClient discoveryClient,
ZuulProperties zuulProperties) {
return new DiscoveryClientRouteLocator("/", discoveryClient, zuulProperties);
}
}
/**
* Ribbon Load balancer with fixed server list for "simple" pointing to localhost,
* which holds the mocked zuul-gateway
*
* f.e. a call with feign would normally look like:
* http://gateway/provider/rest/path/to/your/{url}
* which is mapped to:
* http://localhost:{zuulport}/provider/rest/path/to/your/{url}
*/
#Configuration
class SimpleRibbonClientConfiguration {
#Value("${server.port}")
private Integer zuulPort;
#Bean
public ServerList<Server> ribbonServerList() {
return new StaticServerList<>(new Server("localhost", zuulPort));
}
}

Calling services from other application in the cluster

Is it possible to call services or actors from one application to another in a Service Fabric Cluster ? When I tryed (using ActorProxy.Create with the proper Uri), I got a "No MethodDispatcher is found for interface"
Yes, it is possible. As long as you have the right Uri to the Service (or ActorService) and you have access to the assembly with the interface defining your service or actor the it should not be much different than calling the Service/Actor from within the same application. It you have enabled security for your service then you have to setup the certificates for the exchange as well.
If I have a simple service defined as:
public interface ICalloutService : IService
{
Task<string> SayHelloAsync();
}
internal sealed class CalloutService : StatelessService, ICalloutService
{
public CalloutService(StatelessServiceContext context)
: base(context) { }
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
yield return new ServiceInstanceListener(this.CreateServiceRemotingListener);
}
public Task<string> SayHelloAsync()
{
return Task.FromResult("hello");
}
}
and a simple actor:
public interface ICalloutActor : IActor
{
Task<string> SayHelloAsync();
}
[StatePersistence(StatePersistence.None)]
internal class CalloutActor : Actor, ICalloutActor
{
public CalloutActor(ActorService actorService, ActorId actorId)
: base(actorService, actorId) {}
public Task<string> SayHelloAsync()
{
return Task.FromResult("hello");
}
}
running in a application like this:
Then you can call it from another application within the same cluster:
// Call the service
var calloutServiceUri = new Uri(#"fabric:/ServiceFabric.SO.Answer._41655575/CalloutService");
var calloutService = ServiceProxy.Create<ICalloutService>(calloutServiceUri);
var serviceHello = await calloutService.SayHelloAsync();
// Call the actor
var calloutActorServiceUri = new Uri(#"fabric:/ServiceFabric.SO.Answer._41655575/CalloutActorService");
var calloutActor = ActorProxy.Create<ICalloutActor>(new ActorId(DateTime.Now.Millisecond), calloutActorServiceUri);
var actorHello = await calloutActor.SayHelloAsync();
You can find the right Uri in the Service Fabric Explorer if you click the service and look at the name. By default the Uri of a service is: fabric:/{applicationName}/{serviceName}.
The only tricky part is how do you get the interface from the external service to your calling service? You could simply reference the built .exe for the service you wish to call or you could package the assembly containing the interface as a NuGet package and put on a private feed.
If you don't do this and you instead just share the code between your Visual Studio solutions the Service Fabric will think these are two different interfaces, even if they share the exact same signature. If you do it for a Service you get an NotImplementedException saying "Interface id '{xxxxxxxx}' is not implemented by object '{service}'" and if you do it for an Actor you get an KeyNotfoundException saying "No MethodDispatcher is found for interface id '-{xxxxxxxxxx}'".
So, to fix your problem, make sure you reference the same assembly that is in the application you want to call in the external application that is calling.