Executing one bean before another - java

Right now I have the following two beans defined in my controller which are connecting to two different databases. The two beans in the current scenario
are executing at the same time as soon as controller receives doc_id and empID_ from the webservice call. I don't want this to happen.
CURRENT SCENARIO:
#RequestMapping(value="/showEmpDetails", method=RequestMethod.GET)
public String showEmpDetails
(
#RequestParam(value="doc_id", defaultValue="0") String doc_id,
#RequestParam(value="emp_id", defaultValue="1234") String empID_
)
{ String jsonString = "";
try {
// Bean 1 defined for an Oracle database
EmployeeDao empDao = (EmployeeDao) context.getBean("empDao");
// Bean 2 defined for different Oracle database
EmployeeDao empForValueDao = (EmployeeDao) context.getBean("empValueDao");
List<ShowDescription> beanONE = empForValueDao.getemployeeDetails(empID_);
List<ShowDescription> beanTWO = empDao.getCompanyShowDocument(doc_id);
}
return JsonString;
}
EXPECTED SCENARIO:
I want the beanONE to execute first, return a value back in the controller after calling the getemployeeDetails method and then pass that value at
the time of second bean call next to doc_id as shown below. In this manner the SQL query I have used inside the getCompanyShowDocument method can make
use of this value and get me the results I am expecting.
#RequestMapping(value="/showEmpDetails", method=RequestMethod.GET)
public String showEmpDetails
(
#RequestParam(value="doc_id", defaultValue="0") String doc_id,
#RequestParam(value="emp_id", defaultValue="1234") String empID_
)
{ String jsonString = "";
try {
// Bean 1 defined for different Oracle database
EmployeeDao empForValueDao = (EmployeeDao) context.getBean("empValueDao");
// Bean 2 defined for an Oracle database
EmployeeDao empDao = (EmployeeDao) context.getBean("empDao");
List<ShowDescription> beanONE = empForValueDao.getemployeeDetails(empID_);
List<ShowDescription> beanTWO = empDao.getCompanyShowDocument(doc_id,returnedValue);
}
return JsonString;
}
In XML I have the beans defined as follows :
<bean id="empDao" class="abc.edg.myproj.dao.impl.EmployeeDaoImpl">
<property name="dataSource"><ref bean="DB_ONE"/></property>
</bean>
<bean id="empValueDao" class="abc.edg.myproj.dao.impl.EmployeeDaoImpl">
<property name="dataSource"><ref bean="DB_TWO"/></property>
</bean>
Is it possible to achieve what I described above? Please advise. Thanks
Adding getemployeeeDetails method below as requested in the comment:
public List<ShowDescription> getemployeeDetails(String empID) throws DaoException
{
DataSource ds = null;
Connection conn = null;
PreparedStatement pstmt2 = null;
ResultSet rs2 = null;
List<ShowDescription> employeeValue = new ArrayList<ShowDescription>();
try {
ds = jdbcTemplate.getDataSource();
conn = ds.getConnection();
pstmt2 = conn.prepareStatement(selectValueSQL);
pstmt2.setString(1, empID);
rs2 = pstmt2.executeQuery();
while(rs2.next()) {
ShowDescription employeeRecord = new ShowDescription();
employeeRecord.setEmployeeValue(rs2.getString("value"));
employeeValue.add(employeeRecord);
System.out.println("I am inside getemployeeDetails method to get the cvtermPropValue");
System.out.println(employeeRecord.getEmployeeValue()); // Prints the value
}
} catch(Throwable th) {
//some code
} finally {
// Closing all resources here
}
return employeeValue;
}

Related

MongoURI #value variable is getting nulled

In my code below, mongoURI initially pulls the correct URI string from application.properties, and connects to the database successfully. However, once I make a call to getUserByAuth0ID, I'm getting a "java.net.UnknownHostException: null: Name or service not known" error and debug statements show that mongoURI is now set to null.
What's going on? Nowhere in my code do I touch the value of mongoURI. My previous version of the code has mongoURI hardcoded as a variable and it runs with no issues.
#Service
public class DBConnectService {
private static MongoCollection<User> users;
private static Logger logger = LogManager.getLogger(DBConnectService.class);
#Value("${package.mongoURI}")
private String mongoURI;
/** Opens a connection to mongodb for the length of the program operation */
#PostConstruct
public void init() {
logger.info("Connecting to MongoDB");
try {
System.out.println (mongoURI); // URI prints out correctly here
CodecRegistry pojoCodecRegistry = fromProviders(PojoCodecProvider.builder().automatic(true).build());
CodecRegistry codecRegistry = fromRegistries(MongoClientSettings.getDefaultCodecRegistry(), pojoCodecRegistry);
MongoClientSettings clientSettings = MongoClientSettings.builder()
.applyConnectionString(new ConnectionString(mongoURI))
.codecRegistry(codecRegistry)
.build();
MongoClient mongoClient = MongoClients.create(clientSettings);
MongoDatabase database = mongoClient.getDatabase("db");
users = database.getCollection("users", User.class);
} catch(Exception e) {
logger.error("MongoDB connection failure:\n" + e);
}
}
public User getUserByAuth0ID (String authID) {
System.out.println (mongoURI); // URI prints out here as null
User user = getUser(authID, "auth0ID");
if (user == null) {
user = createUserAccount(authID);
}
return user;
}
public static User getUser (String info, String field) {
User user = users.find(eq(field, info)).first();
return user;
}
public static User createUserAccount (String authID) {
JsonObject newUserInfo = Auth0Service.getUserInfo(authID);
if (newUserInfo.get("email_verified").getAsBoolean()) {
User newUser = new User()
.setEmail(newUserInfo.get("email").getAsString())
.setName(newUserInfo.get("name").getAsString())
.setAuth0ID(authID);
users.insertOne(newUser);
return newUser;
} else {
logger.info ("Email NOT verified");
return null;
}
}
Application.properties line:
# --- MongoDB ---
package.mongoURI = mongodb+srv://admin:secretURL/?retryWrites=true&w=majority
Your #Value annotation has incorrect details of mongoURI.Either use #Value("${nornir.mongoURI}") or change to package.mongoURI inside application.properties.
Edit:
It is more likely you are calling getUserByAuth0ID manually something like --
DBConnectService service = new DBConnectService();
service.getUserByAuth0ID();
Because if mongoURI is coming as null, it means, this method getUserByAuth0ID is not getting called via spring way, i.e. by autowiring DBConnectService & then accessing this method; but rather it is getting called manually i.e. by manually creating object of DBConnectService.
If this is case, then it is obvious that your normal java object don't know about #Value annotation & hence it is not setting any value.
#PostConstruct will always works as it will get executed at startup when bean is getting created & hence #Value is working properly there.
To fix this issue, make sure you have spring bean of DBConnectService & you are accessing getUserByAuth0ID via that bean.
Edit 2 : --
Basic pseudo about how to use this in your calling class :
#Autowired
DBConnectService service;
public void yourdbMethod(){
service.getUserByAuth0ID();
}

How to write a test case for method which creates the table and add values

I'm setting up java project where user enter his details and the data will be saved in the the database bellow is my code:
public String CreateUserDetails() throws SQLException, JsonProcessingException
{
iterationResourse = new IterationResourse();
dbcon = DatabaseConnection.getInstance();
iteratinDetails = IterationDetailsParser.getInstance();
try {
String sqlUser = "INSERT INTO user (User_Id,Username,Active_Indi)VALUES(?,?,?)";
PreparedStatement statement = (PreparedStatement) dbcon.con.prepareStatement(sqlUser);
statement.setString(1, iterationResourse.ConvertObjectToString(iteratinDetails.getUserId()));
statement.setString(2, iterationResourse.ConvertObjectToString(iteratinDetails.getUserObj()));
statement.setBoolean(3, true );
statement.executeUpdate();
statement.close();
System.out.println("user created");
st = "user created";
} catch (SQLException e)
{
System.out.println("user id alredy exits");
userIdExits = false;
ObjectMapper mapperUser = new ObjectMapper();
JsonNode rootNode = mapperUser.createObjectNode();
((ObjectNode) rootNode).put("Response", "User ID alreday exits");
String jsonString = mapperUser.writerWithDefaultPrettyPrinter().writeValueAsString(rootNode);
System.out.println(jsonString);
iterationResourse.response = jsonString;
st = "Response\", \"User ID alreday exits";
}
return st;
}
I have to write a test case for the above code i have tried the fallowing code. i am trying to mock all the objects that i am trying to use form the other class , the expected result should be string that returns "User created" . but i am unable the get the expected result based on the current code.
public class UserDatabaseTest {
User user = null;
IterationResourse iterationResourse;
DatabaseConnection db;
IterationDetailsParser iterationDetails ;
#Before
public void setUp()
{
iterationResourse = mock(IterationResourse.class);
db = mock(DatabaseConnection.class);
iterationDetails = mock(IterationDetailsParser.class);
user = new User();
}
#Test
public void test() throws JsonProcessingException, SQLException {
Object Object = "3";
String value = "3";
when(db.getInstance().GetDBConnection()).thenReturn(db.getInstance().GetDBConnection());
when(iterationDetails.getUserId()).thenReturn(Object);
when(iterationResourse.ConvertObjectToString(Object)).thenReturn(value);
assertEquals(user.CreateUserDetails(), "user created");
}
}
There are two cases to be written here.
CreateUserDetails return "user created"
Else return "User ID already exists" (i fixed the two typos)
As stated in the comments you should really abstract your DAO layer. But at a high level, you want to mock the DatabaseConnection and return mocks for anything it may return. Doing this prevents NPE's when calling your code base.
Once your mocks are in place the test should return "user created". For the second test have one of your mock throw an SQLException and you can test that "User ID already exists" is returned. I would probably just pass iteratinDetails as a parameter, seems like a dependency for this method.
Lastly, you should not be testing that your code has created database tables and populated them correctly. As long as the data you are passing in (which is something you can test) you should have faith that SQL is going to execute scripts as intended. If you really wanted to get crazy, you could do some mocking to ensure that the statement was prepared properly. IMO that's overkill.
Goodluck!

How to pass value from servlet to Dao class and perform operation and return List/ Arraylist to JSP page

Hello i am new at JSP developing and i need some help about JSP MVC programming I want to pass a value from Servlet and in Dao class i want to receive it in List function and perform operation and return th array to JSP page to use ..
Servlet
String company = "ABCD";
ObsBean ComName = new ObsBean();
ComName.setCompanyName(company);
dao.getComNotify(ComName);
Bean Class (ObsBean)
private String CompanyName;
public String getCompanyName() {
return CompanyName;
}
public void setCompanyName(String CompanyName) {
this.CompanyName = CompanyName;
}
**DAO Class (ObsDao) **
public List getComNotify(ObsBean ComName) {
List<ObsBean> comNotify = new ArrayList<ObsBean>();
String cname = ComName.getCompanyName();//getting from bean class by getter
try {
String sql = "SELECT * from ObsNotify where notto='"+cname+"'";
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
while (rs.next()) {
ObsBean userNotify = new ObsBean();
userNotify.setNotifyName(rs.getString("notname"));
userNotify.setNotifyBy(rs.getString("notby"));
userNotify.setNotifyTo(rs.getString("notto"));
userNotify.setNotifyDate(rs.getString("notdate"));
comNotify.add(userNotify);
}
}
catch (Exception e) {
out.print("Error for User Notification - : "+e);
}
return comNotify;
}
IN JSP Page :
<%
ObsDao dao = new ObsDao();
List<ObsBean> ComNotify = dao.getComNotify();
for (ObsBean UserNotifi : ComNotify) {
.........
.........
}
%>
This is my complete code , but it shows error , why ?
ERRORS :
HTTP Status 500 – Internal Server Error
Type Exception Report
Message javax.servlet.ServletException: java.lang.NoSuchMethodError: com.ApexCorner.ModelDao.ObsDao.getComNotify()Ljava/util/List;
Description The server encountered an unexpected condition that prevented it from fulfilling the request.
Exception
org.apache.jasper.JasperException: javax.servlet.ServletException: java.lang.NoSuchMethodError: com.ApexCorner.ModelDao.ObsDao.getComNotify()Ljava/util/List;
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:565)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:466)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:385)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:329)
javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Based on your code I assume that "notto" in your table is a company name, so if your sql statement is correct i would rewrite your code as follows:
public List getComNotify(ObsBean Comname) {
List<ObsBean> comNotify = new ArrayList<ObsBean>();
String COM = Comname.getcompanyname();
try {
String sql = "SELECT * from ObsNotify where notto='"+COM+"'";
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
while (rs.next()) {
ObsBean userNotify = new ObsBean();
int totalRows = rs.getRow();
userNotify.setNotifyName(rs.getString("notname"));
userNotify.setNotifyBy(rs.getString("notby"));
comNotify.add(userNotify);
}
}
catch (Exception e) {
out.print("Error for User Notification - : "+e);
}
return comNotify;
}
Comname is an object of the ObsBean type, you should retrieve the company name as a string before you can apply it to the sql statement, also note that java is case sensitive.
in JSP do something like
<%
ObsDao dao = new ObsDao();
ObsDao otherdao = new ObsDao();
otherdao.setCompanyName("My company")
List<ObsBean> ComNotify = dao.getComNotify(otherdao);
for (ObsBean UserNotifi : ComNotify) {
.........
.........
}
%>
In your Dao class, there should be getter method for CompanyName. So try following code:
STRING COM = Comname; ,<-- change this line to String COM=Comname.getCompanyName();

JAXRS + JerseyTest testing a REST Service

I've created a Rest service with four methods, GET,POST,UPDATE and DELETE.
These methods make connections to a Database to retrieve and store data.
Now I want to test each method. I've used the Jersey Test Framework for this. And it is working as long as I remove the code what actually makes the call to the database. When I leave the code that makes the call to the database it throws an exception that it could not connect to the database.
EDIT: I have done some research and used dependancy injection. The db calls are moved to a separate class but I'm still doing something wrong.
DatabaseResults. In this class the call to the DB is made.
public class DatabaseResults {
private final String getQuery = "SELECT * FROM movies";
private Connection connection = null;
private PreparedStatement pstmt = null;
private final ArrayList<Movie> jsonList = new ArrayList<>();
public JSONObject getAllMovies() throws SQLException {
try {
ComboPooledDataSource dataSource = DatabaseUtility.getDataSource();
connection = dataSource.getConnection();
pstmt = connection.prepareStatement(getQuery);
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
jsonList.add(new Movie(rs.getString(1), rs.getString(2), rs.getString(4), rs.getString(3)));
}
} catch (SQLException ex) {
System.out.println(ex);
System.out.println("Could not retrieve a connection");
connection.rollback();
} finally {
connection.close();
}
JSONObject jsonObject = new JSONObject();
jsonObject.put("movies", jsonList);
return jsonObject;
}
}
MoviesResource that contains the REST methods
#Path("movies")
public class MoviesResource {
....
private DatabaseResults dbResults = null;
public MoviesResource() {
this(new DatabaseResults());
}
MoviesResource(DatabaseResults dbr){
this.dbResults = dbr;
}
....
#GET
#Produces(MediaType.APPLICATION_JSON)
public Response getAllMovies() throws JSONException, SQLException {
return Response.status(200).entity(dbResults.getAllMovies().toString()).build();
}
The Test class
#RunWith(MockitoJUnit44Runner.class)
public class MovieResourceTest extends JerseyTest {
JSONObject jsonObject = new JSONObject();
#Mock
DatabaseResults dbr;
#Before
public void setup() throws SQLException{
jsonObject.put("id", "hello");
when(dbr.getAllMovies()).thenReturn(jsonObject);
}
Client client = ClientBuilder.newClient();
WebTarget target = client
.target("http://localhost:9998/RestServiceMovies/resources");
#Override
protected Application configure() {
return new ResourceConfig(MoviesResource.class);
}
#Test
public void getAllMoviesTest() throws SQLException {
String responseGetAllMovies = target("/movies").request().get(String.class);
Assert.assertTrue("hello".equals(responseGetAllMovies));
}
At this moment I can run the tests but still when I test the getAllMovies() method it makes a call to the real database instead of returning the jsonObject.
I have the feeling that a connection is missing between the mock object and the constructor from the MovieResource class?
When you register your resource as a class
new ResourceConfig(MoviesResource.class)
you are telling Jersey to create the instance. If you don't have any DI configured, it will just call the no-arg constructor. In your no-arg constructor, you are just creating the service yourself. It knows nothing about your mock.
What you should do instead is register the resource class as an instance. That way you can pass the mock to the constructor.
MockitoAnnotations.initMocks(this);
return new ResourceConfig()
.register(new MoviesResource(dbr));
Don't use the Mockito runner. Instead use the MockitoAnnotations.initMocks method. That way you control when the #Mocks are injected. If you use the runner, the injection will not happen in time, as the the configure method is called by the framework before the Mockito injection happens.

how to set more than rows to pojo class variables using jdbcTemplate

I am new to Spring, I am trying to fetch the data from table and set to pojo class like below code using spring jdbcTemplate,
#RequestMapping(value = "/getdevicedata/{macId}", method = RequestMethod.GET, produces = "application/json")
#ResponseBody
public DeviceAnalyse getDevicedata(#PathVariable String macId, HttpServletResponse response) throws Exception {
DeviceAnalyse deviceAnalyse = new DeviceAnalyse();
//List<DeviceAnalyse> deviceAnalyse = new ArrayList<>();
if (!isValidMacId(macId)) {
deviceAnalyse.setDId("Invalid device Id");
return deviceAnalyse;
}
DeviceAnalyse temp = new DeviceAnalyse();
try{
temp = new DeviceAnalyse();
String sql = "select value,serverTimeStamp,sensorType,percentage from tablename";
temp = (DeviceAnalyse)jdbcTemplate.queryForObject(sql, new Object[]{macId}, new BeanPropertyRowMapper(DeviceAnalyse.class));
deviceAnalyse.setPercentage(temp.getPercentage());
deviceAnalyse.setSensorType(temp.getSensorType());
deviceAnalyse.setServerTimeStamp(temp.getServerTimeStamp());
deviceAnalyse.setValue(temp.getValue());
}
catch(Exception e){
System.out.println(e);
e.printStackTrace();
deviceAnalyse.setPercentage(0L);
deviceAnalyse.setSensorType("");
deviceAnalyse.setServerTimeStamp(null);
deviceAnalyse.setValue(0L);
}
return deviceAnalyse;
}
here DeviceAnalyse is my pojo class which have all getter setter. but i am getting Incorrect result size: expected 1, actual 4.
How to fix this and set all retrieving values to pojo class? like
while(resultset.next())
{
deviceAnalyse.setPercentage(temp.getPercentage());
deviceAnalyse.setSensorType(temp.getSensorType());
deviceAnalyse.setServerTimeStamp(temp.getServerTimeStamp());
deviceAnalyse.setValue(temp.getValue());
}
You made one simple mistake in your code. You should call jdbcTemplate.query instead of jdbcTemplate.queryForObject.
jdbcTemplate.queryForObject expects exactly one row in the result because RowMapperResultSetExtractor becomes initialized with 1. Instead jdbcTemplate.query returns all rows.
Don't forget to change your temp variable to List<DeviceAnalyse>.
Calling jdbcTemplate may look like this:
List<DeviceAnalyse> temp = jdbcTemplate.query(sql, new Object[]{macId}, new BeanPropertyRowMapper(DeviceAnalyse.class));

Categories

Resources