How do i use ViewAccsessScope beans when testing in Arquillian? - java-ee-6

When i use #ViewAccsessScoped beans from CODI i get the following error, when using Arquillian for testing my beans.
org.jboss.arquillian.test.spi.ArquillianProxyException: org.jboss.weld.context.ContextNotActiveException : WELD-001303 No active contexts for scope type org.apache.myfaces.extensions.cdi.core.api.scope.conversation.ViewAccessScoped
is there anyway to get this to work?
//Trind

You can check GroupedConversationContext#isActive to know if it's an issue with your setup or an issue with Arquillian. They just use the standard JSF API for doing the check.

I tried to mock the FacesContext and got it working no idea if this is the best approch however.
I used Mockito to when doing the mocks.
FacesContext mock = null;
final Map<Object, Object> attributes = new HashMap<Object, Object>();
public void mockFacesContext() {
if (mock == null) {
mock = Mockito.mock(FacesContext.class);
try {
Method m = FacesContext.class.getDeclaredMethod(
"setCurrentInstance", FacesContext.class);
m.setAccessible(true);
m.invoke(FacesContext.class, mock);
} catch (Exception e) {
e.printStackTrace();
}
Mockito.when(mock.getAttributes()).thenReturn(attributes);
ExternalContext ext = Mockito.mock(ExternalContext.class);
Mockito.when(ext.getSession(false)).thenReturn(
Mockito.mock(HttpSession.class));
Mockito.when(mock.getExternalContext()).thenReturn(ext);
UIViewRoot uiViewRoot = Mockito.mock(UIViewRoot.class);
Mockito.when(uiViewRoot.getViewId()).thenReturn("/test");
Mockito.when(uiViewRoot.getLocale()).thenReturn(new Locale("se"));
Mockito.when(mock.getViewRoot()).thenReturn(uiViewRoot);
Application application = Mockito.mock(Application.class);
Mockito.when(application.getSupportedLocales()).thenReturn(
Mockito.mock(Iterator.class));
Mockito.when(mock.getApplication()).thenReturn(application);
}
return mock;
}

Related

How do I populate mongo repositories automatically?

Using Spring Data MongoDB with MongoRepository. I have this bean
#Bean
public Jackson2RepositoryPopulatorFactoryBean repositoryPopulator() {
Jackson2RepositoryPopulatorFactoryBean factory = new Jackson2RepositoryPopulatorFactoryBean();
try {
factory.setResources(resourceResolver.getResources("classpath:static/collections/*.json"));
} catch (IOException e) {
log.error("Could not load data", e);
}
return factory;
}
which just works fine with fongo (db is dropped at the end of a test run) but not with real mongo. If I leave the bean as it is and I switch to real mongo instance, then I get my data base populated but only the first run, if I re-run the project (+tests) then it fails because it's already populated (getting DuplicateKeyException).
How do I populate only on the case the repositories are empty?
Consider using data migration tools like Mongobee. This is basically Liquibase/Flyway for MongoDB.
#Bean
public Jackson2RepositoryPopulatorFactoryBean repositoryPopulator() throws Exception {
Jackson2RepositoryPopulatorFactoryBean factory = new Jackson2RepositoryPopulatorFactoryBean();
try {
Resource[] resources = resourceResolver.getResources("classpath:static/collections/*.json");
//resources to list so I can add only the necessary resources
List<Resource> resourcesToFill = new ArrayList<>();
for (Resource r : resources) {
String collection = r.getFilename().substring(0, r.getFilename().length() - 5);
if (!mongoTemplate().collectionExists(collection))
resourcesToFill.add(r);
}
//back to Array...
resources = new Resource[resourcesToFill.size()];
for(int i=0; i<resources.length; i++)
resources[i] = resourcesToFill.get(i);
factory.setResources(resources); // <-- the reason of this shitty code, why the hell use Array?
} catch (IOException e) {
log.error("Could not load data", e);
}
return factory;
}

Display available REST resources in development stage

I was wondering wheather it's possible to output the available REST paths of a Java EE web app (war deplopyment) as a summary on a page. Of course, for security reasons only in development mode. Is there something available for this?
Thanks
Here is a quick + dirty example which will return all paths for the scanned ResourceClasses:
Path("/paths")
public class PathResource {
#GET
#Produces(MediaType.TEXT_PLAIN)
public Response paths(#Context HttpServletRequest request) {
StringBuilder out = new StringBuilder();
String applicationPath = "/"; // the path your Application is mapped to
#SuppressWarnings("unchecked")
Map<String, ResteasyDeployment> deployments = (Map<String, ResteasyDeployment>) request.getServletContext().getAttribute("resteasy.deployments");
ResteasyDeployment deployment = deployments.get(applicationPath);
List<String> scannedResourceClasses = deployment.getScannedResourceClasses();
try {
for (String className : scannedResourceClasses) {
Class<?> clazz = Class.forName(className);
String basePath = "";
if (clazz.isAnnotationPresent(Path.class)) {
basePath = clazz.getAnnotation(Path.class).value();
}
out.append(String.format("BasePath for Resource '%s': '%s'", className, basePath)).append('\n');
for (Method method : clazz.getDeclaredMethods()) {
if (method.isAnnotationPresent(Path.class)) {
String path = method.getAnnotation(Path.class).value();
out.append(String.format("Path for Method '%s': '%s'", method.getName(), basePath + path)).append('\n');
}
}
}
} catch(ClassNotFoundException ex) {
throw new IllegalArgumentException(ex);
}
return Response.ok(out).build();
}
}
For developers who are working with Eclipse. Simply use open the Project Exlorer view and see the list of available resources under JAX-RS Web Services. I'm positive there is something similar for other IDEs.

Camel JPA - No Persistence provider for EntityManager named camel

I am trying to get the following code to work so I can consume from a JPA entity.
String DATASOURCE_CONTEXT = "java:jboss/datasources/WikiDS";
Connection result = null;
DataSource datasource = null;
try {
Context initialContext = new InitialContext();
datasource = (DataSource)initialContext.lookup(DATASOURCE_CONTEXT);
if (datasource == null) {
System.out.println("Data source is null");
}
else {
System.out.println("Data source is OK!!!");
}
}
catch(NamingException ex) {
System.out.println("Naming exception is: " + ex.getMessage());
}
SimpleRegistry reg = new SimpleRegistry() ;
reg.put("myDataSource",datasource);
CamelContext context = new DefaultCamelContext(reg);
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false");
context.addComponent("test-jms", JmsComponent.jmsComponentAutoAcknowledge(connectionFactory));
context.addRoutes(new RouteBuilder() {
public void configure() {
from("jpa://org.apache.camel.example.jmstofile?consumer.namedQuery=step1&consumeDelete=false").to("file://test");
}
});
ProducerTemplate template = context.createProducerTemplate();
context.start();
Whatever I do I get the following exception.
[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.1.1:java (default-cli) on project camel-example-jms-file: An exception occured while executing the Java class. null: InvocationTargetException: No Persistence provider for EntityManager named camel.
Any ideas how to fix this?
Regards,
Sean
Add &persistenceUnit=<name-of-your-unit> to your URI, where <name-of-your-unit> is the name of the persistence unit given in persistence.xml.

JPA #OneToMany not persisting/cascading

I have the following code in UserController in my Session Scoped Bean
public void addItemToBundle(ItemEntity item){
//System.out.println(item.getTitle());
try {
em.getTransaction().begin();
UserEntity user = em.find(UserEntity.class, this.username);
BundleEntity bundle = new BundleEntity();
BundleEntityPK compositePk = new BundleEntityPK();
compositePk.setCheckedOutDate(new Date());
compositePk.setItemId(item.getItemId());
compositePk.setUsername(user.getUsername());
bundle.setId(compositePk);
Set<BundleEntity> bundles = new HashSet<BundleEntity>();
bundles.add(bundle);
user.setBundleEntities(bundles);
em.persist(user);
em.flush();
em.getTransaction().commit();
} finally {
}
}
public String addToBundle(){
try {
addItemToBundle(item);
} catch (NullPointerException e) {
e.getMessage();
}
return null;
}
This code uses private ItemEntity item; which gets passed in by the following JSF markup:
<p:commandLink action="#{itemController.item}">
<f:setPropertyActionListener target="#{itemController.selectedItem}" value="#{movie}" />
</p:commandLink>
(I'm using PrimeFaces in this example) The problem is that the addItemToBundle is not calling any SQL code in the console (I have FINE enabled) and the bundle never gets created or added to the user. I also tried em.persist(user) and em.flush() and setting cascadeType in my UserEntity with no luck.
#OneToMany(mappedBy="userEntity",cascade=CascadeType.PERSIST)
private Set<BundleEntity> bundleEntities;
Thanks!
You know that this:
try {
addItemToBundle(item);
} catch (NullPointerException e) {
e.getMessage();
}
is very bad practice, right? Maybe, that's the problem here, you run into a NPE and never notice it.
You should at least log the exception to know what's going on there (just for demo purposes, I've used stdout, please replace with your favorite logging framework):
try {
addItemToBundle(item);
} catch (NullPointerException e) {
System.err.println(e.getMessage()); //use logger here
}

Autofac Contrib Multi Tenant throws "Request is not available in this context" exception

I am using http://code.google.com/p/autofac/wiki/MultitenantIntegration version 2.4.4 with Autofac 2.4.4 on an ASP.Net MVC 3.0.
I use the new Asp.Net MVC 3 support (using AutofacDependencyResolver). I encounter a problem that the tenant identification strategy class (implementing ITenantIdentificationStrategy) throws "Request is not available in this context" exception.
I tried using AutofacContrib.Multitenant.Web.RequestParameterTenantIdentificationStrategy class and it also throws the same exception.
My application_start looks as follow
protected void Application_Start()
{
//wire up all the necessary objects used in this web application
IContainer container = BootStrap.RegisterAll().Build();
//multi tenant support
MultitenantContainer multiTenant = new MultiTenancy().Register(container);
DependencyResolver.SetResolver(new AutofacDependencyResolver(multiTenant.BeginLifetimeScope()));
}
Never mind. HttpContext.Current.Request is not available at Application_Start in IIS 7.0. The only solution to this is to capture the HTTPException and set the TenantId to null at Catch and return false.
public bool TryIdentifyTenant(out object tenantId)
{
var current = HttpContext.Current;
try
{
if (current == null)
{
tenantId = null;
return false;
}
var request = current.Request;
}
catch (HttpException)
{
tenantId = null;
return false;
}
//continue with your tenant identification
}