From 9c5e7aa3bfdec546740f0dc0d1a3befc36195e8e Mon Sep 17 00:00:00 2001 From: Norbert Schmitt Date: Tue, 10 Jul 2018 14:17:47 +0200 Subject: [PATCH 01/45] Bumped Version to v1.1.1-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9f116dc27..d76b0e6a2 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 - 1.1.0 + 1.1.1-SNAPSHOT From 585e7e9c501506580cfda0c97e5f645ac849b46e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3akim=20von=20Kistowski?= Date: Fri, 20 Jul 2018 13:23:49 +0200 Subject: [PATCH 02/45] added profile that changes database content --- examples/httploadgenerator/teastore_buy.lua | 95 +++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 examples/httploadgenerator/teastore_buy.lua diff --git a/examples/httploadgenerator/teastore_buy.lua b/examples/httploadgenerator/teastore_buy.lua new file mode 100644 index 000000000..adc113d34 --- /dev/null +++ b/examples/httploadgenerator/teastore_buy.lua @@ -0,0 +1,95 @@ +--[[ + teastore_browse profile. Sends cyclical requests to webui instance or front-end loadbalancer. + Browses store and updates shopping carts. + Does not perform any actions that would change the database. +--]] + +--[[ + Global Variables. Initialized at load driver startup. +--]] +prefix = "http://10.1.1.1:8080/tools.descartes.teastore.webui/" +productviewcount = 30 +postIndex = {3, 11, 13} + + +--[[ + Gets called at the beginning of each "call cycle", perform as much work as possible here. + Initialize all global variables here. + Note that math.random is already initialized using a fixed seed (5) for reproducibility. +--]] +function onCycle() + userpostfix = 1 + math.random(90) + calls = { + "", + "login", + --[[[POST]--]]"loginAction?username=user"..userpostfix.."&password=password", + --[[[POST]--]]"category?page=1&category=", + "product?id=", + --[[[POST]--]]"cartAction?addToCart=&productid=", + "category?page=1&category=", + "category?page=", + --[[[POST]--]]"cartAction?addToCart=&productid=", + "order", + --[[[POST]--]]"cartAction?firstname=User&lastname=User&address1=Road&address2=City&cardtype=volvo&cardnumber=314159265359&expirydate=12/2050&confirm=Confirm", + "profile", + --[[[POST]--]]"loginAction?logout=", + } +end + +--[[ + Gets called with ever increasing callnums for each http call until it returns nil. + Once it returns nil, onCycle() is called again and callnum is reset to 1 (Lua convention). + + Here, you can use our HTML helper functions for conditional calls on returned texts (usually HTML, thus the name). + We offer: + - html.getMatches( regex ) + Returns all lines in the returned text stream that match a provided regex. + - html.extractMatches( prefixRegex, postfixRegex ) + Returns all matches that are preceeded by a prefixRegex match and followed by a postfixRegex match. + The regexes must have one unique match for each line in which they apply. + - html.extractMatches( prefixRegex, matchingRegex, postfixRegex ) + Variant of extractMatches with a matching regex defining the string that is to be extracted. +--]] +function onCall(callnum) + if callnum == 2 then + local categoryids = html.extractMatches("href=.*category.*?category=","\\d+","&page=1.") + categoryid = categoryids[math.random(#categoryids)] + elseif callnum == 5 then + local productids = html.extractMatches("href=.*product.*?id=","\\d+",". >\\d+.*") + page = math.random(pagecount) + elseif callnum == 9 then + local productids = html.extractMatches("href=.*product.*?id=","\\d+",". > Date: Fri, 20 Jul 2018 15:32:35 +0200 Subject: [PATCH 03/45] Fixed warnings and made auth checkstyle compliant --- .../tools.descartes.teastore.auth/.checkstyle | 17 +- .../tools.descartes.teastore.auth/.classpath | 24 +- .../teastore/auth/rest/AuthCartREST.java | 121 ------ .../teastore/auth/rest/AuthCartRest.java | 135 +++++++ .../auth/rest/AuthUserActionsREST.java | 186 --------- .../auth/rest/AuthUserActionsRest.java | 189 +++++++++ .../auth/security/BCryptProvider.java | 6 +- .../auth/security/ConstantKeyProvider.java | 20 +- .../teastore/auth/security/IKeyProvider.java | 26 +- .../auth/security/ISecurityProvider.java | 51 ++- .../auth/security/ISessionIdGenerator.java | 13 +- .../security/RandomSessionIdGenerator.java | 13 +- .../auth/security/SHASecurityProvider.java | 77 ---- .../auth/security/ShaSecurityProvider.java | 78 ++++ .../teastore/auth/servlet/IndexServlet.java | 65 --- .../teastore/auth/startup/AuthStartup.java | 64 +-- .../auth/rest/AbstractStoreRestTest.java | 325 +++++++-------- .../teastore/auth/rest/CartTest.java | 380 +++++++++--------- .../teastore/auth/rest/EmptyAuthStartup.java | 68 ++-- .../teastore/auth/rest/LoginLogoutTest.java | 133 +++--- .../security/ConstantKeyProviderTest.java | 20 +- .../security/SHASecurityProviderTest.java | 35 -- .../security/ShaSecurityProviderTest.java | 35 ++ .../tools.descartes.teastore.image/.classpath | 12 +- .../.classpath | 18 +- .../.classpath | 24 +- .../tools.descartes.teastore.webui/.classpath | 12 +- .../server.xml | 1 + .../.classpath | 12 +- .../loadbalancers/ServiceLoadBalancer.java | 1 - 30 files changed, 1117 insertions(+), 1044 deletions(-) delete mode 100644 services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/rest/AuthCartREST.java create mode 100644 services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/rest/AuthCartRest.java delete mode 100644 services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/rest/AuthUserActionsREST.java create mode 100644 services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/rest/AuthUserActionsRest.java delete mode 100644 services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/SHASecurityProvider.java create mode 100644 services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/ShaSecurityProvider.java delete mode 100644 services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/servlet/IndexServlet.java delete mode 100644 services/tools.descartes.teastore.auth/src/test/java/tools/descartes/teastore/auth/security/SHASecurityProviderTest.java create mode 100644 services/tools.descartes.teastore.auth/src/test/java/tools/descartes/teastore/auth/security/ShaSecurityProviderTest.java diff --git a/services/tools.descartes.teastore.auth/.checkstyle b/services/tools.descartes.teastore.auth/.checkstyle index f65bf8d78..4f3e8dd10 100644 --- a/services/tools.descartes.teastore.auth/.checkstyle +++ b/services/tools.descartes.teastore.auth/.checkstyle @@ -1,7 +1,10 @@ - - - - - - - + + + + + + + + + + diff --git a/services/tools.descartes.teastore.auth/.classpath b/services/tools.descartes.teastore.auth/.classpath index ea8ef927d..692bc2913 100644 --- a/services/tools.descartes.teastore.auth/.classpath +++ b/services/tools.descartes.teastore.auth/.classpath @@ -33,9 +33,25 @@ - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/rest/AuthCartREST.java b/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/rest/AuthCartREST.java deleted file mode 100644 index 44f2df762..000000000 --- a/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/rest/AuthCartREST.java +++ /dev/null @@ -1,121 +0,0 @@ -/** - * 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 tools.descartes.teastore.auth.rest; - -import javax.ws.rs.Consumes; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.Response; - -import tools.descartes.teastore.entities.OrderItem; -import tools.descartes.teastore.entities.Product; -import tools.descartes.teastore.entities.message.SessionBlob; -import tools.descartes.teastore.registryclient.Service; -import tools.descartes.teastore.registryclient.rest.LoadBalancedCRUDOperations; -import tools.descartes.teastore.registryclient.util.NotFoundException; -import tools.descartes.teastore.registryclient.util.TimeoutException; -import tools.descartes.teastore.auth.security.SHASecurityProvider; - -/** - * Rest endpoint for the store cart. - * @author Simon - */ -@Path("cart") -@Produces({ "application/json" }) -@Consumes({ "application/json" }) -public class AuthCartREST { - - /** - * Adds product to cart. If the product is already in the cart the quantity is increased. - * @param blob Sessionblob - * @param pid productid - * @return Response containing session blob with updated cart - */ - @POST - @Path("add/{pid}") - public Response addProductToCart(SessionBlob blob, @PathParam("pid") final Long pid) { - Product product; - try { - product = LoadBalancedCRUDOperations.getEntity(Service.PERSISTENCE, "products", Product.class, pid); - } catch (TimeoutException e) { - return Response.status(408).build(); - } catch (NotFoundException e) { - return Response.status(404).build(); - } - - for (OrderItem oItem: blob.getOrderItems()) { - if (oItem.getProductId() == pid) { - oItem.setQuantity(oItem.getQuantity() + 1); - return Response.status(Response.Status.OK).entity(blob).build(); - } - } - OrderItem item = new OrderItem(); - item.setProductId(pid); - item.setQuantity(1); - item.setUnitPriceInCents(product.getListPriceInCents()); - blob.getOrderItems().add(item); - blob = new SHASecurityProvider().secure(blob); - return Response.status(Response.Status.OK).entity(blob).build(); - } - - /** - * Remove product from cart. - * @param blob Sessionblob - * @param pid product id - * @return Response containing Sessionblob with updated cart - */ - @POST - @Path("remove/{pid}") - public Response removeProductFromCart(SessionBlob blob, @PathParam("pid") final Long pid) { - OrderItem toRemove = null; - for (OrderItem item: blob.getOrderItems()) { - if (item.getProductId() == pid) { - toRemove = item; - } - } - if (toRemove != null) { - blob.getOrderItems().remove(toRemove); - blob = new SHASecurityProvider().secure(blob); - return Response.status(Response.Status.OK).entity(blob).build(); - } else { - return Response.status(Response.Status.NOT_FOUND).build(); - } - } - - /** - * Updates quantity of product in cart. - * @param blob Sessionblob - * @param pid Productid - * @param quantity New quantity - * @return Response containing Sessionblob with updated cart - */ - @PUT - @Path("{pid}") - public Response updateQuantity(SessionBlob blob, @PathParam("pid") final Long pid, - @QueryParam("quantity") int quantity) { - for (OrderItem item: blob.getOrderItems()) { - if (item.getProductId() == pid) { - item.setQuantity(quantity); - blob = new SHASecurityProvider().secure(blob); - return Response.status(Response.Status.OK).entity(blob).build(); - } - } - return Response.status(Response.Status.NOT_FOUND).build(); - } - -} diff --git a/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/rest/AuthCartRest.java b/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/rest/AuthCartRest.java new file mode 100644 index 000000000..e770fab65 --- /dev/null +++ b/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/rest/AuthCartRest.java @@ -0,0 +1,135 @@ +/** + * 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 tools.descartes.teastore.auth.rest; + +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Response; + +import tools.descartes.teastore.auth.security.ShaSecurityProvider; +import tools.descartes.teastore.entities.OrderItem; +import tools.descartes.teastore.entities.Product; +import tools.descartes.teastore.entities.message.SessionBlob; +import tools.descartes.teastore.registryclient.Service; +import tools.descartes.teastore.registryclient.rest.LoadBalancedCRUDOperations; +import tools.descartes.teastore.registryclient.util.NotFoundException; +import tools.descartes.teastore.registryclient.util.TimeoutException; + +/** + * Rest endpoint for the store cart. + * + * @author Simon + */ +@Path("cart") +@Produces({ "application/json" }) +@Consumes({ "application/json" }) +public class AuthCartRest { + + /** + * Adds product to cart. If the product is already in the cart the quantity is + * increased. + * + * @param blob + * Sessionblob + * @param pid + * productid + * @return Response containing session blob with updated cart + */ + @POST + @Path("add/{pid}") + public Response addProductToCart(SessionBlob blob, @PathParam("pid") final Long pid) { + Product product; + try { + product = LoadBalancedCRUDOperations.getEntity(Service.PERSISTENCE, "products", Product.class, + pid); + } catch (TimeoutException e) { + return Response.status(408).build(); + } catch (NotFoundException e) { + return Response.status(404).build(); + } + + for (OrderItem orderItem : blob.getOrderItems()) { + if (orderItem.getProductId() == pid) { + orderItem.setQuantity(orderItem.getQuantity() + 1); + return Response.status(Response.Status.OK).entity(blob).build(); + } + } + OrderItem item = new OrderItem(); + item.setProductId(pid); + item.setQuantity(1); + item.setUnitPriceInCents(product.getListPriceInCents()); + blob.getOrderItems().add(item); + blob = new ShaSecurityProvider().secure(blob); + return Response.status(Response.Status.OK).entity(blob).build(); + } + + /** + * Remove product from cart. + * + * @param blob + * Sessionblob + * @param pid + * product id + * @return Response containing Sessionblob with updated cart + */ + @POST + @Path("remove/{pid}") + public Response removeProductFromCart(SessionBlob blob, @PathParam("pid") final Long pid) { + OrderItem toRemove = null; + for (OrderItem item : blob.getOrderItems()) { + if (item.getProductId() == pid) { + toRemove = item; + } + } + if (toRemove != null) { + blob.getOrderItems().remove(toRemove); + blob = new ShaSecurityProvider().secure(blob); + return Response.status(Response.Status.OK).entity(blob).build(); + } else { + return Response.status(Response.Status.NOT_FOUND).build(); + } + } + + /** + * Updates quantity of product in cart. + * + * @param blob + * Sessionblob + * @param pid + * Productid + * @param quantity + * New quantity + * @return Response containing Sessionblob with updated cart + */ + @PUT + @Path("{pid}") + public Response updateQuantity(SessionBlob blob, @PathParam("pid") final Long pid, + @QueryParam("quantity") int quantity) { + for (OrderItem item : blob.getOrderItems()) { + if (item.getProductId() == pid) { + item.setQuantity(quantity); + blob = new ShaSecurityProvider().secure(blob); + return Response.status(Response.Status.OK).entity(blob).build(); + } + } + return Response.status(Response.Status.NOT_FOUND).build(); + } + +} diff --git a/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/rest/AuthUserActionsREST.java b/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/rest/AuthUserActionsREST.java deleted file mode 100644 index 0de077a04..000000000 --- a/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/rest/AuthUserActionsREST.java +++ /dev/null @@ -1,186 +0,0 @@ -/** - * 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 tools.descartes.teastore.auth.rest; - -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; - -import javax.ws.rs.Consumes; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.Response; - -import tools.descartes.teastore.entities.Order; -import tools.descartes.teastore.entities.OrderItem; -import tools.descartes.teastore.entities.User; -import tools.descartes.teastore.entities.message.SessionBlob; -import tools.descartes.teastore.registryclient.Service; -import tools.descartes.teastore.registryclient.loadbalancers.LoadBalancerTimeoutException; -import tools.descartes.teastore.registryclient.rest.LoadBalancedCRUDOperations; -import tools.descartes.teastore.registryclient.util.NotFoundException; -import tools.descartes.teastore.registryclient.util.TimeoutException; -import tools.descartes.teastore.auth.security.BCryptProvider; -import tools.descartes.teastore.auth.security.RandomSessionIdGenerator; -import tools.descartes.teastore.auth.security.SHASecurityProvider; - -/** - * Rest endpoint for the store user actions. - * - * @author Simon - */ -@Path("useractions") -@Produces({ "application/json" }) -@Consumes({ "application/json" }) -public class AuthUserActionsREST { - - /** - * - * Persists order in database. - * - * @param blob - * SessionBlob - * @param totalPriceInCents - * totalPrice - * @param addressName - * address - * @param address1 - * address - * @param address2 - * address - * @param creditCardCompany - * creditcard - * @param creditCardNumber - * creditcard - * @param creditCardExpiryDate - * creditcard - * @return Response containing SessionBlob - */ - @POST - @Path("placeorder") - public Response placeOrder(SessionBlob blob, @QueryParam("totalPriceInCents") long totalPriceInCents, - @QueryParam("addressName") String addressName, @QueryParam("address1") String address1, - @QueryParam("address2") String address2, @QueryParam("creditCardCompany") String creditCardCompany, - @QueryParam("creditCardNumber") String creditCardNumber, - @QueryParam("creditCardExpiryDate") String creditCardExpiryDate) { - if (new SHASecurityProvider().validate(blob) == null || blob.getOrderItems().isEmpty()) { - return Response.status(Response.Status.NOT_FOUND).build(); - } - - blob.getOrder().setUserId(blob.getUID()); - blob.getOrder().setTotalPriceInCents(totalPriceInCents); - blob.getOrder().setAddressName(addressName); - blob.getOrder().setAddress1(address1); - blob.getOrder().setAddress2(address2); - blob.getOrder().setCreditCardCompany(creditCardCompany); - blob.getOrder().setCreditCardExpiryDate(creditCardExpiryDate); - blob.getOrder().setCreditCardNumber(creditCardNumber); - blob.getOrder().setTime(LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)); - - long orderId; - try { - orderId = LoadBalancedCRUDOperations.sendEntityForCreation(Service.PERSISTENCE, "orders", Order.class, - blob.getOrder()); - } catch (LoadBalancerTimeoutException e) { - return Response.status(408).build(); - } catch (NotFoundException e) { - return Response.status(404).build(); - } - for (OrderItem item : blob.getOrderItems()) { - try { - item.setOrderId(orderId); - LoadBalancedCRUDOperations.sendEntityForCreation(Service.PERSISTENCE, "orderitems", OrderItem.class, - item); - } catch (TimeoutException e) { - return Response.status(408).build(); - } catch (NotFoundException e) { - return Response.status(404).build(); - } - } - blob.setOrder(new Order()); - blob.getOrderItems().clear(); - blob = new SHASecurityProvider().secure(blob); - return Response.status(Response.Status.OK).entity(blob).build(); - } - - /** - * User login. - * - * @param blob - * SessionBlob - * @param name - * Username - * @param password - * password - * @return Response with SessionBlob containing login information. - */ - @POST - @Path("login") - public Response login(SessionBlob blob, @QueryParam("name") String name, @QueryParam("password") String password) { - User user; - try { - user = LoadBalancedCRUDOperations.getEntityWithProperties(Service.PERSISTENCE, "users", User.class, "name", - name); - } catch (TimeoutException e) { - return Response.status(408).build(); - } catch (NotFoundException e) { - return Response.status(Response.Status.OK).entity(blob).build(); - } - long tic = System.currentTimeMillis(); - while (System.currentTimeMillis() - tic < 1500) { - } - - if (user != null -// && BCryptProvider.checkPassword(password, user.getPassword()) - ) { - blob.setUID(user.getId()); - blob.setSID(new RandomSessionIdGenerator().getSessionID()); - blob = new SHASecurityProvider().secure(blob); - return Response.status(Response.Status.OK).entity(blob).build(); - } - return Response.status(Response.Status.OK).entity(blob).build(); - } - - /** - * User logout. - * - * @param blob - * SessionBlob - * @return Response with SessionBlob - */ - @POST - @Path("logout") - public Response logout(SessionBlob blob) { - blob.setUID(null); - blob.setSID(null); - blob.setOrder(new Order()); - blob.getOrderItems().clear(); - return Response.status(Response.Status.OK).entity(blob).build(); - } - - /** - * Checks if user is logged in. - * - * @param blob - * Sessionblob - * @return Response with true if logged in - */ - @POST - @Path("isloggedin") - public Response isLoggedIn(SessionBlob blob) { - return Response.status(Response.Status.OK).entity(new SHASecurityProvider().validate(blob)).build(); - } - -} diff --git a/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/rest/AuthUserActionsRest.java b/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/rest/AuthUserActionsRest.java new file mode 100644 index 000000000..1b84253ac --- /dev/null +++ b/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/rest/AuthUserActionsRest.java @@ -0,0 +1,189 @@ +/** + * 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 tools.descartes.teastore.auth.rest; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Response; + +import tools.descartes.teastore.auth.security.RandomSessionIdGenerator; +import tools.descartes.teastore.auth.security.ShaSecurityProvider; +import tools.descartes.teastore.entities.Order; +import tools.descartes.teastore.entities.OrderItem; +import tools.descartes.teastore.entities.User; +import tools.descartes.teastore.entities.message.SessionBlob; +import tools.descartes.teastore.registryclient.Service; +import tools.descartes.teastore.registryclient.loadbalancers.LoadBalancerTimeoutException; +import tools.descartes.teastore.registryclient.rest.LoadBalancedCRUDOperations; +import tools.descartes.teastore.registryclient.util.NotFoundException; +import tools.descartes.teastore.registryclient.util.TimeoutException; + +/** + * Rest endpoint for the store user actions. + * + * @author Simon + */ +@Path("useractions") +@Produces({ "application/json" }) +@Consumes({ "application/json" }) +public class AuthUserActionsRest { + + /** + * Persists order in database. + * + * @param blob + * SessionBlob + * @param totalPriceInCents + * totalPrice + * @param addressName + * address + * @param address1 + * address + * @param address2 + * address + * @param creditCardCompany + * creditcard + * @param creditCardNumber + * creditcard + * @param creditCardExpiryDate + * creditcard + * @return Response containing SessionBlob + */ + @POST + @Path("placeorder") + public Response placeOrder(SessionBlob blob, + @QueryParam("totalPriceInCents") long totalPriceInCents, + @QueryParam("addressName") String addressName, @QueryParam("address1") String address1, + @QueryParam("address2") String address2, + @QueryParam("creditCardCompany") String creditCardCompany, + @QueryParam("creditCardNumber") String creditCardNumber, + @QueryParam("creditCardExpiryDate") String creditCardExpiryDate) { + if (new ShaSecurityProvider().validate(blob) == null || blob.getOrderItems().isEmpty()) { + return Response.status(Response.Status.NOT_FOUND).build(); + } + + blob.getOrder().setUserId(blob.getUID()); + blob.getOrder().setTotalPriceInCents(totalPriceInCents); + blob.getOrder().setAddressName(addressName); + blob.getOrder().setAddress1(address1); + blob.getOrder().setAddress2(address2); + blob.getOrder().setCreditCardCompany(creditCardCompany); + blob.getOrder().setCreditCardExpiryDate(creditCardExpiryDate); + blob.getOrder().setCreditCardNumber(creditCardNumber); + blob.getOrder().setTime(LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)); + + long orderId; + try { + orderId = LoadBalancedCRUDOperations.sendEntityForCreation(Service.PERSISTENCE, "orders", + Order.class, blob.getOrder()); + } catch (LoadBalancerTimeoutException e) { + return Response.status(408).build(); + } catch (NotFoundException e) { + return Response.status(404).build(); + } + for (OrderItem item : blob.getOrderItems()) { + try { + item.setOrderId(orderId); + LoadBalancedCRUDOperations.sendEntityForCreation(Service.PERSISTENCE, "orderitems", + OrderItem.class, item); + } catch (TimeoutException e) { + return Response.status(408).build(); + } catch (NotFoundException e) { + return Response.status(404).build(); + } + } + blob.setOrder(new Order()); + blob.getOrderItems().clear(); + blob = new ShaSecurityProvider().secure(blob); + return Response.status(Response.Status.OK).entity(blob).build(); + } + + /** + * User login. + * + * @param blob + * SessionBlob + * @param name + * Username + * @param password + * password + * @return Response with SessionBlob containing login information. + */ + @POST + @Path("login") + public Response login(SessionBlob blob, @QueryParam("name") String name, + @QueryParam("password") String password) { + User user; + try { + user = LoadBalancedCRUDOperations.getEntityWithProperties(Service.PERSISTENCE, "users", + User.class, "name", name); + } catch (TimeoutException e) { + return Response.status(408).build(); + } catch (NotFoundException e) { + return Response.status(Response.Status.OK).entity(blob).build(); + } + long tic = System.currentTimeMillis(); + while (System.currentTimeMillis() - tic < 1500) { + } + + if (user != null + // && BCryptProvider.checkPassword(password, user.getPassword()) + ) { + blob.setUID(user.getId()); + blob.setSID(new RandomSessionIdGenerator().getSessionId()); + blob = new ShaSecurityProvider().secure(blob); + return Response.status(Response.Status.OK).entity(blob).build(); + } + return Response.status(Response.Status.OK).entity(blob).build(); + } + + /** + * User logout. + * + * @param blob + * SessionBlob + * @return Response with SessionBlob + */ + @POST + @Path("logout") + public Response logout(SessionBlob blob) { + blob.setUID(null); + blob.setSID(null); + blob.setOrder(new Order()); + blob.getOrderItems().clear(); + return Response.status(Response.Status.OK).entity(blob).build(); + } + + /** + * Checks if user is logged in. + * + * @param blob + * Sessionblob + * @return Response with true if logged in + */ + @POST + @Path("isloggedin") + public Response isLoggedIn(SessionBlob blob) { + return Response.status(Response.Status.OK).entity(new ShaSecurityProvider().validate(blob)) + .build(); + } + +} diff --git a/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/BCryptProvider.java b/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/BCryptProvider.java index ee7bf6f85..e8e287e43 100644 --- a/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/BCryptProvider.java +++ b/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/BCryptProvider.java @@ -4,7 +4,7 @@ public class BCryptProvider { - public static boolean checkPassword(String password, String password2) { - return BCrypt.checkpw(password, password2); - } + public static boolean checkPassword(String password, String password2) { + return BCrypt.checkpw(password, password2); + } } diff --git a/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/ConstantKeyProvider.java b/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/ConstantKeyProvider.java index 1a1550161..9abf5a002 100644 --- a/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/ConstantKeyProvider.java +++ b/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/ConstantKeyProvider.java @@ -11,24 +11,26 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package tools.descartes.teastore.auth.security; import tools.descartes.teastore.entities.message.SessionBlob; /** - * Class for testing. Provides a constant key. - * DO NOT ADOPT THIS FOR ANY REAL PRODUCTION WORKLOAD! + * Class for testing. Provides a constant key. DO NOT ADOPT THIS FOR ANY REAL + * PRODUCTION WORKLOAD! + * * @author Joakim von Kistowski * */ public class ConstantKeyProvider implements IKeyProvider { - /** - * {@inheritDoc} - */ - @Override - public String getKey(SessionBlob blob) { - return "thebestsecretkey"; - } + /** + * {@inheritDoc} + */ + @Override + public String getKey(SessionBlob blob) { + return "thebestsecretkey"; + } } diff --git a/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/IKeyProvider.java b/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/IKeyProvider.java index 019781479..87ca1bb1a 100644 --- a/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/IKeyProvider.java +++ b/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/IKeyProvider.java @@ -11,26 +11,28 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package tools.descartes.teastore.auth.security; import tools.descartes.teastore.entities.message.SessionBlob; /** - * Provides keys for the security provider. - * The key provider must ensure that keys accross - * replicated stores are consistent. + * Provides keys for the security provider. The key provider must ensure that + * keys accross replicated stores are consistent. + * * @author Joakim von Kistowski * */ public interface IKeyProvider { - /** - * Returns a key for a session blob. - * Key must be the same, regardless of the - * store instance upon which this call is made. - * @param blob The blob to secure. - * @return The key. - */ - public String getKey(SessionBlob blob); - + /** + * Returns a key for a session blob. Key must be the same, regardless of the + * store instance upon which this call is made. + * + * @param blob + * The blob to secure. + * @return The key. + */ + public String getKey(SessionBlob blob); + } diff --git a/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/ISecurityProvider.java b/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/ISecurityProvider.java index 7209b3965..0c4e2e493 100644 --- a/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/ISecurityProvider.java +++ b/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/ISecurityProvider.java @@ -11,37 +11,44 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package tools.descartes.teastore.auth.security; import tools.descartes.teastore.entities.message.SessionBlob; /** * Utilities for securing (e.g. encrypting) session blobs. + * * @author Joakim von Kistowski * */ public interface ISecurityProvider { - /** - * Get the key provider for this security provider. - * @return The key provider. - */ - public IKeyProvider getKeyProvider(); - - /** - * Secures a session blob. May encrypt or hash values within the blob. - * @param blob The blob to secure. - * @return A secure blob to be passed on to the web ui. - */ - public SessionBlob secure(SessionBlob blob); - - /** - * Validates a secured session blob. Returns a valid and - * readable (e.g. decrypted) blob. Returns null for invalid blobs. - * @param blob The blob to secure. - * @return The valid and - * readable (e.g. decrypted) blob. Returns null for invalid blobs. - */ - public SessionBlob validate(SessionBlob blob); - + /** + * Get the key provider for this security provider. + * + * @return The key provider. + */ + public IKeyProvider getKeyProvider(); + + /** + * Secures a session blob. May encrypt or hash values within the blob. + * + * @param blob + * The blob to secure. + * @return A secure blob to be passed on to the web ui. + */ + public SessionBlob secure(SessionBlob blob); + + /** + * Validates a secured session blob. Returns a valid and readable (e.g. + * decrypted) blob. Returns null for invalid blobs. + * + * @param blob + * The blob to secure. + * @return The valid and readable (e.g. decrypted) blob. Returns null for + * invalid blobs. + */ + public SessionBlob validate(SessionBlob blob); + } diff --git a/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/ISessionIdGenerator.java b/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/ISessionIdGenerator.java index cca55ee0d..073725260 100644 --- a/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/ISessionIdGenerator.java +++ b/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/ISessionIdGenerator.java @@ -1,14 +1,17 @@ package tools.descartes.teastore.auth.security; + /** * Generator for Session ids. + * * @author Simon * */ public interface ISessionIdGenerator { - /** - * Generates session id. - * @return session id - */ - public String getSessionID(); + /** + * Generates session id. + * + * @return session id + */ + public String getSessionId(); } diff --git a/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/RandomSessionIdGenerator.java b/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/RandomSessionIdGenerator.java index 603fbf2f9..d4fbda3da 100644 --- a/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/RandomSessionIdGenerator.java +++ b/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/RandomSessionIdGenerator.java @@ -4,16 +4,17 @@ /** * Generates random session id. + * * @author Simon * */ public class RandomSessionIdGenerator implements ISessionIdGenerator { - private static Random random = new Random(); - - @Override - public String getSessionID() { - return "" + random.nextInt(); - } + private static Random random = new Random(); + + @Override + public String getSessionId() { + return "" + random.nextInt(); + } } diff --git a/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/SHASecurityProvider.java b/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/SHASecurityProvider.java deleted file mode 100644 index 05c5554a1..000000000 --- a/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/SHASecurityProvider.java +++ /dev/null @@ -1,77 +0,0 @@ -package tools.descartes.teastore.auth.security; - -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; - -import tools.descartes.teastore.entities.message.SessionBlob; - -/** - * Secruity provider using AES. - * @author Simon - * - */ -public class SHASecurityProvider implements ISecurityProvider { - - @Override - public IKeyProvider getKeyProvider() { - return new ConstantKeyProvider(); - } - - @Override - public SessionBlob secure(SessionBlob blob) { - if (blob.getUID() == null || blob.getSID() == null) { - return blob; - } - blob.setToken(null); - String blobString = blobToString(blob); - blob.setToken(getSHA512(blobString)); - return blob; - } - - private String blobToString(SessionBlob blob) { - ObjectMapper o = new ObjectMapper(); - try { - return URLEncoder.encode(o.writeValueAsString(blob), "UTF-8"); - } catch (JsonProcessingException | UnsupportedEncodingException e) { - throw new IllegalStateException("Could not save blob!"); - } - } - - @Override - public SessionBlob validate(SessionBlob blob) { - if (blob.getToken() == null) { - return null; - } - - String token = blob.getToken(); - blob.setToken(null); - String blobString = blobToString(blob); - String validationToken = getSHA512(blobString); - if (validationToken.equals(token)) { - return blob; - } - return null; - } - - private String getSHA512(String passwordToHash) { - String generatedPassword = null; - try { - String salt = getKeyProvider().getKey(null); - MessageDigest md = MessageDigest.getInstance("SHA-512"); - md.update(salt.getBytes("UTF-8")); - byte[] bytes = md.digest(passwordToHash.getBytes("UTF-8")); - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < bytes.length; i++) { - sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1)); - } - generatedPassword = sb.toString(); - } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { - e.printStackTrace(); - } - return generatedPassword; - } -} diff --git a/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/ShaSecurityProvider.java b/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/ShaSecurityProvider.java new file mode 100644 index 000000000..c3730f199 --- /dev/null +++ b/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/security/ShaSecurityProvider.java @@ -0,0 +1,78 @@ +package tools.descartes.teastore.auth.security; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import tools.descartes.teastore.entities.message.SessionBlob; + +/** + * Secruity provider using AES. + * + * @author Simon + * + */ +public class ShaSecurityProvider implements ISecurityProvider { + + @Override + public IKeyProvider getKeyProvider() { + return new ConstantKeyProvider(); + } + + @Override + public SessionBlob secure(SessionBlob blob) { + if (blob.getUID() == null || blob.getSID() == null) { + return blob; + } + blob.setToken(null); + String blobString = blobToString(blob); + blob.setToken(getSha512(blobString)); + return blob; + } + + private String blobToString(SessionBlob blob) { + ObjectMapper o = new ObjectMapper(); + try { + return URLEncoder.encode(o.writeValueAsString(blob), "UTF-8"); + } catch (JsonProcessingException | UnsupportedEncodingException e) { + throw new IllegalStateException("Could not save blob!"); + } + } + + @Override + public SessionBlob validate(SessionBlob blob) { + if (blob.getToken() == null) { + return null; + } + + String token = blob.getToken(); + blob.setToken(null); + String blobString = blobToString(blob); + String validationToken = getSha512(blobString); + if (validationToken.equals(token)) { + return blob; + } + return null; + } + + private String getSha512(String passwordToHash) { + String generatedPassword = null; + try { + String salt = getKeyProvider().getKey(null); + MessageDigest md = MessageDigest.getInstance("SHA-512"); + md.update(salt.getBytes("UTF-8")); + byte[] bytes = md.digest(passwordToHash.getBytes("UTF-8")); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < bytes.length; i++) { + sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1)); + } + generatedPassword = sb.toString(); + } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { + e.printStackTrace(); + } + return generatedPassword; + } +} diff --git a/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/servlet/IndexServlet.java b/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/servlet/IndexServlet.java deleted file mode 100644 index 0c97a7b61..000000000 --- a/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/servlet/IndexServlet.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * 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 tools.descartes.teastore.auth.servlet; - -import java.io.IOException; -import javax.servlet.ServletException; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * Index Servlet for Persistence. Provides some basic debug information for - * deployers and testers. - * @author Joakim von Kistowski - */ -@WebServlet("/index") -public class IndexServlet extends HttpServlet { - private static final long serialVersionUID = 1L; - - /** - * @see HttpServlet#HttpServlet() - */ - public IndexServlet() { - super(); - } - - /** - * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) - * @param request The request. - * @param response The response. - * @throws ServletException In case of servlet Exception. - * @throws IOException In case of IOException. - */ - protected void doGet(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - response.getWriter().println("This is the auth module running at " - + request.getProtocol() + "://" + request.getLocalAddr() + ":" - + request.getLocalPort() + "/" + request.getContextPath()); - } - - /** - * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) - * @param request The request. - * @param response The response. - * @throws ServletException In case of servlet Exception. - * @throws IOException In case of IOException. - */ - protected void doPost(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - doGet(request, response); - } - -} diff --git a/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/startup/AuthStartup.java b/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/startup/AuthStartup.java index 57058ea50..49d8f64ec 100644 --- a/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/startup/AuthStartup.java +++ b/services/tools.descartes.teastore.auth/src/main/java/tools/descartes/teastore/auth/startup/AuthStartup.java @@ -11,6 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package tools.descartes.teastore.auth.startup; import javax.servlet.ServletContextEvent; @@ -24,41 +25,44 @@ /** * Application Lifecycle Listener implementation class Registry Client Startup. + * * @author Simon Eismann * */ @WebListener public class AuthStartup implements ServletContextListener { - - private static final int REST_READ_TIMOUT = 1750; - - /** - * Also set this accordingly in RegistryClientStartup. - */ - - /** - * Empty constructor. - */ - public AuthStartup() { - - } - /** - * @see ServletContextListener#contextDestroyed(ServletContextEvent) - * @param arg0 The servlet context event at destruction. - */ - public void contextDestroyed(ServletContextEvent event) { - RegistryClient.getClient().unregister(event.getServletContext().getContextPath()); - } + private static final int REST_READ_TIMOUT = 1750; + + /** + * Also set this accordingly in RegistryClientStartup. + */ + + /** + * Empty constructor. + */ + public AuthStartup() { + + } + + /** + * shutdown routine. + * @see ServletContextListener#contextDestroyed(ServletContextEvent) + * @param event The servlet context event at destruction. + */ + public void contextDestroyed(ServletContextEvent event) { + RegistryClient.getClient().unregister(event.getServletContext().getContextPath()); + } + + /** + * startup routine. + * @see ServletContextListener#contextInitialized(ServletContextEvent) + * @param event The servlet context event at initialization. + */ + public void contextInitialized(ServletContextEvent event) { + RESTClient.setGlobalReadTimeout(REST_READ_TIMOUT); + ServiceLoadBalancer.preInitializeServiceLoadBalancers(Service.PERSISTENCE, Service.RECOMMENDER); + RegistryClient.getClient().register(event.getServletContext().getContextPath()); + } - /** - * @see ServletContextListener#contextInitialized(ServletContextEvent) - * @param arg0 The servlet context event at initialization. - */ - public void contextInitialized(ServletContextEvent event) { - RESTClient.setGlobalReadTimeout(REST_READ_TIMOUT); - ServiceLoadBalancer.preInitializeServiceLoadBalancers(Service.PERSISTENCE, Service.RECOMMENDER); - RegistryClient.getClient().register(event.getServletContext().getContextPath()); - } - } diff --git a/services/tools.descartes.teastore.auth/src/test/java/tools/descartes/teastore/auth/rest/AbstractStoreRestTest.java b/services/tools.descartes.teastore.auth/src/test/java/tools/descartes/teastore/auth/rest/AbstractStoreRestTest.java index 9fa9d322a..8e2f0d09f 100644 --- a/services/tools.descartes.teastore.auth/src/test/java/tools/descartes/teastore/auth/rest/AbstractStoreRestTest.java +++ b/services/tools.descartes.teastore.auth/src/test/java/tools/descartes/teastore/auth/rest/AbstractStoreRestTest.java @@ -5,6 +5,10 @@ import static com.github.tomakehurst.wiremock.client.WireMock.post; import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.tomakehurst.wiremock.client.WireMock; +import com.github.tomakehurst.wiremock.junit.WireMockRule; import java.util.HashMap; import java.util.LinkedList; import java.util.List; @@ -22,174 +26,175 @@ import org.junit.After; import org.junit.Before; import org.junit.Rule; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.github.tomakehurst.wiremock.client.WireMock; -import com.github.tomakehurst.wiremock.junit.WireMockRule; +import tools.descartes.teastore.auth.rest.AuthCartRest; +import tools.descartes.teastore.auth.rest.AuthUserActionsRest; import tools.descartes.teastore.entities.Category; import tools.descartes.teastore.entities.Product; import tools.descartes.teastore.registryclient.Service; -import tools.descartes.teastore.auth.rest.AuthCartREST; -import tools.descartes.teastore.auth.rest.AuthUserActionsREST; - - /** * Abstract base for testing of the stores rest functionality. + * * @author Simon * */ public abstract class AbstractStoreRestTest { - @Rule - public WireMockRule wireMockRule = new WireMockRule(18080); - - private Tomcat storeTomcat; - private String testWorkingDir = System.getProperty("java.io.tmpdir"); - /** - * Sets up a store. - * @throws Throwable Throws uncaught throwables for test to fail. - */ - @Before - public void setup() throws Throwable { - BasicConfigurator.configure(); - - storeTomcat = new Tomcat(); - storeTomcat.setPort(3000); - storeTomcat.setBaseDir(testWorkingDir); - storeTomcat.enableNaming(); - Context context3 = storeTomcat.addWebapp("/tools.descartes.teastore.auth", testWorkingDir); - ContextEnvironment registryURL3 = new ContextEnvironment(); - registryURL3.setDescription(""); - registryURL3.setOverride(false); - registryURL3.setType("java.lang.String"); - registryURL3.setName("registryURL"); - registryURL3.setValue("http://localhost:18080/tools.descartes.teastore.registry/rest/services/"); - context3.getNamingResources().addEnvironment(registryURL3); - ContextEnvironment servicePort3 = new ContextEnvironment(); - servicePort3.setDescription(""); - servicePort3.setOverride(false); - servicePort3.setType("java.lang.String"); - servicePort3.setName("servicePort"); - servicePort3.setValue("3000"); - context3.getNamingResources().addEnvironment(servicePort3); - ResourceConfig restServletConfig3 = new ResourceConfig(); - restServletConfig3.register(AuthCartREST.class); - restServletConfig3.register(AuthUserActionsREST.class); - ServletContainer restServlet3 = new ServletContainer(restServletConfig3); - storeTomcat.addServlet("/tools.descartes.teastore.auth", "restServlet", restServlet3); - context3.addServletMappingDecoded("/rest/*", "restServlet"); - context3.addApplicationListener(EmptyAuthStartup.class.getName()); - - // Mock registry - List strings = new LinkedList(); - strings.add("localhost:18080"); - String json = new ObjectMapper().writeValueAsString(strings); - List strings2 = new LinkedList(); - strings2.add("localhost:3000"); - String json2 = new ObjectMapper().writeValueAsString(strings2); - wireMockRule.stubFor(get(urlEqualTo( - "/tools.descartes.teastore.registry/rest/services/" + Service.IMAGE.getServiceName() + "/")) - .willReturn(okJson(json))); - wireMockRule.stubFor(get(urlEqualTo( - "/tools.descartes.teastore.registry/rest/services/" + Service.AUTH.getServiceName() + "/")) - .willReturn(okJson(json2))); - wireMockRule.stubFor(WireMock.put(WireMock.urlMatching( - "/tools.descartes.teastore.registry/rest/services/" + Service.AUTH.getServiceName() + "/.*")) - .willReturn(okJson(json2))); - wireMockRule.stubFor(WireMock.delete(WireMock.urlMatching( - "/tools.descartes.teastore.registry/rest/services/" + Service.AUTH.getServiceName() + "/.*")) - .willReturn(okJson(json2))); - wireMockRule.stubFor(get(urlEqualTo( - "/tools.descartes.teastore.registry/rest/services/" + Service.PERSISTENCE.getServiceName() + "/")) - .willReturn(okJson(json))); - wireMockRule.stubFor(get(urlEqualTo( - "/tools.descartes.teastore.registry/rest/services/" + Service.RECOMMENDER.getServiceName() + "/")) - .willReturn(okJson(json))); - - // Mock images - HashMap img = new HashMap<>(); - img.put("andreBauer", "andreBauer"); - img.put("johannesGrohmann", "johannesGrohmann"); - img.put("joakimKistowski", "joakimKistowski"); - img.put("simonEismann", "simonEismann"); - img.put("norbertSchmitt", "norbertSchmitt"); - img.put("descartesLogo", "descartesLogo"); - img.put("icon", "icon"); - mockValidPostRestCall(img, "/tools.descartes.teastore.image/rest/image/getWebImages"); - - storeTomcat.start(); - } - - /** - * Dismantles the embedded Tomcat. - * @throws Throwable Throws uncaught throwables for test to fail. - */ - @After - public void dismantle() throws Throwable { - if (storeTomcat.getServer() != null && storeTomcat.getServer().getState() != LifecycleState.DESTROYED) { - if (storeTomcat.getServer().getState() != LifecycleState.STOPPED) { - storeTomcat.stop(); - } - storeTomcat.destroy(); - } - } - - protected void mockValidPostRestCall(Object input, String path) { - try { - wireMockRule - .stubFor(post(urlEqualTo(path)).willReturn(okJson(new ObjectMapper().writeValueAsString(input)))); - } catch (JsonProcessingException e) { - e.printStackTrace(); - } - } - - protected void mockInValidGetRestCall(Status status, String path) { - wireMockRule.stubFor(get(urlEqualTo(path)).willReturn(WireMock.status(status.getStatusCode()))); - } - - protected void mockValidGetRestCall(Object input, String path) { - try { - wireMockRule - .stubFor(get(urlEqualTo(path)).willReturn(okJson(new ObjectMapper().writeValueAsString(input)))); - } catch (JsonProcessingException e) { - e.printStackTrace(); - } - } - - protected void mockCategories(int numberCategories) { - List categories = new LinkedList(); - for (int i = 0; i < numberCategories; i++) { - Category category = new Category(); - category.setId(i); - category.setName("Category " + i); - category.setDescription("Description " + i); - categories.add(category); - } - mockValidGetRestCall(categories, "/tools.descartes.teastore.auth/rest/categories"); - } - - protected void mockProduct106() { - Product p = new Product(); - p.setCategoryId(1); - p.setDescription("desc"); - p.setId(106); - p.setListPriceInCents(99); - p.setName("a product"); - mockValidGetRestCall(p, "/tools.descartes.teastore.persistence/rest/products/106"); - } - - protected void mockInvalidProduct() { - mockInValidGetRestCall(Response.Status.NOT_FOUND, "/tools.descartes.teastore.persistence/rest/products/-1"); - } - - protected void mockProduct107() { - Product p = new Product(); - p.setCategoryId(2); - p.setDescription("desc"); - p.setId(107); - p.setListPriceInCents(99); - p.setName("another product"); - mockValidGetRestCall(p, "/tools.descartes.teastore.persistence/rest/products/107"); - } -} + @Rule + public WireMockRule wireMockRule = new WireMockRule(18080); + + private Tomcat storeTomcat; + private String testWorkingDir = System.getProperty("java.io.tmpdir"); + + /** + * Sets up a store. + * + * @throws Throwable + * Throws uncaught throwables for test to fail. + */ + @Before + public void setup() throws Throwable { + BasicConfigurator.configure(); + + storeTomcat = new Tomcat(); + storeTomcat.setPort(3000); + storeTomcat.setBaseDir(testWorkingDir); + storeTomcat.enableNaming(); + ContextEnvironment registryUrl3 = new ContextEnvironment(); + registryUrl3.setDescription(""); + registryUrl3.setOverride(false); + registryUrl3.setType("java.lang.String"); + registryUrl3.setName("registryURL"); + registryUrl3 + .setValue("http://localhost:18080/tools.descartes.teastore.registry/rest/services/"); + Context context3 = storeTomcat.addWebapp("/tools.descartes.teastore.auth", testWorkingDir); + context3.getNamingResources().addEnvironment(registryUrl3); + ContextEnvironment servicePort3 = new ContextEnvironment(); + servicePort3.setDescription(""); + servicePort3.setOverride(false); + servicePort3.setType("java.lang.String"); + servicePort3.setName("servicePort"); + servicePort3.setValue("3000"); + context3.getNamingResources().addEnvironment(servicePort3); + ResourceConfig restServletConfig3 = new ResourceConfig(); + restServletConfig3.register(AuthCartRest.class); + restServletConfig3.register(AuthUserActionsRest.class); + ServletContainer restServlet3 = new ServletContainer(restServletConfig3); + storeTomcat.addServlet("/tools.descartes.teastore.auth", "restServlet", restServlet3); + context3.addServletMappingDecoded("/rest/*", "restServlet"); + context3.addApplicationListener(EmptyAuthStartup.class.getName()); + + // Mock registry + List strings = new LinkedList(); + strings.add("localhost:18080"); + String json = new ObjectMapper().writeValueAsString(strings); + List strings2 = new LinkedList(); + strings2.add("localhost:3000"); + String json2 = new ObjectMapper().writeValueAsString(strings2); + wireMockRule.stubFor(get(urlEqualTo( + "/tools.descartes.teastore.registry/rest/services/" + Service.IMAGE.getServiceName() + "/")) + .willReturn(okJson(json))); + wireMockRule.stubFor(get(urlEqualTo( + "/tools.descartes.teastore.registry/rest/services/" + Service.AUTH.getServiceName() + "/")) + .willReturn(okJson(json2))); + wireMockRule.stubFor( + WireMock.put(WireMock.urlMatching("/tools.descartes.teastore.registry/rest/services/" + + Service.AUTH.getServiceName() + "/.*")).willReturn(okJson(json2))); + wireMockRule.stubFor( + WireMock.delete(WireMock.urlMatching("/tools.descartes.teastore.registry/rest/services/" + + Service.AUTH.getServiceName() + "/.*")).willReturn(okJson(json2))); + wireMockRule.stubFor(get(urlEqualTo("/tools.descartes.teastore.registry/rest/services/" + + Service.PERSISTENCE.getServiceName() + "/")).willReturn(okJson(json))); + wireMockRule.stubFor(get(urlEqualTo("/tools.descartes.teastore.registry/rest/services/" + + Service.RECOMMENDER.getServiceName() + "/")).willReturn(okJson(json))); + + // Mock images + HashMap img = new HashMap<>(); + img.put("andreBauer", "andreBauer"); + img.put("johannesGrohmann", "johannesGrohmann"); + img.put("joakimKistowski", "joakimKistowski"); + img.put("simonEismann", "simonEismann"); + img.put("norbertSchmitt", "norbertSchmitt"); + img.put("descartesLogo", "descartesLogo"); + img.put("icon", "icon"); + mockValidPostRestCall(img, "/tools.descartes.teastore.image/rest/image/getWebImages"); + + storeTomcat.start(); + } + + /** + * Dismantles the embedded Tomcat. + * + * @throws Throwable + * Throws uncaught throwables for test to fail. + */ + @After + public void dismantle() throws Throwable { + if (storeTomcat.getServer() != null + && storeTomcat.getServer().getState() != LifecycleState.DESTROYED) { + if (storeTomcat.getServer().getState() != LifecycleState.STOPPED) { + storeTomcat.stop(); + } + storeTomcat.destroy(); + } + } + + protected void mockValidPostRestCall(Object input, String path) { + try { + wireMockRule.stubFor( + post(urlEqualTo(path)).willReturn(okJson(new ObjectMapper().writeValueAsString(input)))); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + } + + protected void mockInValidGetRestCall(Status status, String path) { + wireMockRule.stubFor(get(urlEqualTo(path)).willReturn(WireMock.status(status.getStatusCode()))); + } + + protected void mockValidGetRestCall(Object input, String path) { + try { + wireMockRule.stubFor( + get(urlEqualTo(path)).willReturn(okJson(new ObjectMapper().writeValueAsString(input)))); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + } + + protected void mockCategories(int numberCategories) { + List categories = new LinkedList(); + for (int i = 0; i < numberCategories; i++) { + Category category = new Category(); + category.setId(i); + category.setName("Category " + i); + category.setDescription("Description " + i); + categories.add(category); + } + mockValidGetRestCall(categories, "/tools.descartes.teastore.auth/rest/categories"); + } + + protected void mockProduct106() { + Product p = new Product(); + p.setCategoryId(1); + p.setDescription("desc"); + p.setId(106); + p.setListPriceInCents(99); + p.setName("a product"); + mockValidGetRestCall(p, "/tools.descartes.teastore.persistence/rest/products/106"); + } + + protected void mockInvalidProduct() { + mockInValidGetRestCall(Response.Status.NOT_FOUND, + "/tools.descartes.teastore.persistence/rest/products/-1"); + } + + protected void mockProduct107() { + Product p = new Product(); + p.setCategoryId(2); + p.setDescription("desc"); + p.setId(107); + p.setListPriceInCents(99); + p.setName("another product"); + mockValidGetRestCall(p, "/tools.descartes.teastore.persistence/rest/products/107"); + } +} diff --git a/services/tools.descartes.teastore.auth/src/test/java/tools/descartes/teastore/auth/rest/CartTest.java b/services/tools.descartes.teastore.auth/src/test/java/tools/descartes/teastore/auth/rest/CartTest.java index 781c5c85e..e7a1be69b 100644 --- a/services/tools.descartes.teastore.auth/src/test/java/tools/descartes/teastore/auth/rest/CartTest.java +++ b/services/tools.descartes.teastore.auth/src/test/java/tools/descartes/teastore/auth/rest/CartTest.java @@ -1,199 +1,221 @@ package tools.descartes.teastore.auth.rest; +import com.fasterxml.jackson.core.JsonProcessingException; import javax.ws.rs.core.Response; import org.junit.Assert; import org.junit.Test; import org.mindrot.jbcrypt.BCrypt; -import com.fasterxml.jackson.core.JsonProcessingException; - import tools.descartes.teastore.entities.User; import tools.descartes.teastore.entities.message.SessionBlob; import tools.descartes.teastore.registryclient.rest.LoadBalancedStoreOperations; import tools.descartes.teastore.registryclient.util.NotFoundException; - - /** * Abstract base for testing of the stores user actions funtionality. + * * @author Simon * */ public class CartTest extends AbstractStoreRestTest { - - /** - * Tests for the loggin, logout and isloggedin functionality. - * @throws JsonProcessingException - */ - @Test - public void runTest() throws JsonProcessingException { - mockProduct106(); - mockProduct107(); - mockInvalidProduct(); - mockUser1(); - mockInvalidUser(); - mockCreateOrderItems(); - mockCreateOrder(); - - SessionBlob notLoggedIn = new SessionBlob(); - - notLoggedIn = LoadBalancedStoreOperations.addProductToCart(notLoggedIn, 106L); - Assert.assertEquals(1, notLoggedIn.getOrderItems().size()); - Assert.assertEquals(106, notLoggedIn.getOrderItems().get(0).getProductId()); - Assert.assertEquals(1, notLoggedIn.getOrderItems().get(0).getQuantity()); - - notLoggedIn = LoadBalancedStoreOperations.addProductToCart(notLoggedIn, 107L); - Assert.assertEquals(2, notLoggedIn.getOrderItems().size()); - Assert.assertEquals(107, notLoggedIn.getOrderItems().get(1).getProductId()); - Assert.assertEquals(1, notLoggedIn.getOrderItems().get(1).getQuantity()); - - notLoggedIn = LoadBalancedStoreOperations.addProductToCart(notLoggedIn, 106L); - Assert.assertEquals(2, notLoggedIn.getOrderItems().size()); - Assert.assertEquals(2, notLoggedIn.getOrderItems().get(0).getQuantity()); - - notLoggedIn = LoadBalancedStoreOperations.addProductToCart(notLoggedIn, 107L); - Assert.assertEquals(2, notLoggedIn.getOrderItems().size()); - Assert.assertEquals(2, notLoggedIn.getOrderItems().get(1).getQuantity()); - - try { - LoadBalancedStoreOperations.addProductToCart(notLoggedIn, -1L); - Assert.fail(); - } catch (NotFoundException e) {} - - notLoggedIn = LoadBalancedStoreOperations.updateQuantity(notLoggedIn, 106L, 7); - Assert.assertEquals(7, notLoggedIn.getOrderItems().get(0).getQuantity()); - - try { - LoadBalancedStoreOperations.updateQuantity(notLoggedIn, 106L, -1); - Assert.fail(); - } catch (IllegalArgumentException e) { - } - - try { - LoadBalancedStoreOperations.updateQuantity(notLoggedIn, -1L, 7); - Assert.fail(); - } catch (NotFoundException e) {} - - try { - LoadBalancedStoreOperations.updateQuantity(notLoggedIn, 108L, 7); - Assert.fail(); - } catch (NotFoundException e) {} - - notLoggedIn = LoadBalancedStoreOperations.removeProductFromCart(notLoggedIn, 106L); - Assert.assertEquals(1, notLoggedIn.getOrderItems().size()); - Assert.assertEquals(107, notLoggedIn.getOrderItems().get(0).getProductId()); - - try { - LoadBalancedStoreOperations.removeProductFromCart(notLoggedIn, 106L); - Assert.fail(); - } catch (NotFoundException e) {} - - notLoggedIn = LoadBalancedStoreOperations.removeProductFromCart(notLoggedIn, 107L); - Assert.assertEquals(0, notLoggedIn.getOrderItems().size()); - - - notLoggedIn = LoadBalancedStoreOperations.addProductToCart(notLoggedIn, 107L); - - try { - LoadBalancedStoreOperations.placeOrder(notLoggedIn, "", "", "", "", "2015-12-12", -1L, ""); - Assert.fail(); - } catch (NotFoundException e) {} - - SessionBlob loggedIn = new SessionBlob(); - loggedIn = LoadBalancedStoreOperations.login(loggedIn, "user1", "password"); - - loggedIn = LoadBalancedStoreOperations.addProductToCart(loggedIn, 106L); - Assert.assertEquals(1, loggedIn.getOrderItems().size()); - Assert.assertEquals(106, loggedIn.getOrderItems().get(0).getProductId()); - Assert.assertEquals(1, loggedIn.getOrderItems().get(0).getQuantity()); - - loggedIn = LoadBalancedStoreOperations.addProductToCart(loggedIn, 107L); - Assert.assertEquals(2, loggedIn.getOrderItems().size()); - Assert.assertEquals(107, loggedIn.getOrderItems().get(1).getProductId()); - Assert.assertEquals(1, loggedIn.getOrderItems().get(1).getQuantity()); - - loggedIn = LoadBalancedStoreOperations.addProductToCart(loggedIn, 106L); - Assert.assertEquals(2, loggedIn.getOrderItems().size()); - Assert.assertEquals(2, loggedIn.getOrderItems().get(0).getQuantity()); - - loggedIn = LoadBalancedStoreOperations.addProductToCart(loggedIn, 107L); - Assert.assertEquals(2, loggedIn.getOrderItems().size()); - Assert.assertEquals(2, loggedIn.getOrderItems().get(1).getQuantity()); - - try { - LoadBalancedStoreOperations.addProductToCart(loggedIn, -1L); - Assert.fail(); - } catch (NotFoundException e) {} - - loggedIn = LoadBalancedStoreOperations.updateQuantity(loggedIn, 106L, 7); - Assert.assertEquals(7, loggedIn.getOrderItems().get(0).getQuantity()); - - try { - loggedIn = LoadBalancedStoreOperations.updateQuantity(loggedIn, 106L, -1); - Assert.fail(); - } catch (IllegalArgumentException e) { - } - - try { - LoadBalancedStoreOperations.updateQuantity(loggedIn, -1L, 7); - Assert.fail(); - } catch (NotFoundException e) {} - - try { - LoadBalancedStoreOperations.updateQuantity(loggedIn, 108L, 7); - Assert.fail(); - } catch (NotFoundException e) {} - - loggedIn = LoadBalancedStoreOperations.removeProductFromCart(loggedIn, 106L); - Assert.assertEquals(1, loggedIn.getOrderItems().size()); - Assert.assertEquals(107, loggedIn.getOrderItems().get(0).getProductId()); - - try { - LoadBalancedStoreOperations.removeProductFromCart(loggedIn, 106L); - Assert.fail(); - } catch (NotFoundException e) {} - - loggedIn = LoadBalancedStoreOperations.removeProductFromCart(loggedIn, 107L); - Assert.assertEquals(0, loggedIn.getOrderItems().size()); - - try { - LoadBalancedStoreOperations.placeOrder(loggedIn, "", "", "", "", "2015-12-12", -1L, ""); - Assert.fail(); - } catch (NotFoundException e) {} - - loggedIn = LoadBalancedStoreOperations.addProductToCart(loggedIn, 107L); - loggedIn = LoadBalancedStoreOperations.placeOrder(loggedIn, "", "", "", "", "2015-12-12", -1L, ""); - Assert.assertTrue(loggedIn != null); - Assert.assertTrue(loggedIn.getOrderItems().isEmpty()); - Assert.assertTrue(loggedIn.getOrder().getAddress1() == null); - } - - private void mockUser1() { - User u = new User(); - u.setEmail("asdas@asda.de"); - u.setRealName("asdas asdasd"); - u.setUserName("user1"); - u.setPassword(BCrypt.hashpw("password", BCrypt.gensalt())); - u.setId(1231245125); - mockValidGetRestCall(u, "/tools.descartes.teastore.persistence/rest/users/name/user1"); - } - - private void mockInvalidUser() { - mockInValidGetRestCall(Response.Status.NOT_FOUND, "/tools.descartes.teastore.persistence/rest/users/name/user/-1"); - } - - /** - * Returns id of newly created object - */ - private void mockCreateOrderItems() { - mockValidPostRestCall(8, "/tools.descartes.teastore.persistence/rest/orderitems"); - } - - /** - * Returns id of newly created object - */ - private void mockCreateOrder() { - mockValidPostRestCall(7, "/tools.descartes.teastore.persistence/rest/orders"); - } + + /** + * Tests for the loggin, logout and isloggedin functionality. + * + * @throws JsonProcessingException exception if json can not be processed + */ + @Test + public void runTest() throws JsonProcessingException { + mockProduct106(); + mockProduct107(); + mockInvalidProduct(); + mockUser1(); + mockInvalidUser(); + mockCreateOrderItems(); + mockCreateOrder(); + + SessionBlob notLoggedIn = new SessionBlob(); + + notLoggedIn = LoadBalancedStoreOperations.addProductToCart(notLoggedIn, 106L); + Assert.assertEquals(1, notLoggedIn.getOrderItems().size()); + Assert.assertEquals(106, notLoggedIn.getOrderItems().get(0).getProductId()); + Assert.assertEquals(1, notLoggedIn.getOrderItems().get(0).getQuantity()); + + notLoggedIn = LoadBalancedStoreOperations.addProductToCart(notLoggedIn, 107L); + Assert.assertEquals(2, notLoggedIn.getOrderItems().size()); + Assert.assertEquals(107, notLoggedIn.getOrderItems().get(1).getProductId()); + Assert.assertEquals(1, notLoggedIn.getOrderItems().get(1).getQuantity()); + + notLoggedIn = LoadBalancedStoreOperations.addProductToCart(notLoggedIn, 106L); + Assert.assertEquals(2, notLoggedIn.getOrderItems().size()); + Assert.assertEquals(2, notLoggedIn.getOrderItems().get(0).getQuantity()); + + notLoggedIn = LoadBalancedStoreOperations.addProductToCart(notLoggedIn, 107L); + Assert.assertEquals(2, notLoggedIn.getOrderItems().size()); + Assert.assertEquals(2, notLoggedIn.getOrderItems().get(1).getQuantity()); + + try { + LoadBalancedStoreOperations.addProductToCart(notLoggedIn, -1L); + Assert.fail(); + } catch (NotFoundException e) { + e.printStackTrace(); + } + + notLoggedIn = LoadBalancedStoreOperations.updateQuantity(notLoggedIn, 106L, 7); + Assert.assertEquals(7, notLoggedIn.getOrderItems().get(0).getQuantity()); + + try { + LoadBalancedStoreOperations.updateQuantity(notLoggedIn, 106L, -1); + Assert.fail(); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } + + try { + LoadBalancedStoreOperations.updateQuantity(notLoggedIn, -1L, 7); + Assert.fail(); + } catch (NotFoundException e) { + e.printStackTrace(); + } + + try { + LoadBalancedStoreOperations.updateQuantity(notLoggedIn, 108L, 7); + Assert.fail(); + } catch (NotFoundException e) { + e.printStackTrace(); + } + + notLoggedIn = LoadBalancedStoreOperations.removeProductFromCart(notLoggedIn, 106L); + Assert.assertEquals(1, notLoggedIn.getOrderItems().size()); + Assert.assertEquals(107, notLoggedIn.getOrderItems().get(0).getProductId()); + + try { + LoadBalancedStoreOperations.removeProductFromCart(notLoggedIn, 106L); + Assert.fail(); + } catch (NotFoundException e) { + e.printStackTrace(); + } + + notLoggedIn = LoadBalancedStoreOperations.removeProductFromCart(notLoggedIn, 107L); + Assert.assertEquals(0, notLoggedIn.getOrderItems().size()); + + notLoggedIn = LoadBalancedStoreOperations.addProductToCart(notLoggedIn, 107L); + + try { + LoadBalancedStoreOperations.placeOrder(notLoggedIn, "", "", "", "", "2015-12-12", -1L, ""); + Assert.fail(); + } catch (NotFoundException e) { + e.printStackTrace(); + } + + SessionBlob loggedIn = new SessionBlob(); + loggedIn = LoadBalancedStoreOperations.login(loggedIn, "user1", "password"); + + loggedIn = LoadBalancedStoreOperations.addProductToCart(loggedIn, 106L); + Assert.assertEquals(1, loggedIn.getOrderItems().size()); + Assert.assertEquals(106, loggedIn.getOrderItems().get(0).getProductId()); + Assert.assertEquals(1, loggedIn.getOrderItems().get(0).getQuantity()); + + loggedIn = LoadBalancedStoreOperations.addProductToCart(loggedIn, 107L); + Assert.assertEquals(2, loggedIn.getOrderItems().size()); + Assert.assertEquals(107, loggedIn.getOrderItems().get(1).getProductId()); + Assert.assertEquals(1, loggedIn.getOrderItems().get(1).getQuantity()); + + loggedIn = LoadBalancedStoreOperations.addProductToCart(loggedIn, 106L); + Assert.assertEquals(2, loggedIn.getOrderItems().size()); + Assert.assertEquals(2, loggedIn.getOrderItems().get(0).getQuantity()); + + loggedIn = LoadBalancedStoreOperations.addProductToCart(loggedIn, 107L); + Assert.assertEquals(2, loggedIn.getOrderItems().size()); + Assert.assertEquals(2, loggedIn.getOrderItems().get(1).getQuantity()); + + try { + LoadBalancedStoreOperations.addProductToCart(loggedIn, -1L); + Assert.fail(); + } catch (NotFoundException e) { + e.printStackTrace(); + } + + loggedIn = LoadBalancedStoreOperations.updateQuantity(loggedIn, 106L, 7); + Assert.assertEquals(7, loggedIn.getOrderItems().get(0).getQuantity()); + + try { + loggedIn = LoadBalancedStoreOperations.updateQuantity(loggedIn, 106L, -1); + Assert.fail(); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } + + try { + LoadBalancedStoreOperations.updateQuantity(loggedIn, -1L, 7); + Assert.fail(); + } catch (NotFoundException e) { + e.printStackTrace(); + } + + try { + LoadBalancedStoreOperations.updateQuantity(loggedIn, 108L, 7); + Assert.fail(); + } catch (NotFoundException e) { + e.printStackTrace(); + } + + loggedIn = LoadBalancedStoreOperations.removeProductFromCart(loggedIn, 106L); + Assert.assertEquals(1, loggedIn.getOrderItems().size()); + Assert.assertEquals(107, loggedIn.getOrderItems().get(0).getProductId()); + + try { + LoadBalancedStoreOperations.removeProductFromCart(loggedIn, 106L); + Assert.fail(); + } catch (NotFoundException e) { + e.printStackTrace(); + } + + loggedIn = LoadBalancedStoreOperations.removeProductFromCart(loggedIn, 107L); + Assert.assertEquals(0, loggedIn.getOrderItems().size()); + + try { + LoadBalancedStoreOperations.placeOrder(loggedIn, "", "", "", "", "2015-12-12", -1L, ""); + Assert.fail(); + } catch (NotFoundException e) { + e.printStackTrace(); + } + + loggedIn = LoadBalancedStoreOperations.addProductToCart(loggedIn, 107L); + loggedIn = LoadBalancedStoreOperations.placeOrder(loggedIn, "", "", "", "", "2015-12-12", -1L, + ""); + Assert.assertTrue(loggedIn != null); + Assert.assertTrue(loggedIn.getOrderItems().isEmpty()); + Assert.assertTrue(loggedIn.getOrder().getAddress1() == null); + } + + private void mockUser1() { + User u = new User(); + u.setEmail("asdas@asda.de"); + u.setRealName("asdas asdasd"); + u.setUserName("user1"); + u.setPassword(BCrypt.hashpw("password", BCrypt.gensalt())); + u.setId(1231245125); + mockValidGetRestCall(u, "/tools.descartes.teastore.persistence/rest/users/name/user1"); + } + + private void mockInvalidUser() { + mockInValidGetRestCall(Response.Status.NOT_FOUND, + "/tools.descartes.teastore.persistence/rest/users/name/user/-1"); + } + + /** + * Returns id of newly created object. + */ + private void mockCreateOrderItems() { + mockValidPostRestCall(8, "/tools.descartes.teastore.persistence/rest/orderitems"); + } + + /** + * Returns id of newly created object. + */ + private void mockCreateOrder() { + mockValidPostRestCall(7, "/tools.descartes.teastore.persistence/rest/orders"); + } } diff --git a/services/tools.descartes.teastore.auth/src/test/java/tools/descartes/teastore/auth/rest/EmptyAuthStartup.java b/services/tools.descartes.teastore.auth/src/test/java/tools/descartes/teastore/auth/rest/EmptyAuthStartup.java index c8eb17e4c..ecce3ca55 100644 --- a/services/tools.descartes.teastore.auth/src/test/java/tools/descartes/teastore/auth/rest/EmptyAuthStartup.java +++ b/services/tools.descartes.teastore.auth/src/test/java/tools/descartes/teastore/auth/rest/EmptyAuthStartup.java @@ -11,6 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package tools.descartes.teastore.auth.rest; import javax.servlet.ServletContextEvent; @@ -22,41 +23,44 @@ /** * Application Lifecycle Listener implementation class Registry Client Startup. + * * @author Simon Eismann * */ @WebListener public class EmptyAuthStartup implements ServletContextListener { - - private static final int TEST_REST_READ_TIMOUT = 5000; - private static final int TEST_REST_CONNECT_TIMOUT = 3000; - - /** - * Also set this accordingly in RegistryClientStartup. - */ - - /** - * Empty constructor. - */ - public EmptyAuthStartup() { - - } - - /** - * @see ServletContextListener#contextDestroyed(ServletContextEvent) - * @param arg0 The servlet context event at destruction. - */ - public void contextDestroyed(ServletContextEvent event) { - } - - /** - * @see ServletContextListener#contextInitialized(ServletContextEvent) - * @param arg0 The servlet context event at initialization. - */ - public void contextInitialized(ServletContextEvent event) { - RESTClient.setGlobalConnectTimeout(TEST_REST_CONNECT_TIMOUT); - RESTClient.setGlobalReadTimeout(TEST_REST_READ_TIMOUT); - ServiceLoadBalancer.preInitializeServiceLoadBalancers(Service.PERSISTENCE, Service.RECOMMENDER); - } - + + private static final int TEST_REST_READ_TIMOUT = 5000; + private static final int TEST_REST_CONNECT_TIMOUT = 3000; + + /** + * Also set this accordingly in RegistryClientStartup. + */ + + /** + * Empty constructor. + */ + public EmptyAuthStartup() { + + } + + /** + * shutdown routine. + * @see ServletContextListener#contextDestroyed(ServletContextEvent) + * @param event The servlet context event at destruction. + */ + public void contextDestroyed(ServletContextEvent event) { + } + + /** + * startup routine. + * @see ServletContextListener#contextInitialized(ServletContextEvent) + * @param event The servlet context event at initialization. + */ + public void contextInitialized(ServletContextEvent event) { + RESTClient.setGlobalConnectTimeout(TEST_REST_CONNECT_TIMOUT); + RESTClient.setGlobalReadTimeout(TEST_REST_READ_TIMOUT); + ServiceLoadBalancer.preInitializeServiceLoadBalancers(Service.PERSISTENCE, Service.RECOMMENDER); + } + } diff --git a/services/tools.descartes.teastore.auth/src/test/java/tools/descartes/teastore/auth/rest/LoginLogoutTest.java b/services/tools.descartes.teastore.auth/src/test/java/tools/descartes/teastore/auth/rest/LoginLogoutTest.java index a0c94e790..150048e45 100644 --- a/services/tools.descartes.teastore.auth/src/test/java/tools/descartes/teastore/auth/rest/LoginLogoutTest.java +++ b/services/tools.descartes.teastore.auth/src/test/java/tools/descartes/teastore/auth/rest/LoginLogoutTest.java @@ -1,5 +1,7 @@ package tools.descartes.teastore.auth.rest; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.sun.mail.iap.Response; import javax.ws.rs.core.Response.Status; @@ -7,82 +9,79 @@ import org.junit.Test; import org.mindrot.jbcrypt.BCrypt; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.sun.mail.iap.Response; - import tools.descartes.teastore.entities.User; import tools.descartes.teastore.entities.message.SessionBlob; import tools.descartes.teastore.registryclient.rest.LoadBalancedStoreOperations; - - /** * Abstract base for testing of the stores user actions funtionality. + * * @author Simon * */ public class LoginLogoutTest extends AbstractStoreRestTest { - /** - * Tests for the loggin, logout and isloggedin functionality. - * @throws JsonProcessingException - */ - @Test - public void runTest() throws JsonProcessingException { - mockUser1(); - mockProduct106(); - mockCreateOrder(); - mockCreateOrderItems(); - - SessionBlob blob = new SessionBlob(); - Assert.assertFalse(LoadBalancedStoreOperations.isLoggedIn(blob)); - - mockInValidGetRestCall(Status.NOT_FOUND, "/tools.descartes.teastore.persistence/rest/users/name/notauser"); - blob = LoadBalancedStoreOperations.login(blob, "notauser", "notapassword"); - Assert.assertFalse(LoadBalancedStoreOperations.isLoggedIn(blob)); - - blob = LoadBalancedStoreOperations.login(blob, "user1", "password"); - Assert.assertTrue(LoadBalancedStoreOperations.isLoggedIn(blob)); - - blob = LoadBalancedStoreOperations.logout(blob); - Assert.assertFalse(LoadBalancedStoreOperations.isLoggedIn(blob)); - - blob = LoadBalancedStoreOperations.logout(blob); - Assert.assertFalse(LoadBalancedStoreOperations.isLoggedIn(blob)); - - blob = LoadBalancedStoreOperations.login(blob, "user1", "password"); - blob = LoadBalancedStoreOperations.addProductToCart(blob, 106); - Assert.assertTrue(LoadBalancedStoreOperations.isLoggedIn(blob)); - - blob = LoadBalancedStoreOperations.removeProductFromCart(blob, 106); - Assert.assertTrue(LoadBalancedStoreOperations.isLoggedIn(blob)); - - blob = LoadBalancedStoreOperations.addProductToCart(blob, 106); - blob = LoadBalancedStoreOperations.updateQuantity(blob, 106, 2); - Assert.assertTrue(LoadBalancedStoreOperations.isLoggedIn(blob)); - - blob = LoadBalancedStoreOperations.placeOrder(blob, "", "", "", "", "2015-12-12", -1L, ""); - Assert.assertTrue(LoadBalancedStoreOperations.isLoggedIn(blob)); - - blob = LoadBalancedStoreOperations.logout(blob); - Assert.assertFalse(LoadBalancedStoreOperations.isLoggedIn(blob)); - } - - private void mockCreateOrderItems() { - mockValidPostRestCall(Response.OK, "/tools.descartes.teastore.persistence/rest/orderitems"); - } - - private void mockCreateOrder() { - mockValidPostRestCall(7, "/tools.descartes.teastore.persistence/rest/orders"); - } - - private void mockUser1() { - User u = new User(); - u.setEmail("asdas@asda.de"); - u.setRealName("asdas asdasd"); - u.setUserName("user1"); - u.setPassword(BCrypt.hashpw("password", BCrypt.gensalt())); - u.setId(1231245125); - mockValidGetRestCall(u, "/tools.descartes.teastore.persistence/rest/users/name/user1"); - } + /** + * Tests for the loggin, logout and isloggedin functionality. + * @throws JsonProcessingException if json can not be parsed + */ + @Test + public void runTest() throws JsonProcessingException { + mockUser1(); + mockProduct106(); + mockCreateOrder(); + mockCreateOrderItems(); + + SessionBlob blob = new SessionBlob(); + Assert.assertFalse(LoadBalancedStoreOperations.isLoggedIn(blob)); + + mockInValidGetRestCall(Status.NOT_FOUND, + "/tools.descartes.teastore.persistence/rest/users/name/notauser"); + blob = LoadBalancedStoreOperations.login(blob, "notauser", "notapassword"); + Assert.assertFalse(LoadBalancedStoreOperations.isLoggedIn(blob)); + + blob = LoadBalancedStoreOperations.login(blob, "user1", "password"); + Assert.assertTrue(LoadBalancedStoreOperations.isLoggedIn(blob)); + + blob = LoadBalancedStoreOperations.logout(blob); + Assert.assertFalse(LoadBalancedStoreOperations.isLoggedIn(blob)); + + blob = LoadBalancedStoreOperations.logout(blob); + Assert.assertFalse(LoadBalancedStoreOperations.isLoggedIn(blob)); + + blob = LoadBalancedStoreOperations.login(blob, "user1", "password"); + blob = LoadBalancedStoreOperations.addProductToCart(blob, 106); + Assert.assertTrue(LoadBalancedStoreOperations.isLoggedIn(blob)); + + blob = LoadBalancedStoreOperations.removeProductFromCart(blob, 106); + Assert.assertTrue(LoadBalancedStoreOperations.isLoggedIn(blob)); + + blob = LoadBalancedStoreOperations.addProductToCart(blob, 106); + blob = LoadBalancedStoreOperations.updateQuantity(blob, 106, 2); + Assert.assertTrue(LoadBalancedStoreOperations.isLoggedIn(blob)); + + blob = LoadBalancedStoreOperations.placeOrder(blob, "", "", "", "", "2015-12-12", -1L, ""); + Assert.assertTrue(LoadBalancedStoreOperations.isLoggedIn(blob)); + + blob = LoadBalancedStoreOperations.logout(blob); + Assert.assertFalse(LoadBalancedStoreOperations.isLoggedIn(blob)); + } + + private void mockCreateOrderItems() { + mockValidPostRestCall(Response.OK, "/tools.descartes.teastore.persistence/rest/orderitems"); + } + + private void mockCreateOrder() { + mockValidPostRestCall(7, "/tools.descartes.teastore.persistence/rest/orders"); + } + + private void mockUser1() { + User u = new User(); + u.setEmail("asdas@asda.de"); + u.setRealName("asdas asdasd"); + u.setUserName("user1"); + u.setPassword(BCrypt.hashpw("password", BCrypt.gensalt())); + u.setId(1231245125); + mockValidGetRestCall(u, "/tools.descartes.teastore.persistence/rest/users/name/user1"); + } } diff --git a/services/tools.descartes.teastore.auth/src/test/java/tools/descartes/teastore/auth/security/ConstantKeyProviderTest.java b/services/tools.descartes.teastore.auth/src/test/java/tools/descartes/teastore/auth/security/ConstantKeyProviderTest.java index f8649c773..0398d3b1e 100644 --- a/services/tools.descartes.teastore.auth/src/test/java/tools/descartes/teastore/auth/security/ConstantKeyProviderTest.java +++ b/services/tools.descartes.teastore.auth/src/test/java/tools/descartes/teastore/auth/security/ConstantKeyProviderTest.java @@ -1,26 +1,26 @@ package tools.descartes.teastore.auth.security; - import org.junit.Assert; import org.junit.Test; -import tools.descartes.teastore.entities.message.SessionBlob; import tools.descartes.teastore.auth.security.ConstantKeyProvider; +import tools.descartes.teastore.entities.message.SessionBlob; /** * Test for the ConstantKeyProvider. + * * @author Simon * */ public class ConstantKeyProviderTest { - /** - * checks the getKey() functionality. - */ - @Test - public void test() { - Assert.assertEquals("thebestsecretkey", new ConstantKeyProvider().getKey(null)); - Assert.assertEquals("thebestsecretkey", new ConstantKeyProvider().getKey(new SessionBlob())); - } + /** + * checks the getKey() functionality. + */ + @Test + public void test() { + Assert.assertEquals("thebestsecretkey", new ConstantKeyProvider().getKey(null)); + Assert.assertEquals("thebestsecretkey", new ConstantKeyProvider().getKey(new SessionBlob())); + } } diff --git a/services/tools.descartes.teastore.auth/src/test/java/tools/descartes/teastore/auth/security/SHASecurityProviderTest.java b/services/tools.descartes.teastore.auth/src/test/java/tools/descartes/teastore/auth/security/SHASecurityProviderTest.java deleted file mode 100644 index b71e52a0a..000000000 --- a/services/tools.descartes.teastore.auth/src/test/java/tools/descartes/teastore/auth/security/SHASecurityProviderTest.java +++ /dev/null @@ -1,35 +0,0 @@ -package tools.descartes.teastore.auth.security; - - -import org.junit.Assert; -import org.junit.Test; - -import tools.descartes.teastore.entities.message.SessionBlob; -import tools.descartes.teastore.auth.security.SHASecurityProvider; - -/** - * Test for the SHASecurityProviuder. - * @author Simon - * - */ -public class SHASecurityProviderTest { - - /** - * checks security token behavior. - */ - @Test - public void test() { - SHASecurityProvider provider = new SHASecurityProvider(); - SessionBlob blob = new SessionBlob(); - blob.setSID("1234"); - blob.setUID(123456L); - Assert.assertTrue(provider.validate(blob) == null); - provider.secure(blob); - Assert.assertTrue(provider.validate(blob) != null); - blob.setUID(13L); - Assert.assertTrue(provider.validate(blob) == null); - provider.secure(blob); - Assert.assertTrue(provider.validate(blob) != null); - } - -} diff --git a/services/tools.descartes.teastore.auth/src/test/java/tools/descartes/teastore/auth/security/ShaSecurityProviderTest.java b/services/tools.descartes.teastore.auth/src/test/java/tools/descartes/teastore/auth/security/ShaSecurityProviderTest.java new file mode 100644 index 000000000..3a46c0c15 --- /dev/null +++ b/services/tools.descartes.teastore.auth/src/test/java/tools/descartes/teastore/auth/security/ShaSecurityProviderTest.java @@ -0,0 +1,35 @@ +package tools.descartes.teastore.auth.security; + +import org.junit.Assert; +import org.junit.Test; + +import tools.descartes.teastore.auth.security.ShaSecurityProvider; +import tools.descartes.teastore.entities.message.SessionBlob; + +/** + * Test for the SHASecurityProviuder. + * + * @author Simon + * + */ +public class ShaSecurityProviderTest { + + /** + * checks security token behavior. + */ + @Test + public void test() { + ShaSecurityProvider provider = new ShaSecurityProvider(); + SessionBlob blob = new SessionBlob(); + blob.setSID("1234"); + blob.setUID(123456L); + Assert.assertTrue(provider.validate(blob) == null); + provider.secure(blob); + Assert.assertTrue(provider.validate(blob) != null); + blob.setUID(13L); + Assert.assertTrue(provider.validate(blob) == null); + provider.secure(blob); + Assert.assertTrue(provider.validate(blob) != null); + } + +} diff --git a/services/tools.descartes.teastore.image/.classpath b/services/tools.descartes.teastore.image/.classpath index 534fbbbb0..c2f8fd59e 100644 --- a/services/tools.descartes.teastore.image/.classpath +++ b/services/tools.descartes.teastore.image/.classpath @@ -38,7 +38,15 @@ - - + + + + + + + + + + diff --git a/services/tools.descartes.teastore.persistence/.classpath b/services/tools.descartes.teastore.persistence/.classpath index b9e92e543..46d53f70c 100644 --- a/services/tools.descartes.teastore.persistence/.classpath +++ b/services/tools.descartes.teastore.persistence/.classpath @@ -39,8 +39,20 @@ - - - + + + + + + + + + + + + + + + diff --git a/services/tools.descartes.teastore.recommender/.classpath b/services/tools.descartes.teastore.recommender/.classpath index 97f6cad59..8edec816c 100644 --- a/services/tools.descartes.teastore.recommender/.classpath +++ b/services/tools.descartes.teastore.recommender/.classpath @@ -33,9 +33,25 @@ - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/services/tools.descartes.teastore.webui/.classpath b/services/tools.descartes.teastore.webui/.classpath index 4fff6fdc3..9a98769d6 100644 --- a/services/tools.descartes.teastore.webui/.classpath +++ b/services/tools.descartes.teastore.webui/.classpath @@ -33,7 +33,15 @@ - - + + + + + + + + + + diff --git a/utilities/tools.descartes.teastore.dockerbase/server.xml b/utilities/tools.descartes.teastore.dockerbase/server.xml index da2cd4d03..d0d60f1ea 100644 --- a/utilities/tools.descartes.teastore.dockerbase/server.xml +++ b/utilities/tools.descartes.teastore.dockerbase/server.xml @@ -1,4 +1,5 @@ + + + copy-dockerfile + generate-resources + + copy-resources + + + ${project.basedir} + true + + + ../../utilities/tools.descartes.teastore.kieker/WebuiDockerfile + + Dockerfile + + + + + copy-monitoring generate-resources From 1b49c068aa280d74095a15dff24eb3a32bb61a26 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 3 Aug 2018 15:42:11 +0200 Subject: [PATCH 42/45] removed double copy of dockerfile in webui --- services/tools.descartes.teastore.webui/pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/services/tools.descartes.teastore.webui/pom.xml b/services/tools.descartes.teastore.webui/pom.xml index 5038fef0b..2a7b5e6ee 100644 --- a/services/tools.descartes.teastore.webui/pom.xml +++ b/services/tools.descartes.teastore.webui/pom.xml @@ -241,7 +241,6 @@ ../../utilities/tools.descartes.teastore.kieker/ kieker.monitoring.properties - Dockerfile start_kieker.sh From 0d6ba6828abf3821e1d67a45e3d12cbf33fe0c31 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 3 Aug 2018 15:50:28 +0200 Subject: [PATCH 43/45] build from new base image --- .../tools.descartes.teastore.kieker/WebuiDockerfile/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/tools.descartes.teastore.kieker/WebuiDockerfile/Dockerfile b/utilities/tools.descartes.teastore.kieker/WebuiDockerfile/Dockerfile index 943ef2339..400a03fb2 100644 --- a/utilities/tools.descartes.teastore.kieker/WebuiDockerfile/Dockerfile +++ b/utilities/tools.descartes.teastore.kieker/WebuiDockerfile/Dockerfile @@ -1,4 +1,4 @@ -FROM descartesresearch/teastore-base:latest +FROM se-docker-registry.cloud.descartes.tools/teastore-base:latest MAINTAINER Chair of Software Engineering EXPOSE 8080 From a5b3f297f6c8b936aa49025599ed61f49b8ed79c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3akim=20von=20Kistowski?= Date: Tue, 7 Aug 2018 09:37:54 +0200 Subject: [PATCH 44/45] changed teastore-base for webui dockerfile --- utilities/tools.descartes.teastore.dockerbase/.classpath | 2 +- .../WebuiDockerfile/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/utilities/tools.descartes.teastore.dockerbase/.classpath b/utilities/tools.descartes.teastore.dockerbase/.classpath index 9ba938055..ba9029aa3 100644 --- a/utilities/tools.descartes.teastore.dockerbase/.classpath +++ b/utilities/tools.descartes.teastore.dockerbase/.classpath @@ -1,5 +1,5 @@ - + diff --git a/utilities/tools.descartes.teastore.dockerbase/WebuiDockerfile/Dockerfile b/utilities/tools.descartes.teastore.dockerbase/WebuiDockerfile/Dockerfile index db683e05b..41ec9cf52 100644 --- a/utilities/tools.descartes.teastore.dockerbase/WebuiDockerfile/Dockerfile +++ b/utilities/tools.descartes.teastore.dockerbase/WebuiDockerfile/Dockerfile @@ -1,4 +1,4 @@ -FROM se-docker-registry.cloud.descartes.tools/teastore-base:latest +FROM descartesresearch/teastore-base:latest MAINTAINER Chair of Software Engineering COPY target/*.war /usr/local/tomcat/webapps/ From 504aba04279ea7f6bc4f4e62a969d8f427059a03 Mon Sep 17 00:00:00 2001 From: Norbert Schmitt Date: Mon, 13 Aug 2018 10:44:24 +0200 Subject: [PATCH 45/45] Set version to 1.2.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3498cb942..4bc2bbacb 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 - 1.1.1-SNAPSHOT + 1.2.0