Trying to get JSF(Faces) working within Spring WebFlow - jsf

I been trying to add some JSF(Face) code into my Spring Webflow project but I am getting the following error:
java.lang.IllegalStateException: FacesContext has not been initialized within the current Web Flow request. Check the configuration for your <webflow:flow-executor>. For JSF you will need FlowFacesContextLifecycleListener configured as one of its flow execution listeners.
Here is my flow.xml file
<?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:webflow="http://www.springframework.org/schema/webflow-config"
xmlns:faces="http://www.springframework.org/schema/faces"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/webflow-config
http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.3.xsd
http://www.springframework.org/schema/faces
http://www.springframework.org/schema/faces/spring-faces-2.2.xsd">
<!-- Executes flows: the central entry point into the Spring Web Flow system -->
<webflow:flow-executor id="flowExecutor">
<webflow:flow-execution-listeners>
<webflow:listener ref="facesContextListener"/>
</webflow:flow-execution-listeners>
</webflow:flow-executor>
<!-- The registry of executable flow definitions -->
<webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices" base-path="/WEB-INF">
<webflow:flow-location-pattern value="**/*-flow.xml" />
</webflow:flow-registry>
<!-- Configures the Spring Web Flow JSF integration -->
<faces:flow-builder-services id="flowBuilderServices" />
<!-- A listener maintain one FacesContext instance per Web Flow request. -->
<bean id="facesContextListener"
class="org.springframework.faces.webflow.FlowFacesContextLifecycleListener" />
</beans>
and here is my flow:
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
<var name="customer" class="org.smith.webflowtemplate.domain.Customer"/>
<view-state id="checkbox-input" model="customer" >
<transition on="submit" to="preview" validate="false"/>
<transition on="cancel" to="thanks" validate="false"/>
</view-state>
<view-state id="preview" model="customer">
<transition on="accept" to="endState"/>
</view-state>
<end-state id="endState" view="/index.jsp" />
</flow>

You need to add a Faces Context listener like this:
<flow-executor id="flowExecutor">
<flow-execution-listeners>
<listener ref="facesContextListener" />
</flow-execution-listeners>
</flow-executor>
<beans:bean id="facesContextListener" class="org.springframework.faces.webflow.FlowFacesContextLifecycleListener" />

Related

Spring Integration with Oracle AQ

I'm trying to learn Spring Integration and for this i would like to create an application like this:
From Oracle i send messages (on Oracle Queue), this message will be intercepted from a Java application (build with Spring Integration) and the application will send an email based on message received. The message will contain To: - Cc: and the text to send.
To make this kind of communication i've decided to use JMS (i think in Oracle this is made with Oracle AQ).
In the database i've already created the Queue and now i'm trying to create a simple applicationContext.xml to start this handshake.
Looking on the net i've found really few articles about this (Spring Integration + Oracle AQ) and i'm getting some error. The main error is this: java.lang.ClassNotFoundException: oracle.jms.AQjmsFactory
Right now this is my applicationContext.xml
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:int="http://www.springframework.org/schema/integration"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:orcl="http://www.springframework.org/schema/data/orcl"
xmlns:int-jms="http://www.springframework.org/schema/integration/jms"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/integration/jms http://www.springframework.org/schema/integration/jms/spring-integration-jms.xsd
http://www.springframework.org/schema/data/orcl http://www.springframework.org/schema/data/orcl/spring-data-orcl-1.0.xsd">
<int:channel id="inbound" />
<int:channel id="outbound" />
<bean id="simpleMessageListener" class="it.dirimo.SimpleMessageListener" />
<int-jms:inbound-channel-adapter
channel="inbound"
connection-factory="connectionFactory"
destination-name="Q1">
<int:poller fixed-delay="1000" />
</int-jms:inbound-channel-adapter>
<int:service-activator input-channel="inbound" output-channel="outbound" ref="simpleMessageListener" method="onMessage" />
<int-jms:outbound-channel-adapter id="jmsOut"
channel="outbound"
connection-factory="connectionFactory"
destination-name="sampleQueue" />
<int:poller id="poller" default="true" fixed-delay="10000" />
<orcl:aq-jms-connection-factory id="connectionFactory"
data-source="dataSource"
use-local-data-source-transaction="true"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" lazy-init="false">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#localhost:1521:ORCL" />
<property name="username" value="user" />
<property name="password" value="password" />
</bean>
</beans>
Maybe i'm using "old" technologies (for example i've seen for the first time this org.apache.commons.dbcp.BasicDataSource)
Unfortunally i'm so new about Spring Integration and i've seen for the first time Oracle Queue (i'm using Oracle for work but never used any kind of Queue).
Some advice of how to proceed will be apreciated :)
EDIT 1
To solve the problem about the AQjmsFactory need to include aqapi.jar
java.lang.ClassNotFoundException: oracle.jms.AQjmsFactory
This simply means you are missing the jar that contains that class from the classpath.
Oracle, typically, requires that you manually download their jars from them directly.

Where do you set and access run-time configuration parameters per environment for service fabric?

For two environments, local and cloud, how would I set up custom settings or parameters for resources such as Sql databases, storage accounts, etc... Ideally it would be one parameter name called in code to say, point a DbContext towards a particular database, that in configurations for either a local or cloud environment be different. Thank you.
In order to have per environment variables for running Service Fabric locally and in the cloud this is what you must do:
Add your custom config section and parameters to the Settings.xml file of the Service/Actor project (located at \PackageRoot\Config\Settings.xml from the project root). Leave the parameters blank as we will be setting these elsewhere per environment. Here is an example one.
<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<!-- Add your custom configuration sections and parameters here -->
<Section Name="UserDatabase">
<Parameter Name="UserDatabaseConnectionString" Value="" />
</Section>
</Settings>
In the ApplicationManifest.xml file of your Service Fabric project, there will be <ServiceManifestImport> elements for each of your included projects. Underneath that will be a <ConfigOverrides> element where we will declare what values for our configs will be supplanted by values set per environment in the local and cloud xml files underneath ApplicationParameters in our Service Fabric project. In that same ApplicationManifest.xml file, you'll need to add the parameter that will be present in the local and cloud xml files, otherwise they'll be overwritten upon build.
Continuing with the example above, this is how it would be set.
<Parameters>
<Parameter Name="ServiceName_InstanceCount" DefaultValue="-1" />
<Parameter Name="UserDatabaseConnectionString" DefaultValue="" />
</Parameters>
<ConfigOverrides>
<ConfigOverride Name="Config">
<Settings>
<Section Name="UserDatabase">
<Parameter Name="UserDatabaseConnectionString" Value="[UserDatabaseConnectionString]" />
</Section>
</Settings>
</ConfigOverride>
</ConfigOverrides>
In the local.xml and cloud.xml files underneath ApplicationParameters in your Service Fabric project, you will specify your environment specific variables like so.
<?xml version="1.0" encoding="utf-8"?>
<Application xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="fabric:/AppFabricName.ServiceFabric" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Parameters>
<Parameter Name="ServiceName_InstanceCount" Value="1" />
<Parameter Name="UserDatabaseConnectionString" Value="Server=(localdb)\MsSqlLocalDb;Database=Users;User=ReadOnlyUser;Password=XXXXX;" />
</Parameters>
</Application>
Finally, in your Service/Actor you can access these per-environment configuration variables like so.
var configurationPackage = Context.CodePackageActivationContext.GetConfigurationPackageObject("Config");
var connectionStringParameter = configurationPackage.Settings.Sections["UserDatabase"].Parameters["UserDatabaseConnectionString"];
You can just use environment variables just like any other application, this also works with guest executable within service fabric unlike the settings.xml as this requires the built-in service fabric runtime.
Within your application you can access environment variables just like any other .net application though the GetEnvironmentVariable method on the Environment class:
var baseUri = Environment.GetEnvironmentVariable("SuperWebServiceBaseUri");
Then we need to setup some default environment variables values, this is done within the ServiceManifest.xml manifest file of the service.
<?xml version="1.0" encoding="utf-8" ?>
<ServiceManifest Name="MyServicePkg" Version="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- snip -->
<CodePackage Name="Code" Version="1.0.0">
<!-- snip -->
<EnvironmentVariables>
<EnvironmentVariable Name="SuperWebServiceBaseUri" Value="http://localhost:12345"/>
</EnvironmentVariables>
</CodePackage>
<!-- snip -->
</ServiceManifest>
These environment variable can then be overridden within the ApplicationManifest.xml file by using the following code:
<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ApplicationTypeName="ChileTargetType" ApplicationTypeVersion="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Parameters>
<!-- snip -->
</Parameters>
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="MyServicePkg" ServiceManifestVersion="1.0.0" />
<EnvironmentOverrides CodePackageRef="Code">
<EnvironmentVariable Name="SuperWebServiceBaseUri" Value="https://the-real-live-super-base-uri.com/"/>
</EnvironmentOverrides>
</ServiceManifestImport>
<!-- snip -->
</ApplicationManifest>
This then can be parameterised like any other application manifest setting using the local.xml and cloud.xml.
<?xml version="1.0" encoding="utf-8"?>
<Application xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="fabric:/AppFabricName.ServiceFabric" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Parameters>
<Parameter Name="MyService_SuperWebServiceBaseUri" Value="https://another-base-uri.com/" />
</Parameters>
</Application>
Then we'll have to update the ApplicationManifest.xml to support these parameters;
<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ApplicationTypeName="ChileTargetType" ApplicationTypeVersion="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Parameters>
<Parameter Name="MyService_SuperWebServiceBaseUri" DefaultValue="https://the-real-live-super-base-uri.com/" />
</Parameters>
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="MyServicePkg" ServiceManifestVersion="1.0.0" />
<EnvironmentOverrides CodePackageRef="Code">
<EnvironmentVariable Name="SuperWebServiceBaseUri" Value="[MyService_SuperWebServiceBaseUri]"/>
</EnvironmentOverrides>
</ServiceManifestImport>
<!-- snip -->
</ApplicationManifest>
The above answers explain well how it is done. I want to add a sidemark, why it is that 'convoluted':
It has to be this way, as the services are intended to be self-contained. They should run by default in any application they are linked into. Independent of the application's Manifest. So the service can only rely on parameters, which are at least predefined in its own configuration.
These presettings can then be overwritten by the application. This is the only universal approach.

Spring Secutiry logout not destroying JSESSIONID defined in web-fragment

I am using Spring security to secure my rest API. Following are my configurations;
spring-secutiry.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<security:http auto-config="true">
<!-- Authentication Type and Intercepter Configurations -->
<security:http-basic />
<security:intercept-url pattern="/**" />
<security:anonymous enabled="false" />
<security:session-management invalid-session-url="/">
<security:concurrency-control max-sessions="1" />
</security:session-management>
<security:logout logout-url="/signOff" invalidate-session="true"
delete-cookies="JSESSIONID" logout-success-url="/" />
</security:http>
<bean id="myAuthenticationProvider"
class="com.myauthenticator.spring.secutiry.MyAuthenticationProvider" />
<security:authentication-manager>
<security:authentication-provider ref="myAuthenticationProvider" />
</security:authentication-manager>
</beans>
There is no such implementation for custom logout. I am expecting Spring to intercept call to /signOff and destroys token and redirect me to / because of the configuration in logout-success-url which should challenge for a BASIC auth once more but its loading my home page.
It seems like my spring configurations are not correct i.e. not all calls are intercepted by Spring filter. I have following configurations in my web.xml to priorities my web-fragment which contains my Spring Security Filter;
web.xml
<absolute-ordering>
<name>MyAuthenticator</name>
<others/>
</absolute-ordering>
Note: My filter and custom authentication are implemented as a web-fragment which looks like as follows;
web-fragement.xml
<web-fragment
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
xmlns:webfragment="http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd"
id="T24Authenticator" version="3.0">
<display-name>T24 Authentication Provider</display-name>
<name>MyAuthenticator</name>
<!-- Spring Security -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
.....
I think there is something wrong with my configurations! But I can't spot it, can anyone?

Configuring Web Flow for use with JSF

I am trying to do Configuring Web Flow for use with JSF. from the following site
http://static.springsource.org/spring-webflow/docs/2.3.x/reference/html/ch13s04.html
but I am getting the following error:
Description Resource Path Location Type
The prefix "si" for attribute "si:schemaLocation" associated with an element type "beans" is not bound. flowwithjsf.xml /WebFlowWithJSFIntegration/src/main/webapp/WEB-INF/spring line 12 XML Problem
Here is my XML it looks just like the site:
<?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:webflow="http://www.springframework.org/schema/webflow-config"
xmlns:faces="http://www.springframework.org/schema/faces"
si:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/webflow-config
http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.3.xsd
http://www.springframework.org/schema/faces
http://www.springframework.org/schema/faces/spring-faces-2.2.xsd">
<!-- Executes flows: the central entry point into the Spring Web Flow system -->
<webflow:flow-executor id="flowExecutor">
<webflow:flow-execution-listeners>
<webflow:listener ref="facesContextListener"/>
</webflow:flow-execution-listeners>
</webflow:flow-executor>
<!-- The registry of executable flow definitions -->
<webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices" base-path="/WEB-INF">
<webflow:flow-location-pattern value="**/*-flow.xml" />
</webflow:flow-registry>
<!-- Configures the Spring Web Flow JSF integration -->
<faces:flow-builder-services id="flowBuilderServices" />
<!-- A listener maintain one FacesContext instance per Web Flow request. -->
<bean id="facesContextListener"
class="org.springframework.faces.webflow.FlowFacesContextLifecycleListener" />
</beans>
try changing si:schemaLocation="... by xsi:schemaLocation="... I think that is why you are having this error
"To use this schema, include it in one of your infrastructure-layer beans files"
10.2 Spring docs

spring web security questions

All,
I have my application setup so that i can use a specific username and password combination:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<http use-expressions="true" access-denied-page="/start.jsf">
<intercept-url pattern="/start.jsf" filters="none" />
<intercept-url pattern="/web/**" access="isAuthenticated()" />
<form-login login-page="/start.jsf" default-target-url="/web/user/homepage.jsf" authentication-failure-url="/start.jsf?state=failure"/>
<logout logout-success-url="/start.jsf?state=logout" />
</http>
<!-- <authentication-manager alias="authenticationManager">
<authentication-provider>
<password-encoder hash="md5" />
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="SELECT U.email_address AS username, U.password as password, 'true' as enabled FROM users U where U.email_address=?"
authorities-by-username-query="SELECT U.email_address AS username, 'USER' as authority FROM users U WHERE U.email_address=?"
role-prefix="ROLE_" />
</authentication-provider>
</authentication-manager> -->
<authentication-manager alias="authenticationManager">
<authentication-provider>
<password-encoder hash="md5"/>
<user-service>
<user name="user1" password="a564de63c2d0da68cf47586ee05984d7" authorities="ROLE_SUPERVISOR, ROLE_USER, ROLE_TELLER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
Problem is that when I ask it to goto the dataSource, it cannot find the datasource. Reason for this is I have another ApplicationContext.xml in a config folder where all my java source files are. How do people normally organize the project so that this file is able to pickup the datasource file? I want to setup the project accordingly...thanks for the input!
Also, the login works, however, once the user logs in, I want to be able to get the userid/password and I'm not able to. How is that possible?
Implying that you have 2 XML files (in classpath) with spring context config: main-ctx.xml and security-ctx.xml and your are instantiating your app context using main-ctx.xml.
Then you can include config from security-ctx.xml into app context using this in main-ctx.xml (depends on your files locations path may be different):
<import resource="classpath:security-ctx.xml"/>
So you can define dataSource in main-ctx.xml and use it in security-ctx.xml in authentication-manager configuration.

Resources