diff --git a/basic/jdbc/README.md b/basic/jdbc/README.md index e6c5bec1..11f00839 100644 --- a/basic/jdbc/README.md +++ b/basic/jdbc/README.md @@ -4,6 +4,18 @@ Spring Integration - JDBC Sample # Overview This sample provides example of how the Jdbc Adapters can be used. +The example presented covers the following two use cases + +* Find a User detail from the database based on the name provided +* Create a new Person record in the table + +The first example demonstrates the use of outbound gateway to search for a user record using the +spring integration's jdbc outbound gateway + +The second example on other hand demonstrates how the jdbc outbound gateway be used to create a new +Person record and then return the newly created Person record. +This example demonstrates how to make use of the sql parameter source factory to extract +the required values to be inserted/updated/selected in the query provided. # Getting Started @@ -14,12 +26,48 @@ You can run the application by either - mvn package - mvn exec:java -Currently one example exists. On the command prompt you can enter the following valid values and get a response back: +Make an appropriate choice for searching a User or creating a Person + +For selecting the User, on the command prompt you can enter the following valid values and get a response back: * 'a' * 'b' * 'foo' +For creating the person record, select the appropriate steps as prompted by the application + +#Some details about the sample "Person Outbound Gateway" + +We use the outbound gateway to insert records in a Person table based on the values contained +in the message payload that is received over the channel to the adapter. + +The following are used to configure the gateway + +* The request and reply channels +* The data source for the database +* The the update/insert statement to be executed. +* Optional request SQL Parameter source factory +* The select query to be executed after the insert is done +* Optional reply SQL Parameter source factory +* RowMapper if you intend to map the ResultSet to your custom object + +The following sequence of events happen when we invoke the createPerson method on the gateway + +* The parameter of type Person is sent as a payload of a message over the reply-channel +* The outbound gateway reads this message and extracts the payload +* It then executes the given insert statement, the values to be inserted are derived from the payload + request-sql-parameter-source-factory provided is used to generate a parameter source. +* Since we expect an identity column to be generated, keys-generated is set to true +* The result of the insert is then use to create a reply sql parameter source, + the factory reply-sql-parameter-source-factory generates the required parameter source +* The select query provided is executed +* The ResultMapper is used to convert this ResultSet to a Person object +* The Person object is then sent as a payload of the Message over the reply channel. +* The Person payload is extracted from the Message and returned to the calling application. + +For executing the program and see the results, execute the junit test case +org.springframework.integration.samples.jdbc.OutboundGatewayTest + # Resources For help please take a look at the Spring Integration documentation: diff --git a/basic/jdbc/pom.xml b/basic/jdbc/pom.xml index 33e8ae93..976b160b 100644 --- a/basic/jdbc/pom.xml +++ b/basic/jdbc/pom.xml @@ -123,7 +123,7 @@ com.h2database h2 1.3.160 - - + + - + \ No newline at end of file diff --git a/basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/Gender.java b/basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/Gender.java new file mode 100644 index 00000000..24a2f65a --- /dev/null +++ b/basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/Gender.java @@ -0,0 +1,52 @@ +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.integration.samples.jdbc; + +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; + +/** + * Represents the gender of the person + * @author Amol Nayak + * + */ +public enum Gender { + + MALE("M"),FEMALE("F"); + private static Map map; + + private String identifier; + + private Gender(String identifier) { + this.identifier = identifier; + } + + public String getIdentifier() { + return identifier; + } + + public static Gender getGenderByIdentifier(String identifier) { + return map.get(identifier); + } + + static { + map = new HashMap(); + for(Gender gender:EnumSet.allOf(Gender.class)) { + map.put(gender.getIdentifier(), gender); + } + } +} diff --git a/basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/Main.java b/basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/Main.java index 0edab38b..2a607b88 100644 --- a/basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/Main.java +++ b/basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/Main.java @@ -15,12 +15,16 @@ */ package org.springframework.integration.samples.jdbc; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; import java.util.Scanner; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.integration.samples.jdbc.service.PersonService; import org.springframework.integration.samples.jdbc.service.UserService; @@ -28,6 +32,7 @@ import org.springframework.integration.samples.jdbc.service.UserService; * Starts the Spring Context and will initialize the Spring Integration routes. * * @author Gunnar Hillert + * @author Amol Nayak * @version 1.0 * */ @@ -60,7 +65,8 @@ public final class Main { final Scanner scanner = new Scanner(System.in); - final UserService service = context.getBean(UserService.class); + final UserService userService = context.getBean(UserService.class); + final PersonService personService = context.getBean(PersonService.class); LOGGER.info("\n=========================================================" + "\n " @@ -68,25 +74,27 @@ public final class Main { + "\n " + "\n=========================================================" ); - System.out.print("Please enter a string and press : "); - while (!scanner.hasNext("q")) { - + System.out.println("Please enter a choice and press : "); + System.out.println("\t1. Find user details"); + System.out.println("\t2. Create a new person detail"); + System.out.println("\tq. Quit the application"); + System.out.print("Enter you choice: "); + while (true) { final String input = scanner.nextLine(); - final User user = service.findUser(input); - - if (user != null) { - - System.out.println( - String.format("User found - Username: '%s', Email: '%s', Password: '%s'", - user.getUsername(), user.getEmail(), user.getPassword())); - - } else { - System.out.println( - String.format("No User found for username: '%s'.", input)); - } - - System.out.print("Please enter a string and press :"); + if("1".equals(input.trim())) + getUserDetails(scanner,userService); + else if("2".equals(input.trim())) + createPersonDetails(scanner,personService); + else if("q".equals(input.trim())) + break; + else + System.out.println("Invalid choice\n\n"); + System.out.println("Please enter your choice and press : "); + System.out.println("\t1. Find user details"); + System.out.println("\t2. Create a new person detail"); + System.out.println("\tq. Quit the application"); + System.out.print("Enter you choice: "); } LOGGER.info("Exiting application...bye."); @@ -94,4 +102,69 @@ public final class Main { System.exit(0); } + + private static void createPersonDetails(final Scanner scanner,PersonService service) { + while(true) { + System.out.print("\nEnter the Person's name:"); + String name = scanner.nextLine(); + Gender gender; + while(true) { + System.out.print("Enter the Person's gender(M/F):"); + String genderStr = scanner.nextLine(); + if("m".equalsIgnoreCase(genderStr) || "f".equalsIgnoreCase(genderStr)) { + gender = Gender.getGenderByIdentifier(genderStr.toUpperCase()); + break; + } + } + Date dateOfBirth; + SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy"); + while(true) { + System.out.print("Enter the Person's Date of birth in DD/MM/YYYY format:"); + String dobStr = scanner.nextLine(); + try { + dateOfBirth = format.parse(dobStr); + break; + } catch (ParseException e) { + //Silently suppress and ask to enter details again + } + } + + Person person = new Person(); + person.setDateOfBirth(dateOfBirth); + person.setGender(gender); + person.setName(name); + person = service.createPerson(person); + System.out.println("Created person record with id: " + person.getPersonId()); + System.out.print("Do you want to create another person? (y/n)"); + String choice = scanner.nextLine(); + if(!"y".equalsIgnoreCase(choice)) + break; + } + } + /** + * @param service + * @param input + */ + private static void getUserDetails(final Scanner scanner,final UserService service) { + while(true) { + System.out.print("Please enter a string and press : "); + String input = scanner.nextLine(); + final User user = service.findUser(input); + if (user != null) { + + System.out.println( + String.format("User found - Username: '%s', Email: '%s', Password: '%s'", + user.getUsername(), user.getEmail(), user.getPassword())); + + } else { + System.out.println( + String.format("No User found for username: '%s'.", input)); + } + System.out.print("Do you want to find another user? (y/n)"); + String choice = scanner.nextLine(); + if(!"y".equalsIgnoreCase(choice)) + break; + } + + } } diff --git a/basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/Person.java b/basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/Person.java new file mode 100644 index 00000000..b6781e36 --- /dev/null +++ b/basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/Person.java @@ -0,0 +1,81 @@ +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.integration.samples.jdbc; + +import java.util.Date; + +/** + * A simple POJO representing a Person + * @author Amol Nayak + * + */ +public class Person { + + private int personId; + private String name; + private Gender gender; + private Date dateOfBirth; + + + + /** + * Sets the person id + * @return + */ + public int getPersonId() { + return personId; + } + /** + * Get the person Id + * @param personId + */ + public void setPersonId(int personId) { + this.personId = personId; + } + + /** + * Gets the name of the person + * @return + */ + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + /** + * Gets the gender of the person + * @return + */ + public Gender getGender() { + return gender; + } + public void setGender(Gender gender) { + this.gender = gender; + } + + /** + * Gets the date of birth of the person + * @return + */ + public Date getDateOfBirth() { + return dateOfBirth; + } + public void setDateOfBirth(Date dateOfBirth) { + this.dateOfBirth = dateOfBirth; + } +} diff --git a/basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/PersonMapper.java b/basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/PersonMapper.java new file mode 100644 index 00000000..06530d5b --- /dev/null +++ b/basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/PersonMapper.java @@ -0,0 +1,41 @@ +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.integration.samples.jdbc; + +import java.sql.ResultSet; +import java.sql.SQLException; + +import org.springframework.jdbc.core.RowMapper; + +/** + * The result set mapper that will map the {@link ResultSet} to the {@link Person} instance + * @author Amol Nayak + * + */ +public class PersonMapper implements RowMapper { + + /* (non-Javadoc) + * @see org.springframework.jdbc.core.RowMapper#mapRow(java.sql.ResultSet, int) + */ + public Person mapRow(ResultSet rs, int rowNum) throws SQLException { + Person person = new Person(); + person.setPersonId(rs.getInt("id")); + person.setName(rs.getString("name")); + person.setGender(Gender.getGenderByIdentifier(rs.getString("gender"))); + person.setDateOfBirth(rs.getDate("dateOfBirth")); + return person; + } +} diff --git a/basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/service/PersonService.java b/basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/service/PersonService.java new file mode 100644 index 00000000..5f5bc27f --- /dev/null +++ b/basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/service/PersonService.java @@ -0,0 +1,35 @@ +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.integration.samples.jdbc.service; + +import org.springframework.integration.samples.jdbc.Person; + +/** + * The Service used to create Person instance in database + * @author Amol Nayak + * + */ +public interface PersonService { + + /** + * Creates a {@link Person} instance from the {@link Person} instance passed + * + * @param the created person instance, it will contain the generated primary key and the formated name + * @return + */ + Person createPerson(Person person); + +} diff --git a/basic/jdbc/src/main/resources/META-INF/spring/integration/spring-integration-context.xml b/basic/jdbc/src/main/resources/META-INF/spring/integration/spring-integration-context.xml index bd04abaa..5c9e0f98 100644 --- a/basic/jdbc/src/main/resources/META-INF/spring/integration/spring-integration-context.xml +++ b/basic/jdbc/src/main/resources/META-INF/spring/integration/spring-integration-context.xml @@ -13,7 +13,7 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/basic/jdbc/src/main/resources/setup-tables.sql b/basic/jdbc/src/main/resources/setup-tables.sql index a57cd2a0..dee1726a 100644 --- a/basic/jdbc/src/main/resources/setup-tables.sql +++ b/basic/jdbc/src/main/resources/setup-tables.sql @@ -1,5 +1,6 @@ create table IF NOT EXISTS USERS(USERNAME varchar(100),PASSWORD varchar(100), EMAIL varchar(100)); create table IF NOT EXISTS DUMMY(DUMMY_VALUE varchar(10)); +create table IF NOT EXISTS Person(id integer identity primary key , name varchar(100), gender varchar(1), dateOfBirth date); INSERT INTO USERS(USERNAME, PASSWORD, EMAIL) VALUES ('a', 'secret', 'spring-integration@awesome.com'); INSERT INTO USERS(USERNAME, PASSWORD, EMAIL) VALUES ('b', 's3cr3t', 'spring@rocks.com'); INSERT INTO USERS(USERNAME, PASSWORD, EMAIL) VALUES ('foo', 'bar', 'foo@bar.de'); \ No newline at end of file diff --git a/basic/jdbc/src/test/java/org/springframework/integration/samples/jdbc/OutboundGatewayTest.java b/basic/jdbc/src/test/java/org/springframework/integration/samples/jdbc/OutboundGatewayTest.java new file mode 100644 index 00000000..0ced7c93 --- /dev/null +++ b/basic/jdbc/src/test/java/org/springframework/integration/samples/jdbc/OutboundGatewayTest.java @@ -0,0 +1,53 @@ +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.integration.samples.jdbc; + +import java.util.Calendar; + +import org.apache.log4j.Logger; +import org.junit.Assert; +import org.junit.Test; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.integration.samples.jdbc.service.PersonService; + +/** + * The test class for jdbc outbound gateway + * @author Amol Nayak + * + */ +public class OutboundGatewayTest { + + private Logger logger = Logger.getLogger(OutboundGatewayTest.class); + + @Test + public void insertPersonRecord() { + ApplicationContext context + = new ClassPathXmlApplicationContext("/META-INF/spring/integration/spring-integration-context.xml"); + PersonService service = context.getBean(PersonService.class); + logger.info("Creating person Instance"); + Person person = new Person(); + Calendar dateOfBirth = Calendar.getInstance(); + dateOfBirth.set(1980, 0, 1); + person.setDateOfBirth(dateOfBirth.getTime()); + person.setName("Name Of The Person"); + person.setGender(Gender.MALE); + person = service.createPerson(person); + Assert.assertNotNull("Expected a non null instance of Person, got null", person); + logger.info("\n\tGenerated person with id: " + person.getPersonId() + ", with name: " + person.getName()); + } + +} diff --git a/basic/pom.xml b/basic/pom.xml index c183f4c5..61289677 100644 --- a/basic/pom.xml +++ b/basic/pom.xml @@ -29,6 +29,7 @@ ws-outbound-gateway xml xmpp +