diff --git a/README.md b/README.md index 1ce3dcd..3de911a 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Stock-Microservice -This is a microservice cutted out of a [Monolith](https://gitlab.com/matthiasstock/monolith). +This microservice is cut out of a [Monolith](https://gitlab.com/matthiasstock/monolith). [![Build Status](https://travis-ci.org/genofire/hs_master-kss-monolith.svg?branch=master)](https://travis-ci.org/genofire/hs_master-kss-monolith) [![CircleCI](https://circleci.com/gh/genofire/hs_master-kss-monolith/tree/master.svg?style=svg)](https://circleci.com/gh/genofire/hs_master-kss-monolith/tree/master) [![Coverage Status](https://coveralls.io/repos/github/genofire/hs_master-kss-monolith/badge.svg?branch=master)](https://coveralls.io/github/genofire/hs_master-kss-monolith?branch=master) [![GoDoc](https://godoc.org/github.com/genofire/hs_master-kss-monolith?status.svg)](https://godoc.org/github.com/genofire/hs_master-kss-monolith) @@ -9,14 +9,14 @@ This is a microservice cutted out of a [Monolith](https://gitlab.com/matthiassto * [Easy dummy Shop-Cart in browser-cache](https://stock.pub.warehost.de/dummy_cart/) ## Features of this stock mircoservice -* The main functionality of the microservice is to store the goods with their storage location and the date, when they are too old to be sell. +* The main functionality of the microservice is to store goods with their storage location and the date, when they are too old to sell. * Functionality of the admin frontend * Add new goods to the stock - * Manually remove a single goods from the stock, for example when they are rancid - * Remove single goods from the stock, when they are send to a costumer - * Block goods from the stock, when a costumer adds them to his cart + * Manually remove a single good from the stock, for example when it is fouled + * Remove a single good from the stock, when it is send to a costumer + * Block goods from the stock, when a costumer adds them to his shop-cart * Functionality of the costumer frontend - * Show the store with a traffic light food labelling + * Show the stock of a product with a traffic light food labelling system * Optional Features - * Admin frontend: display of a statistic on the amount and average of goods in the stock - * Admin frontend: display a traffic light food labelling for each good, which indicates whether the good is too old + * Admin frontend: display of a statistic of the current and average amount of goods in the stock + * Admin frontend: display a traffic light food labelling system for each good, which indicates whether the good is too old diff --git a/cmd/stock/main.go b/cmd/stock/main.go index ecf5c76..1cda8f3 100644 --- a/cmd/stock/main.go +++ b/cmd/stock/main.go @@ -1,4 +1,4 @@ -// Package that containts the cmd binary of the microservice to run it +// Package that contains the cmd binary of the microservice to run it package main import ( @@ -50,13 +50,15 @@ func main() { } grw := runtime.NewGoodReleaseWorker(config.GoodRelease) cw := runtime.NewCacheWorker() - fw := worker.NewWorker(config.FouledDeleter.Duration, func() { runtime.GoodFouled() }) + fw := worker.NewWorker(config.FouledDeleter.Duration, func() { + runtime.GoodFouled() + }) go grw.Start() go cw.Start() if config.FouledDeleter.Duration != time.Duration(0) { go fw.Start() } - // Startwebsrver + // Start webserver router := goji.NewMux() web.BindAPI(router) diff --git a/config_monolith.conf b/config_monolith.conf deleted file mode 100644 index 2229050..0000000 --- a/config_monolith.conf +++ /dev/null @@ -1,24 +0,0 @@ -# bind the webserver to a dynamic ports -webserver_bind = ":65000" -webroot = "webroot" - -good_availablity_template = "contrib/good_availablity.svg" - -[database] -type = "sqlite3" -# logging = true -connection = "file::memory:?mode=memory&cache=shared" -# For Master-Slave cluster -# read_connection = "" - -[good_release] -every = "5m" -after = "30m" - -[cache_clean] -every = "5m" -after = "30m" - -[microservice_dependencies] -product = "http://localhost:65000/api-test/product/%d/" -permission = "http://localhost:65000/api-test/session/%s/%d/" diff --git a/contrib/good_availablity.svg b/contrib/good_availablity.svg index ca93384..4712224 100644 --- a/contrib/good_availablity.svg +++ b/contrib/good_availablity.svg @@ -1,8 +1,7 @@ - - - + + {{if eq .Count 0}} diff --git a/documentation/microservice_stock/chapter/Struktur.tex b/documentation/microservice_stock/chapter/Struktur.tex index 357d59f..92a63f8 100644 --- a/documentation/microservice_stock/chapter/Struktur.tex +++ b/documentation/microservice_stock/chapter/Struktur.tex @@ -58,8 +58,9 @@ Die Packages und Go-Files des Application Layers umfassen die Logik des Microser \paragraph{http:} Go-Files, die die Anwendungslogik (Funktionen) und die API-Routen beinhalten \begin{itemize} \item \texttt{bindapi.go}: Funktionen, die für das Binden der URL-Pfade notwendig sind - \item \texttt{good.go}: Funktionen für die Verwaltung der Waren im Warenbestand - \item \texttt{good\_show.go}: Funktionen für die Auflistung und Zählung der vorhandenen Waren sowie die Feststellung ihrer Verfügbarkeit + \item \texttt{good.go}: Funktionen für das Hinzufügen von Waren zum Warenbestand und die Anzeige, ob eine Ware abgelaufen ist + \item \texttt{good\_lock.go}: Funktionen für das Blockieren von Waren, die sich im Warenkorb befinden + \item \texttt{good\_show.go}: Funktionen für die Auflistung und Zählung der vorhandenen Waren sowie die Feststellung ihrer Verfügbarkeit \item \texttt{good\_temp.go}: Hilfsfunktionen, die für die Darstellung des Warenbestandes als Ampel im Kunden-Frontend benötigt werden \item \texttt{status.go}: Funktion, die den Status des Microservice abfragt \end{itemize} @@ -77,9 +78,9 @@ Die Packages und Go-Files des Application Layers umfassen die Logik des Microser \begin{itemize} \item \texttt{auth.go}: Hilfsfunktionen zur Prüfung, ob eine Berechtigung für den Zugriff vorliegt \item \texttt{cache\_worker.go}: Hilfsfunktionen für das Löschen und Anlegen von Cache-Workers + \item \texttt{good\_fouled.go}: Hilfsfunktion, um abgelaufene Waren automatisch aus dem Warenbestand zu entfernen \item \texttt{good\_release.go}: Hilfsfunktionen zum Blockieren und Entsperren von Waren \item \texttt{productcache.go}: Hilfsfunktionen zum Anlegen eines Caches für Produkte - \item \texttt{runtime.go}: Übergreifende Hintergrundfunktionalitäten \end{itemize} @@ -122,7 +123,7 @@ connection = "file::memory:?mode=memory&cache=shared" \newpage \subsection{Integrierte Tests} \label{subsec: Integrierte Test} -Neben den bisherigen Packages, die bereits Whitebox-Tests umfassen, ist in dem Package \textbf{\texttt{test}} ein weiteres Go-File (\texttt{testRest.go}) enthalten. Dieses setzt einen Test des Webservers um, bei dem auf Testdaten eines Produktkataloges zurückgegriffen wird. Mit Hilfe der integrierten Tests wird in der hier beschriebenen Version eine Code-Coverage von 100\% erreicht, das heißt jedes Stück Code wird mindestens einmal zur Ausführung gebracht. +Neben den bisherigen Packages, die bereits Whitebox-Tests umfassen, ist in dem Package \textbf{\texttt{test}} ein weiteres Go-File (\texttt{testrest.go}) enthalten. Dieses setzt einen Test des Webservers um, bei dem auf Testdaten eines Produktkataloges zurückgegriffen wird. Mit Hilfe der integrierten Tests wird in der hier beschriebenen Version eine Code-Coverage von 100\% erreicht, das heißt jedes Stück Code wird mindestens einmal zur Ausführung gebracht. \subsection{Anpassung des Monolithen} \label{subsec: Anpassung des Monolithen} diff --git a/documentation/microservice_stock/documentation.pdf b/documentation/microservice_stock/documentation.pdf index 362a284..841596a 100644 Binary files a/documentation/microservice_stock/documentation.pdf and b/documentation/microservice_stock/documentation.pdf differ diff --git a/http/good.go b/http/good.go index 8c7faa9..5baaecb 100644 --- a/http/good.go +++ b/http/good.go @@ -28,8 +28,8 @@ func addGood(w http.ResponseWriter, r *http.Request) { id, err := strconv.ParseInt(pat.Param(r, "productid"), 10, 64) if err != nil { - log.Warn("false productid format") - http.Error(w, "the product id is false", http.StatusNotAcceptable) + log.Warn("false product id format") + http.Error(w, "the product id has a false format", http.StatusNotAcceptable) return } log = log.WithField("productid", id) @@ -40,7 +40,7 @@ func addGood(w http.ResponseWriter, r *http.Request) { return } if !ok { - log.Warn("false product, product not found") + log.Warn("product not found") http.Error(w, "the product was not found", http.StatusNotFound) return } @@ -66,7 +66,7 @@ func addGood(w http.ResponseWriter, r *http.Request) { } if db.Error != nil { - log.Error("database not able to write", db.Error) + log.Error("database unable to write", db.Error) http.Error(w, "the product could not be written into the database", http.StatusInternalServerError) } lib.Write(w, &obj) @@ -79,7 +79,7 @@ func delGood(w http.ResponseWriter, r *http.Request) { log := logger.HTTP(r) id, err := strconv.ParseInt(pat.Param(r, "goodid"), 10, 64) if err != nil { - log.Warn("wrong goodid format") + log.Warn("wrong good id format") http.Error(w, "the good id has a false format", http.StatusNotAcceptable) return } @@ -90,8 +90,8 @@ func delGood(w http.ResponseWriter, r *http.Request) { good.ID = id db := good.FilterAvailable(database.Read).First(&good) if db.RecordNotFound() { - log.Warnf("good could not found: %s", db.Error) - http.Error(w, "the good could not found", http.StatusNotFound) + log.Warnf("could not find good: %s", db.Error) + http.Error(w, "the good was not found", http.StatusNotFound) return } good.ManuelleDelete = true @@ -99,8 +99,8 @@ func delGood(w http.ResponseWriter, r *http.Request) { db = database.Write.Save(&good) if db.Error != nil { - log.Warnf("good could not delete: %s", db.Error) - http.Error(w, "the good could not delete", http.StatusInternalServerError) + log.Warnf("could not delete good: %s", db.Error) + http.Error(w, "the good could not be deleted", http.StatusInternalServerError) return } log.Info("done") diff --git a/http/good_lock.go b/http/good_lock.go index 334df63..166a940 100644 --- a/http/good_lock.go +++ b/http/good_lock.go @@ -1,3 +1,4 @@ +// Package that contains all api routes of this microservice package http import ( @@ -14,6 +15,7 @@ type LockGood struct { Count int `json:"count"` } +// Function to lock goods func lockGoods(w http.ResponseWriter, r *http.Request) { log := logger.HTTP(r) secret := r.Header.Get("secret") @@ -37,8 +39,8 @@ func lockGoods(w http.ResponseWriter, r *http.Request) { } if len(goods) <= 0 { - log.Warn("try to log nothing") - http.Error(w, "try to log nothing", http.StatusBadRequest) + log.Warn("tried to log nothing") + http.Error(w, "tried to log nothing", http.StatusBadRequest) return } @@ -47,9 +49,9 @@ func lockGoods(w http.ResponseWriter, r *http.Request) { for _, good := range goods { if good.ProductID <= 0 { - log.Warn("try to log nothing") + log.Warn("tried to log nothing") tx.Rollback() - http.Error(w, "try to log nothing", http.StatusBadRequest) + http.Error(w, "tried to log nothing", http.StatusBadRequest) return } for i := 0; i < good.Count; i++ { @@ -68,7 +70,7 @@ func lockGoods(w http.ResponseWriter, r *http.Request) { if db.Error != nil || db.RowsAffected != 1 { http.Error(w, "the good was not found in database", http.StatusInternalServerError) tx.Rollback() - log.Panic("more then one good locked: ", db.Error) + log.Panic("there is more than one good locked: ", db.Error) return } count += 1 @@ -81,6 +83,7 @@ func lockGoods(w http.ResponseWriter, r *http.Request) { } +// Function to release locked goods func releaseGoods(w http.ResponseWriter, r *http.Request) { log := logger.HTTP(r) secret := r.Header.Get("secret") @@ -91,14 +94,14 @@ func releaseGoods(w http.ResponseWriter, r *http.Request) { result := db.RowsAffected if err != nil { - log.Warn("database error during release goods: ", err) - http.Error(w, "secret could not validate", http.StatusInternalServerError) + log.Warn("database error during the release of goods: ", err) + http.Error(w, "the secret could not be validated", http.StatusInternalServerError) return } if result <= 0 { log.Warn("no goods found") - http.Error(w, "no goods found to release", http.StatusNotFound) + http.Error(w, "there are no goods to release", http.StatusNotFound) return } diff --git a/http/good_lock_test.go b/http/good_lock_test.go index e881835..41927ed 100644 --- a/http/good_lock_test.go +++ b/http/good_lock_test.go @@ -11,6 +11,7 @@ import ( "github.com/genofire/hs_master-kss-monolith/test" ) +// Function to test lockGoods() func TestLockGoods(t *testing.T) { assertion, router := test.Init(t) good := &models.Good{ @@ -58,6 +59,7 @@ func TestLockGoods(t *testing.T) { test.Close() } +// Function to test releaseGoods() func TestReleaseGoods(t *testing.T) { now := time.Now() assertion, router := test.Init(t) diff --git a/http/good_show_test.go b/http/good_show_test.go index 1ef9dc9..2159924 100644 --- a/http/good_show_test.go +++ b/http/good_show_test.go @@ -38,7 +38,7 @@ func TestListGood(t *testing.T) { test.Close() } -// Function to getGoodAvailability() and getGoodAvailabilityCount() +// Function to test getGoodAvailability() and getGoodAvailabilityCount() func TestGetGoodAvailable(t *testing.T) { now := time.Now() assertion, router := test.Init(t) @@ -99,7 +99,7 @@ func TestGetGoodAvailable(t *testing.T) { } -// Function to getGoodFreshness() +// Function to test getGoodFreshness() func TestGetGoodFreshness(t *testing.T) { now := time.Now().Add(36 * time.Hour) assertion, router := test.Init(t) diff --git a/http/good_temp.go b/http/good_temp.go index bf8b18e..bce32b5 100644 --- a/http/good_temp.go +++ b/http/good_temp.go @@ -9,19 +9,19 @@ import ( "text/template" ) -// Path to the svg image template, that shows the availablity or freshness of a given good +// Path to the svg image template, that shows the availability or freshness of a given good // with a traffic light food labeling system var GoodAvailabilityTemplate string var GoodFreshnessTemplate string -// Function to calculate a percent value from a given value and an maximum value +// Function to calculate a percent value from a given value and a maximum value func tempPercent(value, max int) int { return value * 100 / max } // Function to calculate a partial radius, depending on a percentage value func tempProcessRadius(value, max, radius int) float64 { - return (1 - float64(value)/float64(max)) * float64(radius) * 2 * 3.14 + return (1 - float64(value) / float64(max)) * float64(radius) * 2 * 3.14 } // Function to get the SVG, that shows the availability with a traffic light food labeling system for a given good diff --git a/http/good_test.go b/http/good_test.go index 1b144ff..c57016c 100644 --- a/http/good_test.go +++ b/http/good_test.go @@ -73,14 +73,14 @@ func TestAddGood(t *testing.T) { runtime.HasPermission("testsessionkey", runtime.PermissionCreateGood) runtime.CleanCache() - // Test gatewaytimeout on product exists + // Test the gatewaytimeout on product exists _, w = session.JSONRequest("POST", "/api/good/1", good) assertion.Equal(http.StatusGatewayTimeout, w.StatusCode) time.Sleep(time.Duration(10) * time.Millisecond) runtime.CleanCache() - // Test gatewaytimeout on permission exists + // Test the gatewaytimeout on permission exists _, w = session.JSONRequest("POST", "/api/good/1", good) assertion.Equal(http.StatusGatewayTimeout, w.StatusCode) diff --git a/lib/database/database.go b/lib/database/database.go index 2a929fd..3d33ce1 100644 --- a/lib/database/database.go +++ b/lib/database/database.go @@ -23,14 +23,14 @@ var ( // Configuration of the database connection type Config struct { - // type of the database, currently supports sqlite and postgres - Type string - // connection configuration - Connection string - // create another connection for reading only + // Type of the database (currently supports sqlite and postgres) + Type string + // Connection configuration + Connection string + // Create another connection for reading only ReadConnection string - // enable logging of the generated sql string - Logging bool + // Enable logging of the generated sql string + Logging bool } // Function to open a database and set the given configuration diff --git a/lib/http/io.go b/lib/http/io.go index e6eb562..a9945d1 100644 --- a/lib/http/io.go +++ b/lib/http/io.go @@ -22,7 +22,7 @@ func Read(r *http.Request, to interface{}) (err error) { func Write(w http.ResponseWriter, data interface{}) { js, err := json.Marshal(data) if err != nil { - http.Error(w, "failed to encode response: "+err.Error(), http.StatusInternalServerError) + http.Error(w, "failed to encode response: " + err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") diff --git a/lib/worker/worker.go b/lib/worker/worker.go index 991d2f1..6442b34 100644 --- a/lib/worker/worker.go +++ b/lib/worker/worker.go @@ -1,4 +1,4 @@ -// Package with a lib for cronjobs to run in background +// Package with a lib for cronjobs to run in the background package worker import "time" diff --git a/lib/worker/worker_test.go b/lib/worker/worker_test.go index 041729e..e551ad9 100644 --- a/lib/worker/worker_test.go +++ b/lib/worker/worker_test.go @@ -1,4 +1,4 @@ -// Package with a lib for cronjobs to run in background +// Package with a lib for cronjobs to run in the background package worker import ( @@ -14,7 +14,7 @@ func TestWorker(t *testing.T) { runtime := 0 - w := NewWorker(time.Duration(5)*time.Millisecond, func() { + w := NewWorker(time.Duration(5) * time.Millisecond, func() { runtime = runtime + 1 }) go w.Start() diff --git a/models/config.go b/models/config.go index 7f3d926..73a4c32 100644 --- a/models/config.go +++ b/models/config.go @@ -13,27 +13,27 @@ import ( // Config file for this daemon (more information at the config_example.conf in this git repository) type Config struct { // address under which the api and static content of the webserver runs - WebserverBind string `toml:"webserver_bind"` + WebserverBind string `toml:"webserver_bind"` // path to deliver static content - Webroot string `toml:"webroot"` + Webroot string `toml:"webroot"` - Database database.Config `toml:"database"` - GoodRelease GoodReleaseConfig `toml:"good_release"` - CacheClean CacheWorkerConfig `toml:"cache_clean"` + Database database.Config `toml:"database"` + GoodRelease GoodReleaseConfig `toml:"good_release"` + CacheClean CacheWorkerConfig `toml:"cache_clean"` - // path to the svg image templates to show the availablity and freshness + // path to the SVG image templates to show the availability and freshness // of a given good with a traffic light food labeling system GoodAvailabilityTemplate string `toml:"good_availablity_template"` GoodFreshnessTemplate string `toml:"good_freshness_template"` - FouledDeleter Duration `toml:"fouled_deleted"` + FouledDeleter Duration `toml:"fouled_deleted"` - // URLs to other microservices that this services uses + // URLs to other microservices, which this service uses MicroserviceDependencies struct { - Product string `toml:"product"` - Permission string `toml:"permission"` - } `toml:"microservice_dependencies"` + Product string `toml:"product"` + Permission string `toml:"permission"` + } `toml:"microservice_dependencies"` } // Configuration of the Worker to clean the cache from values of other microservice @@ -48,7 +48,7 @@ type CacheWorkerConfig struct { type GoodReleaseConfig struct { // Run worker every Duration Every Duration `toml:"every"` - // Unlock those which are not used since Duration + // Unlock those, which are not used since Duration After Duration `toml:"after"` } diff --git a/models/duration.go b/models/duration.go index 7d0858f..3aa5a5d 100644 --- a/models/duration.go +++ b/models/duration.go @@ -8,7 +8,7 @@ import ( ) // Duration is a TOML datatype -// A duration string is a possibly signed sequence of decimal numbers and a unit suffix, +// A duration string is a possibly signed sequence of decimal numbers and a unit suffix, // such as "300s", "1.5h" or "5d". Valid time units are "s", "m", "h", "d", "w". type Duration struct { time.Duration @@ -28,8 +28,8 @@ func (d *Duration) UnmarshalTOML(dataInterface interface{}) error { return fmt.Errorf("invalid duration: \"%s\"", data) } - unit := data[len(data)-1] - value, err := strconv.Atoi(string(data[:len(data)-1])) + unit := data[len(data) - 1] + value, err := strconv.Atoi(string(data[:len(data) - 1])) if err != nil { return fmt.Errorf("unable to parse duration %s: %s", data, err) } diff --git a/models/good.go b/models/good.go index 9aecd6b..0a883ad 100644 --- a/models/good.go +++ b/models/good.go @@ -10,18 +10,18 @@ import ( "github.com/genofire/hs_master-kss-monolith/lib/database" ) -// Goods managed in this stock microservice +// Type of goods managed in this stock microservice type Good struct { - ID int64 `json:"id"` - ProductID int64 `json:"product_id"` - Position string `json:"position"` - Comment string `json:"comment"` - FouledAt *time.Time `json:"fouled_at"` + ID int64 `json:"id"` + ProductID int64 `json:"product_id"` + Position string `json:"position"` + Comment string `json:"comment"` + FouledAt *time.Time `json:"fouled_at"` - RecievedAt *time.Time `sql:"default:current_timestamp" json:"recieved_at"` + RecievedAt *time.Time `sql:"default:current_timestamp" json:"recieved_at"` // Make it temporary unusable - LockedAt *time.Time `json:"-"` - LockedSecret string `json:"-"` + LockedAt *time.Time `json:"-"` + LockedSecret string `json:"-"` // Make it unusable DeletedAt *time.Time `json:"-"` ManuelleDelete bool `json:"-"` diff --git a/models/structstorage.go b/models/structstorage.go deleted file mode 100644 index 761c714..0000000 --- a/models/structstorage.go +++ /dev/null @@ -1,4 +0,0 @@ -// Package with the mostly static content (models) of this microservice -package models - -// Store all the structs diff --git a/monolith/src/main/java/de/mstock/monolith/domain/DataTransferObjectFactory.java b/monolith/src/main/java/de/mstock/monolith/domain/DataTransferObjectFactory.java index eff14ad..d46644c 100644 --- a/monolith/src/main/java/de/mstock/monolith/domain/DataTransferObjectFactory.java +++ b/monolith/src/main/java/de/mstock/monolith/domain/DataTransferObjectFactory.java @@ -16,108 +16,109 @@ import de.mstock.monolith.web.ReviewDTO; public class DataTransferObjectFactory { - /** - * Creates a Data Transfer Object (DTO). - * - * @param category database entity - * @param locale the requested locale - * @return DTO - */ - public CategoryDTO createCategoryDTO(Category category, Locale locale) { - CategoryI18n i18n = category.getI18n().get(locale.getLanguage()); - CategoryDTO categoryDTO = new CategoryDTO(); - categoryDTO.setName(i18n.getName()); - categoryDTO.setPrettyUrlFragment(i18n.getPrettyUrlFragment()); - return categoryDTO; - } - - /** - * Creates a Data Transfer Object (DTO). - * - * @param product database entity - * @param locale the requested locale - * @return DTO - */ - public ProductDTO createProductDTO(Product product, Locale locale) { - return createProductDTO(product, locale, NumberFormat.getCurrencyInstance(locale)); - } - - private ProductDTO createProductDTO(Product product, Locale locale, NumberFormat numberFormat) { - ProductDTO productDTO = createProductWithoutReviewsDTO(product, locale, numberFormat); - ProductI18n i18n = product.getI18n().get(locale.getLanguage()); - productDTO.setReviews(createReviewDTOs(i18n.getReviews())); - return productDTO; - } - - /** - * Creates Data Transfer Objects (DTOs). - * - * @param products database entities - * @param locale the requested locale - * @return DTOs - */ - public List createProductDTOs(List products, Locale locale) { - List productDTOs = new ArrayList<>(products.size()); - NumberFormat numberFormat = NumberFormat.getCurrencyInstance(locale); - for (Product product : products) { - productDTOs.add(createProductDTO(product, locale, numberFormat)); + /** + * Creates a Data Transfer Object (DTO). + * + * @param category database entity + * @param locale the requested locale + * @return DTO + */ + public CategoryDTO createCategoryDTO(Category category, Locale locale) { + CategoryI18n i18n = category.getI18n().get(locale.getLanguage()); + CategoryDTO categoryDTO = new CategoryDTO(); + categoryDTO.setName(i18n.getName()); + categoryDTO.setPrettyUrlFragment(i18n.getPrettyUrlFragment()); + return categoryDTO; } - return productDTOs; - } - /** - * Creates Data Transfer Objects (DTOs) without loading their reviews. - * - * @param products database entities - * @param locale the requested locale - * @return DTOs - */ - public List createProductWithoutReviewsDTOs(List products, Locale locale) { - List productDTOs = new ArrayList<>(products.size()); - NumberFormat numberFormat = NumberFormat.getCurrencyInstance(locale); - for (Product product : products) { - productDTOs.add(createProductWithoutReviewsDTO(product, locale, numberFormat)); + /** + * Creates a Data Transfer Object (DTO). + * + * @param product database entity + * @param locale the requested locale + * @return DTO + */ + public ProductDTO createProductDTO(Product product, Locale locale) { + return createProductDTO(product, locale, NumberFormat.getCurrencyInstance(locale)); } - return productDTOs; - } - private ProductDTO createProductWithoutReviewsDTO(Product product, Locale locale, - NumberFormat numberFormat) { - ProductI18n i18n = product.getI18n().get(locale.getLanguage()); - String price = numberFormat.format(i18n.getPrice()); - ProductDTO productDTO = new ProductDTO(); - productDTO.setId(product.getId()); - productDTO.setItemNumber(product.getItemNumber()); - productDTO.setUnit(product.getUnit()); - productDTO.setName(i18n.getName()); - productDTO.setPrettyUrlFragment(i18n.getPrettyUrlFragment()); - productDTO.setPrice(price); - productDTO.setDescription(i18n.getDescription()); - return productDTO; - } - - /** - * Creates a Data Transfer Object (DTO). - * - * @param review database entity - * @return DTO - */ - public ReviewDTO createReviewDTO(Review review) { - ReviewDTO dto = new ReviewDTO(); - dto.setLanguage(review.getLocaleLanguage()); - dto.setRatingStars(review.getRatingStars()); - dto.setFirstName(review.getFirstName()); - dto.setLastName(review.getLastName()); - dto.setText(review.getText()); - return dto; - } - - private List createReviewDTOs(List reviews) { - List ratingDTOs = new ArrayList<>(reviews.size()); - for (Review review : reviews) { - ratingDTOs.add(createReviewDTO(review)); + private ProductDTO createProductDTO(Product product, Locale locale, NumberFormat numberFormat) { + ProductDTO productDTO = createProductWithoutReviewsDTO(product, locale, numberFormat); + ProductI18n i18n = product.getI18n().get(locale.getLanguage()); + productDTO.setReviews(createReviewDTOs(i18n.getReviews())); + return productDTO; + } + + /** + * Creates Data Transfer Objects (DTOs). + * + * @param products database entities + * @param locale the requested locale + * @return DTOs + */ + public List createProductDTOs(List products, Locale locale) { + List productDTOs = new ArrayList<>(products.size()); + NumberFormat numberFormat = NumberFormat.getCurrencyInstance(locale); + for (Product product : products) { + productDTOs.add(createProductDTO(product, locale, numberFormat)); + } + return productDTOs; + } + + /** + * Creates Data Transfer Objects (DTOs) without loading their reviews. + * + * @param products database entities + * @param locale the requested locale + * @return DTOs + */ + public List createProductWithoutReviewsDTOs(List products, Locale locale) { + List productDTOs = new ArrayList<>(products.size()); + NumberFormat numberFormat = NumberFormat.getCurrencyInstance(locale); + for (Product product : products) { + productDTOs.add(createProductWithoutReviewsDTO(product, locale, numberFormat)); + } + return productDTOs; + } + + private ProductDTO createProductWithoutReviewsDTO(Product product, Locale locale, + NumberFormat numberFormat) { + ProductI18n i18n = product.getI18n().get(locale.getLanguage()); + String price = numberFormat.format(i18n.getPrice()); + ProductDTO productDTO = new ProductDTO(); + // Addition: productDTO.setID() + productDTO.setId(product.getId()); + productDTO.setItemNumber(product.getItemNumber()); + productDTO.setUnit(product.getUnit()); + productDTO.setName(i18n.getName()); + productDTO.setPrettyUrlFragment(i18n.getPrettyUrlFragment()); + productDTO.setPrice(price); + productDTO.setDescription(i18n.getDescription()); + return productDTO; + } + + /** + * Creates a Data Transfer Object (DTO). + * + * @param review database entity + * @return DTO + */ + public ReviewDTO createReviewDTO(Review review) { + ReviewDTO dto = new ReviewDTO(); + dto.setLanguage(review.getLocaleLanguage()); + dto.setRatingStars(review.getRatingStars()); + dto.setFirstName(review.getFirstName()); + dto.setLastName(review.getLastName()); + dto.setText(review.getText()); + return dto; + } + + private List createReviewDTOs(List reviews) { + List ratingDTOs = new ArrayList<>(reviews.size()); + for (Review review : reviews) { + ratingDTOs.add(createReviewDTO(review)); + } + return Collections.unmodifiableList(ratingDTOs); } - return Collections.unmodifiableList(ratingDTOs); - } } diff --git a/monolith/src/main/java/de/mstock/monolith/web/HomepageController.java b/monolith/src/main/java/de/mstock/monolith/web/HomepageController.java index 19d0aea..5754576 100644 --- a/monolith/src/main/java/de/mstock/monolith/web/HomepageController.java +++ b/monolith/src/main/java/de/mstock/monolith/web/HomepageController.java @@ -17,16 +17,18 @@ public class HomepageController { @Autowired private ShopService shopService; + // Addition: contant with the address of the stock microservice adminfrontend private final String STOCKADMINFRONTENDTEMPLATE = "https://stock.pub.warehost.de/index.html"; /** - * Redirect + * Redirect to stock admin frontend * - * @param model Template model + * @param model Template model * @return The constant template name for the stock admin frontend. */ @RequestMapping(value = "/stockadmin", method = RequestMethod.GET) - public String redirect(Model model) {return "redirect:"+ this.STOCKADMINFRONTENDTEMPLATE; + public String redirect(Model model) { + return "redirect:" + this.STOCKADMINFRONTENDTEMPLATE; } /** diff --git a/monolith/src/main/java/de/mstock/monolith/web/ProductDTO.java b/monolith/src/main/java/de/mstock/monolith/web/ProductDTO.java index d14dafd..a7d3245 100644 --- a/monolith/src/main/java/de/mstock/monolith/web/ProductDTO.java +++ b/monolith/src/main/java/de/mstock/monolith/web/ProductDTO.java @@ -15,6 +15,7 @@ public class ProductDTO { private String description; private List reviews; + // Addition: int id, getId() and setID() public int getId() { return id; } diff --git a/monolith/src/main/resources/templates/product.html b/monolith/src/main/resources/templates/product.html index d221277..9b2d0bf 100644 --- a/monolith/src/main/resources/templates/product.html +++ b/monolith/src/main/resources/templates/product.html @@ -31,7 +31,10 @@

Product Name

+ + +

0,00 Euro

Description.

diff --git a/monolith/src/main/resources/templates/stockadmin.html b/monolith/src/main/resources/templates/stockadmin.html deleted file mode 100644 index f80b4b6..0000000 --- a/monolith/src/main/resources/templates/stockadmin.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - -
-
- -
-
-
- - -
-

© 2017

-
-
- - - - - \ No newline at end of file diff --git a/runtime/auth.go b/runtime/auth.go index f567dff..e0461ee 100644 --- a/runtime/auth.go +++ b/runtime/auth.go @@ -10,20 +10,20 @@ import ( "sync" ) -// URL to the microservice which manages permissions +// URL to the microservice, which manages permissions var PermissionURL string // Type of permission type Permission int -// Some permissions (the real permissions need to come from the permission microservice) +// Some permissions (the real permissions need to come from a permission microservice) const ( // permission to add goods to the stock - // e.g. if a good is received and now available to sell + // e.g. if a good is received and now available for selling PermissionCreateGood = 1 // permission to delete goods from the stock - // e.g. if a good becomes fouled and has to be removed + // e.g. if a good becomes fouled and has to be removed manually PermissionDeleteGood = 2 ) diff --git a/runtime/cache_worker_test.go b/runtime/cache_worker_test.go index 7476f51..40f00e5 100644 --- a/runtime/cache_worker_test.go +++ b/runtime/cache_worker_test.go @@ -8,7 +8,7 @@ import ( "github.com/genofire/hs_master-kss-monolith/models" ) -// Function to test the cache Worker +// Function to test the cacheWorker func TestCacheWorker(t *testing.T) { productExistCache[2] = boolMicroServiceCache{LastCheck: time.Now(), Value: true} diff --git a/runtime/good_fouled.go b/runtime/good_fouled.go index a62d43c..b062452 100644 --- a/runtime/good_fouled.go +++ b/runtime/good_fouled.go @@ -8,7 +8,7 @@ import ( "github.com/genofire/hs_master-kss-monolith/models" ) -// Function to remove automaticle goods after the are fouled +// Function to automatically remove goods, if they are fouled func GoodFouled() int { var goods []*models.Good var g models.Good diff --git a/runtime/good_fouled_test.go b/runtime/good_fouled_test.go index f8f67c4..89bb34a 100644 --- a/runtime/good_fouled_test.go +++ b/runtime/good_fouled_test.go @@ -11,7 +11,7 @@ import ( "github.com/genofire/hs_master-kss-monolith/models" ) -// Function to test the unlocking of goods +// Function to test fouledDelete() func TestFouledDelete(t *testing.T) { assert := assert.New(t) database.Open(database.Config{ diff --git a/runtime/good_release_test.go b/runtime/good_release_test.go index 1cbf305..8f18093 100644 --- a/runtime/good_release_test.go +++ b/runtime/good_release_test.go @@ -11,7 +11,7 @@ import ( "github.com/genofire/hs_master-kss-monolith/models" ) -// Function to test the unlocking of goods +// Function to test goodRelease() func TestGoodRelease(t *testing.T) { assert := assert.New(t) database.Open(database.Config{ diff --git a/runtime/productcache_test.go b/runtime/productcache_test.go index d541715..b0b00cc 100644 --- a/runtime/productcache_test.go +++ b/runtime/productcache_test.go @@ -9,7 +9,7 @@ import ( "github.com/stretchr/testify/assert" ) -// Function to test, if and which products exist (get information from the products catalogue) +// Function to test, if and which products exist (get information from the product catalogue) func TestProductExists(t *testing.T) { assert := assert.New(t) diff --git a/runtime/runtime.go b/runtime/runtime.go deleted file mode 100644 index 2049f4a..0000000 --- a/runtime/runtime.go +++ /dev/null @@ -1,5 +0,0 @@ -// Package with supporting functionality to run the microservice -package runtime - -// some mingled functionality to handle in background - diff --git a/test/testrest.go b/test/testrest.go index eb0185f..1a73189 100644 --- a/test/testrest.go +++ b/test/testrest.go @@ -25,6 +25,7 @@ type MockTransport struct { running bool } +// Function to use the http handler func (t *MockTransport) RoundTrip(req *http.Request) (*http.Response, error) { if !t.running { return nil, errors.New("mock a error") @@ -33,9 +34,13 @@ func (t *MockTransport) RoundTrip(req *http.Request) (*http.Response, error) { t.Handler.ServeHTTP(w, req) return w.Result(), nil } + +// Function to start the http handler func (t *MockTransport) Start() { t.running = true } + +// Function to close/stop the http handler func (t *MockTransport) Close() { t.running = false } @@ -73,7 +78,7 @@ func Close() { mock.Close() } -// Handle a test session with cookies +// Struct to dandle a test session with cookies type Request struct { req *http.Request cookies []*http.Cookie diff --git a/webroot/api-test/product/1/index.html b/webroot/api-test/product/1/index.html index 80376f8..d7ae1c0 100644 --- a/webroot/api-test/product/1/index.html +++ b/webroot/api-test/product/1/index.html @@ -1,4 +1,4 @@ { - "id": 1, - "title": "Kiwi" +"id": 1, +"title": "Kiwi" } diff --git a/webroot/api-test/product/2/index.html b/webroot/api-test/product/2/index.html index 00526ed..00332d5 100644 --- a/webroot/api-test/product/2/index.html +++ b/webroot/api-test/product/2/index.html @@ -1,4 +1,4 @@ { - "id": 2, - "title": "Blueberries" +"id": 2, +"title": "Blueberries" } diff --git a/webroot/api-test/product/3/index.html b/webroot/api-test/product/3/index.html index bf6a229..f10251a 100644 --- a/webroot/api-test/product/3/index.html +++ b/webroot/api-test/product/3/index.html @@ -1,4 +1,4 @@ { - "id": 3, - "title": "Cherries" +"id": 3, +"title": "Cherries" } diff --git a/webroot/api-test/product/4/index.html b/webroot/api-test/product/4/index.html index 923db88..df11269 100644 --- a/webroot/api-test/product/4/index.html +++ b/webroot/api-test/product/4/index.html @@ -1,4 +1,4 @@ { - "id": 4, - "title": "Potatoes" +"id": 4, +"title": "Potatoes" } diff --git a/webroot/api-test/product/5/index.html b/webroot/api-test/product/5/index.html index 1a4844b..926d7e0 100644 --- a/webroot/api-test/product/5/index.html +++ b/webroot/api-test/product/5/index.html @@ -1,4 +1,4 @@ { - "id": 5, - "title": "Tomatoes" +"id": 5, +"title": "Tomatoes" } diff --git a/webroot/api-test/product/6/index.html b/webroot/api-test/product/6/index.html index 9ddd068..bbef7ed 100644 --- a/webroot/api-test/product/6/index.html +++ b/webroot/api-test/product/6/index.html @@ -1,4 +1,4 @@ { - "id": 6, - "title": "Rhubarb" +"id": 6, +"title": "Rhubarb" } diff --git a/webroot/api-test/product/index.html b/webroot/api-test/product/index.html index 80b7db2..47d53fe 100644 --- a/webroot/api-test/product/index.html +++ b/webroot/api-test/product/index.html @@ -1,8 +1,8 @@ [ - {"id":1, "title": "Kiwi"}, - {"id":2, "title": "Blueberries"}, - {"id":3, "title": "Cherries"}, - {"id":4, "title": "Potatoes"}, - {"id":5, "title": "Tomatoes"}, - {"id":6, "title": "Rhubarb"} +{"id":1, "title": "Kiwi"}, +{"id":2, "title": "Blueberries"}, +{"id":3, "title": "Cherries"}, +{"id":4, "title": "Potatoes"}, +{"id":5, "title": "Tomatoes"}, +{"id":6, "title": "Rhubarb"} ] diff --git a/webroot/dummy_cart/index.html b/webroot/dummy_cart/index.html index e320443..5db4836 100644 --- a/webroot/dummy_cart/index.html +++ b/webroot/dummy_cart/index.html @@ -1,79 +1,81 @@ - - - - - - microStock Dummy Cart + + + + + + microStock Dummy Cart - - -
-
-
-
- -
-
- -
-
- -
-
-
- - - - - - - - - - - - - - - -
CountProduct
{{item.count}}{{getProduct(item.product_id).title}} -
-
-
- - - - - - - - - + + + + + + + + diff --git a/webroot/index.html b/webroot/index.html index cbb3565..29134b5 100644 --- a/webroot/index.html +++ b/webroot/index.html @@ -1,48 +1,49 @@ - - - - - - Stock Admin + + + + + + Stock Admin - -
+
-