#EnableFeignClients package scan - spring boot - regex

I have annotated spring boot application with Feign Client
#SpringBootApplication
#EnableFeignClients({"com.ms.Foo1.api", "com.ms.Foo2.api",
"com.ms.Foo3.api", "com.ms.Foo4.api", "com.ms.Foo5.api", "com.ms.Foo6.api",
"com.ms.Foo7.api", "com.ms.Foo8.api", "com.ms.Foo9.api", "com.ms.Foo10.api"})
public class AnalyticsApplication extends SpringBootServletInitializer {
}
everything working fine, AS I just modify the bases packages. its start scanning package outside the api.
#SpringBootApplication
#EnableFeignClients({"com.ms.*.api"})
public class AnalyticsApplication extends SpringBootServletInitializer {
}
I am expecting that #EnableFeignClients({"com.ms.*.api"}) will scan only clients inside the api but it start scanning outside the api package as well.
what I need to change ? or can we apply regex here instead of mention every package ?

You can use a regex filter on #ComponentScan like this:
#ComponentScan(basePackages = "com.ms",
includeFilters = #Filter(type = FilterType.REGEX, pattern="com.ms.*.api"))
public class AnalyticsApplication extends SpringBootServletInitializer {
}
But #EnableFeignClients haven't this feature. The only thing you can do is:
#EnableFeignClients(basePackages = "com.ms")
public class AnalyticsApplication extends SpringBootServletInitializer {
}

Related

Mock #AuthenticationPrincipal MockMvc with addFilters = false

I am using mockMvc to write unit tests for Controllers in Rest Application.
I am facing challenge in testing below rest End Point -
#GetMapping("/details")
public ResponseEntity<UserDetails> getUserDetails(#AuthenticationPrincipal UserDetails userDetails)
{
return ResponseEntity.ok(userDetails);
}
As you can see , I need to mock #AuthenticationPrincipal to get this rest end Point unit tested
Now the challenge is the unit test class I am using has below skeleton :
public class ControllerTest extends BaseControllerTest{
}
and BaseControllerTest is :
#WebMvcTest
#ContextConfiguration(
classes = {
TestClass1.class,
TestClass2.class,
})
#AutoConfigureMockMvc(addFilters = false)//here is a problem
#TestExecutionListeners(MockitoTestExecutionListener.class)
#ActiveProfiles("test")
public class BaseControllerTest extends AbstractTestNGSpringContextTests {
}
So as you can see all filters are disabled as we are usig addFilters = false.
When I debugged the unit tests with eclipse I can see NO SPRING SECURITY FILTERS are being added in call chain as addFilters = true
I have searched a lot on public forum and it seems using annotations like #WithUserDetails and #WithMockUser , it is possible to achieve this.
But these will not work as there is no spring security behind the scenes
Can anybody please help here ?

Repository Test in spring boot leads to Unknown entity Exception

com.mohendra.user
server
Application.class //Main class
package2
package3
domain
Campaigns.class
SmsDomainPackage.class
repository
CampaignRepository.class
The above is my folder structure, I am tryring to test CampaignRepository using spring dataJpaTest ,
I have written the following test
#ComponentScan(basePackages = "com.mohendra.user")
#EntityScan(basePackageClasses = SmsDomainPackage.class)
#RunWith(SpringRunner.class)
#SpringBootTest(classes = Application.class)
#DataJpaTest
#RestClientTest
public class CampaignRepositoryTest {
#Autowired
private TestEntityManager entityManager;
#Autowired
private CampaignRepository repository;
#Before
public void setUp() throws Exception {
}
#Test
public void findByCode() {
Campaigns campaigns = new Campaigns();
campaigns.setName("Name");
campaigns.setCode("HELP123");
campaigns.setStartDate(new Date());
campaigns.setEndDate(new Date());
this.entityManager.persist(campaigns);
Campaigns campaigns1 = repository.findByCode("HELP123");
System.out.println();
}
}
The test gives an exception of
java.lang.IllegalArgumentException: Unknown entity:
com.mohendra.user.package3.domain.Campaigns
I have also used #ComponentScan as you can see, and I've also used #EntityScan to try scan entities from packages, but both of them dont work.
I cannot change my folder structure to make it standard, as it is not my project. Is there a solution to it?
The Application class should be in the root package. That way you will not need any #CompontenScan or #EntityScan because Spring Boot scans everything below your root package
Therefor I recomment to put Application.class in the package com.mohendra.user
And you have to decide which test slice you want. You have three:
#SpringBootTest(classes = Application.class)
#DataJpaTest
#RestClientTest
But I assume that you only want #DataJpaTest

Testing a spring boot service without running #SpringBootApplication

I have a spring boot commandline app:
#SpringBootApplication
public class TheApplication implements CommandLineRunner {
public void run(String... args) throws Exception {
...
}
}
and I'd like to test a #Service that TheApplication uses. Normally this is fine if it's an mvc app where TheApplication does not have any functionality but in this case it's a CommandLineRunner and every time I want to test a #Service, run is called, creating a problem with the tests. I need to annotate the test as the #Service uses #Value to configure itself but these annotations cause the application to start and the run method to be invoked.
Is there a way to run a spring boot test:
#RunWith(SpringRunner.class)
#SpringBootTest
public class AccessTokenTest {
...
}
without TheApplication::run being invoked?
Turns out it's fairly easy according to this answer.
#Configuration
#ComponentScan(excludeFilters = #ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = CommandLineRunner.class))
#EnableAutoConfiguration
public class TestApplicationConfiguration {
}
#RunWith(SpringRunner.class)
#SpringBootTest(classes = TestApplicationConfiguration.class)
public class TheTest {
#Autowired
TheService theService;
...
}

Java8 cannot use wsgen with a webservice endpoint that extends another class (Works with Java7)

I'm trying to use wsgen to generate wsdl files. If my webservice class extends another class I get an error but if I remove the extends it works. This is the error message:
error: compilation failed, errors should have been reported
Also wsgen -fullversion:
wsgen full version "JAX-WS RI 2.2.9-b130926.1035 svn-revision#8c29a9a53251ff741fca1664a8221dc876b2eac8"
Please note that I only have this problem when I use Java8. But the same code works when I use Java 7, and wsgen -version:
JAX-WS RI 2.2.4-b01
Here is more details and how to reproduce it:
I'm using Java8 and I have three files:
webservice
basewebservice.java
webservice.java
webserviceImpl.java
basewebservice.java:
package webservice;
public class basewebservice { }
webservice.java
package webservice;
import javax.jws.WebMethod; import javax.jws.WebService;
#WebService
public interface webservice {
#WebMethod
public String hello();
}
webserviceImpl.java
package webservice;
import javax.jws.WebService;
#WebService(endpointInterface="webservice.webservice",
serviceName="webservice")
public class webserviceImpl extends basewebservice
implements webservice {
#Override
public String hello() {
return "heLLoo";
}
}
I use this command to generate wsdl file:
wsgen -cp "." webservice.webserviceImpl -r . -wsdl
It only works when I remove the extends basewebservice.
You need to use an #XMLSeeAlso annotation on the BaseWebService. Check out this question - Java Web Services/JAXB - Abstract superclass

How do I create mock if my trait uses self-type restriction?

I'm trying to use cake pattern and mocking. After reading bunch of blog-posts with tons of fashionable terms I can't make it working :(
I'm using Spray and have following http service
trait ApiServiceAbstract extends HttpService with SprayJsonSupport {
this : AppProvider =>
// tons of routes here
}
where AppProvider is
trait AppProvider {
val api : ApiManager
}
For real server I combine it like this
class ApiServiceActor extends Actor with ApiServiceAbstract with RealApiManager {
}
where RealApiManager extends AppProvider.
Also ApiManager must be mixed in with DbProvider which looks like this
trait ApiManager {
this : DbProvider =>
}
trait RealDbProvider extends DbProvider {
override lazy val dbManager = new DBManager
}
In my unit-test I only want to test http portion and have mocked ApiManager which simply checks that object passed by the client is correct one.
I cannot do this
override lazy val api = mock[ApiManager]
because ApiManager has to be mixed in with DbProvider. How can I fix this ? I see two options right now:
Switch to mocking library that can instantiate classes with constructors with parameters (e.g. Mockito)
Add init(db : DBManager) method and have var in ApiManager which is ugly
I'm not sure of my answer because you don't provide all the source code (ApiManager...)
You could create an intermediary trait.
trait ApiManagerDefaultMixin extends ApiManager with DbProvider
and then
val apiManager = new ApiManagerDefaultMixin {
override lazy val api = mock[ApiManager]
}