I am using Arquillian to write black box tests for my RESTful application. I am actually capable of debug the test classes, but unable to debug my application classes. I would like to know exactly how to do that.
My arquillian.xml:
<arquillian xmlns="http://jboss.org/schema/arquillian"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://jboss.org/schema/arquillian
http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
<container qualifier="jbossas-managed" default="true">
<configuration>
<property name="jbossHome">D:\desenv\arquivos\servidores\wildfly-9.0.1.Final-test</property>
<property name="allowConnectingToRunningServer">true</property>
<property name="javaVmArguments">-Dorg.apache.deltaspike.ProjectStage=IntegrationTest</property>
</configuration>
</container>
One of my test classes:
#RunAsClient
#RunWith(Arquillian.class)
public class AuthenticationBlackBoxTest extends AbstractBlackBoxTest {
#Test
public void testInvalidCredentials(#ArquillianResource URL baseURI) {
Client client = ClientBuilder.newClient();
WebTarget target = client.target(baseURI.toString()).path("api/v1/auth");
Response response = target.request(MediaType.APPLICATION_JSON)
.post(Entity.entity(new Credentials("invalid", "invalid"), MediaType.APPLICATION_JSON));
Assert.assertEquals(401, response.getStatus());
response.close();
client.close();
}
#Test
public void testValidCredentials(#ArquillianResource URL baseURI) {
Client client = ClientBuilder.newClient();
WebTarget target = client.target(baseURI.toString()).path("api/v1/auth");
Entity<Credentials> credentialsEntity = Entity.entity(new Credentials("adm#adm.com", "123"), MediaType.APPLICATION_JSON);
Response response = target.request(MediaType.APPLICATION_JSON)
.post(credentialsEntity);
Assert.assertEquals(200, response.getStatus());
response.close();
client.close();
}
}
Inside arquillian.xml for javaVmArguments element add -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y.
Then in your favourite IDE you have to define a new Remote Debug configuration where you specify the host(localhost), port(8787). Place your break point, then run your test and finally start the remote debug. Official doc here.
Related
I run Red Hat middleware with CodeReady Studio 12.16.0.GA on standalone Spring-boot environment as local Camel context. I have local RabbitMQ running in Docker.
I have failed to setup any scenario using tutorials on web in/out JMS using Camel.
All tutorials don't use camel-context.xml configuration only pure java spring.
Please help me to configure camel-context.xml and all resource to use RabbitMQ or just any JMS.
Thanks in advance.
Here is simple camel-context.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring https://camel.apache.org/schema/spring/camel-spring.xsd">
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
<route id="simple-route">
<from id="_to1" uri="jms:myQeue?connectionFactory=#myConnectionFactory&jmsMessageType=Text"/>
<log id="route-log" message=">>> ${body}"/>
</route>
</camelContext>
</beans>
and simple spring application to run it
package org.mycompany;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;
#SpringBootApplication
#ImportResource({"classpath:spring/camel-context.xml"})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
But it went to exception
Caused by: org.apache.camel.ResolveEndpointFailedException: Failed to resolve endpoint: jms://myQeue?connectionFactory=%23myConnectionFactory&jmsMessageType=Text due to: No bean could be found in the registry for: myConnectionFactory of type: javax.jms.ConnectionFactory
I have added registration of ConnectionFactory
ConnectionFactory myCF = new ConnectionFactory();
myCF.setUsername("guest");
myCF.setPassword("guest");
myCF.setVirtualHost("/");
myCF.setHost("localhost");
myCF.setPort(5672);
SimpleRegistry reg = new SimpleRegistry();
reg.put("myConnectionFactory", myCF);
CamelContext camContext = new DefaultCamelContext(reg);
but new exception arose I think because of using com.rabbitmq.client.ConnectionFactory
Caused by: org.apache.camel.FailedToCreateRouteException: Failed to create route simple-route: Route(simple-route)[[From[jms:queue:myQeue?connectionFactory... because of connectionFactory must be specified
How to define javax.jms.ConnectionFactory to registry?
I need to intercept a response from the server that was generated for a specific API call and change it.
I used the JAX-RS 'WriterInterceptor' for this and I have created a NameBinding as well. But the server is intercepting every response out from the server. What am I doing wrong here?
Shown below is the code I have tried. Why is the name binding does not work? (I have verified that when calling other API resources the particular method that I have use name binding is not called.)
Name Binding.
package com.example.common.cm.endpoint;
#Target({ElementType.TYPE, ElementType.METHOD})
#NameBinding
#Retention(RetentionPolicy.RUNTIME)
public #interface JSONtoJWT {}
The Interceptor.
package com.example.common.cm.endpoint;
#Provider
#JSONtoJWT
public class TestInterceptor implements WriterInterceptor {
private static final Log log = LogFactory.getLog(TestInterceptor.class);
#Override
public void aroundWriteTo(WriterInterceptorContext writerInterceptorContext) throws IOException, WebApplicationException {
log.info("interceptor invoked");
OutputStream outputStream = writerInterceptorContext.getOutputStream();
outputStream.write(("{\"message\": \"Message added in the writer interceptor in the server side\"}").getBytes());
writerInterceptorContext.setOutputStream(outputStream);
writerInterceptorContext.proceed();
log.info("Proceeded");
}
}
API Resource.
package com.example.cm.endpoint.u3.acc;
#Path("/u3/some-validation")
#Consumes({ "application/json; charset=utf-8" })
#Produces({ "application/json; charset=utf-8" })
public class SomeValidationApi {
#POST
#Path("/")
#JSONtoJWT
#Consumes({ "application/json; charset=utf-8" })
#Produces({ "application/json; charset=utf-8" })
public Response someValidationPost(#ApiParam(value = "validations post" ,required=true ) SomeValidationRequestDTO someValidationConsent)
{
return delegate.someValidationPost(someValidationConsent);
}
}
beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml"/>
<context:property-placeholder/>
<context:annotation-config/>
<bean class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer"/>
<bean class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer"/>
<jaxrs:server id="services" address="/">
<jaxrs:serviceBeans>
***Some other beans here***
<bean class="com.example.cm.endpoint.u3.acc.SomeValidationApi/>
</jaxrs:serviceBeans>
<jaxrs:providers>
<bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider"/>
<bean class="com.example.common.cm.endpoint.TestInterceptor"/>
</jaxrs:providers>
</jaxrs:server>
</beans>
When I use the above every response from the server is intercepted and the message is added. But I want only the particular resource to invoke the Interceptor.
Also, Other than JAX-RS interceptor with writerInterceptor, are there any other good alternative to achieve this?
I am trying to implement a module to send messages from a CXF client to a server (SOAP endpoint) using HTTPS. I am able to achieve this by following the guide here: https://camel.apache.org/how-to-switch-the-cxf-consumer-between-http-and-https-without-touching-the-spring-configuration.html
The following configuration is key:
<ctx:property-placeholder location="classpath:orderEntry.cfg" />
<!-- other properties -->
<http:conduit name="{http://www.company.com/product/orderEntry/service/1}OrderEntry.http-conduit">
<http:tlsClientParameters disableCNCheck="true">
<sec:trustManagers>
<sec:keyStore type="JKS" password="${trustStore.password}" file="${trustStore.file}"/>
</sec:trustManagers>
<!-- other config -->
</http:tlsClientParameters>
</http:conduit>
The above configuration refers to a config file that has these properties stored:
orderEntry.cfg
--------------
endpointUri=https://localhost:8181/OrderEntry
trustStore.password=password
trustStore.file=etc/myApp.ts
As noted earlier, I am able to send messages via https when I follow the guide.
But I am concerned about the password being stored in plain text here. Is there a way that I can have the password wired from Java code (which can probably read the password from an encrypted source) and provide it to the http conduit when it needs it?
Have you tried location attribute value with file prefix?
E.g. location="file:/my/custom/location/orderEntry.cfg"
See: https://stackoverflow.com/a/17303537
Update:
If it works with your custom bean, you can try create trust managers as a bean and inject it into the conduit configuration like bellow:
blueprint.xml
<bean id="serviceTrustManager"
class="my.app.security.KeyStores" factory-method="loadTrustManagers">
<argument index="0" value="${my.app.service.trustStorePath}"/>
<argument index="1" value="${my.app.service.trustStoreEncryptedPassword}"/>
</bean>
<http:conduit name="{http://www.company.com/product/orderEntry/service/1}OrderEntry.http-conduit">
<http:tlsClientParameters disableCNCheck="true">
<sec:trustManagers ref="serviceTrustManager"/>
</http:tlsClientParameters>
</http:conduit>
Java code:
public class KeyStores {
public static TrustManager[] loadTrustManagers(String trustStorePath, String trustStoreEncryptedPassword) {
String trustStoreDecryptedPassword = PasswordDescriptor.decryptPassword(trustStoreEncryptedPassword); //Password decryption logic here
KeyStore trustStore = KeyStores.loadKeyStore("JKS", trustStorePath, trustStoreDecryptedPassword); //IO logic here
TrustManagerFactory trustFactory;
try {
trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustFactory.init(trustStore);
} catch (NoSuchAlgorithmException | KeyStoreException ex) {
throw new IllegalStateException(ex);
}
return trustFactory.getTrustManagers();
}
}
I'm building an MVC5 web app connecting to a MS SQL 2008 database, so that the users can search and make changes to data stored there. I've looked at a bunch of autofac tutorials and examples, but can't seem to make any of them work.
I'm assuming my autofac configuration is the problem, because when I run the app it says my model is null. Which I think means the autofac is not connecting to the datbase.
So, in my global.asax.cs file I have the following:
protected void Application_Start()
{
#region Autofac
// Register Controllers
var builder = new ContainerBuilder();
builder.RegisterControllers(typeof(MvcApplication).Assembly); //all controllers in assembly at once ?
builder.RegisterControllers(Assembly.GetExecutingAssembly());
builder.RegisterFilterProvider();
// Set the Dependency Resolver
IContainer container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
// Register Model Binders
builder.RegisterModelBinders(typeof(MvcApplication).Assembly); //all binders in assembly at once ?
builder.RegisterModelBinderProvider();
// Register Modules
builder.RegisterModule<PersistenceModule>();
#endregion
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
I have a hibernate.cfg.xml file as
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" />
</configSections>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<property name="connection.connection_string">Data Source=DEVSRV\SQLSERVER;Initial Catalog=tipdemo;Persist Security Info=True;User ID=admin;Password=***********</property>
<property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
<property name="proxyfactory.factory_class">NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu</property>
<!--<mapping assembly="NHibernateTest"/> -->
</session-factory>
</hibernate-configuration>
</configuration>
And my PersistenceModule class is:
public class PersistenceModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
if (builder == null)
throw new ArgumentException("builder", "builder is null");
base.Load(builder);
}
private ISessionFactory ConfigureDB()
{
Configuration cfg = new Configuration().Configure(System.Web.HttpContext.Current.Server.MapPath("~/Config/hibernate.cfg.xml"));
cfg.AddAssembly(typeof(Domain.General.Project).Assembly);
return cfg.BuildSessionFactory();
}
}
You can't register things in the container after it's built.
On line 11 in the sample for Application_Start you're building the container, but then after you set the DependencyResolver you're registering more stuff with the ContainerBuilder. You can't do that - you have to register everything first, then build the container as the last thing you do.
That's why it's never entering your PersistenceModule - you've already built the container, so it's not actually getting registered.
If, for some reason, you need to add registrations to an already-built container, you need to create an all new ContainerBuilder and call builder.Update(container). However, I strongly recommend you just reorder things so the container is built last rather than go the Update route if possible.
I'm having a problem with injecting EntityManager by using #PersistenceContext. I try to inject EntityManager in EJB class with #PersistenceContext and I always get NullPointerException.
Here is EJB class:
#Stateless
public class BookEJB {
public BookEJB(){
}
#PersistenceContext(unitName = "BookWebStorePU")
private EntityManager em;
public Book createBook(Book book) throws Exception {
System.out.println("EM: " + em);
em.persist(book);
return book;
}
public Book findBookByIsbn10(String isbn10){
Book book = new Book();
em.find(Book.class, isbn10);
return book;
}
//Other methods here
}
Here's Persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="BookWebStorePU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<validation-mode>NONE</validation-mode>
<properties>
<property name="javax.persistence.schema-generation.database.action" value="create"/>
<property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:derby://localhost:1527/BookWebStoreDB"/>
<property name="javax.persistence.jdbc.user" value="bookwebstoreadmin"/>
<property name="javax.persistence.jdbc.password" value="password"/>
<!-- Let EclipseLink create database schemas automatically -->
<property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
<property name="eclipselink.ddl-generation.output-mode" value="database"/>
</properties>
Here's my test file:
public class BookDaoTests {
private BookEJB bookDao;
private Book newBook;
#Before
public void init() {
newBook = new Book();
newBook.setName("Flying Cow");
newBook.setDescription("Super cool story about flying cow");
newBook.setAuthor("Me");
newBook.setIsbn10("0123456789");
newBook.setIllustrations(true);
newBook.setPublishYear(2013);
newBook.setNumberOfPages(1567);
newBook.setQuantity(58);
bookDao = new BookEJB();
}
#Test
public void createBook() throws Exception{
bookDao.createBook(newBook);
Assert.assertEquals("Book was created!", bookDao.findBookByIsbn10("0123456789"), newBook);
}
}
So when I run that test file I get following error:
Testcase: createBook(com.mysite.bookstore.tests.BookDaoTests): Caused an ERROR
null
java.lang.NullPointerException
at com.mysite.bookwebstore.beans.BookEJB.createBook(BookEJB.java:27)
at com.mysite.bookstore.tests.BookDaoTests.createBook(BookDaoTests.java:46)
EM: null
I use following technologies:
Glassfish 4
JavaEE 7
JSF
EclipseLink 2.1
Java DB
I hope we can find some solution for this problem. I have been tackling now 3 days of this problem and searched and tested solutions from Google and from Stackoverflow but none of the solutions helped/worked. To make sure that the EntityManager was really null, I debugged test file and saw that indeed it gives null. So how can I solve this problem?
The EntityManager instance, is injected when the EJB is deployed in the Container.
If you take a look at the lifecycle of enterprise bean, you will see clearly when dependency injection occurs.
When the Container sees the #Persistencecontext annotation it will inject a container-managed EntityManager.
The problem is that the code executed in this test is not managed by the Container, therefore, no one inject the necessary dependencies.
bookDao = new BookEJB();
When you run the test, the BookEJB class is just a simple POJO, the #Stateless and #PersistenceContext annotations are simply ignored.
You have several alternatives in order to test your EJB, take a look at this link.