Rest Services with jax b - java

I have written this service in my rest app Rest Application:
#DELETE
#Consumes(MediaType.APPLICATION_JSON)
#Path("/companies")
public void removeCompany(Company company) throws AdminFacadeException {
AdminFacade facade = (AdminFacade)req.getSession(false).getAttribute("facade");
facade.removeCompany(company);
}
and this is where the error ocure in the dao layer:
#Override
public void removeCompany(Object obj, Company company) throws CompanyDBException {
Connection con = (Connection) obj;
String sql = "Delete from company where id=" + company.getCompanyId();
try {
Statement stmt = con.createStatement();
int rowsChanged = stmt.executeUpdate(sql);
if (rowsChanged == 0) {
throw new CompanyDBException(
"CompanyDAO: Failed to remove company. ID: " + company.getCompanyId() + " can not be found.");
}
} catch (SQLException e) {
throw new CompanyDBException("CompanyDAO: Failed to remove company. ID: " + company.getCompanyId(), e);
}
}
When I created the company inside the service and set the id that I got from the client there was no problem. However, now when I changed the service to consume json, the eror(500) occurred in the DB method in the line
String sql=..........., it cant get the company.getCompanyId. more
String sql=...........,it cant get the company.getCompanyId.
I am giving some more information: The company id is automatically generated but I cant see how it is change anything, the company object getting transferred well, the id in my company bean is long, in the Company bean there is annotation #XmlRootElement.
Can someone explain what am i missing

Related

How can I count the number of HTTP method calls in my REST API and put it into a database?

I have a simple program that is supposed to get a user from github's API and I want to count the times the method is called.
Here is my REST Controller with a GET method (that's the method to be counted):
#RestController
#RequestMapping("/api/v1")
public class UserController {
private UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
#GetMapping("/user/info/{login}")
public User getUser(#PathVariable String login) throws IOException {
userService.insertRecord(login);
return userService.fetchUser(login);
}
}
My program works (more or less) as it's supposed to, BUT .insertRecord() method does not work at all. It basically does nothing. The method SHOULD check if the database already has a user of the given login. If yes - then it should proceed to update the record and increment the REQUEST_COUNT number by 1. If no - then it should create a new record of a given login and REQUEST_COUNT as 1. The table in my database has only two column - LOGIN and REUQEST_COUNT.
But that method literally does nothing, the table in my database remains untouched.
public void insertRecord(String login) {
//this part checks if there is a login like that in the database already
String sql = "select * from calls where LOGIN = ?";
PreparedStatement preparedStatement;
ResultSet resultSet;
try {
preparedStatement = getConnection().prepareStatement(sql);
preparedStatement.setString(1, login);
resultSet = preparedStatement.executeQuery();
//if there's a result - I am trying to increment the value of REQUEST_COUNT column by 1.
if (resultSet.next()) {
String updateSql = "update calls set REQUEST_COUNT = REQUEST_COUNT + 1 where login = ?";
PreparedStatement updatePreparedStatement;
try {
updatePreparedStatement = getConnection().prepareStatement(updateSql);
updatePreparedStatement.setString(1, login);
} catch (SQLException e) {
logger.error("Could not insert a record into the database.");
e.printStackTrace();
}
//if there is no result - I want to insert a new record.
} else {
String insertSql = "insert into calls (LOGIN, REQUEST_COUNT) values (?, ?)";
try (final PreparedStatement insertPreparedStatement = getConnection().prepareStatement(insertSql)) {
insertPreparedStatement.setString(1, login);
insertPreparedStatement.setInt(2, 1);
} catch (SQLException e) {
logger.error("Could not insert a record into the database.");
e.printStackTrace();
}
}
} catch (SQLException e) {
logger.error("Operation failed.");
e.printStackTrace();
}
}
No Logger's messages are printed either, it's as if the method was simply completely ignored.
Please, help.
Because you are not calling updatePreparedStatement.executeUpdate() !
The sql will only take effetc after you call executeUpdate().
You can put a filter that will execute before/after the endpoint executed. And in that particular filter, you can also track which endpoint is executed and take appropriate action for any specific endpoint.

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!

Java - How to delete an entity from Google Cloud Datastore

Architecture: I have a web application from where I'm interacting with the Datastore and a client (raspberry pi) which is calling methods from the web application using Google Cloud Endpoints.
I have to add that I'm not very familiar with web applications and I assume that something's wrong with the setConsumed() method because I can see the call of /create in the app engine dashboard but there's no entry for /setConsumed.
I'm able to add entities to the Datastore using objectify:
//client method
private static void sendSensorData(long index, String serialNumber) throws IOException {
SensorData data = new SensorData();
data.setId(index+1);
data.setSerialNumber(serialNumber);
sensor.create(data).execute();
}
//api method in the web application
#ApiMethod(name = "create", httpMethod = "post")
public SensorData create(SensorData data, User user) {
// check if user is authenticated and authorized
if (user == null) {
log.warning("User is not authenticated");
System.out.println("Trying to authenticate user...");
createUser(user);
// throw new RuntimeException("Authentication required!");
} else if (!Constants.EMAIL_ADDRESS.equals(user.getEmail())) {
log.warning("User is not authorised, email: " + user.getEmail());
throw new RuntimeException("Not authorised!");
}
data.save();
return data;
}
//method in entity class SensorData
public Key<SensorData> save() {
return ofy().save().entity(this).now();
}
However, I'm not able to delete an entity from the datastore using the following code.
EDIT: There are many logs of the create-request in Stackdriver Logging, but none of setConsumed(). So it seems like the calls don't even reach the API although both methods are in the same class.
EDIT 2: The entity gets removed when I invoke the method from the Powershell so the problem is most likely on client side.
//client method
private static void removeSensorData(long index) throws IOException {
sensor.setConsumed(index+1);
}
//api method in the web application
#ApiMethod(name = "setConsumed", httpMethod = "put")
public void setConsumed(#Named("id") Long id, User user) {
// check if user is authenticated and authorized
if (user == null) {
log.warning("User is not authenticated");
System.out.println("Trying to authenticate user...");
createUser(user);
// throw new RuntimeException("Authentication required!");
} else if (!Constants.EMAIL_ADDRESS.equals(user.getEmail())) {
log.warning("User is not authorised, email: " + user.getEmail());
throw new RuntimeException("Not authorised!");
}
Key serialKey = KeyFactory.createKey("SensorData", id);
datastore.delete(serialKey);
}
This is what I follow to delete an entity from datastore.
public boolean deleteEntity(String propertyValue) {
String entityName = "YOUR_ENTITY_NAME";
String gql = "SELECT * FROM "+entityName +" WHERE property= "+propertyValue+"";
Query<Entity> query = Query.newGqlQueryBuilder(Query.ResultType.ENTITY, gql)
.setAllowLiteral(true).build();
try{
QueryResults<Entity> results = ds.run(query);
if (results.hasNext()) {
Entity rs = results.next();
ds.delete(rs.getKey());
return true;
}
return false;
}catch(Exception e){
logger.error(e.getMessage());
return false;
}
}
If you don't want to use literals, you can also use binding as follows:
String gql = "SELECT * FROM "+entityName+" WHERE property1= #prop1 AND property2= #prop2";
Query<Entity> query = Query.newGqlQueryBuilder(Query.ResultType.ENTITY, gql)
.setBinding("prop1", propertyValue1)
.setBinding("prop2", propertyValue2)
.build();
Hope this helps.
I was able to solve it by myself finally!
The problem was just related to the data type of the index used for removeSensorData(long index) which came out of a for-loop and therefore was an Integer instead of a long.

Why is my setter called twice?

I am working on a REST web service, using JAX-RS, JPA and JAXB, for the management of games and their highscores. A game has the following properties: name, url and highscoreTableSize.
A short description of what I'm trying to do: I have the createRow() method in the controller which consumes JSON (the JSON serialization of a Game object, class Game being annotated with #XmlRootElement), which calls the static createRow() from the Game model class, and inside of it the setUrl() is called. The thing is that, for some reason, the setter is called twice.
Now what it happens is that, if the url sent in the body of the request is not valid against a pattern, after the "mysterious" first call it becomes null, and the second time the setter is called, it goes inside if (url == null), instead of going inside if (!matcher.matches()), when actually the latter is the real situation, because I've sent a mistyped URL.
Does anybody know why this is happening and how can I solve this?
Thank you in advance!
Class Game:
#Entity
#Table(name="games")
#XmlRootElement(name = "Game")
public class Game implements Serializable {
//properties
public void setUrl(String url) throws CustomWebServiceException {
String regex = "^(https?|ftp|file)://[-a-zA-Z0-9+&##/%?=~_|!:,.;]*[-a-zA-Z0-9+&##/%=~_|]";
Pattern pattern = Pattern.compile(regex);
System.out.println("URL: " + url);
if ( url == null || url.length() == 0) {
throw new CustomWebServiceException(Response.Status.BAD_REQUEST, new ErrorMessage("The url of the game is mandatory!"));
} else {
Matcher matcher = pattern.matcher(url);
if (!matcher.matches()) {
throw new CustomWebServiceException(Response.Status.BAD_REQUEST, new ErrorMessage("The url is invalid! Please check its syntax!"));
} else {
this.url = url;
}
}
}
public static Response createRow(EntityManager em, UserTransaction ut, String name, Game gameData) throws Exception {
ut.begin();
Game _game = em.find(Game.class, name);
if (_game != null) {
Util.tryRollback(ut);
ErrorMessage errorMessage = new ErrorMessage(
"The game with name " + name
+ " already exists in the database!");
throw new CustomWebServiceException(Response.Status.CONFLICT,
errorMessage);
}
String url = gameData.getUrl();
Integer highscoreTableSize = gameData.getHighscoreTableSize();
Game newGame = new Game();
newGame.setName(name);
newGame.setUrl(url);
newGame.setHighscoreTableSize(highscoreTableSize);
em.persist(newGame);
// force the persistence manager to save data to DB
ut.commit();
if (highscoreTableSize == null) {
highscoreTableSize = 7;
}
SuccessfulRequestMessage succesfulRequestMessage = new SuccessfulRequestMessage(
" Game entry created with name: " + name
+ ", url: " + url + " and highscoreTableSize: " + highscoreTableSize
+ ".");
return Response.status(Status.CREATED).entity(succesfulRequestMessage).type(MediaType.APPLICATION_JSON).build();
}
}
Controller:
#PUT
#Path("/{name}")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response createRow(
#PathParam("name") String name,
Game gameData) throws CustomWebServiceException {
try {
return Game.createRow(em, ut, name, gameData);
} catch (SystemException | NotSupportedException | IllegalStateException | SecurityException | HeuristicMixedException
| HeuristicRollbackException | RollbackException e) {
Util.tryRollback(ut);
ErrorMessage errorMessage = new ErrorMessage(
"Error when trying to create entry:" + e.toString()
+ " with message: " + e.getMessage());
throw new CustomWebServiceException(
Response.Status.INTERNAL_SERVER_ERROR, errorMessage);
} catch (CustomWebServiceException e) {
throw e;
} catch (Exception e) {
Util.tryRollback(ut);
ErrorMessage errorMessage = new ErrorMessage(
"During creation of game data, the following error(s) was(were) encountered: "
+ e.toString());
throw new CustomWebServiceException(Response.Status.BAD_REQUEST,
errorMessage);
}
}
Well, it should be called twice as per your code. Once during deserialization and once you do it yourself:
newGame.setUrl(url);
Using the same class for model and for representation is a bad idea in general.
IMHO,What you should do:
Separate your "JSON" game from the object you save in the database
Don't do validation in your setters. There is a Spring Validation for that. Use that to make sure that your JSON object is valid and then just go directly for the database.
You can use dozer to automatically convert model object to representation objects and vice versa
Edit:
Without using any libraries the easiest thing you can do is to move validation to a method in your controller:
void validateInput(Game game) throws Exception {
if (game == null) {
throw new Exception("Game object is not present in the request");
}
if (game.getUrl() == null || !game.maches({some-fancyreg-exp}) {
throw new Exception("Game URL is not valid");
}
//etc, check the rest of the fields
}
Call validateInput(game) in your controller. After that you can be sure that the input is valid. Quick and dirty. Let setters be setters.

Creating a web service in Java/Eclipse to get values from a database

I need to create a web service in Java using Eclipse. My requirement is to connect to a database with that web service and retrieve some values. Please send me at least one example program that shows how to achieve this. I have Googled, but the results I got didn't make things clear to me.
Hi #Rohith this is anatomy Web Services for connect to database,
#WebService(serviceName = "your_service_name")
public class YourClass {
public YourClass() {
super();
}
#WebMethod(operationName = "your_operation_name")
#WebResult(name = "your_response_name")
public YourDTORes your_method_name(#WebParam(name = "your") YourDTOReq request) {
YourDTORes response = new YourDTORes();
YourClassBD bd = null; // create a connection to database
Connection conn = null;
Statement st = null;
String sql = null;
try {
bd = new YourClassBD();
conn = bd.getYourMethodConnection();
sql = "select yourField from yourTable " +
"where yourField=2000 " +
"AND yourField = stuff";
st = conn.createStatement();
if(st.execute(sql)) {
ResultSet rs = st.getResultSet();
if(rs.next()) {
System.out.println("SUCCESS INSERT: " + rs.getString(1));
return response;
} else {
response.setMessageErr("ERROR.");
return response;
}
}
} catch(Exception e) {
response.setMessageErr("Service ERROR.");
e.printStackTrace();
return response;
}
return response;
}
}
The code above is a simple example for you connected to database. If you have problem let me know. Thxs.
I hope help you. :)
this is the sample for accessing database from jsp
http://www.roseindia.net/jsp/connect-jsp-mysql.shtml
with getting started to web services springboot is a margic. just dive in to http://start.spring.io then create a project with the dependencies (web, mysql, and jpa)
they also have sample projects that will help you get started with ease. consider checking youtube tutorials there are alot of resources there.

Categories

Resources