diff --git a/LICENSE b/LICENSE index 261eeb9e..29f81d81 100644 --- a/LICENSE +++ b/LICENSE @@ -1,201 +1,201 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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. + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/README.md b/README.md index 58329d37..6d9edf2c 100644 --- a/README.md +++ b/README.md @@ -1,141 +1,137 @@ -# devon4quarkus cloud native reference project - -This is the reference project of [devon4quarkus](https://github.com/devonfw/devon4quarkus). - -If you want to learn more about Quarkus, please visit its website: https://quarkus.io/ . - -## Database & Jaeger & Prometheus - -The app uses data persistence and you need a working database to use it. We also use tracing and metrics collector. -There is a `docker-compose.yaml` in the root of this repo that provides all of them. -You can start the DB and Jaeger containers using simple cmd: -``` -docker-compose up -``` -If you want to use other DB, modify the params in `application.properties` - -To access Jaeger UI(tracing): http://localhost:16686 -To access Prometheus(metrics): http://localhost:9090/graph -To access health check of our app: http://localhost:8080/q/health - -## Running the application in dev mode - -You can run your application in dev mode that enables live coding using: -```shell script -./mvnw compile quarkus:dev -``` - -> **_NOTE:_** Quarkus now ships with a Dev UI, which is available in dev mode only at http://localhost:8080/q/dev/. - -## Running tests - -You can run tests from your IDE or via Maven. Simply run `./mvnw test ` or `./mvnw package` - -## Tkit quarkus - -Adding tkit libs to our project gives us several new features. Check the logs for example, all our business methods are now logged and timed. -The REST API now handles exceptions gracefully(as JSON response), and we get server side pagination with very little effort. -Our tests are now real integration tests with real postgres DB, and are stuitable for CI envs. - -## Access your REST endpoint - -Go to http://localhost:8080/animals - - -## OpenAPI & Swagger UI - -With your app running, go to http://localhost:8080/q/swagger-ui to see the Swagger UI visualizing your API. You can access the YAML OpenAPI schema under http://localhost:8080/q/openapi - -## Packaging and running the application - -The application can be packaged using: -```shell script -./mvnw package -``` -It produces the `quarkus-run.jar` file in the `target/quarkus-app/` directory. -Be aware that it’s not an _über-jar_ as the dependencies are copied into the `target/quarkus-app/lib/` directory. - -If you want to build an _über-jar_, execute the following command: -```shell script -./mvnw package -Dquarkus.package.type=uber-jar -``` - -The application is now runnable using `java -jar target/quarkus-app/quarkus-run.jar`. - -## Creating a native executable - -You can create a native executable using: -```shell script -./mvnw package -Pnative -``` - -Or, if you don't have GraalVM installed, you can run the native executable build in a container using: -```shell script -./mvnw package -Pnative -Dquarkus.native.container-build=true -``` - -You can then execute your native executable with: `./target/demo-quarkus-1.0.0-SNAPSHOT-runner` - -If you want to learn more about building native executables, please consult https://quarkus.io/guides/maven-tooling.html. - -## Maven settings - -It is recommended to use vanilla maven settings (no custom mirror, proxy) for better performance. If you have modified your default settings `~/.m2/settings.xml` please revert it, or run the maven commands with the clean settings included in this project using `-s ./settings.xml` - -## Deploy to kubernetes - -Create your k3d cluster and registry -```shell -k3d registry create registry --port 5000 -k3d cluster create -c k8s/dev.yaml -``` - -Package your app as docker container and push to local k3d registry: -> **_NOTE:_** Be sure to package your app as native before -```shell -docker build -f src/main/docker/Dockerfile.jvm . -t k3d-registry:5000/demo-quarkus:latest -docker push k3d-registry:5000/demo-quarkus:latest -``` - -If `push` fails because of unresolved host, you can add it manually (`c:\windows\system32\drivers\etc\hosts` on Windows or `/etc/hosts` on Linux) -```shell -127.0.0.1 k3d-registry -``` - -Then apply the k8s resources to your cluster(make sure your kubectl has the correct context first) - -```shell -kubectl apply -f k8s/postgres-deployment.yaml -kubectl apply -f k8s/postgres-service.yaml -kubectl apply -f k8s/deployment.yaml -kubectl apply -f k8s/service.yaml -kubectl apply -f k8s/ingress.yaml -``` - -Give it a few moments and then go to http://demo-quarkus.localhost - -## Helm - -Check our helm chart and update dependencies. -``` -helm lint helm/ -helm dependency update helm/ -``` - -Deploy helm chart in the k8s cluster -> **_NOTE:_** Be sure to remove your old resources -```shell -kubectl delete Service demo-quarkus -kubectl delete Deployment demo-quarkus -kubectl delete Ingress demo-quarkus -``` -``` -helm install demo-quarkus ./helm -helm list -``` - -We can also package helm as artefact for the helm repository: -``` -helm package helm/ -Successfully packaged chart and saved it to: .../demo-quarkus-1.0.0.tgz -``` +# devon4quarkus cloud native reference project + +This is the reference project of [devon4quarkus](https://github.com/devonfw/devon4quarkus). + +If you want to learn more about Quarkus, please visit its website: https://quarkus.io/ . + +## Database & Jaeger & Prometheus + +The app uses data persistence and you need a working database to use it. We also use tracing and metrics collector. +There is a `docker-compose.yaml` in the root of this repo that provides all of them. +You can start the DB and Jaeger containers using simple cmd: +``` +docker-compose up +``` +If you want to use other DB, modify the params in `application.properties` + +To access Jaeger UI(tracing): http://localhost:16686 +To access Prometheus(metrics): http://localhost:9090/graph +To access health check of our app: http://localhost:8080/q/health + +## Running the application in dev mode + +You can run your application in dev mode that enables live coding using: +```shell script +./mvnw compile quarkus:dev +``` + +> **_NOTE:_** Quarkus now ships with a Dev UI, which is available in dev mode only at http://localhost:8080/q/dev/. + +## Running tests + +You can run tests from your IDE or via Maven. Simply run `./mvnw test ` or `./mvnw package` + +## Tkit quarkus + +Adding tkit libs to our project gives us several new features. Check the logs for example, all our business methods are now logged and timed. +The REST API now handles exceptions gracefully(as JSON response), and we get server side pagination with very little effort. +Our tests are now real integration tests with real postgres DB, and are stuitable for CI envs. + +## Access your REST endpoint + +Go to http://localhost:8080/animals + + +## OpenAPI & Swagger UI + +With your app running, go to http://localhost:8080/q/swagger-ui to see the Swagger UI visualizing your API. You can access the YAML OpenAPI schema under http://localhost:8080/q/openapi + +## Packaging and running the application + +The application can be packaged using: +```shell script +./mvnw package +``` +It produces the `quarkus-run.jar` file in the `target/quarkus-app/` directory. +Be aware that it’s not an _über-jar_ as the dependencies are copied into the `target/quarkus-app/lib/` directory. + +If you want to build an _über-jar_, execute the following command: +```shell script +./mvnw package -Dquarkus.package.type=uber-jar +``` + +The application is now runnable using `java -jar target/quarkus-app/quarkus-run.jar`. + +## Creating a native executable + +You can create a native executable using: +```shell script +./mvnw package -Pnative +``` + +Or, if you don't have GraalVM installed, you can run the native executable build in a container using: +```shell script +./mvnw package -Pnative -Dquarkus.native.container-build=true +``` + +You can then execute your native executable with: `./target/demo-quarkus-1.0.0-SNAPSHOT-runner` + +If you want to learn more about building native executables, please consult https://quarkus.io/guides/maven-tooling.html. + +## Maven settings + +It is recommended to use vanilla maven settings (no custom mirror, proxy) for better performance. If you have modified your default settings `~/.m2/settings.xml` please revert it, or run the maven commands with the clean settings included in this project using `-s ./settings.xml` + +## Deploy to kubernetes + +To deploy the application, you need a Kubernetes cluster and a registry from which to pull the application image. + +Package your app as docker container and push the image to your local registry: + +```shell +docker build -f src/main/docker/Dockerfile.jvm . -t your-registry/demo-quarkus:latest +docker push your-registry/demo-quarkus:latest +``` + +Also enter the path to your registry in the `k8s/application-deployment.yaml` file so that Kubernetes knows where to get the image from. The location to change is marked with a "TODO" comment. + +Then apply the k8s resources to your cluster (make sure your kubectl has the correct context first) + +```shell +kubectl apply -f k8s/postgres-deployment.yaml +kubectl apply -f k8s/postgres-service.yaml +kubectl apply -f k8s/application-deployment.yaml +kubectl apply -f k8s/application-service.yaml +kubectl apply -f k8s/ingress.yaml +``` + +Give it a few moments and then open http://demo-quarkus.localhost/products/ in your browser. + +## Helm + +> **_NOTE:_** Be sure to remove your old resources first +```shell +kubectl delete -f k8s +``` + +First, in the `src/main/helm/values.yaml` file, specify the path to your registry from which you want to obtain the image. +Then you can deploy the application with the following command: + +```shell +helm install demo-quarkus src/main/helm +``` + +This will deploy the application and the corresponding Postgres database. +Try it out by opening http://demo-quarkus.localhost/products/ in your browser. + +To terminate the instances use the following command: +```shell +helm uninstall demo-quarkus +``` + +### OpenTelemetry integration + +Quarkus can be easily configured to support OpenTelemetry features that can be used in combination with tools such as Jaeger or VictoriaMetrics to monitor traces and metrics. +To learn more about OpenTelemetry, see the devonfw architecture browser in the [chapter about OpenTelemetry](https://devonfw.com/website/pages/architectures/solutions/monitoring_openTelemetry/). + +The `documentation` folder contains a guide with instructions on how to set up the application in combination with these tools. diff --git a/azure-terraform/Install-Terraform.ps1 b/azure-terraform/Install-Terraform.ps1 new file mode 100644 index 00000000..694431cd --- /dev/null +++ b/azure-terraform/Install-Terraform.ps1 @@ -0,0 +1,45 @@ + +Function Install-Terraform +{ + # Ensure to run the function with administrator privilege + if (-not (New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) + { Write-Host -ForegroundColor Red -Object "!!! Please run as Administrator !!!"; return } + + # Terrafrom download Url + $Url = 'https://www.terraform.io/downloads.html' + + # Local path to download the terraform zip file + $DownloadPath = 'C:\Terraform\' + + # Reg Key to set the persistent PATH + $RegPathKey = 'HKLM:\System\CurrentControlSet\Control\Session Manager\Environment' + + # Create the local folder if it doesn't exist + if ((Test-Path -Path $DownloadPath) -eq $false) { $null = New-Item -Path $DownloadPath -ItemType Directory -Force } + + # Download the Terraform exe in zip format + $Web = Invoke-WebRequest -Uri $Url + $FileInfo = $Web.Links | Where-Object href -match windows_amd64 + $DownloadLink = $FileInfo.href + $FileName = Split-Path -Path $DownloadLink -Leaf + $DownloadFile = [string]::Concat( $DownloadPath, $FileName ) + Invoke-RestMethod -Method Get -Uri $DownloadLink -OutFile $DownloadFile + + # Extract & delete the zip file + Expand-Archive -Path $DownloadFile -DestinationPath $DownloadPath -Force + Remove-Item -Path $DownloadFile -Force + + # Setting the persistent path in the registry if it is not set already + if ($DownloadPath -notin $($ENV:Path -split ';')) + { + $PathString = (Get-ItemProperty -Path $RegPathKey -Name PATH).Path + $PathString += ";$DownloadPath" + Set-ItemProperty -Path $RegPathKey -Name PATH -Value $PathString + + # Setting the path for the current session + $ENV:Path += ";$DownloadPath" + } + + # Verify the download + Invoke-Expression -Command "terraform version" +} diff --git a/azure-terraform/installation_setup_linux.sh b/azure-terraform/installation_setup_linux.sh new file mode 100644 index 00000000..ef13acfc --- /dev/null +++ b/azure-terraform/installation_setup_linux.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +echo "Install Azure CLI...." +#Get packages needed for the install process: +sudo apt-get update +sudo apt-get install ca-certificates curl apt-transport-https lsb-release gnupg + +#Download and install the Microsoft signing key: +curl -sL https://packages.microsoft.com/keys/microsoft.asc | +gpg --dearmor | +sudo tee /etc/apt/trusted.gpg.d/microsoft.gpg > /dev/null + +#Add the Azure CLI software repository +AZ_REPO=$(lsb_release -cs) +echo "deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ $AZ_REPO main" | +sudo tee /etc/apt/sources.list.d/azure-cli.list + +#Update repository information and install the azure-cli package +sudo apt-get update +sudo apt-get install azure-cli + +echo "az version" +az --version + +echo "Install the Kubectl...." + +az aks install-cli +kubectl version --client + +echo "Install helm package..." +curl https://baltocdn.com/helm/signing.asc | sudo apt-key add - +sudo apt-get install apt-transport-https --yes +echo "deb https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list +sudo apt-get update +sudo apt-get install helm +sudo helm version + +#terraform Installation +echo "Install Terraform..." +sudo apt-get update && sudo apt-get install -y gnupg software-properties-common curl +curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add - +sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main" +sudo apt-get update && sudo apt-get install terraform + +#terraform -help +terraform version + +#terraform destroy +#terraform destroy --auto-approve + + \ No newline at end of file diff --git a/azure-terraform/installation_setup_windows.ps1 b/azure-terraform/installation_setup_windows.ps1 new file mode 100644 index 00000000..e0daba98 --- /dev/null +++ b/azure-terraform/installation_setup_windows.ps1 @@ -0,0 +1,31 @@ + +echo "Install Azure cli..." +$ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest -Uri https://aka.ms/installazurecliwindows -OutFile .\AzureCLI.msi; Start-Process msiexec.exe -Wait -ArgumentList '/I AzureCLI.msi /quiet'; rm .\AzureCLI.msi + +echo "az version" +az --version + +echo "Install Chocolatey package " +#Install Chocolatey package before helm install +Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) +#Verify choco installation +choco + +echo "Install Kubectl.." +Install-AzAksKubectl + +#echo "Install kubectl using choco" +#choco install kubernetes-cli +#kubectl version --client + + + +echo "Install Helm package" +#Install Helm +choco install kubernetes-helm +#Verify helm installation +helm + +echo "Install Terraform.." +. .\Install-Terraform.ps1 +Install-Terraform diff --git a/azure-terraform/script_execute.sh b/azure-terraform/script_execute.sh new file mode 100644 index 00000000..e0e108fe --- /dev/null +++ b/azure-terraform/script_execute.sh @@ -0,0 +1,47 @@ + +echo "Switch into Terraform AKS Cluster Set-up directory" +cd terraform-aks-setup +# make sure terraform CLI is installed +#terraform + +# format the tf files +#terraform fmt + +# initialize terraform Azure modules +terraform init + +# validate the template +terraform validate + +# plan and save the infra changes into tfplan file +terraform plan + +# apply the infra changes +terraform apply --auto-approve + +# delete the infra +#terraform destroy + +cd ../ +echo "Switch into Terraform Helm Release directory" +cd terraform-helm-deploy +# make sure terraform CLI is installed +#terraform + +# format the tf files +#terraform fmt + +# initialize terraform Azure modules +terraform init + +# validate the template +terraform validate + +# plan and save the infra changes into tfplan file +terraform plan + +# apply the infra changes +terraform apply --auto-approve + +# delete the infra +#terraform destroy diff --git a/azure-terraform/terraform-aks-setup/main.tf b/azure-terraform/terraform-aks-setup/main.tf new file mode 100644 index 00000000..c07eaa5c --- /dev/null +++ b/azure-terraform/terraform-aks-setup/main.tf @@ -0,0 +1,31 @@ +resource "azurerm_resource_group" "aks-rg" { + name = var.resource_group_name + location = var.location +} + + +resource "azurerm_kubernetes_cluster" "aks" { + name = var.cluster_name + kubernetes_version = var.kubernetes_version + location = var.location + resource_group_name = azurerm_resource_group.aks-rg.name + dns_prefix = var.cluster_name + + default_node_pool { + name = "system" + node_count = var.system_node_count + vm_size = "Standard_DS2_v2" + type = "VirtualMachineScaleSets" + availability_zones = [1, 2, 3] + enable_auto_scaling = false + } + + identity { + type = "SystemAssigned" + } + + network_profile { + load_balancer_sku = "Standard" + network_plugin = "kubenet" + } +} diff --git a/azure-terraform/terraform-aks-setup/output.tf b/azure-terraform/terraform-aks-setup/output.tf new file mode 100644 index 00000000..5140c09c --- /dev/null +++ b/azure-terraform/terraform-aks-setup/output.tf @@ -0,0 +1,40 @@ +output "aks_node_rg" { + value = azurerm_kubernetes_cluster.aks.node_resource_group +} +output "kubernetes_cluster_name" { + value = azurerm_kubernetes_cluster.aks.name +} + +output "aks_id" { + value = azurerm_kubernetes_cluster.aks.id +} + +output "aks_fqdn" { + value = azurerm_kubernetes_cluster.aks.fqdn +} + +output "host" { + value = azurerm_kubernetes_cluster.aks.kube_config.0.host +} +/* +output "client_key" { + value = azurerm_kubernetes_cluster.aks.kube_config.0.client_key +} + +output "client_certificate" { + value = azurerm_kubernetes_cluster.aks.kube_config.0.client_certificate +} + +output "kube_config" { + value = azurerm_kubernetes_cluster.aks.kube_config_raw + sensitive = true +} + +output "cluster_username" { + value = azurerm_kubernetes_cluster.aks.kube_config.0.username +} + +output "cluster_password" { + value = azurerm_kubernetes_cluster.aks.kube_config.0.password +} +*/ \ No newline at end of file diff --git a/azure-terraform/terraform-aks-setup/provider.tf b/azure-terraform/terraform-aks-setup/provider.tf new file mode 100644 index 00000000..26496f47 --- /dev/null +++ b/azure-terraform/terraform-aks-setup/provider.tf @@ -0,0 +1,16 @@ +provider "azurerm" { + features {} + +} + +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "2.66.0" + } + } + + required_version = ">= 0.14" + +} diff --git a/azure-terraform/terraform-aks-setup/terraform.tfvars b/azure-terraform/terraform-aks-setup/terraform.tfvars new file mode 100644 index 00000000..b339991a --- /dev/null +++ b/azure-terraform/terraform-aks-setup/terraform.tfvars @@ -0,0 +1,5 @@ +resource_group_name = "AKSRG104" +location = "West Europe" +cluster_name = "k8s-cluster" +kubernetes_version = "1.19.13" +system_node_count = 2 diff --git a/azure-terraform/terraform-aks-setup/variables.tf b/azure-terraform/terraform-aks-setup/variables.tf new file mode 100644 index 00000000..3bc2c70c --- /dev/null +++ b/azure-terraform/terraform-aks-setup/variables.tf @@ -0,0 +1,20 @@ +variable "resource_group_name" { + type = string + description = "RG name in Azure" +} +variable "location" { + type = string + description = "Resources location in Azure" +} +variable "cluster_name" { + type = string + description = "AKS name in Azure" +} +variable "kubernetes_version" { + type = string + description = "Kubernetes version" +} +variable "system_node_count" { + type = number + description = "Number of AKS worker nodes" +} diff --git a/azure-terraform/terraform-helm-deploy/helm_release.tf b/azure-terraform/terraform-helm-deploy/helm_release.tf new file mode 100644 index 00000000..86d98910 --- /dev/null +++ b/azure-terraform/terraform-helm-deploy/helm_release.tf @@ -0,0 +1,55 @@ +data "terraform_remote_state" "aks" { + backend = "local" + config = { + path = "../../azure-terraform/terraform-aks-setup/terraform.tfstate" + } +} + +data "azurerm_kubernetes_cluster" "aks" { + name = var.cluster_name + resource_group_name = var.resource_group_name +} + +provider "kubernetes" { + host = data.azurerm_kubernetes_cluster.aks.kube_config.0.host + username = data.azurerm_kubernetes_cluster.aks.kube_config.0.username + password = data.azurerm_kubernetes_cluster.aks.kube_config.0.password + client_certificate = base64decode(data.azurerm_kubernetes_cluster.aks.kube_config.0.client_certificate) + client_key = base64decode(data.azurerm_kubernetes_cluster.aks.kube_config.0.client_key) + cluster_ca_certificate = base64decode(data.azurerm_kubernetes_cluster.aks.kube_config.0.cluster_ca_certificate) +} + +provider "helm" { + kubernetes { + host = data.azurerm_kubernetes_cluster.aks.kube_config.0.host + username = data.azurerm_kubernetes_cluster.aks.kube_config.0.username + password = data.azurerm_kubernetes_cluster.aks.kube_config.0.password + client_certificate = base64decode(data.azurerm_kubernetes_cluster.aks.kube_config.0.client_certificate) + client_key = base64decode(data.azurerm_kubernetes_cluster.aks.kube_config.0.client_key) + cluster_ca_certificate = base64decode(data.azurerm_kubernetes_cluster.aks.kube_config.0.cluster_ca_certificate) +} +} + +resource helm_release otel-release { + name = "otel-release-controller" + +# repository = "https://github.com/prathibhapadma/quarkus-otel-test-repo/tree/master/charts" + chart = "../../helm-charts/opentelementry" + + set { + name = "service.type" + value = "LoadBalancer" + } +} + +resource helm_release quarkus-app-release { + name = "quarkus-app-controller" + + #repository = "https://github.com/prathibhapadma/quarkus-otel-test-repo/tree/master/charts" + chart = "../../helm-charts/demo-quarkus" + + set { + name = "service.type" + value = "LoadBalancer" + } +} diff --git a/azure-terraform/terraform-helm-deploy/output.tf b/azure-terraform/terraform-helm-deploy/output.tf new file mode 100644 index 00000000..97bc1110 --- /dev/null +++ b/azure-terraform/terraform-helm-deploy/output.tf @@ -0,0 +1,7 @@ +output "Helm-charts" { + value = helm_release.otel-release.name +} + +output "Helm-Charts" { + value = helm_release.quarkus-app-release.name +} diff --git a/azure-terraform/terraform-helm-deploy/provider.tf b/azure-terraform/terraform-helm-deploy/provider.tf new file mode 100644 index 00000000..89d4f49b --- /dev/null +++ b/azure-terraform/terraform-helm-deploy/provider.tf @@ -0,0 +1,15 @@ +provider "azurerm" { + features {} + +} + +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "2.66.0" + } + } + + required_version = ">= 0.14" +} diff --git a/azure-terraform/terraform-helm-deploy/terraform.tfvars b/azure-terraform/terraform-helm-deploy/terraform.tfvars new file mode 100644 index 00000000..58adcfd7 --- /dev/null +++ b/azure-terraform/terraform-helm-deploy/terraform.tfvars @@ -0,0 +1,3 @@ +resource_group_name = "AKSRG104" +cluster_name = "k8s-cluster" + diff --git a/azure-terraform/terraform-helm-deploy/variables.tf b/azure-terraform/terraform-helm-deploy/variables.tf new file mode 100644 index 00000000..32153c45 --- /dev/null +++ b/azure-terraform/terraform-helm-deploy/variables.tf @@ -0,0 +1,23 @@ +variable "resource_group_name" { + type = string + description = "RG name in Azure" +} +variable "cluster_name" { + type = string + description = "AKS cluster_name in Azure" +} +/* +variable "Otel_name" { + type = string + description = "Deloyed Helm chart Name" +} +variable "App_name" { + type = string + description = "Deloyed Helm chart Name" +} + +variable "service_type" { + type = string + description = "Helm Release Service Type" +} +*/ diff --git a/azure-terraform/terraform_doc.asciidoc b/azure-terraform/terraform_doc.asciidoc new file mode 100644 index 00000000..b9ef8dd2 --- /dev/null +++ b/azure-terraform/terraform_doc.asciidoc @@ -0,0 +1,122 @@ + +== Provision an Aks Cluster with Terraform + +:url-az-account: https://portal.azure.com/#home + +:url-az-CLI: https://docs.microsoft.com/en-us/cli/azure/?view=azure-cli-latest + +:url-az-kubectl: https://docs.microsoft.com/en-us/azure/aks/tutorial-kubernetes-deploy-cluster?tabs=azure-cli + +:url-helm: https://helm.sh/docs/intro/install/ + +:url-terraform: https://learn.hashicorp.com/tutorials/terraform/install-cli + +:url-repo-code: https://github.com/devonfw-sample/devon4quarkus-reference/azure-terraform + +:url-script-linux: https://github.com/devonfw-sample/devon4quarkus-reference/azure-terraform/installation_setup_linux.sh + +:url-script-windows: https://github.com/devonfw-sample/devon4quarkus-reference/azure-terraform/installation_setup_windows.ps1 + +The Azure Kubernetes Service (AKS) is a fully managed Kubernetes service for deploying, managing and scaling containerized applications on Azure. + +== *Prerequisites:* + +. Sign up into {url-az-account}[Azure Account]. +. Install the Azure {url-az-CLI}[CLI]. +. Install the {url-az-kubectl}[kubectl]. +. Install the {url-helm}[Helm]. +. Install the {url-terraform}[Terraform]. + +== *Install the Prerequisites using Script* +Install all Prerequisites using an Automated script for Windows and Linux, as shown below. + +* The script located for Linux `devon4quarkus-reference/azure-terraform/installation_setup_linux.sh` and windows `devon4quarkus-reference/azure-terraform/installation_setup_windows.ps1`. + +== *Login to Azure Account* + +Before the terraform implementation we need to login Azure account through `Azure CLI`. +``` +az login +az account set --subscription $SUBSCRIPTION +``` + +== *Set-Up And Initialize Terraform Workspace* + +In your terminal, clone the following {url-repo-code}[repository] code. + +`$ git clone https://github.com/devonfw-sample/devon4quarkus-reference` + +You can explore this repository by changing the directories. + +`cd azure-terraform/terraform-aks-setup` + +List of the files used to provision the AKS Cluster. + +. `aks-cluster.tf` provisions a Resource Group and AKS Cluster. The default node pool defines the number of VMs and the VM type cluster uses. + +. `variables.tf` declares the variables to terraform, It can use reference to its configuration. + +. `terraform.tfvars` defines the variables values to terraform. + +. `outputs.tf` declares values that can be useful to interact with your Aks Cluster. + +. `versions.tf` set the Terraform version and defines the required provider block. + +== *Initialize Terraform* +After you have saved your customized variables file, Initialize your Terraform workspace, which will download the provider and initialize it with the values provided in your terraform.tfvars file. + +`$ terraform init` + +== *Terraform plan* +Terraform plan creates an execution of plan and evaluates a Terraform configuration to determine the desired state of all the resources it declares. + +`$terraform plan` + +== *Terraform apply* +Terraform apply will review the planned actions, your terminal output should indicate the plan is running and what resources will be created. + +`$ terraform apply` + +You can see this terraform apply will provision an Azure Resource Group and Aks Cluster. Confirm the apply with a yes. + +== *Deploy Helm-charts with the Helm Provider* + +The Terraform Helm provider allows you to deploy and manage your Kubernetes applications dynamically and securely. Create the Helm Provider in `helm_release.tf` and configure the helm-charts repository location. + +Change the directory in to `Helm Release Provider`. + +`cd azure-terraform/terraform-helm-deploy` + +Here we need to follow same steps as above process to deploy helm charts in to AKS cluster (Example: terraform init and terraform apply). + +*Note*: According to your working directory, you need to change `terraform-remote-state` path and `Helm Charts` path in `terraform-helm-deploy/helm_release.tf` file. + +== *Creating Terraform Plan using provided script* + +Terraform initialize and apply automated way using the provided script, the script located in `/devon4quarkus-reference/azure-terraform/script_execute.sh` + +== *Configure kubectl* + +Now that you've provisioned your AKS Cluster, you need to configure kubectl. + +Run the following command to retrieve the access credentials for your cluster and automatically configure kubectl. + +`az aks get-credentials --resource-group $(terraform output -raw resource_group_name) --name $(terraform output -raw kubernetes_cluster_name)` + +The Resource Group name and Kubernetes cluster name correspond to the output variables showed after the successful Terraform run. + +== *Access Kubernetes Dashboard* +Run the following command to generate the Azure portal link. + +`az aks browse --resource-group $(terraform output -raw resource_group_name) --name $(terraform output -raw kubernetes_cluster_name)` + +Go to the URL in your preferred browser to view the Kubernetes resource view. + +== *Clean up your workspace* +Run the destroy command and confirm with yes in your terminal. + +`$ terraform destroy` + +``` +Note: terraform destroy can clean your Aks Cluster but not Resource Group, Because we are not authorized to perform RG deletion. For that we need to raise ticket for IT Group. +``` diff --git a/charts/helm/Chart.yaml b/charts/helm/Chart.yaml new file mode 100644 index 00000000..1d1149c3 --- /dev/null +++ b/charts/helm/Chart.yaml @@ -0,0 +1,9 @@ +apiVersion: v3 +name: OpenTelemetry Helm template +version: 1.0.0 +description: Helm chart template for an OpenTelemetry Kubernetes deployment +appVersion: 1.0.0 +keywords: + - template +maintainers: + - name: devon4j Developer diff --git a/charts/helm/templates/configmap.yaml b/charts/helm/templates/configmap.yaml new file mode 100644 index 00000000..7b0c1735 --- /dev/null +++ b/charts/helm/templates/configmap.yaml @@ -0,0 +1,98 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: otel-agent +data: + otel-agent-config: | + receivers: + otlp: + protocols: + grpc: + + processors: + batch: + + exporters: + otlp: + endpoint: "otel-collector.default.svc.cluster.local:4317" + insecure: true + + service: + pipelines: + traces: + receivers: [otlp] + processors: [batch] + exporters: [otlp] + metrics: + receivers: [otlp] + processors: [batch] + exporters: [otlp] +--- + +apiVersion: v1 +kind: ConfigMap +metadata: + name: otel-collector +data: + otel-collector-config: | + receivers: + otlp: + protocols: + grpc: + http: + cors_allowed_origins: + - http://* + - https://* + + processors: + batch: + + exporters: + logging: + zipkin: + endpoint: "http://zipkin-all-in-one.default.svc.cluster.local:9411/api/v2/spans" + format: proto + jaeger: + endpoint: jaeger-all-in-one.default.svc.cluster.local:14250 + insecure: true + prometheus: + endpoint: "0.0.0.0:8889" + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [zipkin, jaeger] + processors: [batch] + metrics: + receivers: [otlp] + processors: [batch] + exporters: [prometheus] +--- + +apiVersion: v1 +kind: ConfigMap +metadata: + name: vmetrics-config +data: + vMetrics.yaml: | + scrape_configs: + - job_name: '{{ .Values.application.metrics.jobname }}' + scrape_interval: 10s + metrics_path: '{{ .Values.application.metrics.url }}' + static_configs: + - targets: ['{{ .Values.application.service.name }}:{{ .Values.application.service.port }}'] +--- + +apiVersion: v1 +kind: ConfigMap +metadata: + name: prometheus +data: + prometheus-config: | + scrape_configs: + - job_name: '{{ .Values.application.metrics.jobname }}' + scrape_interval: 10s + metrics_path: '{{ .Values.application.metrics.url }}' + static_configs: + - targets: ['{{ .Values.application.service.name }}:{{ .Values.application.service.port }}'] \ No newline at end of file diff --git a/charts/helm/templates/grafana-deployment.yaml b/charts/helm/templates/grafana-deployment.yaml new file mode 100644 index 00000000..2b965d62 --- /dev/null +++ b/charts/helm/templates/grafana-deployment.yaml @@ -0,0 +1,43 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + component: grafana + name: grafana +spec: + replicas: 1 + selector: + matchLabels: + component: grafana + template: + metadata: + labels: + component: grafana + spec: + containers: + - image: grafana/grafana + name: grafana + ports: + - containerPort: 3000 + resources: {} + restartPolicy: Always + +--- + +apiVersion: v1 +kind: Service +metadata: + labels: + component: grafana + name: grafana +spec: + ports: + - name: "3000" + port: 3000 + protocol: TCP + targetPort: 3000 + selector: + component: grafana + type: LoadBalancer #ClusterIP +status: + loadBalancer: {} diff --git a/charts/helm/templates/ingress.yaml b/charts/helm/templates/ingress.yaml new file mode 100644 index 00000000..a527080c --- /dev/null +++ b/charts/helm/templates/ingress.yaml @@ -0,0 +1,46 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: ingress +spec: + rules: + - host: {{ .Values.ingress.application.host }} + http: + paths: + - path: "/" + pathType: Prefix + backend: + service: + name: {{ .Values.application.service.name }} + port: + number: {{ .Values.ingress.application.port }} + - host: {{ .Values.ingress.jaeger.host }} + http: + paths: + - path: "/" + pathType: Prefix + backend: + service: + name: jaeger-all-in-one + port: + number: {{ .Values.ingress.jaeger.port }} + - host: {{ .Values.ingress.zipkin.host }} + http: + paths: + - path: "/" + pathType: Prefix + backend: + service: + name: zipkin-all-in-one + port: + number: {{ .Values.ingress.zipkin.port }} + - host: {{ .Values.ingress.grafana.host }} + http: + paths: + - path: "/" + pathType: Prefix + backend: + service: + name: grafana + port: + number: {{ .Values.ingress.grafana.port }} \ No newline at end of file diff --git a/charts/helm/templates/jaeger-all-in-one-deployment.yaml b/charts/helm/templates/jaeger-all-in-one-deployment.yaml new file mode 100644 index 00000000..60516367 --- /dev/null +++ b/charts/helm/templates/jaeger-all-in-one-deployment.yaml @@ -0,0 +1,54 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + component: jaeger-all-in-one + name: jaeger-all-in-one +spec: + replicas: 1 + selector: + matchLabels: + component: jaeger-all-in-one + strategy: {} + template: + metadata: + labels: + component: jaeger-all-in-one + spec: + containers: + - image: jaegertracing/all-in-one:latest + name: jaeger-all-in-one + ports: + - containerPort: 16686 + - containerPort: 14268 + - containerPort: 14250 + resources: {} + restartPolicy: Always + +--- + +apiVersion: v1 +kind: Service +metadata: + labels: + component: jaeger-all-in-one + name: jaeger-all-in-one +spec: + ports: + - name: "16686" + port: 16686 + protocol: TCP + targetPort: 16686 + - name: "14268" + port: 14268 + protocol: TCP + targetPort: 14268 + - name: "14250" + port: 14250 + protocol: TCP + targetPort: 14250 + selector: + component: jaeger-all-in-one + type: LoadBalancer #ClusterIP +status: + loadBalancer: {} diff --git a/charts/helm/templates/otel-agent-deployment.yaml b/charts/helm/templates/otel-agent-deployment.yaml new file mode 100644 index 00000000..5255e516 --- /dev/null +++ b/charts/helm/templates/otel-agent-deployment.yaml @@ -0,0 +1,98 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + component: otel-agent + name: otel-agent +spec: + replicas: 1 + selector: + matchLabels: + component: otel-agent + strategy: + type: Recreate + template: + metadata: + labels: + component: otel-agent + spec: + containers: + - args: + - /otelcol + - --config=/conf/otel-agent-config.yaml + - --log-level=DEBUG + image: otel/opentelemetry-collector:latest + name: otel-agent + ports: + - containerPort: 8888 + - containerPort: 14250 + - containerPort: 14268 + - containerPort: 55678 + - containerPort: 4317 + - containerPort: 9411 + - containerPort: 1777 + - containerPort: 13133 + resources: {} + volumeMounts: + - mountPath: /conf + name: otel-agent-config-volume + volumes: + - name: otel-agent-config-volume + configMap: + name: otel-agent + items: + - key: otel-agent-config + path: otel-agent-config.yaml + restartPolicy: Always + +--- + +apiVersion: v1 +kind: Service +metadata: + labels: + component: otel-agent + name: otel-agent +spec: + ports: + - name: "8887" + port: 8887 + + targetPort: 8888 + - name: "14250" + port: 14250 + protocol: TCP + targetPort: 14250 + - name: "14268" + port: 14268 + protocol: TCP + targetPort: 14268 + - name: "55678" + port: 55678 + protocol: TCP + targetPort: 55678 + - name: "4317" + port: 4317 + protocol: TCP + targetPort: 4317 + - name: "9411" + port: 9411 + protocol: TCP + targetPort: 9411 + - name: "1777" + port: 1777 + protocol: TCP + targetPort: 1777 + - name: "55679" + port: 55679 + protocol: TCP + targetPort: 55679 + - name: "13133" + port: 13133 + protocol: TCP + targetPort: 13133 + selector: + component: otel-agent + type: LoadBalancer #ClusterIP +status: + loadBalancer: {} diff --git a/charts/helm/templates/otel-collector-deployment.yaml b/charts/helm/templates/otel-collector-deployment.yaml new file mode 100644 index 00000000..318ef5bc --- /dev/null +++ b/charts/helm/templates/otel-collector-deployment.yaml @@ -0,0 +1,83 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + component: otel-collector + name: otel-collector +spec: + replicas: 1 + selector: + matchLabels: + component: otel-collector + strategy: + type: Recreate + template: + metadata: + labels: + component: otel-collector + spec: + containers: + - args: + - --config=/conf/otel-collector-config.yaml + - --log-level=DEBUG + image: otel/opentelemetry-collector:latest + name: otel-collector + ports: + - containerPort: 1888 + - containerPort: 8888 + - containerPort: 8889 + - containerPort: 13133 + - containerPort: 4317 + - containerPort: 55679 + resources: {} + volumeMounts: + - mountPath: /conf + name: otel-collector-config-volume + restartPolicy: Always + volumes: + - name: otel-collector-config-volume + configMap: + name: otel-collector + items: + - key: otel-collector-config + path: otel-collector-config.yaml + +--- + +apiVersion: v1 +kind: Service +metadata: + labels: + component: otel-collector + name: otel-collector +spec: + ports: + - name: "1888" + port: 1888 + protocol: TCP + targetPort: 1888 + - name: "8888" + port: 8888 + protocol: TCP + targetPort: 8888 + - name: "8889" + port: 8889 + protocol: TCP + targetPort: 8889 + - name: "13133" + port: 13133 + protocol: TCP + targetPort: 13133 + - name: "4317" + port: 4317 + protocol: TCP + targetPort: 4317 + - name: "55670" + port: 55670 + protocol: TCP + targetPort: 55679 + selector: + component: otel-collector + type: LoadBalancer #ClusterIP +status: + loadBalancer: {} diff --git a/charts/helm/templates/prometheus-deployment.yaml b/charts/helm/templates/prometheus-deployment.yaml new file mode 100644 index 00000000..c9fd2689 --- /dev/null +++ b/charts/helm/templates/prometheus-deployment.yaml @@ -0,0 +1,55 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + component: prometheus + name: prometheus +spec: + replicas: 1 + selector: + matchLabels: + component: prometheus + strategy: + type: Recreate + template: + metadata: + labels: + component: prometheus + spec: + containers: + - image: prom/prometheus:latest + name: prometheus + ports: + - containerPort: 9090 + resources: {} + volumeMounts: + - mountPath: /etc/prometheus/ + name: prometheus-config-volume + restartPolicy: Always + volumes: + - name: prometheus-config-volume + configMap: + name: prometheus + items: + - key: prometheus-config + path: prometheus.yml + +--- + +apiVersion: v1 +kind: Service +metadata: + labels: + component: prometheus + name: prometheus +spec: + ports: + - name: "9090" + port: 9090 + protocol: TCP + targetPort: 9090 + selector: + component: prometheus + type: LoadBalancer #ClusterIP +status: + loadBalancer: {} diff --git a/charts/helm/values.yaml b/charts/helm/values.yaml new file mode 100644 index 00000000..94eb543f --- /dev/null +++ b/charts/helm/values.yaml @@ -0,0 +1,26 @@ +# Application configuration +application: + # Configuration to get the metrics information + metrics: + jobname: "demo-quarkus" + url: "/q/metrics" + + # Configuration of the application service + service: + name: "demo-quarkus" + port: 8080 + +# Ingress configuration +ingress: + application: + host: "application.localhost" + port: 8080 + jaeger: + host: "jaeger.localhost" + port: 16686 + zipkin: + host: "zipkin.localhost" + port: 9411 + grafana: + host: "grafana.localhost" + port: 3000 diff --git a/charts/quarkus-app/Chart.yaml b/charts/quarkus-app/Chart.yaml new file mode 100644 index 00000000..c72fbaae --- /dev/null +++ b/charts/quarkus-app/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: helm-app +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: v1 #"1.16.0" diff --git a/charts/quarkus-app/templates/deployment.yaml b/charts/quarkus-app/templates/deployment.yaml new file mode 100644 index 00000000..9b43c911 --- /dev/null +++ b/charts/quarkus-app/templates/deployment.yaml @@ -0,0 +1,118 @@ +apiVersion: apps/v1 +kind: Deployment +# deployment v1 +metadata: + # metadata labels - tags under which this resources can be found in k8s api + labels: + app: demo-quarkus + app.kubernetes.io/name: demo-quarkus + name: demo-quarkus + namespace: default +spec: + # scale to 2 instances + replicas: 2 + selector: + #how are the pods linked together + matchLabels: + app: demo-quarkus + template: + metadata: + labels: + app: demo-quarkus + spec: + # pod spec, we want a single container in our pods + containers: + - name: demo-quarkus + # where should the image come from + image: 'dockerregistry101/demo-quarkus:latest' + #command: ["java", "-javaagent:agent/opentelemetry-javaagent-all.jar", "-Dotel.metrics.exporter=none", "-Dotel.exporter.otlp.endpoint=http://otel-collector:4317", "-Dotel.resource.attributes="service.name=quarkus-demo"] + #command: ["/deployments/run-java.sh"] + # always perform pull when creating pod + imagePullPolicy: Always + #env Secrets to pull image from regidtry + + # command: ["/deployments/run-java.sh", "&&", "java", "-javaagent:agent/opentelemetry-javaagent-all.jar", "-Dotel.metrics.exporter=none", "-Dotel.exporter.otlp.endpoint=http://otel-collector:4317", "-Dotel.resource.attributes='service.name=quarkus-demo'"] + # env vars so we can connect to DB + env: + - name: QUARKUS_DATASOURCE_JDBC_URL + value: jdbc:postgresql://postgresql:5432/demo + - name: QUARKUS_DATASOURCE_USERNAME + value: demo + - name: QUARKUS_DATASOURCE_PASSWORD + value: demo + - name: quarkus.opentelemetry.enabled + value: "true" + - name: quarkus.opentelemetry.tracer.exporter.otlp.endpoint + value: http://otel-agent:4317 + - name: quarkus.application.name + value: demo-quarkus + + # live & ready probes, using our healthcheck endpoints + livenessProbe: + failureThreshold: 5 + httpGet: + path: /q/health/live + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 30 + successThreshold: 1 + timeoutSeconds: 3 + ports: + - containerPort: 8080 + readinessProbe: + failureThreshold: 5 + httpGet: + path: /q/health/ready + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 30 + successThreshold: 1 + timeoutSeconds: 3 + # we can define init containers, single run jobs that run before our main container does + # we use them to init database and check that its ready + initContainers: + - command: + - /bin/bash + - '-c' + - >- + psql -tc "SELECT 1 FROM pg_database WHERE datname = + 'demo'" | grep -q 1 | psql -c "CREATE USER + demo WITH ENCRYPTED PASSWORD 'demo';" -c + "CREATE DATABASE demo;" -c "GRANT ALL PRIVILEGES + ON DATABASE demo TO demo;" + env: + - name: PGHOST + value: postgresql + - name: PGPORT + value: '5432' + - name: PGDATABASE + value: null + - name: PGUSER + value: postgres + - name: PGPASSWORD + value: postgres + - name: DISABLE_WELCOME_MESSAGE + value: 'true' + image: 'docker.io/bitnami/postgresql:12.2.0' + name: create-db + - command: + - /bin/bash + - '-c' + - until pg_isready; do echo waiting for database; sleep 2; done; + env: + - name: PGHOST + value: postgresql + - name: PGPORT + value: '5432' + - name: PGDATABASE + value: demo + - name: PGUSER + value: demo + - name: PGPASSWORD + value: demo + - name: DISABLE_WELCOME_MESSAGE + value: 'true' + image: 'docker.io/bitnami/postgresql:12.2.0' + name: check-db diff --git a/charts/quarkus-app/templates/ingress.yaml b/charts/quarkus-app/templates/ingress.yaml new file mode 100644 index 00000000..f0390a4d --- /dev/null +++ b/charts/quarkus-app/templates/ingress.yaml @@ -0,0 +1,20 @@ +# a simple ingress for our service +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: demo-quarkus + annotations: + ingress.kubernetes.io/ssl-redirect: "false" +spec: + rules: + - http: + paths: + - path: "/" + pathType: Prefix + backend: + service: + name: demo-quarkus + port: + number: 8080 + # #this will work if you have dnsmasq(tkit env guide) + host: demo-quarkus.localhost diff --git a/charts/quarkus-app/templates/postgres-deployment.yaml b/charts/quarkus-app/templates/postgres-deployment.yaml new file mode 100644 index 00000000..e3d8ff00 --- /dev/null +++ b/charts/quarkus-app/templates/postgres-deployment.yaml @@ -0,0 +1,79 @@ +apiVersion: apps/v1 +kind: Deployment +# deployment v1 +metadata: + name: postgresql +spec: + replicas: 1 + selector: + #how are the pods linked together + matchLabels: + app: postgresql + template: + metadata: + labels: + app: postgresql + spec: + containers: + - name: postgresql + image: 'docker.io/bitnami/postgresql:12.2.0' + ports: + - name: tcp-postgresql + containerPort: 5432 + protocol: TCP + env: + - name: POSTGRESQL_PORT_NUMBER + value: '5432' + - name: POSTGRESQL_VOLUME_DIR + value: /bitnami/postgresql + - name: PGDATA + value: /bitnami/postgresql/data + - name: POSTGRES_USER + value: postgres + #dont even try this in production + - name: POSTGRES_PASSWORD + value: postgres + - name: POSTGRES_DB + value: kubernetes + - name: DISABLE_WELCOME_MESSAGE + value: 'true' + - name: POSTGRESQL_ENABLE_LDAP + value: 'no' + resources: + requests: + cpu: 250m + memory: 256Mi + livenessProbe: + exec: + command: + - /bin/sh + - '-c' + - >- + exec pg_isready -U "postgres" -d "kubernetes" -h 127.0.0.1 -p + 5432 + initialDelaySeconds: 30 + timeoutSeconds: 5 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 6 + readinessProbe: + exec: + command: + - /bin/sh + - '-c' + - '-e' + - > + exec pg_isready -U "postgres" -d "kubernetes" -h 127.0.0.1 -p + 5432 + + [ -f /opt/bitnami/postgresql/tmp/.initialized ] || [ -f + /bitnami/postgresql/.initialized ] + initialDelaySeconds: 5 + timeoutSeconds: 5 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 6 + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent +# we run database without any persistent data volume - not a good idea, but sufficient for demo diff --git a/charts/quarkus-app/templates/postgres-service.yaml b/charts/quarkus-app/templates/postgres-service.yaml new file mode 100644 index 00000000..31cdc930 --- /dev/null +++ b/charts/quarkus-app/templates/postgres-service.yaml @@ -0,0 +1,15 @@ +kind: Service +apiVersion: v1 +metadata: + name: postgresql + labels: + app: postgresql +spec: + ports: + - name: tcp-postgresql + protocol: TCP + port: 5432 + targetPort: tcp-postgresql + selector: + app: postgresql + type: LoadBalancer #ClusterIP diff --git a/charts/quarkus-app/templates/service.yaml b/charts/quarkus-app/templates/service.yaml new file mode 100644 index 00000000..22f1f676 --- /dev/null +++ b/charts/quarkus-app/templates/service.yaml @@ -0,0 +1,17 @@ +kind: Service +apiVersion: v1 +metadata: + name: demo-quarkus + labels: + app: demo-quarkus +spec: + # we expose port 8080 which load balances traffic to the pods and their internal port 8080 + ports: + - name: http-port + protocol: TCP + port: 8080 + targetPort: 8080 +# how to find the pods we are load balancing + selector: + app: demo-quarkus + type: LoadBalancer #ClusterIP diff --git a/docker-compose.yaml b/docker-compose.yaml index c980df7f..616f7e97 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,117 +1,106 @@ -version: "3" - -services: - postgresdb: - image: postgres:11.5 - container_name: postgresdb - environment: - POSTGRES_HOST_AUTH_METHOD: trust - POSTGRES_USER: demo - POSTGRES_PASSWORD: demo - POSTGRES_DB: demo - command: [-cmax_prepared_transactions=100] - ports: - - "5432:5432" - networks: - - demo - - # Collector - otel-collector: - image: otel/opentelemetry-collector-dev:latest - command: ["--config=/conf/otel-collector-config.yaml", "--log-level=DEBUG"] - volumes: - - ./otel-collector-config.yaml:/conf/otel-collector-config.yaml - ports: - - "1888:1888" # pprof extension - - "8888:8888" # Prometheus metrics exposed by the collector - - "8889:8889" # Prometheus exporter metrics - - "13133:13133" # health_check extension - - "4317:4317" # OTLP gRPC receiver - - "55670:55679" # zpages extension - depends_on: - - jaeger-all-in-one - - zipkin-all-in-one - networks: - - demo - - # Zipkin - zipkin-all-in-one: - image: openzipkin/zipkin:latest - ports: - - "9411:9411" - networks: - - demo - - jaeger-all-in-one: - image: jaegertracing/all-in-one:latest - ports: - - "16686:16686" - - "14268" - - "14250" - networks: - - demo - - otel-agent: - image: otel/opentelemetry-collector-dev:latest - command: ["--config=/etc/otel-agent-config.yaml", "--log-level=DEBUG"] - volumes: - - ./otel-agent-config.yaml:/etc/otel-agent-config.yaml - ports: - - "8887:8888" # Prometheus metrics exposed by the agent - - "14250:14250" # Jaeger grpc receiver - - "14268:14268" # Jaeger http thrift receiver - - "55678" # OpenCensus receiver - - "4317" # OTLP gRPC receiver - - "9411" # Zipkin receiver - - "1777:1777" # pprof extension - - "55679:55679" # zpages extension - - "13133" # health_check - depends_on: - - otel-collector - networks: - - demo - - vmagent: - container_name: vmagent - image: victoriametrics/vmagent - depends_on: - - "victoriametrics" - ports: - - 8429:8429 - volumes: - - ./vMetrics.yaml:/etc/victoriametrics/vMetrics.yml - command: - - '--promscrape.config=/etc/victoriametrics/vMetrics.yml' - - '--remoteWrite.url=http://victoriametrics:8428/api/v1/write' - networks: - - demo - - victoriametrics: - container_name: victoriametrics - image: victoriametrics/victoria-metrics - ports: - - 8428:8428 - - 8089:8089 - - 8089:8089/udp - - 2003:2003 - - 2003:2003/udp - - 4242:4242 - command: - - --promscrape.config=/etc/victoriametrics/vMetrics.yml - volumes: - - ./vMetrics.yaml:/etc/victoriametrics/vMetrics.yml:ro - networks: - - demo - - prometheus: - container_name: prometheus - image: prom/prometheus:latest - volumes: - - ./prometheus.yaml:/etc/prometheus/prometheus.yml - ports: - - "9090:9090" - networks: - - demo - -networks: +version: "3" + +services: + postgresdb: + image: 'docker.io/bitnami/postgresql:12.2.0' + container_name: postgresdb + environment: + POSTGRES_HOST_AUTH_METHOD: trust + POSTGRES_USER: demo + POSTGRES_PASSWORD: demo + POSTGRES_DB: demo + command: [-cmax_prepared_transactions=100] + ports: + - "5432:5432" + networks: + - demo + + otel-agent: + image: otel/opentelemetry-collector-dev:latest + command: ["--config=/etc/otel-agent-config.yaml", "--log-level=DEBUG"] + volumes: + - ./otel-agent-config.yaml:/etc/otel-agent-config.yaml + ports: + - "8887:8888" # Prometheus metrics exposed by the agent + - "14250:14250" # Jaeger grpc receiver + - "14268:14268" # Jaeger http thrift receiver + - "55678" # OpenCensus receiver + - "4317" # OTLP gRPC receiver + - "9411" # Zipkin receiver + - "1777:1777" # pprof extension + - "55679:55679" # zpages extension + - "13133" # health_check + depends_on: + - otel-collector + networks: + - demo + + # Collector + otel-collector: + image: otel/opentelemetry-collector-dev:latest + command: ["--config=/conf/otel-collector-config.yaml", "--log-level=DEBUG"] + volumes: + - ./otel-collector-config.yaml:/conf/otel-collector-config.yaml + ports: + - "1888:1888" # pprof extension + - "8888:8888" # Prometheus metrics exposed by the collector + - "8889:8889" # Prometheus exporter metrics + - "13133:13133" # health_check extension + - "4317:4317" # OTLP gRPC receiver + - "55670:55679" # zpages extension + depends_on: + - jaeger-all-in-one + networks: + - demo + + jaeger-all-in-one: + image: jaegertracing/all-in-one:latest + ports: + - "16686:16686" + - "14268" + - "14250" + networks: + - demo + + vmagent: + container_name: vmagent + image: victoriametrics/vmagent + depends_on: + - "victoriametrics" + ports: + - 8429:8429 + volumes: + - ./vMetrics.yaml:/etc/victoriametrics/vMetrics.yml + command: + - '--promscrape.config=/etc/victoriametrics/vMetrics.yml' + - '--remoteWrite.url=http://victoriametrics:8428/api/v1/write' + networks: + - demo + + victoriametrics: + container_name: victoriametrics + image: victoriametrics/victoria-metrics + ports: + - 8428:8428 + - 8089:8089 + - 8089:8089/udp + - 2003:2003 + - 2003:2003/udp + - 4242:4242 + command: + - --promscrape.config=/etc/victoriametrics/vMetrics.yml + volumes: + - ./vMetrics.yaml:/etc/victoriametrics/vMetrics.yml:ro + networks: + - demo + + grafana: + container_name: grafana + image: grafana/grafana + ports: + - "3000:3000" + networks: + - demo + +networks: demo: \ No newline at end of file diff --git a/documentation/opentelemetry-deployment.asciidoc b/documentation/opentelemetry-deployment.asciidoc new file mode 100644 index 00000000..d4f91f5c --- /dev/null +++ b/documentation/opentelemetry-deployment.asciidoc @@ -0,0 +1,86 @@ +:toc: macro +toc::[] + += OpenTelemetry deployment + +Quarkus applications can easily use OpenTelemetry to collect information about traces and metrics. +This guide describes how to set up the application to support OpenTelemetry for exporting and visualizing traces and spans with tools such as Jaeger, VictoriaMetrics, and Grafana. + +For this setup you need a Kubernetes cluster, an installation of Helm and a local Docker registry. + +== Preparation of the application + +First, you need to create the application and Docker image. Use the following commands to package the application, create the Docker image, and push it to your local Docker registry. + +[shell] +---- +mvn clean package + +docker build src/main/docker/Dockerfile.jvm . -t demo-quarkus +docker tag demo-quarkus name-of-your-registry/demo-quarkus +docker push name-of-your-registry/demo-quarkus +---- + +After this the Docker image should be available in your Docker registry. + +== Deploy the OpenTelemetry components + +To deploy the components needed for the OpenTelemetry setup, we use the Helm template from the link:https://github.com/devonfw/architectures/tree/master/solutions/monitoring_openTelemetry/helm[devonfw architecture repository]. +Download the folder from Github or clone the repository by executing `git clone https://github.com/devonfw/architectures.git`. +Before we can deploy the Helm chart, we need to change some values in the `values.yaml` file. Set the following properties. + +[yaml] +---- +application: + metrics: + jobname: "demo-quarkus" + url: "/q/metrics" + + service: + name: "demo-quarkus" + port: 8080 + + ... +---- + +The install the Helm chart by executing `helm install opentelemetry helm` (make sure to pass the correct path to the Helm chart as the last parameter). + +This will deploy the following components: + +* OpenTelemetry agent +* OpenTelemetry collector +* Jaeger +* VictoriaMetrics +* Grafana + +== Configure the application + +The Quarkus application uses the `quarkus-opentelemetry-exporter-otlp` extension to export the traces. The extension is already added to the project. We just need to configure the application accordingly. +To do this, set the following environment variables in the `src/main/helm/templates/application-deployment.yaml` file. + +[yaml] +---- +... +- name: quarkus.opentelemetry.enabled + value: "true" +- name: quarkus.opentelemetry.tracer.exporter.otlp.endpoint + value: http://otel-agent:4317 +- name: quarkus.application.name + value: demo-quarkus +... +---- + +This will enable the export of the traces to the OpenTelemetry collector. + +Then deploy the application by executing `helm install demo-quarkus src/main/helm`. + +== Testing the components + +After these steps, the application and components for OpenTelemetry should work properly. +To verify the application, first open http://demo-quarkus.localhost/products in your browser. You should receive a JSON response listing all the products in the database. + +Open the Jaeger user interface by navigating to http://jaeger.localhost/search in your browser to view the application traces. Select "demo-quarkus" as the service name and view the results. Each time you make a request to the application, you should see a new record. + +Now let's take a look at the metrics. Navigate to http://grafana.localhost/ in your browser to open Grafana. Log in with the default username and password `admin`. Go to the configuration area and add a new datasource to view the metrics. +Select the "Prometheus" entry (VictoriaMetrics is compatible with Prometheus) and enter http://victoriametrics.default.svc.cluster.local:8428 as the URL. +After that you should be able to see the metrics in the Grafana Dashboard. diff --git a/helm-charts/demo-quarkus/Chart.yaml b/helm-charts/demo-quarkus/Chart.yaml new file mode 100644 index 00000000..c72fbaae --- /dev/null +++ b/helm-charts/demo-quarkus/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: helm-app +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: v1 #"1.16.0" diff --git a/helm-charts/demo-quarkus/templates/deployment.yaml b/helm-charts/demo-quarkus/templates/deployment.yaml new file mode 100644 index 00000000..9b43c911 --- /dev/null +++ b/helm-charts/demo-quarkus/templates/deployment.yaml @@ -0,0 +1,118 @@ +apiVersion: apps/v1 +kind: Deployment +# deployment v1 +metadata: + # metadata labels - tags under which this resources can be found in k8s api + labels: + app: demo-quarkus + app.kubernetes.io/name: demo-quarkus + name: demo-quarkus + namespace: default +spec: + # scale to 2 instances + replicas: 2 + selector: + #how are the pods linked together + matchLabels: + app: demo-quarkus + template: + metadata: + labels: + app: demo-quarkus + spec: + # pod spec, we want a single container in our pods + containers: + - name: demo-quarkus + # where should the image come from + image: 'dockerregistry101/demo-quarkus:latest' + #command: ["java", "-javaagent:agent/opentelemetry-javaagent-all.jar", "-Dotel.metrics.exporter=none", "-Dotel.exporter.otlp.endpoint=http://otel-collector:4317", "-Dotel.resource.attributes="service.name=quarkus-demo"] + #command: ["/deployments/run-java.sh"] + # always perform pull when creating pod + imagePullPolicy: Always + #env Secrets to pull image from regidtry + + # command: ["/deployments/run-java.sh", "&&", "java", "-javaagent:agent/opentelemetry-javaagent-all.jar", "-Dotel.metrics.exporter=none", "-Dotel.exporter.otlp.endpoint=http://otel-collector:4317", "-Dotel.resource.attributes='service.name=quarkus-demo'"] + # env vars so we can connect to DB + env: + - name: QUARKUS_DATASOURCE_JDBC_URL + value: jdbc:postgresql://postgresql:5432/demo + - name: QUARKUS_DATASOURCE_USERNAME + value: demo + - name: QUARKUS_DATASOURCE_PASSWORD + value: demo + - name: quarkus.opentelemetry.enabled + value: "true" + - name: quarkus.opentelemetry.tracer.exporter.otlp.endpoint + value: http://otel-agent:4317 + - name: quarkus.application.name + value: demo-quarkus + + # live & ready probes, using our healthcheck endpoints + livenessProbe: + failureThreshold: 5 + httpGet: + path: /q/health/live + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 30 + successThreshold: 1 + timeoutSeconds: 3 + ports: + - containerPort: 8080 + readinessProbe: + failureThreshold: 5 + httpGet: + path: /q/health/ready + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 30 + successThreshold: 1 + timeoutSeconds: 3 + # we can define init containers, single run jobs that run before our main container does + # we use them to init database and check that its ready + initContainers: + - command: + - /bin/bash + - '-c' + - >- + psql -tc "SELECT 1 FROM pg_database WHERE datname = + 'demo'" | grep -q 1 | psql -c "CREATE USER + demo WITH ENCRYPTED PASSWORD 'demo';" -c + "CREATE DATABASE demo;" -c "GRANT ALL PRIVILEGES + ON DATABASE demo TO demo;" + env: + - name: PGHOST + value: postgresql + - name: PGPORT + value: '5432' + - name: PGDATABASE + value: null + - name: PGUSER + value: postgres + - name: PGPASSWORD + value: postgres + - name: DISABLE_WELCOME_MESSAGE + value: 'true' + image: 'docker.io/bitnami/postgresql:12.2.0' + name: create-db + - command: + - /bin/bash + - '-c' + - until pg_isready; do echo waiting for database; sleep 2; done; + env: + - name: PGHOST + value: postgresql + - name: PGPORT + value: '5432' + - name: PGDATABASE + value: demo + - name: PGUSER + value: demo + - name: PGPASSWORD + value: demo + - name: DISABLE_WELCOME_MESSAGE + value: 'true' + image: 'docker.io/bitnami/postgresql:12.2.0' + name: check-db diff --git a/helm-charts/demo-quarkus/templates/ingress.yaml b/helm-charts/demo-quarkus/templates/ingress.yaml new file mode 100644 index 00000000..f0390a4d --- /dev/null +++ b/helm-charts/demo-quarkus/templates/ingress.yaml @@ -0,0 +1,20 @@ +# a simple ingress for our service +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: demo-quarkus + annotations: + ingress.kubernetes.io/ssl-redirect: "false" +spec: + rules: + - http: + paths: + - path: "/" + pathType: Prefix + backend: + service: + name: demo-quarkus + port: + number: 8080 + # #this will work if you have dnsmasq(tkit env guide) + host: demo-quarkus.localhost diff --git a/helm-charts/demo-quarkus/templates/postgres-deployment.yaml b/helm-charts/demo-quarkus/templates/postgres-deployment.yaml new file mode 100644 index 00000000..e3d8ff00 --- /dev/null +++ b/helm-charts/demo-quarkus/templates/postgres-deployment.yaml @@ -0,0 +1,79 @@ +apiVersion: apps/v1 +kind: Deployment +# deployment v1 +metadata: + name: postgresql +spec: + replicas: 1 + selector: + #how are the pods linked together + matchLabels: + app: postgresql + template: + metadata: + labels: + app: postgresql + spec: + containers: + - name: postgresql + image: 'docker.io/bitnami/postgresql:12.2.0' + ports: + - name: tcp-postgresql + containerPort: 5432 + protocol: TCP + env: + - name: POSTGRESQL_PORT_NUMBER + value: '5432' + - name: POSTGRESQL_VOLUME_DIR + value: /bitnami/postgresql + - name: PGDATA + value: /bitnami/postgresql/data + - name: POSTGRES_USER + value: postgres + #dont even try this in production + - name: POSTGRES_PASSWORD + value: postgres + - name: POSTGRES_DB + value: kubernetes + - name: DISABLE_WELCOME_MESSAGE + value: 'true' + - name: POSTGRESQL_ENABLE_LDAP + value: 'no' + resources: + requests: + cpu: 250m + memory: 256Mi + livenessProbe: + exec: + command: + - /bin/sh + - '-c' + - >- + exec pg_isready -U "postgres" -d "kubernetes" -h 127.0.0.1 -p + 5432 + initialDelaySeconds: 30 + timeoutSeconds: 5 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 6 + readinessProbe: + exec: + command: + - /bin/sh + - '-c' + - '-e' + - > + exec pg_isready -U "postgres" -d "kubernetes" -h 127.0.0.1 -p + 5432 + + [ -f /opt/bitnami/postgresql/tmp/.initialized ] || [ -f + /bitnami/postgresql/.initialized ] + initialDelaySeconds: 5 + timeoutSeconds: 5 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 6 + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent +# we run database without any persistent data volume - not a good idea, but sufficient for demo diff --git a/helm-charts/demo-quarkus/templates/postgres-service.yaml b/helm-charts/demo-quarkus/templates/postgres-service.yaml new file mode 100644 index 00000000..31cdc930 --- /dev/null +++ b/helm-charts/demo-quarkus/templates/postgres-service.yaml @@ -0,0 +1,15 @@ +kind: Service +apiVersion: v1 +metadata: + name: postgresql + labels: + app: postgresql +spec: + ports: + - name: tcp-postgresql + protocol: TCP + port: 5432 + targetPort: tcp-postgresql + selector: + app: postgresql + type: LoadBalancer #ClusterIP diff --git a/helm-charts/demo-quarkus/templates/service.yaml b/helm-charts/demo-quarkus/templates/service.yaml new file mode 100644 index 00000000..22f1f676 --- /dev/null +++ b/helm-charts/demo-quarkus/templates/service.yaml @@ -0,0 +1,17 @@ +kind: Service +apiVersion: v1 +metadata: + name: demo-quarkus + labels: + app: demo-quarkus +spec: + # we expose port 8080 which load balances traffic to the pods and their internal port 8080 + ports: + - name: http-port + protocol: TCP + port: 8080 + targetPort: 8080 +# how to find the pods we are load balancing + selector: + app: demo-quarkus + type: LoadBalancer #ClusterIP diff --git a/helm-charts/opentelementry/Chart.yaml b/helm-charts/opentelementry/Chart.yaml new file mode 100644 index 00000000..1d1149c3 --- /dev/null +++ b/helm-charts/opentelementry/Chart.yaml @@ -0,0 +1,9 @@ +apiVersion: v3 +name: OpenTelemetry Helm template +version: 1.0.0 +description: Helm chart template for an OpenTelemetry Kubernetes deployment +appVersion: 1.0.0 +keywords: + - template +maintainers: + - name: devon4j Developer diff --git a/helm-charts/opentelementry/templates/configmap.yaml b/helm-charts/opentelementry/templates/configmap.yaml new file mode 100644 index 00000000..7b0c1735 --- /dev/null +++ b/helm-charts/opentelementry/templates/configmap.yaml @@ -0,0 +1,98 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: otel-agent +data: + otel-agent-config: | + receivers: + otlp: + protocols: + grpc: + + processors: + batch: + + exporters: + otlp: + endpoint: "otel-collector.default.svc.cluster.local:4317" + insecure: true + + service: + pipelines: + traces: + receivers: [otlp] + processors: [batch] + exporters: [otlp] + metrics: + receivers: [otlp] + processors: [batch] + exporters: [otlp] +--- + +apiVersion: v1 +kind: ConfigMap +metadata: + name: otel-collector +data: + otel-collector-config: | + receivers: + otlp: + protocols: + grpc: + http: + cors_allowed_origins: + - http://* + - https://* + + processors: + batch: + + exporters: + logging: + zipkin: + endpoint: "http://zipkin-all-in-one.default.svc.cluster.local:9411/api/v2/spans" + format: proto + jaeger: + endpoint: jaeger-all-in-one.default.svc.cluster.local:14250 + insecure: true + prometheus: + endpoint: "0.0.0.0:8889" + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [zipkin, jaeger] + processors: [batch] + metrics: + receivers: [otlp] + processors: [batch] + exporters: [prometheus] +--- + +apiVersion: v1 +kind: ConfigMap +metadata: + name: vmetrics-config +data: + vMetrics.yaml: | + scrape_configs: + - job_name: '{{ .Values.application.metrics.jobname }}' + scrape_interval: 10s + metrics_path: '{{ .Values.application.metrics.url }}' + static_configs: + - targets: ['{{ .Values.application.service.name }}:{{ .Values.application.service.port }}'] +--- + +apiVersion: v1 +kind: ConfigMap +metadata: + name: prometheus +data: + prometheus-config: | + scrape_configs: + - job_name: '{{ .Values.application.metrics.jobname }}' + scrape_interval: 10s + metrics_path: '{{ .Values.application.metrics.url }}' + static_configs: + - targets: ['{{ .Values.application.service.name }}:{{ .Values.application.service.port }}'] \ No newline at end of file diff --git a/helm-charts/opentelementry/templates/grafana-deployment.yaml b/helm-charts/opentelementry/templates/grafana-deployment.yaml new file mode 100644 index 00000000..2b965d62 --- /dev/null +++ b/helm-charts/opentelementry/templates/grafana-deployment.yaml @@ -0,0 +1,43 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + component: grafana + name: grafana +spec: + replicas: 1 + selector: + matchLabels: + component: grafana + template: + metadata: + labels: + component: grafana + spec: + containers: + - image: grafana/grafana + name: grafana + ports: + - containerPort: 3000 + resources: {} + restartPolicy: Always + +--- + +apiVersion: v1 +kind: Service +metadata: + labels: + component: grafana + name: grafana +spec: + ports: + - name: "3000" + port: 3000 + protocol: TCP + targetPort: 3000 + selector: + component: grafana + type: LoadBalancer #ClusterIP +status: + loadBalancer: {} diff --git a/helm-charts/opentelementry/templates/ingress.yaml b/helm-charts/opentelementry/templates/ingress.yaml new file mode 100644 index 00000000..a527080c --- /dev/null +++ b/helm-charts/opentelementry/templates/ingress.yaml @@ -0,0 +1,46 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: ingress +spec: + rules: + - host: {{ .Values.ingress.application.host }} + http: + paths: + - path: "/" + pathType: Prefix + backend: + service: + name: {{ .Values.application.service.name }} + port: + number: {{ .Values.ingress.application.port }} + - host: {{ .Values.ingress.jaeger.host }} + http: + paths: + - path: "/" + pathType: Prefix + backend: + service: + name: jaeger-all-in-one + port: + number: {{ .Values.ingress.jaeger.port }} + - host: {{ .Values.ingress.zipkin.host }} + http: + paths: + - path: "/" + pathType: Prefix + backend: + service: + name: zipkin-all-in-one + port: + number: {{ .Values.ingress.zipkin.port }} + - host: {{ .Values.ingress.grafana.host }} + http: + paths: + - path: "/" + pathType: Prefix + backend: + service: + name: grafana + port: + number: {{ .Values.ingress.grafana.port }} \ No newline at end of file diff --git a/helm-charts/opentelementry/templates/jaeger-all-in-one-deployment.yaml b/helm-charts/opentelementry/templates/jaeger-all-in-one-deployment.yaml new file mode 100644 index 00000000..60516367 --- /dev/null +++ b/helm-charts/opentelementry/templates/jaeger-all-in-one-deployment.yaml @@ -0,0 +1,54 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + component: jaeger-all-in-one + name: jaeger-all-in-one +spec: + replicas: 1 + selector: + matchLabels: + component: jaeger-all-in-one + strategy: {} + template: + metadata: + labels: + component: jaeger-all-in-one + spec: + containers: + - image: jaegertracing/all-in-one:latest + name: jaeger-all-in-one + ports: + - containerPort: 16686 + - containerPort: 14268 + - containerPort: 14250 + resources: {} + restartPolicy: Always + +--- + +apiVersion: v1 +kind: Service +metadata: + labels: + component: jaeger-all-in-one + name: jaeger-all-in-one +spec: + ports: + - name: "16686" + port: 16686 + protocol: TCP + targetPort: 16686 + - name: "14268" + port: 14268 + protocol: TCP + targetPort: 14268 + - name: "14250" + port: 14250 + protocol: TCP + targetPort: 14250 + selector: + component: jaeger-all-in-one + type: LoadBalancer #ClusterIP +status: + loadBalancer: {} diff --git a/helm-charts/opentelementry/templates/otel-agent-deployment.yaml b/helm-charts/opentelementry/templates/otel-agent-deployment.yaml new file mode 100644 index 00000000..5255e516 --- /dev/null +++ b/helm-charts/opentelementry/templates/otel-agent-deployment.yaml @@ -0,0 +1,98 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + component: otel-agent + name: otel-agent +spec: + replicas: 1 + selector: + matchLabels: + component: otel-agent + strategy: + type: Recreate + template: + metadata: + labels: + component: otel-agent + spec: + containers: + - args: + - /otelcol + - --config=/conf/otel-agent-config.yaml + - --log-level=DEBUG + image: otel/opentelemetry-collector:latest + name: otel-agent + ports: + - containerPort: 8888 + - containerPort: 14250 + - containerPort: 14268 + - containerPort: 55678 + - containerPort: 4317 + - containerPort: 9411 + - containerPort: 1777 + - containerPort: 13133 + resources: {} + volumeMounts: + - mountPath: /conf + name: otel-agent-config-volume + volumes: + - name: otel-agent-config-volume + configMap: + name: otel-agent + items: + - key: otel-agent-config + path: otel-agent-config.yaml + restartPolicy: Always + +--- + +apiVersion: v1 +kind: Service +metadata: + labels: + component: otel-agent + name: otel-agent +spec: + ports: + - name: "8887" + port: 8887 + + targetPort: 8888 + - name: "14250" + port: 14250 + protocol: TCP + targetPort: 14250 + - name: "14268" + port: 14268 + protocol: TCP + targetPort: 14268 + - name: "55678" + port: 55678 + protocol: TCP + targetPort: 55678 + - name: "4317" + port: 4317 + protocol: TCP + targetPort: 4317 + - name: "9411" + port: 9411 + protocol: TCP + targetPort: 9411 + - name: "1777" + port: 1777 + protocol: TCP + targetPort: 1777 + - name: "55679" + port: 55679 + protocol: TCP + targetPort: 55679 + - name: "13133" + port: 13133 + protocol: TCP + targetPort: 13133 + selector: + component: otel-agent + type: LoadBalancer #ClusterIP +status: + loadBalancer: {} diff --git a/helm-charts/opentelementry/templates/otel-collector-deployment.yaml b/helm-charts/opentelementry/templates/otel-collector-deployment.yaml new file mode 100644 index 00000000..318ef5bc --- /dev/null +++ b/helm-charts/opentelementry/templates/otel-collector-deployment.yaml @@ -0,0 +1,83 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + component: otel-collector + name: otel-collector +spec: + replicas: 1 + selector: + matchLabels: + component: otel-collector + strategy: + type: Recreate + template: + metadata: + labels: + component: otel-collector + spec: + containers: + - args: + - --config=/conf/otel-collector-config.yaml + - --log-level=DEBUG + image: otel/opentelemetry-collector:latest + name: otel-collector + ports: + - containerPort: 1888 + - containerPort: 8888 + - containerPort: 8889 + - containerPort: 13133 + - containerPort: 4317 + - containerPort: 55679 + resources: {} + volumeMounts: + - mountPath: /conf + name: otel-collector-config-volume + restartPolicy: Always + volumes: + - name: otel-collector-config-volume + configMap: + name: otel-collector + items: + - key: otel-collector-config + path: otel-collector-config.yaml + +--- + +apiVersion: v1 +kind: Service +metadata: + labels: + component: otel-collector + name: otel-collector +spec: + ports: + - name: "1888" + port: 1888 + protocol: TCP + targetPort: 1888 + - name: "8888" + port: 8888 + protocol: TCP + targetPort: 8888 + - name: "8889" + port: 8889 + protocol: TCP + targetPort: 8889 + - name: "13133" + port: 13133 + protocol: TCP + targetPort: 13133 + - name: "4317" + port: 4317 + protocol: TCP + targetPort: 4317 + - name: "55670" + port: 55670 + protocol: TCP + targetPort: 55679 + selector: + component: otel-collector + type: LoadBalancer #ClusterIP +status: + loadBalancer: {} diff --git a/helm-charts/opentelementry/templates/prometheus-deployment.yaml b/helm-charts/opentelementry/templates/prometheus-deployment.yaml new file mode 100644 index 00000000..c9fd2689 --- /dev/null +++ b/helm-charts/opentelementry/templates/prometheus-deployment.yaml @@ -0,0 +1,55 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + component: prometheus + name: prometheus +spec: + replicas: 1 + selector: + matchLabels: + component: prometheus + strategy: + type: Recreate + template: + metadata: + labels: + component: prometheus + spec: + containers: + - image: prom/prometheus:latest + name: prometheus + ports: + - containerPort: 9090 + resources: {} + volumeMounts: + - mountPath: /etc/prometheus/ + name: prometheus-config-volume + restartPolicy: Always + volumes: + - name: prometheus-config-volume + configMap: + name: prometheus + items: + - key: prometheus-config + path: prometheus.yml + +--- + +apiVersion: v1 +kind: Service +metadata: + labels: + component: prometheus + name: prometheus +spec: + ports: + - name: "9090" + port: 9090 + protocol: TCP + targetPort: 9090 + selector: + component: prometheus + type: LoadBalancer #ClusterIP +status: + loadBalancer: {} diff --git a/helm-charts/opentelementry/values.yaml b/helm-charts/opentelementry/values.yaml new file mode 100644 index 00000000..94eb543f --- /dev/null +++ b/helm-charts/opentelementry/values.yaml @@ -0,0 +1,26 @@ +# Application configuration +application: + # Configuration to get the metrics information + metrics: + jobname: "demo-quarkus" + url: "/q/metrics" + + # Configuration of the application service + service: + name: "demo-quarkus" + port: 8080 + +# Ingress configuration +ingress: + application: + host: "application.localhost" + port: 8080 + jaeger: + host: "jaeger.localhost" + port: 16686 + zipkin: + host: "zipkin.localhost" + port: 9411 + grafana: + host: "grafana.localhost" + port: 3000 diff --git a/helm-otel/Chart.yaml b/helm-otel/Chart.yaml deleted file mode 100644 index 06f4ff4c..00000000 --- a/helm-otel/Chart.yaml +++ /dev/null @@ -1,8 +0,0 @@ -name: docker-compose -description: A generated Helm Chart for docker-compose from Skippbox Kompose -version: 0.0.1 -apiVersion: v1 -keywords: - - docker-compose -sources: -home: diff --git a/helm-otel/templates/configmap.yaml b/helm-otel/templates/configmap.yaml deleted file mode 100644 index c1f106fc..00000000 --- a/helm-otel/templates/configmap.yaml +++ /dev/null @@ -1,98 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: collector-config -data: - collector.yaml: | - receivers: - otlp: - protocols: - grpc: - http: - cors_allowed_origins: - - http://* - - https://* - - exporters: - prometheus: - endpoint: "0.0.0.0:8889" - namespace: promexample - const_labels: - label1: value1 - - zipkin: - endpoint: "http://zipkin-all-in-one:9411/api/v2/spans" - format: proto - - jaeger: - endpoint: jaeger-all-in-one:14250 - insecure: true - - processors: - batch: - - service: - pipelines: - traces: - receivers: [otlp] - exporters: [zipkin, jaeger] - processors: [batch] - metrics: - receivers: [otlp] - processors: [batch] - exporters: [prometheus] ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: agent-config -data: - agent.yaml: | - receivers: - otlp: - protocols: - grpc: - http: - opencensus: - jaeger: - protocols: - grpc: - thrift_http: - zipkin: - - exporters: - otlp: - endpoint: "otel-collector:4317" - insecure: true - logging: - loglevel: debug - - processors: - batch: - - service: - pipelines: - traces: - receivers: [otlp, zipkin, jaeger] - processors: [batch] - exporters: [otlp] - metrics: - receivers: [otlp] - processors: [batch] - exporters: [otlp] ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: vmetrics-config -data: - vMetrics.yaml: | - scrape_configs: - #- job_name: 'otel-collector' - - job_name: 'demo_quarkus' - scrape_interval: 10s - metrics_path: '/q/metrics' - static_configs: - - targets: ['reference-project:8080'] - #- targets: ['otel-collector:8889'] - #- targets: ['otel-collector:8888'] \ No newline at end of file diff --git a/helm-otel/templates/demo-networkpolicy.yaml b/helm-otel/templates/demo-networkpolicy.yaml deleted file mode 100644 index 8b57ef91..00000000 --- a/helm-otel/templates/demo-networkpolicy.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - creationTimestamp: null - name: demo -spec: - ingress: - - from: - - podSelector: - matchLabels: - io.kompose.network/demo: "true" - podSelector: - matchLabels: - io.kompose.network/demo: "true" diff --git a/helm-otel/templates/ingress.yaml b/helm-otel/templates/ingress.yaml deleted file mode 100644 index b9487531..00000000 --- a/helm-otel/templates/ingress.yaml +++ /dev/null @@ -1,40 +0,0 @@ -# a simple ingress for our service: exposed ingress according to https://k3d.io/usage/guides/exposing_services/ -# access via host:8081 - change hosts in hosts-file -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: reference-project - annotations: - ingress.kubernetes.io/ssl-redirect: "false" -spec: - rules: - - host: app.localhost - http: - paths: - - path: "/" - pathType: Prefix - backend: - service: - name: reference-project - port: - number: 8080 - - host: jaeger.localhost - http: - paths: - - path: "/" - pathType: Prefix - backend: - service: - name: jaeger-all-in-one - port: - number: 16686 - - host: zipkin.localhost - http: - paths: - - path: "/" - pathType: Prefix - backend: - service: - name: zipkin-all-in-one - port: - number: 9411 \ No newline at end of file diff --git a/helm-otel/templates/jaeger-all-in-one-deployment.yaml b/helm-otel/templates/jaeger-all-in-one-deployment.yaml deleted file mode 100644 index 0b87db57..00000000 --- a/helm-otel/templates/jaeger-all-in-one-deployment.yaml +++ /dev/null @@ -1,41 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - annotations: - kompose.cmd: C:\ProgramData\chocolatey\lib\kubernetes-kompose\tools\kompose.exe - convert -c - kompose.version: 1.21.0 (992df58d8) - creationTimestamp: null - labels: - io.kompose.service: jaeger-all-in-one - name: jaeger-all-in-one -spec: - replicas: 1 - selector: - matchLabels: - io.kompose.service: jaeger-all-in-one - strategy: {} - template: - metadata: - annotations: - kompose.cmd: C:\ProgramData\chocolatey\lib\kubernetes-kompose\tools\kompose.exe - convert -c - kompose.version: 1.21.0 (992df58d8) - creationTimestamp: null - labels: - io.kompose.network/demo: "true" - io.kompose.service: jaeger-all-in-one - spec: - containers: - - image: jaegertracing/all-in-one:latest - imagePullPolicy: "" - name: jaeger-all-in-one - ports: - - containerPort: 16686 - - containerPort: 14268 - - containerPort: 14250 - resources: {} - restartPolicy: Always - serviceAccountName: "" - volumes: null -status: {} diff --git a/helm-otel/templates/jaeger-all-in-one-service.yaml b/helm-otel/templates/jaeger-all-in-one-service.yaml deleted file mode 100644 index 73843832..00000000 --- a/helm-otel/templates/jaeger-all-in-one-service.yaml +++ /dev/null @@ -1,26 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - annotations: - kompose.cmd: C:\ProgramData\chocolatey\lib\kubernetes-kompose\tools\kompose.exe - convert -c - kompose.version: 1.21.0 (992df58d8) - creationTimestamp: null - labels: - io.kompose.service: jaeger-all-in-one - name: jaeger-all-in-one -spec: - ports: - - name: "16686" - port: 16686 - targetPort: 16686 - - name: "14268" - port: 14268 - targetPort: 14268 - - name: "14250" - port: 14250 - targetPort: 14250 - selector: - io.kompose.service: jaeger-all-in-one -status: - loadBalancer: {} diff --git a/helm-otel/templates/otel-agent-deployment.yaml b/helm-otel/templates/otel-agent-deployment.yaml deleted file mode 100644 index a5b82171..00000000 --- a/helm-otel/templates/otel-agent-deployment.yaml +++ /dev/null @@ -1,58 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - annotations: - kompose.cmd: C:\ProgramData\chocolatey\lib\kubernetes-kompose\tools\kompose.exe - convert -c - kompose.version: 1.21.0 (992df58d8) - creationTimestamp: null - labels: - io.kompose.service: otel-agent - name: otel-agent -spec: - replicas: 1 - selector: - matchLabels: - io.kompose.service: otel-agent - strategy: {} - template: - metadata: - annotations: - kompose.cmd: C:\ProgramData\chocolatey\lib\kubernetes-kompose\tools\kompose.exe - convert -c - kompose.version: 1.21.0 (992df58d8) - creationTimestamp: null - labels: - io.kompose.network/demo: "true" - io.kompose.service: otel-agent - spec: - containers: - - args: - - --config=/conf/agent.yaml - - --log-level=DEBUG - image: otel/opentelemetry-collector-dev:latest - imagePullPolicy: "" - name: otel-agent - ports: - - containerPort: 8888 - - containerPort: 14250 - - containerPort: 14268 - - containerPort: 55678 - - containerPort: 4317 - - containerPort: 9411 - - containerPort: 1777 - - containerPort: 13133 - resources: {} - volumeMounts: - - mountPath: /conf - name: agent-config - volumes: - - configMap: - items: - - key: agent.yaml - path: agent.yaml - name: agent-config - name: agent-config - restartPolicy: Always - serviceAccountName: "" -status: {} diff --git a/helm-otel/templates/otel-agent-service.yaml b/helm-otel/templates/otel-agent-service.yaml deleted file mode 100644 index 0d03d6c6..00000000 --- a/helm-otel/templates/otel-agent-service.yaml +++ /dev/null @@ -1,44 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - annotations: - kompose.cmd: C:\ProgramData\chocolatey\lib\kubernetes-kompose\tools\kompose.exe - convert -c - kompose.version: 1.21.0 (992df58d8) - creationTimestamp: null - labels: - io.kompose.service: otel-agent - name: otel-agent -spec: - ports: - - name: "8887" - port: 8887 - targetPort: 8888 - - name: "14250" - port: 14250 - targetPort: 14250 - - name: "14268" - port: 14268 - targetPort: 14268 - - name: "55678" - port: 55678 - targetPort: 55678 - - name: "4317" - port: 4317 - targetPort: 4317 - - name: "9411" - port: 9411 - targetPort: 9411 - - name: "1777" - port: 1777 - targetPort: 1777 - - name: "55679" - port: 55679 - targetPort: 55679 - - name: "13133" - port: 13133 - targetPort: 13133 - selector: - io.kompose.service: otel-agent -status: - loadBalancer: {} diff --git a/helm-otel/templates/otel-collector-deployment.yaml b/helm-otel/templates/otel-collector-deployment.yaml deleted file mode 100644 index 28d3e64e..00000000 --- a/helm-otel/templates/otel-collector-deployment.yaml +++ /dev/null @@ -1,56 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - annotations: - kompose.cmd: C:\ProgramData\chocolatey\lib\kubernetes-kompose\tools\kompose.exe - convert -c - kompose.version: 1.21.0 (992df58d8) - creationTimestamp: null - labels: - io.kompose.service: otel-collector - name: otel-collector -spec: - replicas: 1 - selector: - matchLabels: - io.kompose.service: otel-collector - strategy: {} - template: - metadata: - annotations: - kompose.cmd: C:\ProgramData\chocolatey\lib\kubernetes-kompose\tools\kompose.exe - convert -c - kompose.version: 1.21.0 (992df58d8) - creationTimestamp: null - labels: - io.kompose.network/demo: "true" - io.kompose.service: otel-collector - spec: - containers: - - args: - - --config=/conf/collector.yaml - - --log-level=DEBUG - image: otel/opentelemetry-collector-dev:latest - imagePullPolicy: "" - name: otel-collector - ports: - - containerPort: 1888 - - containerPort: 8888 - - containerPort: 8889 - - containerPort: 13133 - - containerPort: 4317 - - containerPort: 55679 - resources: {} - volumeMounts: - - mountPath: /conf - name: collector-config - volumes: - - configMap: - items: - - key: collector.yaml - path: collector.yaml - name: collector-config - name: collector-config - restartPolicy: Always - serviceAccountName: "" -status: {} diff --git a/helm-otel/templates/otel-collector-service.yaml b/helm-otel/templates/otel-collector-service.yaml deleted file mode 100644 index 212ffea9..00000000 --- a/helm-otel/templates/otel-collector-service.yaml +++ /dev/null @@ -1,35 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - annotations: - kompose.cmd: C:\ProgramData\chocolatey\lib\kubernetes-kompose\tools\kompose.exe - convert -c - kompose.version: 1.21.0 (992df58d8) - creationTimestamp: null - labels: - io.kompose.service: otel-collector - name: otel-collector -spec: - ports: - - name: "1888" - port: 1888 - targetPort: 1888 - - name: "8888" - port: 8888 - targetPort: 8888 - - name: "8889" - port: 8889 - targetPort: 8889 - - name: "13133" - port: 13133 - targetPort: 13133 - - name: "4317" - port: 4317 - targetPort: 4317 - - name: "55670" - port: 55670 - targetPort: 55679 - selector: - io.kompose.service: otel-collector -status: - loadBalancer: {} diff --git a/helm-otel/templates/postgresdb-deployment.yaml b/helm-otel/templates/postgresdb-deployment.yaml deleted file mode 100644 index 21278090..00000000 --- a/helm-otel/templates/postgresdb-deployment.yaml +++ /dev/null @@ -1,50 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - annotations: - kompose.cmd: C:\ProgramData\chocolatey\lib\kubernetes-kompose\tools\kompose.exe - convert -c - kompose.version: 1.21.0 (992df58d8) - creationTimestamp: null - labels: - io.kompose.service: postgresdb - name: postgresdb -spec: - replicas: 1 - selector: - matchLabels: - io.kompose.service: postgresdb - strategy: {} - template: - metadata: - annotations: - kompose.cmd: C:\ProgramData\chocolatey\lib\kubernetes-kompose\tools\kompose.exe - convert -c - kompose.version: 1.21.0 (992df58d8) - creationTimestamp: null - labels: - io.kompose.network/demo: "true" - io.kompose.service: postgresdb - spec: - containers: - - args: - - -cmax_prepared_transactions=100 - env: - - name: POSTGRES_DB - value: demo - - name: POSTGRES_HOST_AUTH_METHOD - value: trust - - name: POSTGRES_PASSWORD - value: demo - - name: POSTGRES_USER - value: demo - image: postgres:11.5 - imagePullPolicy: "" - name: postgresdb - ports: - - containerPort: 5432 - resources: {} - restartPolicy: Always - serviceAccountName: "" - volumes: null -status: {} diff --git a/helm-otel/templates/postgresdb-service.yaml b/helm-otel/templates/postgresdb-service.yaml deleted file mode 100644 index f2cb0769..00000000 --- a/helm-otel/templates/postgresdb-service.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - annotations: - kompose.cmd: C:\ProgramData\chocolatey\lib\kubernetes-kompose\tools\kompose.exe - convert -c - kompose.version: 1.21.0 (992df58d8) - creationTimestamp: null - labels: - io.kompose.service: postgresdb - name: postgresdb -spec: - ports: - - name: "5432" - port: 5432 - targetPort: 5432 - selector: - io.kompose.service: postgresdb -status: - loadBalancer: {} diff --git a/helm-otel/templates/prometheus-deployment.yaml b/helm-otel/templates/prometheus-deployment.yaml deleted file mode 100644 index ef7999ea..00000000 --- a/helm-otel/templates/prometheus-deployment.yaml +++ /dev/null @@ -1,39 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - annotations: - kompose.cmd: C:\ProgramData\chocolatey\lib\kubernetes-kompose\tools\kompose.exe - convert -c - kompose.version: 1.21.0 (992df58d8) - creationTimestamp: null - labels: - io.kompose.service: prometheus - name: prometheus -spec: - replicas: 1 - selector: - matchLabels: - io.kompose.service: prometheus - strategy: {} - template: - metadata: - annotations: - kompose.cmd: C:\ProgramData\chocolatey\lib\kubernetes-kompose\tools\kompose.exe - convert -c - kompose.version: 1.21.0 (992df58d8) - creationTimestamp: null - labels: - io.kompose.network/demo: "true" - io.kompose.service: prometheus - spec: - containers: - - image: prom/prometheus:latest - imagePullPolicy: "" - name: prometheus - ports: - - containerPort: 9090 - resources: {} - restartPolicy: Always - serviceAccountName: "" - volumes: null -status: {} diff --git a/helm-otel/templates/prometheus-service.yaml b/helm-otel/templates/prometheus-service.yaml deleted file mode 100644 index 9f120e5a..00000000 --- a/helm-otel/templates/prometheus-service.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - annotations: - kompose.cmd: C:\ProgramData\chocolatey\lib\kubernetes-kompose\tools\kompose.exe - convert -c - kompose.version: 1.21.0 (992df58d8) - creationTimestamp: null - labels: - io.kompose.service: prometheus - name: prometheus -spec: - ports: - - name: "9090" - port: 9090 - targetPort: 9090 - selector: - io.kompose.service: prometheus -status: - loadBalancer: {} diff --git a/helm-otel/templates/reference-project-deployment.yaml b/helm-otel/templates/reference-project-deployment.yaml deleted file mode 100644 index 6b02ebe8..00000000 --- a/helm-otel/templates/reference-project-deployment.yaml +++ /dev/null @@ -1,48 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - annotations: - kompose.cmd: C:\ProgramData\chocolatey\lib\kubernetes-kompose\tools\kompose.exe - convert -c - kompose.version: 1.21.0 (992df58d8) - creationTimestamp: null - labels: - io.kompose.service: reference-project - name: reference-project -spec: - replicas: 1 - selector: - matchLabels: - io.kompose.service: reference-project - strategy: {} - template: - metadata: - annotations: - kompose.cmd: C:\ProgramData\chocolatey\lib\kubernetes-kompose\tools\kompose.exe - convert -c - kompose.version: 1.21.0 (992df58d8) - creationTimestamp: null - labels: - io.kompose.network/demo: "true" - io.kompose.service: reference-project - spec: - containers: - - env: - - name: QUARKUS_DATASOURCE_PASSWORD - value: demo - - name: QUARKUS_DATASOURCE_USERNAME - value: demo - - name: quarkus.datasource.jdbc.url - value: jdbc:postgresql://postgresdb:5432/demo - - name: quarkus.opentelemetry.tracer.exporter.jaeger.endpoint - value: http://otel-agent:14250 - image: k3d-myregistry.localhost:5000/ref-project:latest - imagePullPolicy: "" - name: reference-project - ports: - - containerPort: 8080 - resources: {} - restartPolicy: Always - serviceAccountName: "" - volumes: null -status: {} diff --git a/helm-otel/templates/reference-project-service.yaml b/helm-otel/templates/reference-project-service.yaml deleted file mode 100644 index a2697bdd..00000000 --- a/helm-otel/templates/reference-project-service.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - annotations: - kompose.cmd: C:\ProgramData\chocolatey\lib\kubernetes-kompose\tools\kompose.exe - convert -c - kompose.version: 1.21.0 (992df58d8) - creationTimestamp: null - labels: - io.kompose.service: reference-project - name: reference-project -spec: - ports: - - name: "8080" - port: 8080 - targetPort: 8080 - selector: - io.kompose.service: reference-project -status: - loadBalancer: {} diff --git a/helm-otel/templates/victoriametrics-deployment.yaml b/helm-otel/templates/victoriametrics-deployment.yaml deleted file mode 100644 index 0de2ca07..00000000 --- a/helm-otel/templates/victoriametrics-deployment.yaml +++ /dev/null @@ -1,57 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - annotations: - kompose.cmd: C:\ProgramData\chocolatey\lib\kubernetes-kompose\tools\kompose.exe - convert -c - kompose.version: 1.21.0 (992df58d8) - creationTimestamp: null - labels: - io.kompose.service: victoriametrics - name: victoriametrics -spec: - replicas: 1 - selector: - matchLabels: - io.kompose.service: victoriametrics - strategy: {} - template: - metadata: - annotations: - kompose.cmd: C:\ProgramData\chocolatey\lib\kubernetes-kompose\tools\kompose.exe - convert -c - kompose.version: 1.21.0 (992df58d8) - creationTimestamp: null - labels: - io.kompose.network/demo: "true" - io.kompose.service: victoriametrics - spec: - containers: - - args: - - --promscrape.config=/conf/vMetrics.yaml - image: victoriametrics/victoria-metrics - imagePullPolicy: "" - name: victoriametrics - ports: - - containerPort: 8428 - - containerPort: 8089 - - containerPort: 8089 - protocol: UDP - - containerPort: 2003 - - containerPort: 2003 - protocol: UDP - - containerPort: 4242 - resources: {} - volumeMounts: - - mountPath: /conf - name: vmetrics-config - volumes: - - configMap: - items: - - key: vMetrics.yaml - path: vMetrics.yaml - name: vmetrics-config - name: vmetrics-config - restartPolicy: Always - serviceAccountName: "" -status: {} diff --git a/helm-otel/templates/victoriametrics-service.yaml b/helm-otel/templates/victoriametrics-service.yaml deleted file mode 100644 index 2df8b51a..00000000 --- a/helm-otel/templates/victoriametrics-service.yaml +++ /dev/null @@ -1,37 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - annotations: - kompose.cmd: C:\ProgramData\chocolatey\lib\kubernetes-kompose\tools\kompose.exe - convert -c - kompose.version: 1.21.0 (992df58d8) - creationTimestamp: null - labels: - io.kompose.service: victoriametrics - name: victoriametrics -spec: - ports: - - name: "8428" - port: 8428 - targetPort: 8428 - - name: "8089" - port: 8089 - targetPort: 8089 - - name: 8089-udp - port: 8089 - protocol: UDP - targetPort: 8089 - - name: "2003" - port: 2003 - targetPort: 2003 - - name: 2003-udp - port: 2003 - protocol: UDP - targetPort: 2003 - - name: "4242" - port: 4242 - targetPort: 4242 - selector: - io.kompose.service: victoriametrics -status: - loadBalancer: {} diff --git a/helm-otel/templates/vmagent-deployment.yaml b/helm-otel/templates/vmagent-deployment.yaml deleted file mode 100644 index 072b6226..00000000 --- a/helm-otel/templates/vmagent-deployment.yaml +++ /dev/null @@ -1,51 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - annotations: - kompose.cmd: C:\ProgramData\chocolatey\lib\kubernetes-kompose\tools\kompose.exe - convert -c - kompose.version: 1.21.0 (992df58d8) - creationTimestamp: null - labels: - io.kompose.service: vmagent - name: vmagent -spec: - replicas: 1 - selector: - matchLabels: - io.kompose.service: vmagent - strategy: {} - template: - metadata: - annotations: - kompose.cmd: C:\ProgramData\chocolatey\lib\kubernetes-kompose\tools\kompose.exe - convert -c - kompose.version: 1.21.0 (992df58d8) - creationTimestamp: null - labels: - io.kompose.network/demo: "true" - io.kompose.service: vmagent - spec: - containers: - - args: - - --promscrape.config=/conf/vMetrics.yaml - - --remoteWrite.url=http://victoriametrics:8428/api/v1/write - image: victoriametrics/vmagent - imagePullPolicy: "" - name: vmagent - ports: - - containerPort: 8429 - resources: {} - volumeMounts: - - mountPath: /conf - name: vmetrics-config - volumes: - - configMap: - items: - - key: vMetrics.yaml - path: vMetrics.yaml - name: vmetrics-config - name: vmetrics-config - restartPolicy: Always - serviceAccountName: "" -status: {} diff --git a/helm-otel/templates/vmagent-service.yaml b/helm-otel/templates/vmagent-service.yaml deleted file mode 100644 index 97697fca..00000000 --- a/helm-otel/templates/vmagent-service.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - annotations: - kompose.cmd: C:\ProgramData\chocolatey\lib\kubernetes-kompose\tools\kompose.exe - convert -c - kompose.version: 1.21.0 (992df58d8) - creationTimestamp: null - labels: - io.kompose.service: vmagent - name: vmagent -spec: - ports: - - name: "8429" - port: 8429 - targetPort: 8429 - selector: - io.kompose.service: vmagent -status: - loadBalancer: {} diff --git a/helm-otel/templates/zipkin-all-in-one-deployment.yaml b/helm-otel/templates/zipkin-all-in-one-deployment.yaml deleted file mode 100644 index 77bfe8fd..00000000 --- a/helm-otel/templates/zipkin-all-in-one-deployment.yaml +++ /dev/null @@ -1,39 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - annotations: - kompose.cmd: C:\ProgramData\chocolatey\lib\kubernetes-kompose\tools\kompose.exe - convert -c - kompose.version: 1.21.0 (992df58d8) - creationTimestamp: null - labels: - io.kompose.service: zipkin-all-in-one - name: zipkin-all-in-one -spec: - replicas: 1 - selector: - matchLabels: - io.kompose.service: zipkin-all-in-one - strategy: {} - template: - metadata: - annotations: - kompose.cmd: C:\ProgramData\chocolatey\lib\kubernetes-kompose\tools\kompose.exe - convert -c - kompose.version: 1.21.0 (992df58d8) - creationTimestamp: null - labels: - io.kompose.network/demo: "true" - io.kompose.service: zipkin-all-in-one - spec: - containers: - - image: openzipkin/zipkin:latest - imagePullPolicy: "" - name: zipkin-all-in-one - ports: - - containerPort: 9411 - resources: {} - restartPolicy: Always - serviceAccountName: "" - volumes: null -status: {} diff --git a/helm-otel/templates/zipkin-all-in-one-service.yaml b/helm-otel/templates/zipkin-all-in-one-service.yaml deleted file mode 100644 index cb329036..00000000 --- a/helm-otel/templates/zipkin-all-in-one-service.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - annotations: - kompose.cmd: C:\ProgramData\chocolatey\lib\kubernetes-kompose\tools\kompose.exe - convert -c - kompose.version: 1.21.0 (992df58d8) - creationTimestamp: null - labels: - io.kompose.service: zipkin-all-in-one - name: zipkin-all-in-one -spec: - ports: - - name: "9411" - port: 9411 - targetPort: 9411 - selector: - io.kompose.service: zipkin-all-in-one -status: - loadBalancer: {} diff --git a/helm/secrets.yaml b/helm/secrets.yaml new file mode 100644 index 00000000..f49ff397 --- /dev/null +++ b/helm/secrets.yaml @@ -0,0 +1,30 @@ +#ACR secrets +server: ENC[AES256_GCM,data:H6zUjd8okORKe+AF0/3zDTkmp+ASKTnh/dlan7XNuBk=,iv:L1lQmKLREKOwuEdZZNag7pz6H1q5055uoazyBWGGKzg=,tag:B/KT9jem1/c1re1nLC3zIA==,type:str] +username: ENC[AES256_GCM,data:6PXxSZpeDeXBj6oCHH2oHg==,iv:3pJduRctieUJkUOuUN6ArtLKLqojPmDm2B1Y2uKMeLY=,tag:ptafJDYRUUbgq/2q8vxP3Q==,type:str] +password: ENC[AES256_GCM,data:06UPZJ+j47QujPKQljzjJlQOf71o8rWAN0s78Lwhehip6NEzVPj/Ihl63Xo=,iv:4KXvFwp5N9cmvVmDHOt5u2kgLvD9MK4BIxn/E5CaRXM=,tag:g3gfQcCQusMxQN9CpBLnZQ==,type:str] +sops: + attention: This section contains key material that should only be modified with + extra care. See `sops -h`. + version: '1.18' + unencrypted_suffix: _unencrypted + pgp: + - fp: D7FA66E670AE6F41C99CFA70068655072F71EE17 + enc: | + -----BEGIN PGP MESSAGE----- + + hQGMA4in/RHYxChuAQv8DWegA6iWYOvqcEohQgSaJ/Y9y5gcvNaM6Icb17eLnduL + /bdLCGFr8+m4rJpceeOiXalwzps+qe71R8DUOTchKjSO0id0fKIsrDaHvYblIqoe + i0yA3ACGzZQOnfiNQLxawhyztjAqhMxdFw/wMLauQdbMAnwCYtQnbBSKBMD0B8Sw + dapq4SF4mfAlivS2UJ4pIZOKU5odMgMFDxYvegGk1vM/qVUEr08gbKKhA9SK5M6H + 2ypCHkotS8eNRnYSyMs+6ONqhtfM38PI1S2cvTBJT/MyXNEzcA61GM7n/FxhTPrm + 93X5VqliqUke/k//UgmGeiOMGnC//a1+W7I8z+qwaDBtpsNEotTMBGg6nAXOuAlg + UACKQTOIVrAELqcne+7i4DVlDtqWF6OykO88AO/Aqbj105Os2KpyPNoXlbue44iQ + CmHZXuKN+YsU7YYvTanMM5W+eSyttntir3sBvM/GPmBLA9mD0noGCgMTzL1uNMMq + XNzj4re48IyVqCgFfSDH0l4Byqc4oC4+G4XzGwKHmyE0Q2ivSzVBupcLU8Afvnjv + yg31F0Qqm8dj2Sn2a7ioTyToDB9Xt3xEp+OYtusOBKCRfCViFpLyf/dkzwcYRjyq + D54PXEcbKxEQVvD6xHtz + =TbxD + -----END PGP MESSAGE----- + created_at: '2021-11-13T06:46:34Z' + lastmodified: '2021-11-13T06:50:22Z' + mac: ENC[AES256_GCM,data:iykjblBR8AW+kyBhpjwlHvKBH17/BkstHNr4N6JypjATk2IuT8Ro48AQM5c8IJLNrNKkVIAhOXLcGI4pFb9iTI1C2w9GoIlXCp/xNOcQx6q0acIjfxpfKW7N/pjxh5UNp3BJeSf7JXBob6hh/0NX/8t6OtSi6VKuSszAlgzWswY=,iv:Mg1TcBYRG2q+RdFRMTdqchh+2luaJdsfFTIU5HVQpk8=,tag:RD6cY4oidKcWq0Qe6QQkYg==,type:str] diff --git a/helm/templates/deployment.yaml b/helm/templates/deployment.yaml index b9488131..9c98d98c 100644 --- a/helm/templates/deployment.yaml +++ b/helm/templates/deployment.yaml @@ -26,6 +26,10 @@ spec: image: {{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag }} # always perform pull when creating pod imagePullPolicy: Always + envFrom: + - secretRef: + name: credentials + # env vars so we can connect to DB env: - name: QUARKUS_DATASOURCE_JDBC_URL @@ -34,6 +38,12 @@ spec: value: demo - name: QUARKUS_DATASOURCE_PASSWORD value: demo + - name: quarkus.opentelemetry.enabled + value: "true" + - name: quarkus.opentelemetry.tracer.exporter.otlp.endpoint + value: http://otel-agent:4317 + - name: quarkus.application.name + value: demo-quarkus # live & ready probes, using our healthcheck endpoints livenessProbe: failureThreshold: 5 @@ -101,5 +111,5 @@ spec: value: demo - name: DISABLE_WELCOME_MESSAGE value: 'true' - image: 'docker.io/bitnami/postgresql:12.2.0' + image: {{ .Values.postgres.image }}:{{ .Values.postgres.imageTag }} name: check-db diff --git a/helm/templates/postgres-deployment.yaml b/helm/templates/postgres-deployment.yaml new file mode 100644 index 00000000..e4aa9b11 --- /dev/null +++ b/helm/templates/postgres-deployment.yaml @@ -0,0 +1,79 @@ +apiVersion: apps/v1 +kind: Deployment +# deployment v1 +metadata: + name: postgresql +spec: + replicas: 1 + selector: + #how are the pods linked together + matchLabels: + app: postgresql + template: + metadata: + labels: + app: postgresql + spec: + containers: + - name: postgresql + image: '{{ .Values.postgres.image }}:{{ .Values.postgres.imageTag }}' + ports: + - name: tcp-postgresql + containerPort: {{ .Values.postgres.service.port }} + protocol: TCP + env: + - name: POSTGRESQL_PORT_NUMBER + value: '5432' + - name: POSTGRESQL_VOLUME_DIR + value: /bitnami/postgresql + - name: PGDATA + value: /bitnami/postgresql/data + - name: POSTGRES_USER + value: postgres + #dont even try this in production + - name: POSTGRES_PASSWORD + value: postgres + - name: POSTGRES_DB + value: kubernetes + - name: DISABLE_WELCOME_MESSAGE + value: 'true' + - name: POSTGRESQL_ENABLE_LDAP + value: 'no' + resources: + requests: + cpu: 250m + memory: 256Mi + livenessProbe: + exec: + command: + - /bin/sh + - '-c' + - >- + exec pg_isready -U "postgres" -d "kubernetes" -h 127.0.0.1 -p + 5432 + initialDelaySeconds: 30 + timeoutSeconds: 5 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 6 + readinessProbe: + exec: + command: + - /bin/sh + - '-c' + - '-e' + - > + exec pg_isready -U "postgres" -d "kubernetes" -h 127.0.0.1 -p + 5432 + + [ -f /opt/bitnami/postgresql/tmp/.initialized ] || [ -f + /bitnami/postgresql/.initialized ] + initialDelaySeconds: 5 + timeoutSeconds: 5 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 6 + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent +# we run database without any persistent data volume - not a good idea, but sufficient for demo diff --git a/helm/templates/postgres-service.yaml b/helm/templates/postgres-service.yaml new file mode 100644 index 00000000..ef592323 --- /dev/null +++ b/helm/templates/postgres-service.yaml @@ -0,0 +1,15 @@ +kind: Service +apiVersion: v1 +metadata: + name: postgresql + labels: + app: postgresql +spec: + ports: + - name: tcp-postgresql + protocol: TCP + port: {{ .Values.postgres.service.port }} + targetPort: tcp-postgresql + selector: + app: postgresql + type: LoadBalancer #ClusterIP diff --git a/helm/templates/secrets.yaml b/helm/templates/secrets.yaml new file mode 100644 index 00000000..2dc4607a --- /dev/null +++ b/helm/templates/secrets.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Secret +metadata: + name: credentials + #labels: + # app: app + # chart: '{{ .Chart.Name }}-{{ .Chart.Version }}' + # release: '{{ .Release.Name }}' + # heritage: '{{ .Release.Service }}' +type: Opaque +data: + server: {{ .Values.server | b64enc | quote }} + username: {{ .Values.username | b64enc | quote }} + password: {{ .Values.password | b64enc | quote }} diff --git a/helm/templates/service.yaml b/helm/templates/service.yaml index 5b7298be..90e6797e 100644 --- a/helm/templates/service.yaml +++ b/helm/templates/service.yaml @@ -14,4 +14,4 @@ spec: # how to find the pods we are load balancing selector: app: demo-quarkus - type: ClusterIP + type: LoadBalancer #ClusterIP diff --git a/helm/values.yaml b/helm/values.yaml index 01e70f7a..ef3e5568 100644 --- a/helm/values.yaml +++ b/helm/values.yaml @@ -2,9 +2,9 @@ # Application image image: # Docker registry - registry: "k3d-registry:5000" + #registry: dockerregistry101 #"k3d-registry:5000" # Docker repository (application name) - repository: "demo-quarkus" + repository: acrimage101.azurecr.io/acrimage101/demo-quarkus #"demo-quarkus" # Docker image tag (application version) tag: "latest" @@ -26,7 +26,14 @@ pod: # Service configuration service: port: 8080 - + + # Database configuration +postgres: + image: "docker.io/bitnami/postgresql" + imageTag: "12.2.0" + + service: + port: 5432 # Ingress configuration ingress: host: "demo-quarkus.localhost" diff --git a/k8s/application-deployment.yaml b/k8s/application-deployment.yaml new file mode 100644 index 00000000..05e3de33 --- /dev/null +++ b/k8s/application-deployment.yaml @@ -0,0 +1,98 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: demo-quarkus + app.kubernetes.io/name: demo-quarkus + name: demo-quarkus +spec: + # scale to 2 instances + replicas: 2 + selector: + matchLabels: + app: demo-quarkus + template: + metadata: + labels: + app: demo-quarkus + spec: + containers: + - name: demo-quarkus + ## TODO: Insert the registry from which you want to pull the image + image: 'your-registry/demo-quarkus:latest' + imagePullPolicy: Always + env: + - name: QUARKUS_DATASOURCE_JDBC_URL + value: jdbc:postgresql://postgresql:5432/demo + - name: QUARKUS_DATASOURCE_USERNAME + value: demo + - name: QUARKUS_DATASOURCE_PASSWORD + value: demo + livenessProbe: + failureThreshold: 5 + httpGet: + path: /q/health/live + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 30 + successThreshold: 1 + timeoutSeconds: 3 + ports: + - containerPort: 8080 + readinessProbe: + failureThreshold: 5 + httpGet: + path: /q/health/ready + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 30 + successThreshold: 1 + timeoutSeconds: 3 + # we can define init containers, single run jobs that run before our main container does + # we use them to init database and check that its ready + initContainers: + - command: + - /bin/bash + - '-c' + - >- + psql -tc "SELECT 1 FROM pg_database WHERE datname = + 'demo'" | grep -q 1 | psql -c "CREATE USER + demo WITH ENCRYPTED PASSWORD 'demo';" -c + "CREATE DATABASE demo;" -c "GRANT ALL PRIVILEGES + ON DATABASE demo TO demo;" + env: + - name: PGHOST + value: postgresql + - name: PGPORT + value: '5432' + - name: PGDATABASE + value: null + - name: PGUSER + value: postgres + - name: PGPASSWORD + value: postgres + - name: DISABLE_WELCOME_MESSAGE + value: 'true' + image: 'docker.io/bitnami/postgresql:12.2.0' + name: create-db + - command: + - /bin/bash + - '-c' + - until pg_isready; do echo waiting for database; sleep 2; done; + env: + - name: PGHOST + value: postgresql + - name: PGPORT + value: '5432' + - name: PGDATABASE + value: demo + - name: PGUSER + value: demo + - name: PGPASSWORD + value: demo + - name: DISABLE_WELCOME_MESSAGE + value: 'true' + image: 'docker.io/bitnami/postgresql:12.2.0' + name: check-db diff --git a/k8s/application-service.yaml b/k8s/application-service.yaml new file mode 100644 index 00000000..7b678504 --- /dev/null +++ b/k8s/application-service.yaml @@ -0,0 +1,15 @@ +kind: Service +apiVersion: v1 +metadata: + name: demo-quarkus + labels: + app: demo-quarkus +spec: + ports: + - name: http-port + protocol: TCP + port: 8080 + targetPort: 8080 + selector: + app: demo-quarkus + type: ClusterIP diff --git a/k8s/deployment.yaml b/k8s/deployment.yaml index a961bcd0..53d89931 100644 --- a/k8s/deployment.yaml +++ b/k8s/deployment.yaml @@ -24,7 +24,8 @@ spec: containers: - name: demo-quarkus # where should the image come from - image: 'k3d-registry:5000/demo-quarkus:latest' + image: 'acrimage101.azurecr.io/acrimage101/demo-quarkus:latest' + # always perform pull when creating pod imagePullPolicy: Always # env vars so we can connect to DB diff --git a/k8s/dev.yaml b/k8s/dev.yaml deleted file mode 100644 index b02526f3..00000000 --- a/k8s/dev.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: k3d.io/v1alpha2 -kind: Simple -name: dev -servers: 1 -ports: - - port: 80:80 - nodeFilters: - - loadbalancer -registries: - use: k3d-registry:5000 diff --git a/k8s/ingress.yaml b/k8s/ingress.yaml index e26e2d70..cdcd74f1 100644 --- a/k8s/ingress.yaml +++ b/k8s/ingress.yaml @@ -1,20 +1,18 @@ -# a simple ingress for our service -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: demo-quarkus - annotations: - ingress.kubernetes.io/ssl-redirect: "false" -spec: - rules: - - http: - paths: - - path: "/" - pathType: Prefix - backend: - service: - name: demo-quarkus - port: - number: 8080 - # this will work if you have dnsmasq(tkit env guide) +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: demo-quarkus + annotations: + ingress.kubernetes.io/ssl-redirect: "false" +spec: + rules: + - http: + paths: + - path: "/" + pathType: Prefix + backend: + service: + name: demo-quarkus + port: + number: 8080 host: demo-quarkus.localhost \ No newline at end of file diff --git a/k8s/postgres-deployment.yaml b/k8s/postgres-deployment.yaml index 2b2b9f02..a988f8eb 100644 --- a/k8s/postgres-deployment.yaml +++ b/k8s/postgres-deployment.yaml @@ -1,79 +1,77 @@ -apiVersion: apps/v1 -kind: Deployment -# deployment v1 -metadata: - name: postgresql -spec: - replicas: 1 - selector: - #how are the pods linked together - matchLabels: - app: postgresql - template: - metadata: - labels: - app: postgresql - spec: - containers: - - name: postgresql - image: 'docker.io/bitnami/postgresql:12.2.0' - ports: - - name: tcp-postgresql - containerPort: 5432 - protocol: TCP - env: - - name: POSTGRESQL_PORT_NUMBER - value: '5432' - - name: POSTGRESQL_VOLUME_DIR - value: /bitnami/postgresql - - name: PGDATA - value: /bitnami/postgresql/data - - name: POSTGRES_USER - value: postgres - #dont even try this in production - - name: POSTGRES_PASSWORD - value: postgres - - name: POSTGRES_DB - value: kubernetes - - name: DISABLE_WELCOME_MESSAGE - value: 'true' - - name: POSTGRESQL_ENABLE_LDAP - value: 'no' - resources: - requests: - cpu: 250m - memory: 256Mi - livenessProbe: - exec: - command: - - /bin/sh - - '-c' - - >- - exec pg_isready -U "postgres" -d "kubernetes" -h 127.0.0.1 -p - 5432 - initialDelaySeconds: 30 - timeoutSeconds: 5 - periodSeconds: 10 - successThreshold: 1 - failureThreshold: 6 - readinessProbe: - exec: - command: - - /bin/sh - - '-c' - - '-e' - - > - exec pg_isready -U "postgres" -d "kubernetes" -h 127.0.0.1 -p - 5432 - - [ -f /opt/bitnami/postgresql/tmp/.initialized ] || [ -f - /bitnami/postgresql/.initialized ] - initialDelaySeconds: 5 - timeoutSeconds: 5 - periodSeconds: 10 - successThreshold: 1 - failureThreshold: 6 - terminationMessagePath: /dev/termination-log - terminationMessagePolicy: File - imagePullPolicy: IfNotPresent -# we run database without any persistent data volume - not a good idea, but sufficient for demo +apiVersion: apps/v1 +kind: Deployment +metadata: + name: postgresql +spec: + replicas: 1 + selector: + matchLabels: + app: postgresql + template: + metadata: + labels: + app: postgresql + spec: + containers: + - name: postgresql + image: 'docker.io/bitnami/postgresql:12.2.0' + ports: + - name: tcp-postgresql + containerPort: 5432 + protocol: TCP + env: + - name: POSTGRESQL_PORT_NUMBER + value: '5432' + - name: POSTGRESQL_VOLUME_DIR + value: /bitnami/postgresql + - name: PGDATA + value: /bitnami/postgresql/data + - name: POSTGRES_USER + value: postgres + #dont even try this in production + - name: POSTGRES_PASSWORD + value: postgres + - name: POSTGRES_DB + value: kubernetes + - name: DISABLE_WELCOME_MESSAGE + value: 'true' + - name: POSTGRESQL_ENABLE_LDAP + value: 'no' + resources: + requests: + cpu: 250m + memory: 256Mi + livenessProbe: + exec: + command: + - /bin/sh + - '-c' + - >- + exec pg_isready -U "postgres" -d "kubernetes" -h 127.0.0.1 -p + 5432 + initialDelaySeconds: 30 + timeoutSeconds: 5 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 6 + readinessProbe: + exec: + command: + - /bin/sh + - '-c' + - '-e' + - > + exec pg_isready -U "postgres" -d "kubernetes" -h 127.0.0.1 -p + 5432 + + [ -f /opt/bitnami/postgresql/tmp/.initialized ] || [ -f + /bitnami/postgresql/.initialized ] + initialDelaySeconds: 5 + timeoutSeconds: 5 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 6 + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent +# we run database without any persistent data volume - not a good idea, but sufficient for demo diff --git a/k8s/postgres-service.yaml b/k8s/postgres-service.yaml index 58a1d43b..c41f373e 100644 --- a/k8s/postgres-service.yaml +++ b/k8s/postgres-service.yaml @@ -1,15 +1,15 @@ -kind: Service -apiVersion: v1 -metadata: - name: postgresql - labels: - app: postgresql -spec: - ports: - - name: tcp-postgresql - protocol: TCP - port: 5432 - targetPort: tcp-postgresql - selector: - app: postgresql - type: ClusterIP +kind: Service +apiVersion: v1 +metadata: + name: postgresql + labels: + app: postgresql +spec: + ports: + - name: tcp-postgresql + protocol: TCP + port: 5432 + targetPort: tcp-postgresql + selector: + app: postgresql + type: ClusterIP diff --git a/k8s/service.yaml b/k8s/service.yaml index 2b3ebca8..af2219f0 100644 --- a/k8s/service.yaml +++ b/k8s/service.yaml @@ -14,4 +14,4 @@ spec: # how to find the pods we are load balancing selector: app: demo-quarkus - type: ClusterIP + type: LoadBalancer #ClusterIP diff --git a/mvnw b/mvnw index a16b5431..4c1c4271 100644 --- a/mvnw +++ b/mvnw @@ -1,310 +1,310 @@ -#!/bin/sh -# ---------------------------------------------------------------------------- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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 -# -# https://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. -# ---------------------------------------------------------------------------- - -# ---------------------------------------------------------------------------- -# Maven Start Up Batch script -# -# Required ENV vars: -# ------------------ -# JAVA_HOME - location of a JDK home dir -# -# Optional ENV vars -# ----------------- -# M2_HOME - location of maven2's installed home dir -# MAVEN_OPTS - parameters passed to the Java VM when running Maven -# e.g. to debug Maven itself, use -# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -# MAVEN_SKIP_RC - flag to disable loading of mavenrc files -# ---------------------------------------------------------------------------- - -if [ -z "$MAVEN_SKIP_RC" ] ; then - - if [ -f /etc/mavenrc ] ; then - . /etc/mavenrc - fi - - if [ -f "$HOME/.mavenrc" ] ; then - . "$HOME/.mavenrc" - fi - -fi - -# OS specific support. $var _must_ be set to either true or false. -cygwin=false; -darwin=false; -mingw=false -case "`uname`" in - CYGWIN*) cygwin=true ;; - MINGW*) mingw=true;; - Darwin*) darwin=true - # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home - # See https://developer.apple.com/library/mac/qa/qa1170/_index.html - if [ -z "$JAVA_HOME" ]; then - if [ -x "/usr/libexec/java_home" ]; then - export JAVA_HOME="`/usr/libexec/java_home`" - else - export JAVA_HOME="/Library/Java/Home" - fi - fi - ;; -esac - -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=`java-config --jre-home` - fi -fi - -if [ -z "$M2_HOME" ] ; then - ## resolve links - $0 may be a link to maven's home - PRG="$0" - - # need this for relative symlinks - while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG="`dirname "$PRG"`/$link" - fi - done - - saveddir=`pwd` - - M2_HOME=`dirname "$PRG"`/.. - - # make it fully qualified - M2_HOME=`cd "$M2_HOME" && pwd` - - cd "$saveddir" - # echo Using m2 at $M2_HOME -fi - -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --unix "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --unix "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --unix "$CLASSPATH"` -fi - -# For Mingw, ensure paths are in UNIX format before anything is touched -if $mingw ; then - [ -n "$M2_HOME" ] && - M2_HOME="`(cd "$M2_HOME"; pwd)`" - [ -n "$JAVA_HOME" ] && - JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" -fi - -if [ -z "$JAVA_HOME" ]; then - javaExecutable="`which javac`" - if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then - # readlink(1) is not available as standard on Solaris 10. - readLink=`which readlink` - if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then - if $darwin ; then - javaHome="`dirname \"$javaExecutable\"`" - javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" - else - javaExecutable="`readlink -f \"$javaExecutable\"`" - fi - javaHome="`dirname \"$javaExecutable\"`" - javaHome=`expr "$javaHome" : '\(.*\)/bin'` - JAVA_HOME="$javaHome" - export JAVA_HOME - fi - fi -fi - -if [ -z "$JAVACMD" ] ; then - if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - else - JAVACMD="`which java`" - fi -fi - -if [ ! -x "$JAVACMD" ] ; then - echo "Error: JAVA_HOME is not defined correctly." >&2 - echo " We cannot execute $JAVACMD" >&2 - exit 1 -fi - -if [ -z "$JAVA_HOME" ] ; then - echo "Warning: JAVA_HOME environment variable is not set." -fi - -CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher - -# traverses directory structure from process work directory to filesystem root -# first directory with .mvn subdirectory is considered project base directory -find_maven_basedir() { - - if [ -z "$1" ] - then - echo "Path not specified to find_maven_basedir" - return 1 - fi - - basedir="$1" - wdir="$1" - while [ "$wdir" != '/' ] ; do - if [ -d "$wdir"/.mvn ] ; then - basedir=$wdir - break - fi - # workaround for JBEAP-8937 (on Solaris 10/Sparc) - if [ -d "${wdir}" ]; then - wdir=`cd "$wdir/.."; pwd` - fi - # end of workaround - done - echo "${basedir}" -} - -# concatenates all lines of a file -concat_lines() { - if [ -f "$1" ]; then - echo "$(tr -s '\n' ' ' < "$1")" - fi -} - -BASE_DIR=`find_maven_basedir "$(pwd)"` -if [ -z "$BASE_DIR" ]; then - exit 1; -fi - -########################################################################################## -# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -# This allows using the maven wrapper in projects that prohibit checking in binary data. -########################################################################################## -if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found .mvn/wrapper/maven-wrapper.jar" - fi -else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." - fi - if [ -n "$MVNW_REPOURL" ]; then - jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - else - jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - fi - while IFS="=" read key value; do - case "$key" in (wrapperUrl) jarUrl="$value"; break ;; - esac - done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" - if [ "$MVNW_VERBOSE" = true ]; then - echo "Downloading from: $jarUrl" - fi - wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" - if $cygwin; then - wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` - fi - - if command -v wget > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found wget ... using wget" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - wget "$jarUrl" -O "$wrapperJarPath" - else - wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" - fi - elif command -v curl > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found curl ... using curl" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - curl -o "$wrapperJarPath" "$jarUrl" -f - else - curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f - fi - - else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Falling back to using Java to download" - fi - javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" - # For Cygwin, switch paths to Windows format before running javac - if $cygwin; then - javaClass=`cygpath --path --windows "$javaClass"` - fi - if [ -e "$javaClass" ]; then - if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Compiling MavenWrapperDownloader.java ..." - fi - # Compiling the Java class - ("$JAVA_HOME/bin/javac" "$javaClass") - fi - if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - # Running the downloader - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Running MavenWrapperDownloader.java ..." - fi - ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") - fi - fi - fi -fi -########################################################################################## -# End of extension -########################################################################################## - -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} -if [ "$MVNW_VERBOSE" = true ]; then - echo $MAVEN_PROJECTBASEDIR -fi -MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" - -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` - [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` -fi - -# Provide a "standardized" way to retrieve the CLI args that will -# work with both Windows and non-Windows executions. -MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" -export MAVEN_CMD_LINE_ARGS - -WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -exec "$JAVACMD" \ - $MAVEN_OPTS \ - -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 +# +# https://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. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd index c8d43372..66db70c1 100644 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -1,182 +1,182 @@ -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM https://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Maven Start Up Batch script -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir -@REM -@REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files -@REM ---------------------------------------------------------------------------- - -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM set title of command window -title %0 -@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" -set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - -FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( - IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B -) - -@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -@REM This allows using the maven wrapper in projects that prohibit checking in binary data. -if exist %WRAPPER_JAR% ( - if "%MVNW_VERBOSE%" == "true" ( - echo Found %WRAPPER_JAR% - ) -) else ( - if not "%MVNW_REPOURL%" == "" ( - SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - ) - if "%MVNW_VERBOSE%" == "true" ( - echo Couldn't find %WRAPPER_JAR%, downloading it ... - echo Downloading from: %DOWNLOAD_URL% - ) - - powershell -Command "&{"^ - "$webclient = new-object System.Net.WebClient;"^ - "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ - "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ - "}"^ - "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ - "}" - if "%MVNW_VERBOSE%" == "true" ( - echo Finished downloading %WRAPPER_JAR% - ) -) -@REM End of extension - -@REM Provide a "standardized" way to retrieve the CLI args that will -@REM work with both Windows and non-Windows executions. -set MAVEN_CMD_LINE_ARGS=%* - -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause - -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% - -exit /B %ERROR_CODE% +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + +FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/otel-agent-config.yaml b/otel-agent-config.yaml index b0c44d40..22c28f7e 100644 --- a/otel-agent-config.yaml +++ b/otel-agent-config.yaml @@ -1,31 +1,25 @@ -receivers: - otlp: - protocols: - grpc: - opencensus: - jaeger: - protocols: - grpc: - thrift_http: - zipkin: - -exporters: - otlp: - endpoint: "otel-collector:4317" - insecure: true - logging: - loglevel: debug - -processors: - batch: - -service: - pipelines: - traces: - receivers: [otlp, zipkin, jaeger] - processors: [batch] - exporters: [otlp] - metrics: - receivers: [otlp] - processors: [batch] +receivers: + otlp: + protocols: + grpc: + +exporters: + otlp: + endpoint: "otel-collector:4317" + insecure: true + logging: + loglevel: debug + +processors: + batch: + +service: + pipelines: + traces: + receivers: [otlp] + processors: [batch] + exporters: [otlp] + metrics: + receivers: [otlp] + processors: [batch] exporters: [otlp] \ No newline at end of file diff --git a/otel-collector-config.yaml b/otel-collector-config.yaml index 1e5f6977..bcc510bc 100644 --- a/otel-collector-config.yaml +++ b/otel-collector-config.yaml @@ -1,38 +1,24 @@ -receivers: - otlp: - protocols: - grpc: - http: - cors_allowed_origins: - - http://* - - https://* - -exporters: - prometheus: - endpoint: "0.0.0.0:8889" - namespace: promexample - const_labels: - label1: value1 - - zipkin: - endpoint: "http://zipkin-all-in-one:9411/api/v2/spans" - format: proto - - jaeger: - endpoint: jaeger-all-in-one:14250 - insecure: true - -processors: - batch: - -service: - pipelines: - traces: - receivers: [otlp] - exporters: [zipkin, jaeger] - processors: [batch] - metrics: - receivers: [otlp] - processors: [batch] - exporters: [prometheus] +receivers: + otlp: + protocols: + grpc: + http: + cors_allowed_origins: + - http://* + - https://* + +exporters: + jaeger: + endpoint: jaeger-all-in-one:14250 + insecure: true + +processors: + batch: + +service: + pipelines: + traces: + receivers: [otlp] + exporters: [jaeger] + processors: [batch] \ No newline at end of file diff --git a/pom.xml b/pom.xml index cc5049eb..80eaf1c4 100644 --- a/pom.xml +++ b/pom.xml @@ -1,299 +1,309 @@ - - - 4.0.0 - com.devonfw - demo-quarkus - 1.0.0-SNAPSHOT - - 3.8.1 - true - 11 - 11 - UTF-8 - UTF-8 - 2.0.1.Final - quarkus-universe-bom - io.quarkus - 2.0.1.Final - 3.0.0-M5 - 1.4.2.Final - - - - - ${quarkus.platform.group-id} - ${quarkus.platform.artifact-id} - ${quarkus.platform.version} - pom - import - - - - - - - io.quarkus - quarkus-arc - - - - - io.quarkus - quarkus-resteasy-jackson - - - - - io.quarkus - quarkus-hibernate-orm - - - - - io.quarkus - quarkus-jdbc-postgresql - - - - - io.quarkus - quarkus-flyway - - - - - io.quarkus - quarkus-smallrye-openapi - - - - - - io.quarkus - quarkus-opentelemetry - - - io.quarkus - quarkus-opentelemetry-exporter-jaeger - - - io.opentelemetry - opentelemetry-extension-annotations - 1.0.0 - - - io.quarkus - quarkus-smallrye-health - - - io.quarkus - quarkus-micrometer-registry-prometheus - - - io.quarkus - quarkus-smallrye-fault-tolerance - - - - org.hibernate - hibernate-jpamodelgen - - - io.quarkus - quarkus-spring-data-jpa - - - - com.querydsl - querydsl-jpa - 4.3.1 - - - com.querydsl - querydsl-apt - provided - 4.3.1 - - - - - - - - - - org.projectlombok - lombok - 1.18.18 - provided - - - - - org.mapstruct - mapstruct-processor - ${mapstruct.version} - provided - - - org.mapstruct - mapstruct - ${mapstruct.version} - provided - - - - org.projectlombok - lombok-mapstruct-binding - 0.2.0 - provided - - - - - org.tkit.quarkus - tkit-quarkus-rest - 2.4.0 - - - - org.tkit.quarkus - tkit-quarkus-log-cdi - 1.4.5 - - - - org.tkit.quarkus - tkit-quarkus-log-rs - 1.4.5 - - - - org.tkit.quarkus - tkit-quarkus-log-json - 1.4.5 - - - - - org.tkit.quarkus - tkit-quarkus-test - 1.12.0 - test - - - - - io.quarkus - quarkus-junit5 - test - - - - io.rest-assured - rest-assured - test - - - - - - io.quarkus - quarkus-maven-plugin - ${quarkus-plugin.version} - true - - - - build - generate-code - generate-code-tests - - - - - - maven-compiler-plugin - ${compiler-plugin.version} - - true - - - -Amapstruct.defaultComponentModel=cdi - -Amapstruct.defaultInjectionStrategy=CONSTRUCTOR - - - - - maven-surefire-plugin - ${surefire-plugin.version} - - - org.jboss.logmanager.LogManager - ${maven.home} - - - - - - - com.mysema.maven - apt-maven-plugin - 1.1.3 - - - generate-sources - - process - - - target/generated-sources/annotations - com.querydsl.apt.jpa.JPAAnnotationProcessor - - - - - - - - - - native - - - native - - - - - - maven-failsafe-plugin - ${surefire-plugin.version} - - - - integration-test - verify - - - - ${project.build.directory}/${project.build.finalName}-runner - org.jboss.logmanager.LogManager - ${maven.home} - - - - - - - - - native - - - - + + + 4.0.0 + com.devonfw + demo-quarkus + 1.0.0-SNAPSHOT + + 3.8.1 + true + 11 + 11 + UTF-8 + UTF-8 + 2.0.1.Final + quarkus-universe-bom + io.quarkus + 2.0.1.Final + 3.0.0-M5 + 1.4.2.Final + + + + + ${quarkus.platform.group-id} + ${quarkus.platform.artifact-id} + ${quarkus.platform.version} + pom + import + + + + + + + io.quarkus + quarkus-arc + + + + + io.quarkus + quarkus-resteasy-jackson + + + + + io.quarkus + quarkus-hibernate-orm + + + + + io.quarkus + quarkus-jdbc-postgresql + + + + + io.quarkus + quarkus-flyway + + + + + io.quarkus + quarkus-smallrye-openapi + + + + io.quarkus + quarkus-opentelemetry-exporter-otlp + + + io.quarkus + quarkus-smallrye-health + + + io.quarkus + quarkus-micrometer-registry-prometheus + + + io.quarkus + quarkus-smallrye-fault-tolerance + + + org.hibernate + hibernate-jpamodelgen + + + io.quarkus + quarkus-spring-data-jpa + + + com.querydsl + querydsl-jpa + 4.3.1 + + + com.querydsl + querydsl-apt + provided + 4.3.1 + + + + + + + + + + org.projectlombok + lombok + 1.18.18 + provided + + + + + org.mapstruct + mapstruct-processor + ${mapstruct.version} + provided + + + org.mapstruct + mapstruct + ${mapstruct.version} + provided + + + + org.projectlombok + lombok-mapstruct-binding + 0.2.0 + provided + + + + + org.tkit.quarkus + tkit-quarkus-rest + 2.4.0 + + + + org.tkit.quarkus + tkit-quarkus-log-cdi + 1.4.5 + + + + org.tkit.quarkus + tkit-quarkus-log-rs + 1.4.5 + + + + org.tkit.quarkus + tkit-quarkus-log-json + 1.4.5 + + + + + org.tkit.quarkus + tkit-quarkus-test + 1.12.0 + test + + + + + io.quarkus + quarkus-junit5 + test + + + + io.rest-assured + rest-assured + test + + + + + + io.quarkus + quarkus-maven-plugin + ${quarkus-plugin.version} + true + + + + build + generate-code + generate-code-tests + + + + + + maven-compiler-plugin + ${compiler-plugin.version} + + true + + + -Amapstruct.defaultComponentModel=cdi + -Amapstruct.defaultInjectionStrategy=CONSTRUCTOR + + + + + maven-surefire-plugin + ${surefire-plugin.version} + + + org.jboss.logmanager.LogManager + ${maven.home} + + + + + com.mysema.maven + apt-maven-plugin + 1.1.3 + + + generate-sources + + process + + + target/generated-sources/annotations + com.querydsl.apt.jpa.JPAAnnotationProcessor + + + + + + + + + + native + + + native + + + + + + maven-failsafe-plugin + ${surefire-plugin.version} + + + + integration-test + verify + + + + ${project.build.directory}/${project.build.finalName}-runner + org.jboss.logmanager.LogManager + ${maven.home} + + + + + + + + org.codehaus.mojo + servicedocgen-maven-plugin + 1.0.0 + + + + generate + + + + + + + Product Service REST API Documentation + This documentation describes the REST API of the product service with all its operations in detail. + + + + 8443 + product/services/rest + + https + + + + + + + + native + + + + diff --git a/src/main/docker/Dockerfile.jvm b/src/main/docker/Dockerfile.jvm index 7e1eab14..eafeb773 100644 --- a/src/main/docker/Dockerfile.jvm +++ b/src/main/docker/Dockerfile.jvm @@ -1,54 +1,54 @@ -#### -# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode -# -# Before building the container image run: -# -# ./mvnw package -# -# Then, build the image with: -# -# docker build -f src/main/docker/Dockerfile.jvm -t quarkus/quarkus-basics-jvm . -# -# Then run the container using: -# -# docker run -i --rm -p 8080:8080 quarkus/quarkus-basics-jvm -# -# If you want to include the debug port into your docker image -# you will have to expose the debug port (default 5005) like this : EXPOSE 8080 5050 -# -# Then run the container using : -# -# docker run -i --rm -p 8080:8080 -p 5005:5005 -e JAVA_ENABLE_DEBUG="true" quarkus/quarkus-basics-jvm -# -### -FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3 - -ARG JAVA_PACKAGE=java-11-openjdk-headless -ARG RUN_JAVA_VERSION=1.3.8 -ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' -# Install java and the run-java script -# Also set up permissions for user `1001` -RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \ - && microdnf update \ - && microdnf clean all \ - && mkdir /deployments \ - && chown 1001 /deployments \ - && chmod "g+rwX" /deployments \ - && chown 1001:root /deployments \ - && curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \ - && chown 1001 /deployments/run-java.sh \ - && chmod 540 /deployments/run-java.sh \ - && echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/lib/security/java.security - -# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size. -ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" -# We make four distinct layers so if there are application changes the library layers can be re-used -COPY --chown=1001 target/quarkus-app/lib/ /deployments/lib/ -COPY --chown=1001 target/quarkus-app/*.jar /deployments/ -COPY --chown=1001 target/quarkus-app/app/ /deployments/app/ -COPY --chown=1001 target/quarkus-app/quarkus/ /deployments/quarkus/ - -EXPOSE 8080 -USER 1001 - -ENTRYPOINT [ "/deployments/run-java.sh" ] +#### +# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode +# +# Before building the container image run: +# +# ./mvnw package +# +# Then, build the image with: +# +# docker build -f src/main/docker/Dockerfile.jvm -t quarkus/quarkus-basics-jvm . +# +# Then run the container using: +# +# docker run -i --rm -p 8080:8080 quarkus/quarkus-basics-jvm +# +# If you want to include the debug port into your docker image +# you will have to expose the debug port (default 5005) like this : EXPOSE 8080 5050 +# +# Then run the container using : +# +# docker run -i --rm -p 8080:8080 -p 5005:5005 -e JAVA_ENABLE_DEBUG="true" quarkus/quarkus-basics-jvm +# +### +FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3 + +ARG JAVA_PACKAGE=java-11-openjdk-headless +ARG RUN_JAVA_VERSION=1.3.8 +ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' +# Install java and the run-java script +# Also set up permissions for user `1001` +RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \ + && microdnf update \ + && microdnf clean all \ + && mkdir /deployments \ + && chown 1001 /deployments \ + && chmod "g+rwX" /deployments \ + && chown 1001:root /deployments \ + && curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \ + && chown 1001 /deployments/run-java.sh \ + && chmod 540 /deployments/run-java.sh \ + && echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/lib/security/java.security + +# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size. +ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" +# We make four distinct layers so if there are application changes the library layers can be re-used +COPY --chown=1001 target/quarkus-app/lib/ /deployments/lib/ +COPY --chown=1001 target/quarkus-app/*.jar /deployments/ +COPY --chown=1001 target/quarkus-app/app/ /deployments/app/ +COPY --chown=1001 target/quarkus-app/quarkus/ /deployments/quarkus/ + +EXPOSE 8080 +USER 1001 + +ENTRYPOINT [ "/deployments/run-java.sh" ] diff --git a/src/main/docker/Dockerfile.native b/src/main/docker/Dockerfile.native index 9c192020..9d5f28e9 100644 --- a/src/main/docker/Dockerfile.native +++ b/src/main/docker/Dockerfile.native @@ -1,27 +1,27 @@ -#### -# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode -# -# Before building the container image run: -# -# ./mvnw package -Pnative -# -# Then, build the image with: -# -# docker build -f src/main/docker/Dockerfile.native -t quarkus/quarkus-basics . -# -# Then run the container using: -# -# docker run -i --rm -p 8080:8080 quarkus/quarkus-basics -# -### -FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3 -WORKDIR /work/ -RUN chown 1001 /work \ - && chmod "g+rwX" /work \ - && chown 1001:root /work -COPY --chown=1001:root target/*-runner /work/application - -EXPOSE 8080 -USER 1001 - -CMD ["./application", "-Dquarkus.http.host=0.0.0.0"] +#### +# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode +# +# Before building the container image run: +# +# ./mvnw package -Pnative +# +# Then, build the image with: +# +# docker build -f src/main/docker/Dockerfile.native -t quarkus/quarkus-basics . +# +# Then run the container using: +# +# docker run -i --rm -p 8080:8080 quarkus/quarkus-basics +# +### +FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3 +WORKDIR /work/ +RUN chown 1001 /work \ + && chmod "g+rwX" /work \ + && chown 1001:root /work +COPY --chown=1001:root target/*-runner /work/application + +EXPOSE 8080 +USER 1001 + +CMD ["./application", "-Dquarkus.http.host=0.0.0.0"] diff --git a/src/main/docker/Dockerfile.native-distroless b/src/main/docker/Dockerfile.native-distroless index 0c1b52c3..1c9e39e7 100644 --- a/src/main/docker/Dockerfile.native-distroless +++ b/src/main/docker/Dockerfile.native-distroless @@ -1,23 +1,23 @@ -#### -# This Dockerfile is used in order to build a distroless container that runs the Quarkus application in native (no JVM) mode -# -# Before building the container image run: -# -# ./mvnw package -Pnative -# -# Then, build the image with: -# -# docker build -f src/main/docker/Dockerfile.native-distroless -t quarkus/quarkus-basics . -# -# Then run the container using: -# -# docker run -i --rm -p 8080:8080 quarkus/quarkus-basics -# -### -FROM quay.io/quarkus/quarkus-distroless-image:1.0 -COPY target/*-runner /application - -EXPOSE 8080 -USER nonroot - -CMD ["./application", "-Dquarkus.http.host=0.0.0.0"] +#### +# This Dockerfile is used in order to build a distroless container that runs the Quarkus application in native (no JVM) mode +# +# Before building the container image run: +# +# ./mvnw package -Pnative +# +# Then, build the image with: +# +# docker build -f src/main/docker/Dockerfile.native-distroless -t quarkus/quarkus-basics . +# +# Then run the container using: +# +# docker run -i --rm -p 8080:8080 quarkus/quarkus-basics +# +### +FROM quay.io/quarkus/quarkus-distroless-image:1.0 +COPY target/*-runner /application + +EXPOSE 8080 +USER nonroot + +CMD ["./application", "-Dquarkus.http.host=0.0.0.0"] diff --git a/src/main/helm/application/Chart.yaml b/src/main/helm/application/Chart.yaml new file mode 100644 index 00000000..8d4dfe82 --- /dev/null +++ b/src/main/helm/application/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v3 +name: demo-quarkus +version: 1.0.0 +description: Helm chart for the devon4j Quarkus reference application +appVersion: 1.0.0 +keywords: + - devon4j + - demo + - quarkus +maintainers: + - name: devon4j Developer diff --git a/src/main/helm/application/templates/application-deployment.yaml b/src/main/helm/application/templates/application-deployment.yaml new file mode 100644 index 00000000..24de34c9 --- /dev/null +++ b/src/main/helm/application/templates/application-deployment.yaml @@ -0,0 +1,104 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: demo-quarkus + app.kubernetes.io/name: demo-quarkus + name: demo-quarkus +spec: + # scale default to 2 instances + replicas: {{ .Values.application.replicas | default 2 }} + selector: + matchLabels: + app: demo-quarkus + template: + metadata: + labels: + app: demo-quarkus + spec: + containers: + - name: demo-quarkus + image: {{ .Values.application.image.repository }} #{{ .Values.application.image.registry }}/{{ .Values.application.image.repository }}:{{ .Values.application.image.tag }} + imagePullPolicy: Always + env: + - name: QUARKUS_DATASOURCE_JDBC_URL + value: jdbc:postgresql://postgresql:{{ .Values.postgres.service.port }}/demo + - name: QUARKUS_DATASOURCE_USERNAME + value: demo + - name: QUARKUS_DATASOURCE_PASSWORD + value: demo + - name: quarkus.opentelemetry.enabled + value: "true" + - name: quarkus.opentelemetry.tracer.exporter.otlp.endpoint + value: http://otel-agent:4317 + - name: quarkus.application.name + value: demo-quarkus + # live & ready probes, using our healthcheck endpoints + livenessProbe: + failureThreshold: 5 + httpGet: + path: {{ .Values.application.livenessProbe.url }} + port: {{ .Values.application.pod.port }} + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 30 + successThreshold: 1 + timeoutSeconds: 3 + ports: + - containerPort: {{ .Values.application.pod.port }} + readinessProbe: + failureThreshold: 5 + httpGet: + path: {{ .Values.application.readinessProbe.url }} + port: {{ .Values.application.pod.port }} + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 30 + successThreshold: 1 + timeoutSeconds: 3 + # we can define init containers, single run jobs that run before our main container does + # we use them to init database and check that its ready + initContainers: + - command: + - /bin/bash + - '-c' + - >- + psql -tc "SELECT 1 FROM pg_database WHERE datname = + 'demo'" | grep -q 1 | psql -c "CREATE USER + demo WITH ENCRYPTED PASSWORD 'demo';" -c + "CREATE DATABASE demo;" -c "GRANT ALL PRIVILEGES + ON DATABASE demo TO demo;" + env: + - name: PGHOST + value: postgresql + - name: PGPORT + value: '{{ .Values.postgres.service.port }}' + - name: PGDATABASE + value: null + - name: PGUSER + value: postgres + - name: PGPASSWORD + value: postgres + - name: DISABLE_WELCOME_MESSAGE + value: 'true' + image: {{ .Values.postgres.image }}:{{ .Values.postgres.imageTag }} + name: create-db + - command: + - /bin/bash + - '-c' + - until pg_isready; do echo waiting for database; sleep 2; done; + env: + - name: PGHOST + value: postgresql + - name: PGPORT + value: '{{ .Values.postgres.service.port }}' + - name: PGDATABASE + value: demo + - name: PGUSER + value: demo + - name: PGPASSWORD + value: demo + - name: DISABLE_WELCOME_MESSAGE + value: 'true' + image: {{ .Values.postgres.image }}:{{ .Values.postgres.imageTag }} + name: check-db diff --git a/src/main/helm/application/templates/application-service.yaml b/src/main/helm/application/templates/application-service.yaml new file mode 100644 index 00000000..cac1ce9c --- /dev/null +++ b/src/main/helm/application/templates/application-service.yaml @@ -0,0 +1,18 @@ +kind: Service +apiVersion: v1 +metadata: + name: demo-quarkus + labels: + app: demo-quarkus +spec: + ports: + - name: http-port + protocol: TCP + port: {{ .Values.application.service.port }} + targetPort: {{ .Values.application.pod.port }} + selector: + app: demo-quarkus + #type: ClusterIP + type: LoadBalancer +status: + loadBalancer: {} diff --git a/src/main/helm/application/templates/ingress.yaml b/src/main/helm/application/templates/ingress.yaml new file mode 100644 index 00000000..88ae1922 --- /dev/null +++ b/src/main/helm/application/templates/ingress.yaml @@ -0,0 +1,16 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: demo-quarkus +spec: + rules: + - http: + paths: + - path: "/" + pathType: Prefix + backend: + service: + name: demo-quarkus + port: + number: {{ .Values.application.service.port }} + host: {{ .Values.ingress.host }} \ No newline at end of file diff --git a/src/main/helm/application/templates/postgres-deployment.yaml b/src/main/helm/application/templates/postgres-deployment.yaml new file mode 100644 index 00000000..afda775d --- /dev/null +++ b/src/main/helm/application/templates/postgres-deployment.yaml @@ -0,0 +1,77 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: postgresql +spec: + replicas: 1 + selector: + matchLabels: + app: postgresql + template: + metadata: + labels: + app: postgresql + spec: + containers: + - name: postgresql + image: {{ .Values.postgres.image }}:{{ .Values.postgres.imageTag }} + ports: + - name: tcp-postgresql + containerPort: {{ .Values.postgres.service.port }} + protocol: TCP + env: + - name: POSTGRESQL_PORT_NUMBER + value: '{{ .Values.postgres.service.port }}' + - name: POSTGRESQL_VOLUME_DIR + value: /bitnami/postgresql + - name: PGDATA + value: /bitnami/postgresql/data + - name: POSTGRES_USER + value: postgres + #dont even try this in production + - name: POSTGRES_PASSWORD + value: postgres + - name: POSTGRES_DB + value: kubernetes + - name: DISABLE_WELCOME_MESSAGE + value: 'true' + - name: POSTGRESQL_ENABLE_LDAP + value: 'no' + resources: + requests: + cpu: 250m + memory: 256Mi + livenessProbe: + exec: + command: + - /bin/sh + - '-c' + - >- + exec pg_isready -U "postgres" -d "kubernetes" -h 127.0.0.1 -p + 5432 + initialDelaySeconds: 30 + timeoutSeconds: 5 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 6 + readinessProbe: + exec: + command: + - /bin/sh + - '-c' + - '-e' + - > + exec pg_isready -U "postgres" -d "kubernetes" -h 127.0.0.1 -p + 5432 + + [ -f /opt/bitnami/postgresql/tmp/.initialized ] || [ -f + /bitnami/postgresql/.initialized ] + initialDelaySeconds: 5 + timeoutSeconds: 5 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 6 + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent +# we run database without any persistent data volume - not a good idea, but sufficient for demo diff --git a/src/main/helm/application/templates/postgres-service.yaml b/src/main/helm/application/templates/postgres-service.yaml new file mode 100644 index 00000000..d897fe6d --- /dev/null +++ b/src/main/helm/application/templates/postgres-service.yaml @@ -0,0 +1,17 @@ +kind: Service +apiVersion: v1 +metadata: + name: postgresql + labels: + app: postgresql +spec: + ports: + - name: tcp-postgresql + protocol: TCP + port: {{ .Values.postgres.service.port }} + targetPort: tcp-postgresql + selector: + app: postgresql + type: LoadBalancer #ClusterIP +status: + loadBalancer: {} diff --git a/src/main/helm/application/values.yaml b/src/main/helm/application/values.yaml new file mode 100644 index 00000000..5f35a158 --- /dev/null +++ b/src/main/helm/application/values.yaml @@ -0,0 +1,36 @@ +# Application configuration +application: + image: + ## TODO: Insert the registry from which you want to pull the image + #registry: "hub.docker.com/dockerregistry101" + #repository: "guentherjulian/devon4quarkus-reference:latest" + repository: "dockerregistry101/demo-quarkus:latest" + # tag: "latest" + + replicas: 2 + + livenessProbe: + url: /q/health/live + + readinessProbe: + url: /q/health/ready + + pod: + port: 8080 + + service: + port: 8080 + + +# Database configuration +postgres: + image: "docker.io/bitnami/postgresql" + imageTag: "12.2.0" + + service: + port: 5432 + + +# Ingress configuration +ingress: + host: "demo-quarkus.demo-cluster-dns-be5e9d93.hcp.centralus.azmk8s.io" diff --git a/src/main/helm/opentelemetry/Chart.yaml b/src/main/helm/opentelemetry/Chart.yaml new file mode 100644 index 00000000..1d1149c3 --- /dev/null +++ b/src/main/helm/opentelemetry/Chart.yaml @@ -0,0 +1,9 @@ +apiVersion: v3 +name: OpenTelemetry Helm template +version: 1.0.0 +description: Helm chart template for an OpenTelemetry Kubernetes deployment +appVersion: 1.0.0 +keywords: + - template +maintainers: + - name: devon4j Developer diff --git a/src/main/helm/opentelemetry/templates/configmap.yaml b/src/main/helm/opentelemetry/templates/configmap.yaml new file mode 100644 index 00000000..4b3d18a9 --- /dev/null +++ b/src/main/helm/opentelemetry/templates/configmap.yaml @@ -0,0 +1,75 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: otel-agent +data: + otel-agent-config: | + receivers: + otlp: + protocols: + grpc: + + processors: + batch: + + exporters: + otlp: + endpoint: "otel-collector:4317" + insecure: true + + service: + pipelines: + traces: + receivers: [otlp] + processors: [batch] + exporters: [otlp] + metrics: + receivers: [otlp] + processors: [batch] + exporters: [otlp] +--- + +apiVersion: v1 +kind: ConfigMap +metadata: + name: otel-collector +data: + otel-collector-config: | + receivers: + otlp: + protocols: + grpc: + http: + cors_allowed_origins: + - http://* + - https://* + + processors: + batch: + + exporters: + logging: + jaeger: + endpoint: jaeger-all-in-one:14250 + insecure: true + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [jaeger] + processors: [batch] +--- + +apiVersion: v1 +kind: ConfigMap +metadata: + name: vmetrics-config +data: + vMetrics.yaml: | + scrape_configs: + - job_name: '{{ .Values.application.metrics.jobname }}' + scrape_interval: 10s + metrics_path: '{{ .Values.application.metrics.url }}' + static_configs: + - targets: ['{{ .Values.application.service.name }}:{{ .Values.application.service.port }}'] \ No newline at end of file diff --git a/src/main/helm/opentelemetry/templates/grafana-deployment.yaml b/src/main/helm/opentelemetry/templates/grafana-deployment.yaml new file mode 100644 index 00000000..2b965d62 --- /dev/null +++ b/src/main/helm/opentelemetry/templates/grafana-deployment.yaml @@ -0,0 +1,43 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + component: grafana + name: grafana +spec: + replicas: 1 + selector: + matchLabels: + component: grafana + template: + metadata: + labels: + component: grafana + spec: + containers: + - image: grafana/grafana + name: grafana + ports: + - containerPort: 3000 + resources: {} + restartPolicy: Always + +--- + +apiVersion: v1 +kind: Service +metadata: + labels: + component: grafana + name: grafana +spec: + ports: + - name: "3000" + port: 3000 + protocol: TCP + targetPort: 3000 + selector: + component: grafana + type: LoadBalancer #ClusterIP +status: + loadBalancer: {} diff --git a/src/main/helm/opentelemetry/templates/ingress.yaml b/src/main/helm/opentelemetry/templates/ingress.yaml new file mode 100644 index 00000000..6594a825 --- /dev/null +++ b/src/main/helm/opentelemetry/templates/ingress.yaml @@ -0,0 +1,26 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: ingress +spec: + rules: + - host: {{ .Values.ingress.jaeger.host }} + http: + paths: + - path: "/" + pathType: Prefix + backend: + service: + name: jaeger-all-in-one + port: + number: {{ .Values.ingress.jaeger.port }} + - host: {{ .Values.ingress.grafana.host }} + http: + paths: + - path: "/" + pathType: Prefix + backend: + service: + name: grafana + port: + number: {{ .Values.ingress.grafana.port }} \ No newline at end of file diff --git a/src/main/helm/opentelemetry/templates/jaeger-all-in-one-deployment.yaml b/src/main/helm/opentelemetry/templates/jaeger-all-in-one-deployment.yaml new file mode 100644 index 00000000..60516367 --- /dev/null +++ b/src/main/helm/opentelemetry/templates/jaeger-all-in-one-deployment.yaml @@ -0,0 +1,54 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + component: jaeger-all-in-one + name: jaeger-all-in-one +spec: + replicas: 1 + selector: + matchLabels: + component: jaeger-all-in-one + strategy: {} + template: + metadata: + labels: + component: jaeger-all-in-one + spec: + containers: + - image: jaegertracing/all-in-one:latest + name: jaeger-all-in-one + ports: + - containerPort: 16686 + - containerPort: 14268 + - containerPort: 14250 + resources: {} + restartPolicy: Always + +--- + +apiVersion: v1 +kind: Service +metadata: + labels: + component: jaeger-all-in-one + name: jaeger-all-in-one +spec: + ports: + - name: "16686" + port: 16686 + protocol: TCP + targetPort: 16686 + - name: "14268" + port: 14268 + protocol: TCP + targetPort: 14268 + - name: "14250" + port: 14250 + protocol: TCP + targetPort: 14250 + selector: + component: jaeger-all-in-one + type: LoadBalancer #ClusterIP +status: + loadBalancer: {} diff --git a/src/main/helm/opentelemetry/templates/otel-agent-deployment.yaml b/src/main/helm/opentelemetry/templates/otel-agent-deployment.yaml new file mode 100644 index 00000000..31c4257b --- /dev/null +++ b/src/main/helm/opentelemetry/templates/otel-agent-deployment.yaml @@ -0,0 +1,103 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + component: otel-agent + name: otel-agent +spec: + replicas: 1 + selector: + matchLabels: + component: otel-agent + strategy: + type: Recreate + template: + metadata: + labels: + component: otel-agent + spec: + containers: + - args: + - /otelcol + - --config=/conf/otel-agent-config.yaml + - --log-level=DEBUG + image: otel/opentelemetry-collector:latest + name: otel-agent + ports: + - containerPort: 8888 + - containerPort: 14250 + - containerPort: 14268 + - containerPort: 55678 + - containerPort: 4317 + - containerPort: 4318 + - containerPort: 9411 + - containerPort: 1777 + - containerPort: 13133 + resources: {} + volumeMounts: + - mountPath: /conf + name: otel-agent-config-volume + volumes: + - name: otel-agent-config-volume + configMap: + name: otel-agent + items: + - key: otel-agent-config + path: otel-agent-config.yaml + restartPolicy: Always + +--- + +apiVersion: v1 +kind: Service +metadata: + labels: + component: otel-agent + name: otel-agent +spec: + ports: + - name: "8887" + port: 8887 + protocol: TCP + targetPort: 8888 + - name: "14250" + port: 14250 + protocol: TCP + targetPort: 14250 + - name: "14268" + port: 14268 + protocol: TCP + targetPort: 14268 + - name: "55678" + port: 55678 + protocol: TCP + targetPort: 55678 + - name: "4317" + port: 4317 + protocol: TCP + targetPort: 4317 + - name: "4318" + port: 4318 + protocol: TCP + targetPort: 4318 + - name: "9411" + port: 9411 + protocol: TCP + targetPort: 9411 + - name: "1777" + port: 1777 + protocol: TCP + targetPort: 1777 + - name: "55679" + port: 55679 + protocol: TCP + targetPort: 55679 + - name: "13133" + port: 13133 + protocol: TCP + targetPort: 13133 + selector: + component: otel-agent + type: LoadBalancer #ClusterIP +status: + loadBalancer: {} diff --git a/src/main/helm/opentelemetry/templates/otel-collector-deployment.yaml b/src/main/helm/opentelemetry/templates/otel-collector-deployment.yaml new file mode 100644 index 00000000..48c04dd1 --- /dev/null +++ b/src/main/helm/opentelemetry/templates/otel-collector-deployment.yaml @@ -0,0 +1,83 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + component: otel-collector + name: otel-collector +spec: + replicas: 1 + selector: + matchLabels: + component: otel-collector + strategy: + type: Recreate + template: + metadata: + labels: + component: otel-collector + spec: + containers: + - args: + - --config=/conf/otel-collector-config.yaml + - --log-level=DEBUG + image: otel/opentelemetry-collector:latest + name: otel-collector + ports: + - containerPort: 1888 + - containerPort: 8888 + - containerPort: 8889 + - containerPort: 13133 + - containerPort: 4317 + - containerPort: 55679 + resources: {} + volumeMounts: + - mountPath: /conf + name: otel-collector-config-volume + restartPolicy: Always + volumes: + - name: otel-collector-config-volume + configMap: + name: otel-collector + items: + - key: otel-collector-config + path: otel-collector-config.yaml + +--- + +apiVersion: v1 +kind: Service +metadata: + labels: + component: otel-collector + name: otel-collector +spec: + ports: + - name: "1888" + port: 1888 + protocol: TCP + targetPort: 1888 + - name: "8888" + port: 8888 + protocol: TCP + targetPort: 8888 + - name: "8889" + port: 8889 + protocol: TCP + targetPort: 8889 + - name: "13133" + port: 13133 + protocol: TCP + targetPort: 13133 + - name: "4317" + port: 4317 + protocol: TCP + targetPort: 4317 + - name: "55670" + port: 55670 + protocol: TCP + targetPort: 55679 + selector: + component: otel-collector + type: LoadBalancer #ClusterIP +status: + loadBalancer: {} diff --git a/src/main/helm/opentelemetry/templates/prometheus-deployment.yaml b/src/main/helm/opentelemetry/templates/prometheus-deployment.yaml new file mode 100644 index 00000000..c9fd2689 --- /dev/null +++ b/src/main/helm/opentelemetry/templates/prometheus-deployment.yaml @@ -0,0 +1,55 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + component: prometheus + name: prometheus +spec: + replicas: 1 + selector: + matchLabels: + component: prometheus + strategy: + type: Recreate + template: + metadata: + labels: + component: prometheus + spec: + containers: + - image: prom/prometheus:latest + name: prometheus + ports: + - containerPort: 9090 + resources: {} + volumeMounts: + - mountPath: /etc/prometheus/ + name: prometheus-config-volume + restartPolicy: Always + volumes: + - name: prometheus-config-volume + configMap: + name: prometheus + items: + - key: prometheus-config + path: prometheus.yml + +--- + +apiVersion: v1 +kind: Service +metadata: + labels: + component: prometheus + name: prometheus +spec: + ports: + - name: "9090" + port: 9090 + protocol: TCP + targetPort: 9090 + selector: + component: prometheus + type: LoadBalancer #ClusterIP +status: + loadBalancer: {} diff --git a/src/main/helm/opentelemetry/templates/victoriametrics-deployment.yaml b/src/main/helm/opentelemetry/templates/victoriametrics-deployment.yaml new file mode 100644 index 00000000..3819e880 --- /dev/null +++ b/src/main/helm/opentelemetry/templates/victoriametrics-deployment.yaml @@ -0,0 +1,77 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + component: victoriametrics + name: victoriametrics +spec: + replicas: 1 + selector: + matchLabels: + component: victoriametrics + strategy: + type: Recreate + template: + metadata: + labels: + component: victoriametrics + spec: + containers: + - args: + - --promscrape.config=/conf/vMetrics.yaml + image: victoriametrics/victoria-metrics + name: victoriametrics + ports: + - containerPort: 8428 + - containerPort: 8089 + - containerPort: 8089 + protocol: UDP + - containerPort: 2003 + - containerPort: 2003 + protocol: UDP + - containerPort: 4242 + resources: {} + volumeMounts: + - mountPath: /conf + name: vmetrics-config + restartPolicy: Always + volumes: + - configMap: + items: + - key: vMetrics.yaml + path: vMetrics.yaml + name: vmetrics-config + name: vmetrics-config + +--- + +apiVersion: v1 +kind: Service +metadata: + labels: + component: victoriametrics + name: victoriametrics +spec: + ports: + - name: "8428" + port: 8428 + targetPort: 8428 + - name: "8089" + port: 8089 + targetPort: 8089 + - name: 8089-udp + port: 8089 + protocol: UDP + targetPort: 8089 + - name: "2003" + port: 2003 + targetPort: 2003 + - name: 2003-udp + port: 2003 + protocol: UDP + targetPort: 2003 + - name: "4242" + port: 4242 + targetPort: 4242 + selector: + component: victoriametrics diff --git a/src/main/helm/opentelemetry/templates/vmagent-deployment.yaml b/src/main/helm/opentelemetry/templates/vmagent-deployment.yaml new file mode 100644 index 00000000..7d13f5d3 --- /dev/null +++ b/src/main/helm/opentelemetry/templates/vmagent-deployment.yaml @@ -0,0 +1,53 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + component: vmagent + name: vmagent +spec: + replicas: 1 + selector: + matchLabels: + component: vmagent + strategy: + type: Recreate + template: + metadata: + labels: + component: vmagent + spec: + containers: + - args: + - --promscrape.config=/conf/vMetrics.yaml + - --remoteWrite.url=http://victoriametrics:8428/api/v1/write + image: victoriametrics/vmagent + name: vmagent + ports: + - containerPort: 8429 + volumeMounts: + - mountPath: /conf + name: vmetrics-config + restartPolicy: Always + volumes: + - configMap: + items: + - key: vMetrics.yaml + path: vMetrics.yaml + name: vmetrics-config + name: vmetrics-config + +--- + +apiVersion: v1 +kind: Service +metadata: + labels: + component: vmagent + name: vmagent +spec: + ports: + - name: "8429" + port: 8429 + targetPort: 8429 + selector: + component: vmagent diff --git a/src/main/helm/opentelemetry/values.yaml b/src/main/helm/opentelemetry/values.yaml new file mode 100644 index 00000000..5533dad0 --- /dev/null +++ b/src/main/helm/opentelemetry/values.yaml @@ -0,0 +1,19 @@ +# Application configuration +application: + # Configuration to get the metrics information + metrics: + jobname: "demo-quarkus" + url: "/q/metrics" + + service: + name: "demo-quarkus" + port: 8080 + +# Ingress configuration +ingress: + jaeger: + host: "jaeger.demo-cluster-dns-be5e9d93.hcp.centralus.azmk8s.io" + port: 16686 + grafana: + host: "grafana.demo-cluster-dns-be5e9d93.hcp.centralus.azmk8s.io" + port: 3000 diff --git a/src/main/java/com/devonfw/quarkus/DemoApplication.java b/src/main/java/com/devonfw/quarkus/DemoApplication.java index 1c0f6662..1c32839c 100644 --- a/src/main/java/com/devonfw/quarkus/DemoApplication.java +++ b/src/main/java/com/devonfw/quarkus/DemoApplication.java @@ -1,17 +1,17 @@ -package com.devonfw.quarkus; - -import javax.ws.rs.core.Application; - -import org.eclipse.microprofile.openapi.annotations.OpenAPIDefinition; -import org.eclipse.microprofile.openapi.annotations.info.Contact; -import org.eclipse.microprofile.openapi.annotations.info.Info; -import org.eclipse.microprofile.openapi.annotations.tags.Tag; - -@OpenAPIDefinition(tags = { -@Tag(name = "product", description = "Product API.") }, info = @Info(title = "My Demo App RESTful API", version = "1.0.0", contact = @Contact(name = "API Support", email = "support@acme.com"))) -/** - * JaxRS application is not required in quarkus, but it is useful to place central API docs somewhere. We could also use - * package-info.java for this. - */ -public class DemoApplication extends Application { +package com.devonfw.quarkus; + +import javax.ws.rs.core.Application; + +import org.eclipse.microprofile.openapi.annotations.OpenAPIDefinition; +import org.eclipse.microprofile.openapi.annotations.info.Contact; +import org.eclipse.microprofile.openapi.annotations.info.Info; +import org.eclipse.microprofile.openapi.annotations.tags.Tag; + +@OpenAPIDefinition(tags = { +@Tag(name = "product", description = "Product API.") }, info = @Info(title = "My Demo App RESTful API", version = "1.0.0", contact = @Contact(name = "API Support", email = "support@acme.com"))) +/** + * JaxRS application is not required in quarkus, but it is useful to place central API docs somewhere. We could also use + * package-info.java for this. + */ +public class DemoApplication extends Application { } \ No newline at end of file diff --git a/src/main/java/com/devonfw/quarkus/general/domain/model/ApplicationPersistenceEntity.java b/src/main/java/com/devonfw/quarkus/general/domain/model/ApplicationPersistenceEntity.java index f3f9d079..d2400136 100644 --- a/src/main/java/com/devonfw/quarkus/general/domain/model/ApplicationPersistenceEntity.java +++ b/src/main/java/com/devonfw/quarkus/general/domain/model/ApplicationPersistenceEntity.java @@ -1,79 +1,79 @@ -package com.devonfw.quarkus.general.domain.model; - -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.MappedSuperclass; -import javax.persistence.Transient; -import javax.persistence.Version; - -/** - * Abstract base class for all {@link PersistenceEntity persistence entities} with an {@link #getId() id} and a - * {@link #getModificationCounter() modificationCounter} (version) field. All persistence entities of this application - * should inherit from this class. It is using JPA annotations at the getters what has several advantages but also - * implies that you have to annotate transient getter methods with the {@link Transient} annotation. - */ -@MappedSuperclass -public abstract class ApplicationPersistenceEntity { - - private static final long serialVersionUID = 1L; - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private Long id; - - private Integer modificationCounter; - - /** - * The constructor. - */ - public ApplicationPersistenceEntity() { - - super(); - } - - public Long getId() { - - return this.id; - } - - public void setId(Long id) { - - this.id = id; - } - - @Version - public Integer getModificationCounter() { - - return this.modificationCounter; - } - - public void setModificationCounter(Integer version) { - - this.modificationCounter = version; - } - - @Override - public String toString() { - - StringBuilder buffer = new StringBuilder(); - toString(buffer); - return buffer.toString(); - } - - /** - * Method to extend {@link #toString()} logic. - * - * @param buffer is the {@link StringBuilder} where to {@link StringBuilder#append(Object) append} the string - * representation. - */ - protected void toString(StringBuilder buffer) { - - buffer.append(getClass().getSimpleName()); - if (this.id != null) { - buffer.append("[id="); - buffer.append(this.id); - buffer.append("]"); - } - } -} +package com.devonfw.quarkus.general.domain.model; + +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.MappedSuperclass; +import javax.persistence.Transient; +import javax.persistence.Version; + +/** + * Abstract base class for all {@link PersistenceEntity persistence entities} with an {@link #getId() id} and a + * {@link #getModificationCounter() modificationCounter} (version) field. All persistence entities of this application + * should inherit from this class. It is using JPA annotations at the getters what has several advantages but also + * implies that you have to annotate transient getter methods with the {@link Transient} annotation. + */ +@MappedSuperclass +public abstract class ApplicationPersistenceEntity { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + private Integer modificationCounter; + + /** + * The constructor. + */ + public ApplicationPersistenceEntity() { + + super(); + } + + public Long getId() { + + return this.id; + } + + public void setId(Long id) { + + this.id = id; + } + + @Version + public Integer getModificationCounter() { + + return this.modificationCounter; + } + + public void setModificationCounter(Integer version) { + + this.modificationCounter = version; + } + + @Override + public String toString() { + + StringBuilder buffer = new StringBuilder(); + toString(buffer); + return buffer.toString(); + } + + /** + * Method to extend {@link #toString()} logic. + * + * @param buffer is the {@link StringBuilder} where to {@link StringBuilder#append(Object) append} the string + * representation. + */ + protected void toString(StringBuilder buffer) { + + buffer.append(getClass().getSimpleName()); + if (this.id != null) { + buffer.append("[id="); + buffer.append(this.id); + buffer.append("]"); + } + } +} diff --git a/src/main/java/com/devonfw/quarkus/general/service/json/CustomObjectMapper.java b/src/main/java/com/devonfw/quarkus/general/service/json/CustomObjectMapper.java new file mode 100644 index 00000000..e2dbfe85 --- /dev/null +++ b/src/main/java/com/devonfw/quarkus/general/service/json/CustomObjectMapper.java @@ -0,0 +1,23 @@ +package com.devonfw.quarkus.general.service.json; + +import javax.inject.Singleton; + +import org.springframework.data.domain.Page; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; + +import io.quarkus.jackson.ObjectMapperCustomizer; + +@Singleton +public class CustomObjectMapper implements ObjectMapperCustomizer { + + @Override + public void customize(ObjectMapper objectMapper) { + + SimpleModule module = new SimpleModule(); + module.addSerializer(Page.class, new PageSerializer()); + objectMapper.registerModule(module); + } + +} diff --git a/src/main/java/com/devonfw/quarkus/general/service/json/PageSerializer.java b/src/main/java/com/devonfw/quarkus/general/service/json/PageSerializer.java new file mode 100644 index 00000000..f580f701 --- /dev/null +++ b/src/main/java/com/devonfw/quarkus/general/service/json/PageSerializer.java @@ -0,0 +1,50 @@ +package com.devonfw.quarkus.general.service.json; + +import java.io.IOException; + +import org.springframework.data.domain.Page; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +public class PageSerializer extends JsonSerializer { + + @Override + public void serialize(Page page, JsonGenerator gen, SerializerProvider serializers) throws IOException { + + if (page != null) { + gen.writeStartObject(); + + gen.writeObjectField("content", page.getContent()); + gen.writeObjectFieldStart("pageable"); + gen.writeObjectFieldStart("sort"); + gen.writeBooleanField("unsorted", page.getSort().isUnsorted()); + gen.writeBooleanField("sorted", page.getSort().isSorted()); + gen.writeBooleanField("empty", page.getSort().isEmpty()); + gen.writeEndObject(); + gen.writeNumberField("offset", page.getPageable().getOffset()); + gen.writeNumberField("pageSize", page.getPageable().getPageSize()); + gen.writeNumberField("pageNumber", page.getPageable().getPageNumber()); + gen.writeBooleanField("paged", page.getPageable().isPaged()); + gen.writeBooleanField("unpaged", page.getPageable().isUnpaged()); + gen.writeEndObject(); + gen.writeBooleanField("last", page.isLast()); + gen.writeNumberField("totalPages", page.getTotalPages()); + gen.writeNumberField("totalElements", page.getTotalElements()); + gen.writeBooleanField("first", page.isFirst()); + gen.writeNumberField("numberOfElements", page.getNumberOfElements()); + gen.writeObjectFieldStart("sort"); + gen.writeBooleanField("unsorted", page.getSort().isUnsorted()); + gen.writeBooleanField("sorted", page.getSort().isSorted()); + gen.writeBooleanField("empty", page.getSort().isEmpty()); + gen.writeEndObject(); + gen.writeNumberField("number", page.getNumber()); + gen.writeNumberField("size", page.getSize()); + gen.writeBooleanField("empty", page.isEmpty()); + + gen.writeEndObject(); + } + } + +} diff --git a/src/main/java/com/devonfw/quarkus/productmanagement/domain/model/ProductEntity.java b/src/main/java/com/devonfw/quarkus/productmanagement/domain/model/ProductEntity.java index b7b22ac0..9b609017 100644 --- a/src/main/java/com/devonfw/quarkus/productmanagement/domain/model/ProductEntity.java +++ b/src/main/java/com/devonfw/quarkus/productmanagement/domain/model/ProductEntity.java @@ -1,26 +1,26 @@ -package com.devonfw.quarkus.productmanagement.domain.model; - -import java.math.BigDecimal; - -import javax.persistence.Entity; -import javax.persistence.Table; - -import com.devonfw.quarkus.general.domain.model.ApplicationPersistenceEntity; - -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -@Entity -@Table(name = "Product") -// A JPA entity requires at least 2 things @Entity annotation and an ID -// by default, the DB table will have the same name as our class -public class ProductEntity extends ApplicationPersistenceEntity { - - private String title; - - private String description; - - private BigDecimal price; -} +package com.devonfw.quarkus.productmanagement.domain.model; + +import java.math.BigDecimal; + +import javax.persistence.Entity; +import javax.persistence.Table; + +import com.devonfw.quarkus.general.domain.model.ApplicationPersistenceEntity; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@Entity +@Table(name = "Product") +// A JPA entity requires at least 2 things @Entity annotation and an ID +// by default, the DB table will have the same name as our class +public class ProductEntity extends ApplicationPersistenceEntity { + + private String title; + + private String description; + + private BigDecimal price; +} diff --git a/src/main/java/com/devonfw/quarkus/productmanagement/domain/model/ProductSearchCriteria.java b/src/main/java/com/devonfw/quarkus/productmanagement/domain/model/ProductSearchCriteria.java index 4cca919b..d9c7d47b 100644 --- a/src/main/java/com/devonfw/quarkus/productmanagement/domain/model/ProductSearchCriteria.java +++ b/src/main/java/com/devonfw/quarkus/productmanagement/domain/model/ProductSearchCriteria.java @@ -1,19 +1,19 @@ -package com.devonfw.quarkus.productmanagement.domain.model; - -import java.math.BigDecimal; - -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -public class ProductSearchCriteria { - - private String title; - - private Integer pageNumber; - - private Integer pageSize; - - private BigDecimal price, priceMin, priceMax; -} +package com.devonfw.quarkus.productmanagement.domain.model; + +import java.math.BigDecimal; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class ProductSearchCriteria { + + private String title; + + private Integer pageNumber; + + private Integer pageSize; + + private BigDecimal price, priceMin, priceMax; +} diff --git a/src/main/java/com/devonfw/quarkus/productmanagement/domain/repo/ProductFragment.java b/src/main/java/com/devonfw/quarkus/productmanagement/domain/repo/ProductFragment.java index 576fba29..06181a2f 100644 --- a/src/main/java/com/devonfw/quarkus/productmanagement/domain/repo/ProductFragment.java +++ b/src/main/java/com/devonfw/quarkus/productmanagement/domain/repo/ProductFragment.java @@ -1,16 +1,16 @@ -package com.devonfw.quarkus.productmanagement.domain.repo; - -import org.springframework.data.domain.Page; - -import com.devonfw.quarkus.productmanagement.domain.model.ProductEntity; -import com.devonfw.quarkus.productmanagement.service.v1.model.ProductSearchCriteriaDto; - -public interface ProductFragment { - public Page findAllCriteriaApi(ProductSearchCriteriaDto dto); - - public Page findAllQueryDsl(ProductSearchCriteriaDto dto); - - public Page findByTitleNativeQuery(ProductSearchCriteriaDto dto); - - public Page findByTitleQuery(ProductSearchCriteriaDto dto); -} +package com.devonfw.quarkus.productmanagement.domain.repo; + +import org.springframework.data.domain.Page; + +import com.devonfw.quarkus.productmanagement.domain.model.ProductEntity; +import com.devonfw.quarkus.productmanagement.service.v1.model.ProductSearchCriteriaDto; + +public interface ProductFragment { + public Page findAllCriteriaApi(ProductSearchCriteriaDto dto); + + public Page findAllQueryDsl(ProductSearchCriteriaDto dto); + + public Page findByTitleNativeQuery(ProductSearchCriteriaDto dto); + + public Page findByTitleQuery(ProductSearchCriteriaDto dto); +} diff --git a/src/main/java/com/devonfw/quarkus/productmanagement/domain/repo/ProductFragmentImpl.java b/src/main/java/com/devonfw/quarkus/productmanagement/domain/repo/ProductFragmentImpl.java index 3c7e0c78..2c7592b1 100644 --- a/src/main/java/com/devonfw/quarkus/productmanagement/domain/repo/ProductFragmentImpl.java +++ b/src/main/java/com/devonfw/quarkus/productmanagement/domain/repo/ProductFragmentImpl.java @@ -1,114 +1,114 @@ -package com.devonfw.quarkus.productmanagement.domain.repo; - -import java.util.ArrayList; -import java.util.List; - -import javax.inject.Inject; -import javax.persistence.EntityManager; -import javax.persistence.Query; -import javax.persistence.TypedQuery; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Predicate; -import javax.persistence.criteria.Root; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.PageRequest; - -import com.devonfw.quarkus.productmanagement.domain.model.ProductEntity; -import com.devonfw.quarkus.productmanagement.domain.model.ProductEntity_; -import com.devonfw.quarkus.productmanagement.domain.model.QProductEntity; -import com.devonfw.quarkus.productmanagement.service.v1.model.ProductSearchCriteriaDto; -import com.querydsl.jpa.impl.JPAQuery; - -public class ProductFragmentImpl implements ProductFragment { - - @Inject - EntityManager em; - - @Override - public Page findAllCriteriaApi(ProductSearchCriteriaDto dto) { - - CriteriaQuery cq = this.em.getCriteriaBuilder().createQuery(ProductEntity.class); - Root root = cq.from(ProductEntity.class); - List predicates = new ArrayList<>(); - CriteriaBuilder cb = this.em.getCriteriaBuilder(); - if (dto.getTitle() != null && !dto.getTitle().isEmpty()) { - predicates.add(cb.like(root.get(ProductEntity_.TITLE), dto.getTitle())); - } - - if (dto.getPrice() != null) { - predicates.add(cb.gt(root.get(ProductEntity_.PRICE), dto.getPrice())); - } else if (dto.getPriceMin() != null || dto.getPriceMax() != null) { - if (dto.getPriceMin() != null) { - predicates.add(cb.gt(root.get(ProductEntity_.PRICE), dto.getPriceMin())); - } - if (dto.getPriceMax() != null) { - predicates.add(cb.lt(root.get(ProductEntity_.PRICE), dto.getPriceMax())); - } - } - - if (!predicates.isEmpty()) - - { - cq.where(predicates.toArray(new Predicate[0])); - } - - // Order by title - cq.orderBy(cb.desc(root.get(ProductEntity_.TITLE))); - - TypedQuery products = this.em.createQuery(cq).setFirstResult(dto.getPageNumber() * dto.getPageSize()) - .setMaxResults(dto.getPageSize()); - return new PageImpl(products.getResultList(), PageRequest.of(dto.getPageNumber(), dto.getPageSize()), - products.getResultList().size()); - } - - @Override - public Page findAllQueryDsl(ProductSearchCriteriaDto dto) { - - QProductEntity product = QProductEntity.productEntity; - JPAQuery query = new JPAQuery(this.em); - query.from(product); - if (dto.getTitle() != null && !dto.getTitle().isEmpty()) { - query.where(product.title.eq(dto.getTitle())); - } - - if (dto.getPrice() != null) { - query.where(product.price.eq(dto.getPrice())); - } else if (dto.getPriceMin() != null || dto.getPriceMax() != null) { - if (dto.getPriceMin() != null) { - query.where(product.price.gt(dto.getPriceMin())); - } - if (dto.getPriceMax() != null) { - query.where(product.price.lt(dto.getPriceMax())); - } - } - - // Order by title - query.orderBy(product.title.desc()); - - List products = query.limit(dto.getPageSize()).offset(dto.getPageNumber() * dto.getPageSize()) - .fetch(); - return new PageImpl<>(products, PageRequest.of(dto.getPageNumber(), dto.getPageSize()), products.size()); - } - - @Override - public Page findByTitleQuery(ProductSearchCriteriaDto dto) { - - Query query = this.em.createQuery("select a from ProductEntity a where a.title = :title"); - query.setParameter("title", dto.getTitle()); - List products = query.getResultList(); - return new PageImpl<>(products, PageRequest.of(dto.getPageNumber(), dto.getPageSize()), products.size()); - } - - @Override - public Page findByTitleNativeQuery(ProductSearchCriteriaDto dto) { - - Query query = this.em.createNativeQuery("select * from ProductEntity where title = :title", ProductEntity.class); - query.setParameter("title", dto.getTitle()); - List products = query.getResultList(); - return new PageImpl<>(products, PageRequest.of(dto.getPageNumber(), dto.getPageSize()), products.size()); - } - -} +package com.devonfw.quarkus.productmanagement.domain.repo; + +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; +import javax.persistence.EntityManager; +import javax.persistence.Query; +import javax.persistence.TypedQuery; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; + +import com.devonfw.quarkus.productmanagement.domain.model.ProductEntity; +import com.devonfw.quarkus.productmanagement.domain.model.ProductEntity_; +import com.devonfw.quarkus.productmanagement.domain.model.QProductEntity; +import com.devonfw.quarkus.productmanagement.service.v1.model.ProductSearchCriteriaDto; +import com.querydsl.jpa.impl.JPAQuery; + +public class ProductFragmentImpl implements ProductFragment { + + @Inject + EntityManager em; + + @Override + public Page findAllCriteriaApi(ProductSearchCriteriaDto dto) { + + CriteriaQuery cq = this.em.getCriteriaBuilder().createQuery(ProductEntity.class); + Root root = cq.from(ProductEntity.class); + List predicates = new ArrayList<>(); + CriteriaBuilder cb = this.em.getCriteriaBuilder(); + if (dto.getTitle() != null && !dto.getTitle().isEmpty()) { + predicates.add(cb.like(root.get(ProductEntity_.TITLE), dto.getTitle())); + } + + if (dto.getPrice() != null) { + predicates.add(cb.gt(root.get(ProductEntity_.PRICE), dto.getPrice())); + } else if (dto.getPriceMin() != null || dto.getPriceMax() != null) { + if (dto.getPriceMin() != null) { + predicates.add(cb.gt(root.get(ProductEntity_.PRICE), dto.getPriceMin())); + } + if (dto.getPriceMax() != null) { + predicates.add(cb.lt(root.get(ProductEntity_.PRICE), dto.getPriceMax())); + } + } + + if (!predicates.isEmpty()) + + { + cq.where(predicates.toArray(new Predicate[0])); + } + + // Order by title + cq.orderBy(cb.desc(root.get(ProductEntity_.TITLE))); + + TypedQuery products = this.em.createQuery(cq).setFirstResult(dto.getPageNumber() * dto.getPageSize()) + .setMaxResults(dto.getPageSize()); + return new PageImpl(products.getResultList(), PageRequest.of(dto.getPageNumber(), dto.getPageSize()), + products.getResultList().size()); + } + + @Override + public Page findAllQueryDsl(ProductSearchCriteriaDto dto) { + + QProductEntity product = QProductEntity.productEntity; + JPAQuery query = new JPAQuery(this.em); + query.from(product); + if (dto.getTitle() != null && !dto.getTitle().isEmpty()) { + query.where(product.title.eq(dto.getTitle())); + } + + if (dto.getPrice() != null) { + query.where(product.price.eq(dto.getPrice())); + } else if (dto.getPriceMin() != null || dto.getPriceMax() != null) { + if (dto.getPriceMin() != null) { + query.where(product.price.gt(dto.getPriceMin())); + } + if (dto.getPriceMax() != null) { + query.where(product.price.lt(dto.getPriceMax())); + } + } + + // Order by title + query.orderBy(product.title.desc()); + + List products = query.limit(dto.getPageSize()).offset(dto.getPageNumber() * dto.getPageSize()) + .fetch(); + return new PageImpl<>(products, PageRequest.of(dto.getPageNumber(), dto.getPageSize()), products.size()); + } + + @Override + public Page findByTitleQuery(ProductSearchCriteriaDto dto) { + + Query query = this.em.createQuery("select a from ProductEntity a where a.title = :title"); + query.setParameter("title", dto.getTitle()); + List products = query.getResultList(); + return new PageImpl<>(products, PageRequest.of(dto.getPageNumber(), dto.getPageSize()), products.size()); + } + + @Override + public Page findByTitleNativeQuery(ProductSearchCriteriaDto dto) { + + Query query = this.em.createNativeQuery("select * from ProductEntity where title = :title", ProductEntity.class); + query.setParameter("title", dto.getTitle()); + List products = query.getResultList(); + return new PageImpl<>(products, PageRequest.of(dto.getPageNumber(), dto.getPageSize()), products.size()); + } + +} diff --git a/src/main/java/com/devonfw/quarkus/productmanagement/domain/repo/ProductRepository.java b/src/main/java/com/devonfw/quarkus/productmanagement/domain/repo/ProductRepository.java index 39a68d4f..9f4f517e 100644 --- a/src/main/java/com/devonfw/quarkus/productmanagement/domain/repo/ProductRepository.java +++ b/src/main/java/com/devonfw/quarkus/productmanagement/domain/repo/ProductRepository.java @@ -1,16 +1,16 @@ -package com.devonfw.quarkus.productmanagement.domain.repo; - -import org.springframework.data.domain.Page; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.CrudRepository; -import org.springframework.data.repository.query.Param; - -import com.devonfw.quarkus.productmanagement.domain.model.ProductEntity; - -public interface ProductRepository extends CrudRepository, ProductFragment { - - @Query("select a from ProductEntity a where title = :title") - ProductEntity findByTitle(@Param("title") String title); - - Page findAllByOrderByTitle(); +package com.devonfw.quarkus.productmanagement.domain.repo; + +import org.springframework.data.domain.Page; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.query.Param; + +import com.devonfw.quarkus.productmanagement.domain.model.ProductEntity; + +public interface ProductRepository extends CrudRepository, ProductFragment { + + @Query("select a from ProductEntity a where title = :title") + ProductEntity findByTitle(@Param("title") String title); + + Page findAllByOrderByTitle(); } \ No newline at end of file diff --git a/src/main/java/com/devonfw/quarkus/productmanagement/logic/UcFindProduct.java b/src/main/java/com/devonfw/quarkus/productmanagement/logic/UcFindProduct.java index 487232d8..767f5081 100644 --- a/src/main/java/com/devonfw/quarkus/productmanagement/logic/UcFindProduct.java +++ b/src/main/java/com/devonfw/quarkus/productmanagement/logic/UcFindProduct.java @@ -1,24 +1,24 @@ -package com.devonfw.quarkus.productmanagement.logic; - -import org.springframework.data.domain.Page; - -import com.devonfw.quarkus.productmanagement.service.v1.model.ProductDto; -import com.devonfw.quarkus.productmanagement.service.v1.model.ProductSearchCriteriaDto; - -public interface UcFindProduct { - Page findProducts(ProductSearchCriteriaDto dto); - - Page findProductsByCriteriaApi(ProductSearchCriteriaDto dto); - - Page findProductsByQueryDsl(ProductSearchCriteriaDto dto); - - Page findProductsByTitleQuery(ProductSearchCriteriaDto dto); - - Page findProductsByTitleNativeQuery(ProductSearchCriteriaDto dto); - - Page findProductsOrderedByTitle(); - - ProductDto findProduct(String id); - - ProductDto findProductByTitle(String title); -} +package com.devonfw.quarkus.productmanagement.logic; + +import org.springframework.data.domain.Page; + +import com.devonfw.quarkus.productmanagement.service.v1.model.ProductDto; +import com.devonfw.quarkus.productmanagement.service.v1.model.ProductSearchCriteriaDto; + +public interface UcFindProduct { + Page findProducts(ProductSearchCriteriaDto dto); + + Page findProductsByCriteriaApi(ProductSearchCriteriaDto dto); + + Page findProductsByQueryDsl(ProductSearchCriteriaDto dto); + + Page findProductsByTitleQuery(ProductSearchCriteriaDto dto); + + Page findProductsByTitleNativeQuery(ProductSearchCriteriaDto dto); + + Page findProductsOrderedByTitle(); + + ProductDto findProduct(String id); + + ProductDto findProductByTitle(String title); +} diff --git a/src/main/java/com/devonfw/quarkus/productmanagement/logic/UcFindProductImpl.java b/src/main/java/com/devonfw/quarkus/productmanagement/logic/UcFindProductImpl.java index 759f7dc0..20ce0204 100644 --- a/src/main/java/com/devonfw/quarkus/productmanagement/logic/UcFindProductImpl.java +++ b/src/main/java/com/devonfw/quarkus/productmanagement/logic/UcFindProductImpl.java @@ -1,103 +1,103 @@ -package com.devonfw.quarkus.productmanagement.logic; - -import java.util.ArrayList; -import java.util.List; - -import javax.inject.Inject; -import javax.inject.Named; -import javax.transaction.Transactional; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.PageRequest; - -import com.devonfw.quarkus.productmanagement.domain.model.ProductEntity; -import com.devonfw.quarkus.productmanagement.domain.repo.ProductRepository; -import com.devonfw.quarkus.productmanagement.service.v1.mapper.ProductMapper; -import com.devonfw.quarkus.productmanagement.service.v1.model.ProductDto; -import com.devonfw.quarkus.productmanagement.service.v1.model.ProductSearchCriteriaDto; - -import lombok.extern.slf4j.Slf4j; - -@Named -@Transactional -@Slf4j -public class UcFindProductImpl implements UcFindProduct { - @Inject - ProductRepository ProductRepository; - - @Inject - ProductMapper mapper; - - @Override - public Page findProducts(ProductSearchCriteriaDto dto) { - - Iterable productsIterator = this.ProductRepository.findAll(); - List products = new ArrayList(); - productsIterator.forEach(products::add); - List productsDto = this.mapper.map(products); - return new PageImpl<>(productsDto, PageRequest.of(dto.getPageNumber(), dto.getPageSize()), productsDto.size()); - } - - @Override - public Page findProductsByCriteriaApi(ProductSearchCriteriaDto dto) { - - List products = this.ProductRepository.findAllCriteriaApi(dto).getContent(); - List productsDto = this.mapper.map(products); - return new PageImpl<>(productsDto, PageRequest.of(dto.getPageNumber(), dto.getPageSize()), productsDto.size()); - } - - @Override - public Page findProductsByQueryDsl(ProductSearchCriteriaDto dto) { - - List products = this.ProductRepository.findAllQueryDsl(dto).getContent(); - List productsDto = this.mapper.map(products); - return new PageImpl<>(productsDto, PageRequest.of(dto.getPageNumber(), dto.getPageSize()), productsDto.size()); - } - - @Override - public Page findProductsByTitleQuery(ProductSearchCriteriaDto dto) { - - List products = this.ProductRepository.findByTitleQuery(dto).getContent(); - List productsDto = this.mapper.map(products); - return new PageImpl<>(productsDto, PageRequest.of(dto.getPageNumber(), dto.getPageSize()), productsDto.size()); - } - - @Override - public Page findProductsByTitleNativeQuery(ProductSearchCriteriaDto dto) { - - List products = this.ProductRepository.findByTitleNativeQuery(dto).getContent(); - List productsDto = this.mapper.map(products); - return new PageImpl<>(productsDto, PageRequest.of(dto.getPageNumber(), dto.getPageSize()), productsDto.size()); - } - - @Override - public Page findProductsOrderedByTitle() { - - List products = this.ProductRepository.findAllByOrderByTitle().getContent(); - List productsDto = this.mapper.map(products); - return new PageImpl<>(productsDto); - } - - @Override - public ProductDto findProduct(String id) { - - ProductEntity product = this.ProductRepository.findById(Long.valueOf(id)).get(); - if (product != null) { - return this.mapper.map(product); - } else { - return null; - } - } - - @Override - public ProductDto findProductByTitle(String title) { - - ProductEntity product = this.ProductRepository.findByTitle(title); - if (product != null) { - return this.mapper.map(product); - } else { - return null; - } - } +package com.devonfw.quarkus.productmanagement.logic; + +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.transaction.Transactional; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; + +import com.devonfw.quarkus.productmanagement.domain.model.ProductEntity; +import com.devonfw.quarkus.productmanagement.domain.repo.ProductRepository; +import com.devonfw.quarkus.productmanagement.service.v1.mapper.ProductMapper; +import com.devonfw.quarkus.productmanagement.service.v1.model.ProductDto; +import com.devonfw.quarkus.productmanagement.service.v1.model.ProductSearchCriteriaDto; + +import lombok.extern.slf4j.Slf4j; + +@Named +@Transactional +@Slf4j +public class UcFindProductImpl implements UcFindProduct { + @Inject + ProductRepository ProductRepository; + + @Inject + ProductMapper mapper; + + @Override + public Page findProducts(ProductSearchCriteriaDto dto) { + + Iterable productsIterator = this.ProductRepository.findAll(); + List products = new ArrayList(); + productsIterator.forEach(products::add); + List productsDto = this.mapper.map(products); + return new PageImpl<>(productsDto, PageRequest.of(dto.getPageNumber(), dto.getPageSize()), productsDto.size()); + } + + @Override + public Page findProductsByCriteriaApi(ProductSearchCriteriaDto dto) { + + List products = this.ProductRepository.findAllCriteriaApi(dto).getContent(); + List productsDto = this.mapper.map(products); + return new PageImpl<>(productsDto, PageRequest.of(dto.getPageNumber(), dto.getPageSize()), productsDto.size()); + } + + @Override + public Page findProductsByQueryDsl(ProductSearchCriteriaDto dto) { + + List products = this.ProductRepository.findAllQueryDsl(dto).getContent(); + List productsDto = this.mapper.map(products); + return new PageImpl<>(productsDto, PageRequest.of(dto.getPageNumber(), dto.getPageSize()), productsDto.size()); + } + + @Override + public Page findProductsByTitleQuery(ProductSearchCriteriaDto dto) { + + List products = this.ProductRepository.findByTitleQuery(dto).getContent(); + List productsDto = this.mapper.map(products); + return new PageImpl<>(productsDto, PageRequest.of(dto.getPageNumber(), dto.getPageSize()), productsDto.size()); + } + + @Override + public Page findProductsByTitleNativeQuery(ProductSearchCriteriaDto dto) { + + List products = this.ProductRepository.findByTitleNativeQuery(dto).getContent(); + List productsDto = this.mapper.map(products); + return new PageImpl<>(productsDto, PageRequest.of(dto.getPageNumber(), dto.getPageSize()), productsDto.size()); + } + + @Override + public Page findProductsOrderedByTitle() { + + List products = this.ProductRepository.findAllByOrderByTitle().getContent(); + List productsDto = this.mapper.map(products); + return new PageImpl<>(productsDto); + } + + @Override + public ProductDto findProduct(String id) { + + ProductEntity product = this.ProductRepository.findById(Long.valueOf(id)).get(); + if (product != null) { + return this.mapper.map(product); + } else { + return null; + } + } + + @Override + public ProductDto findProductByTitle(String title) { + + ProductEntity product = this.ProductRepository.findByTitle(title); + if (product != null) { + return this.mapper.map(product); + } else { + return null; + } + } } \ No newline at end of file diff --git a/src/main/java/com/devonfw/quarkus/productmanagement/logic/UcManageProduct.java b/src/main/java/com/devonfw/quarkus/productmanagement/logic/UcManageProduct.java index 1b8cf630..64809a74 100644 --- a/src/main/java/com/devonfw/quarkus/productmanagement/logic/UcManageProduct.java +++ b/src/main/java/com/devonfw/quarkus/productmanagement/logic/UcManageProduct.java @@ -1,10 +1,10 @@ -package com.devonfw.quarkus.productmanagement.logic; - -import com.devonfw.quarkus.productmanagement.service.v1.model.NewProductDto; -import com.devonfw.quarkus.productmanagement.service.v1.model.ProductDto; - -public interface UcManageProduct { - ProductDto saveProduct(NewProductDto dto); - - ProductDto deleteProduct(String id); -} +package com.devonfw.quarkus.productmanagement.logic; + +import com.devonfw.quarkus.productmanagement.service.v1.model.NewProductDto; +import com.devonfw.quarkus.productmanagement.service.v1.model.ProductDto; + +public interface UcManageProduct { + ProductDto saveProduct(NewProductDto dto); + + ProductDto deleteProduct(String id); +} diff --git a/src/main/java/com/devonfw/quarkus/productmanagement/logic/UcManageProductImpl.java b/src/main/java/com/devonfw/quarkus/productmanagement/logic/UcManageProductImpl.java index d79477a3..e199e1cc 100644 --- a/src/main/java/com/devonfw/quarkus/productmanagement/logic/UcManageProductImpl.java +++ b/src/main/java/com/devonfw/quarkus/productmanagement/logic/UcManageProductImpl.java @@ -1,40 +1,40 @@ -package com.devonfw.quarkus.productmanagement.logic; - -import javax.inject.Inject; -import javax.inject.Named; -import javax.transaction.Transactional; - -import com.devonfw.quarkus.productmanagement.domain.model.ProductEntity; -import com.devonfw.quarkus.productmanagement.domain.repo.ProductRepository; -import com.devonfw.quarkus.productmanagement.service.v1.mapper.ProductMapper; -import com.devonfw.quarkus.productmanagement.service.v1.model.NewProductDto; -import com.devonfw.quarkus.productmanagement.service.v1.model.ProductDto; - -@Named -@Transactional -public class UcManageProductImpl implements UcManageProduct { - @Inject - ProductRepository productRepository; - - @Inject - ProductMapper mapper; - - @Override - public ProductDto saveProduct(NewProductDto dto) { - - ProductEntity created = this.productRepository.save(this.mapper.create(dto)); - return this.mapper.map(created); - } - - @Override - public ProductDto deleteProduct(String id) { - - ProductEntity product = this.productRepository.findById(Long.valueOf(id)).get(); - if (product != null) { - this.productRepository.delete(product); - return this.mapper.map(product); - } else { - return null; - } - } -} +package com.devonfw.quarkus.productmanagement.logic; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.transaction.Transactional; + +import com.devonfw.quarkus.productmanagement.domain.model.ProductEntity; +import com.devonfw.quarkus.productmanagement.domain.repo.ProductRepository; +import com.devonfw.quarkus.productmanagement.service.v1.mapper.ProductMapper; +import com.devonfw.quarkus.productmanagement.service.v1.model.NewProductDto; +import com.devonfw.quarkus.productmanagement.service.v1.model.ProductDto; + +@Named +@Transactional +public class UcManageProductImpl implements UcManageProduct { + @Inject + ProductRepository productRepository; + + @Inject + ProductMapper mapper; + + @Override + public ProductDto saveProduct(NewProductDto dto) { + + ProductEntity created = this.productRepository.save(this.mapper.create(dto)); + return this.mapper.map(created); + } + + @Override + public ProductDto deleteProduct(String id) { + + ProductEntity product = this.productRepository.findById(Long.valueOf(id)).get(); + if (product != null) { + this.productRepository.delete(product); + return this.mapper.map(product); + } else { + return null; + } + } +} diff --git a/src/main/java/com/devonfw/quarkus/productmanagement/service/v1/ProductRestService.java b/src/main/java/com/devonfw/quarkus/productmanagement/service/v1/ProductRestService.java index b886fcea..b04442b4 100644 --- a/src/main/java/com/devonfw/quarkus/productmanagement/service/v1/ProductRestService.java +++ b/src/main/java/com/devonfw/quarkus/productmanagement/service/v1/ProductRestService.java @@ -1,143 +1,143 @@ -package com.devonfw.quarkus.productmanagement.service.v1; - -import javax.inject.Inject; -import javax.ws.rs.BeanParam; -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.UriInfo; - -import org.eclipse.microprofile.openapi.annotations.Operation; -import org.eclipse.microprofile.openapi.annotations.media.Content; -import org.eclipse.microprofile.openapi.annotations.media.Schema; -import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; -import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; -import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; -import org.springframework.data.domain.PageImpl; -import org.tkit.quarkus.rs.models.PageResultDTO; - -import com.devonfw.quarkus.productmanagement.logic.UcFindProduct; -import com.devonfw.quarkus.productmanagement.logic.UcManageProduct; -import com.devonfw.quarkus.productmanagement.service.v1.model.NewProductDto; -import com.devonfw.quarkus.productmanagement.service.v1.model.ProductDto; -import com.devonfw.quarkus.productmanagement.service.v1.model.ProductSearchCriteriaDto; - -//In Quarkus all JAX-RS resources are treated as CDI beans -//default is Singleton scope -@Path("/products") -// how we serialize response -@Produces(MediaType.APPLICATION_JSON) -// how we deserialize params -@Consumes(MediaType.APPLICATION_JSON) -public class ProductRestService { - - // using @Context we can inject contextual info from JAXRS(e.g. http request, current uri info, endpoint info...) - @Context - UriInfo uriInfo; - - @Inject - UcFindProduct ucFindProduct; - - @Inject - UcManageProduct ucManageProduct; - - @APIResponses({ - @APIResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = PagedProductResponse.class))), - @APIResponse(responseCode = "500") }) - @Operation(operationId = "Get Products", description = "Returns list of Products matching given criteria, uses pagination") - @GET - // REST service methods should not declare exceptions, any thrown error will be transformed by exceptionMapper in - // tkit-rest - // We did not define custom @Path - so it will use class level path - public PageImpl getAll(@BeanParam ProductSearchCriteriaDto dto) { - - return (PageImpl) this.ucFindProduct.findProducts(dto); - } - - @GET - @Path("criteriaApi") - public PageImpl getAllCriteriaApi(@BeanParam ProductSearchCriteriaDto dto) { - - return (PageImpl) this.ucFindProduct.findProductsByCriteriaApi(dto); - } - - @GET - @Path("queryDsl") - public PageImpl getAllQueryDsl(@BeanParam ProductSearchCriteriaDto dto) { - - return (PageImpl) this.ucFindProduct.findProductsByQueryDsl(dto); - } - - @GET - @Path("query") - public PageImpl getAllQuery(@BeanParam ProductSearchCriteriaDto dto) { - - return (PageImpl) this.ucFindProduct.findProductsByTitleQuery(dto); - } - - @GET - @Path("nativeQuery") - public PageImpl getAllNativeQuery(@BeanParam ProductSearchCriteriaDto dto) { - - return (PageImpl) this.ucFindProduct.findProductsByTitleNativeQuery(dto); - } - - @GET - @Path("ordered") - public PageImpl getAllOrderedByTitle() { - - return (PageImpl) this.ucFindProduct.findProductsOrderedByTitle(); - } - - @APIResponses({ - @APIResponse(responseCode = "201", description = "OK, New Product created", content = @Content(schema = @Schema(implementation = NewProductDto.class))), - @APIResponse(responseCode = "400", description = "Client side error, invalid request"), - @APIResponse(responseCode = "500") }) - @Operation(operationId = "createNewProduct", description = "Stores new Product in DB") - @POST - // We did not define custom @Path - so it will use class level path. - // Although we now have 2 methods with same path, it is ok, because it is a different method (get vs post) - public ProductDto createNewProduct(NewProductDto dto) { - - return this.ucManageProduct.saveProduct(dto); - } - - @APIResponses({ - @APIResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ProductDto.class))), - @APIResponse(responseCode = "404", description = "Product not found"), @APIResponse(responseCode = "500") }) - @Operation(operationId = "getProductById", description = "Returns Product with given id") - @GET - @Path("{id}") - public ProductDto getProductById(@Parameter(description = "Product unique id") @PathParam("id") String id) { - - return this.ucFindProduct.findProduct(id); - } - - @GET - @Path("title/{title}") - public ProductDto getProductByTitle(@PathParam("title") String title) { - - return this.ucFindProduct.findProductByTitle(title); - } - - @APIResponses({ - @APIResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ProductDto.class))), - @APIResponse(responseCode = "404", description = "Product not found"), @APIResponse(responseCode = "500") }) - @Operation(operationId = "deleteProductById", description = "Deletes the Product with given id") - @DELETE - @Path("{id}") - public ProductDto deleteProductById(@Parameter(description = "Product unique id") @PathParam("id") String id) { - - return this.ucManageProduct.deleteProduct(id); - } - - private static class PagedProductResponse extends PageResultDTO { - } - -} +package com.devonfw.quarkus.productmanagement.service.v1; + +import javax.inject.Inject; +import javax.ws.rs.BeanParam; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.UriInfo; + +import org.eclipse.microprofile.openapi.annotations.Operation; +import org.eclipse.microprofile.openapi.annotations.media.Content; +import org.eclipse.microprofile.openapi.annotations.media.Schema; +import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; +import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; +import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; +import org.springframework.data.domain.Page; +import org.tkit.quarkus.rs.models.PageResultDTO; + +import com.devonfw.quarkus.productmanagement.logic.UcFindProduct; +import com.devonfw.quarkus.productmanagement.logic.UcManageProduct; +import com.devonfw.quarkus.productmanagement.service.v1.model.NewProductDto; +import com.devonfw.quarkus.productmanagement.service.v1.model.ProductDto; +import com.devonfw.quarkus.productmanagement.service.v1.model.ProductSearchCriteriaDto; + +//In Quarkus all JAX-RS resources are treated as CDI beans +//default is Singleton scope +@Path("/products") +// how we serialize response +@Produces(MediaType.APPLICATION_JSON) +// how we deserialize params +@Consumes(MediaType.APPLICATION_JSON) +public class ProductRestService { + + // using @Context we can inject contextual info from JAXRS(e.g. http request, current uri info, endpoint info...) + @Context + UriInfo uriInfo; + + @Inject + UcFindProduct ucFindProduct; + + @Inject + UcManageProduct ucManageProduct; + + @APIResponses({ + @APIResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = PagedProductResponse.class))), + @APIResponse(responseCode = "500") }) + @Operation(operationId = "Get Products", description = "Returns list of Products matching given criteria, uses pagination") + @GET + // REST service methods should not declare exceptions, any thrown error will be transformed by exceptionMapper in + // tkit-rest + // We did not define custom @Path - so it will use class level path + public Page getAll(@BeanParam ProductSearchCriteriaDto dto) { + + return this.ucFindProduct.findProducts(dto); + } + + @GET + @Path("criteriaApi") + public Page getAllCriteriaApi(@BeanParam ProductSearchCriteriaDto dto) { + + return this.ucFindProduct.findProductsByCriteriaApi(dto); + } + + @GET + @Path("queryDsl") + public Page getAllQueryDsl(@BeanParam ProductSearchCriteriaDto dto) { + + return this.ucFindProduct.findProductsByQueryDsl(dto); + } + + @GET + @Path("query") + public Page getAllQuery(@BeanParam ProductSearchCriteriaDto dto) { + + return this.ucFindProduct.findProductsByTitleQuery(dto); + } + + @GET + @Path("nativeQuery") + public Page getAllNativeQuery(@BeanParam ProductSearchCriteriaDto dto) { + + return this.ucFindProduct.findProductsByTitleNativeQuery(dto); + } + + @GET + @Path("ordered") + public Page getAllOrderedByTitle() { + + return this.ucFindProduct.findProductsOrderedByTitle(); + } + + @APIResponses({ + @APIResponse(responseCode = "200", description = "OK, New Product created", content = @Content(schema = @Schema(implementation = NewProductDto.class))), + @APIResponse(responseCode = "400", description = "Client side error, invalid request"), + @APIResponse(responseCode = "500") }) + @Operation(operationId = "createNewProduct", description = "Stores new Product in DB") + @POST + // We did not define custom @Path - so it will use class level path. + // Although we now have 2 methods with same path, it is ok, because it is a different method (get vs post) + public ProductDto createNewProduct(NewProductDto dto) { + + return this.ucManageProduct.saveProduct(dto); + } + + @APIResponses({ + @APIResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ProductDto.class))), + @APIResponse(responseCode = "404", description = "Product not found"), @APIResponse(responseCode = "500") }) + @Operation(operationId = "getProductById", description = "Returns Product with given id") + @GET + @Path("{id}") + public ProductDto getProductById(@Parameter(description = "Product unique id") @PathParam("id") String id) { + + return this.ucFindProduct.findProduct(id); + } + + @GET + @Path("title/{title}") + public ProductDto getProductByTitle(@PathParam("title") String title) { + + return this.ucFindProduct.findProductByTitle(title); + } + + @APIResponses({ + @APIResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ProductDto.class))), + @APIResponse(responseCode = "404", description = "Product not found"), @APIResponse(responseCode = "500") }) + @Operation(operationId = "deleteProductById", description = "Deletes the Product with given id") + @DELETE + @Path("{id}") + public ProductDto deleteProductById(@Parameter(description = "Product unique id") @PathParam("id") String id) { + + return this.ucManageProduct.deleteProduct(id); + } + + private static class PagedProductResponse extends PageResultDTO { + } + +} diff --git a/src/main/java/com/devonfw/quarkus/productmanagement/service/v1/mapper/ProductMapper.java b/src/main/java/com/devonfw/quarkus/productmanagement/service/v1/mapper/ProductMapper.java index 46c1f856..19c2992d 100644 --- a/src/main/java/com/devonfw/quarkus/productmanagement/service/v1/mapper/ProductMapper.java +++ b/src/main/java/com/devonfw/quarkus/productmanagement/service/v1/mapper/ProductMapper.java @@ -1,21 +1,21 @@ -package com.devonfw.quarkus.productmanagement.service.v1.mapper; - -import java.util.List; - -import org.mapstruct.Mapper; -import org.tkit.quarkus.rs.mappers.OffsetDateTimeMapper; - -import com.devonfw.quarkus.productmanagement.domain.model.ProductEntity; -import com.devonfw.quarkus.productmanagement.service.v1.model.NewProductDto; -import com.devonfw.quarkus.productmanagement.service.v1.model.ProductDto; - -//mapstruct will generate an impl class(CDI bean, see pom.xml) from this interface at compile time -@Mapper(uses = OffsetDateTimeMapper.class) -public interface ProductMapper { - - ProductDto map(ProductEntity model); - - ProductEntity create(NewProductDto dto); - - List map(List Products); -} +package com.devonfw.quarkus.productmanagement.service.v1.mapper; + +import java.util.List; + +import org.mapstruct.Mapper; +import org.tkit.quarkus.rs.mappers.OffsetDateTimeMapper; + +import com.devonfw.quarkus.productmanagement.domain.model.ProductEntity; +import com.devonfw.quarkus.productmanagement.service.v1.model.NewProductDto; +import com.devonfw.quarkus.productmanagement.service.v1.model.ProductDto; + +//mapstruct will generate an impl class(CDI bean, see pom.xml) from this interface at compile time +@Mapper(uses = OffsetDateTimeMapper.class) +public interface ProductMapper { + + ProductDto map(ProductEntity model); + + ProductEntity create(NewProductDto dto); + + List map(List Products); +} diff --git a/src/main/java/com/devonfw/quarkus/productmanagement/service/v1/model/NewProductDto.java b/src/main/java/com/devonfw/quarkus/productmanagement/service/v1/model/NewProductDto.java index 69cf8119..2b5807cd 100644 --- a/src/main/java/com/devonfw/quarkus/productmanagement/service/v1/model/NewProductDto.java +++ b/src/main/java/com/devonfw/quarkus/productmanagement/service/v1/model/NewProductDto.java @@ -1,23 +1,23 @@ -package com.devonfw.quarkus.productmanagement.service.v1.model; - -import java.math.BigDecimal; - -import org.eclipse.microprofile.openapi.annotations.media.Schema; - -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -public class NewProductDto { - - @Schema(nullable = false, description = "Product title", minLength = 3, maxLength = 500) - private String title; - - @Schema(description = "Product description", minLength = 3, maxLength = 500) - private String description; - - @Schema(description = "Product price") - private BigDecimal price; - -} +package com.devonfw.quarkus.productmanagement.service.v1.model; + +import java.math.BigDecimal; + +import org.eclipse.microprofile.openapi.annotations.media.Schema; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class NewProductDto { + + @Schema(nullable = false, description = "Product title", minLength = 3, maxLength = 500) + private String title; + + @Schema(description = "Product description", minLength = 3, maxLength = 500) + private String description; + + @Schema(description = "Product price") + private BigDecimal price; + +} diff --git a/src/main/java/com/devonfw/quarkus/productmanagement/service/v1/model/ProductDto.java b/src/main/java/com/devonfw/quarkus/productmanagement/service/v1/model/ProductDto.java index c3dd0465..b31afd33 100644 --- a/src/main/java/com/devonfw/quarkus/productmanagement/service/v1/model/ProductDto.java +++ b/src/main/java/com/devonfw/quarkus/productmanagement/service/v1/model/ProductDto.java @@ -1,20 +1,20 @@ -package com.devonfw.quarkus.productmanagement.service.v1.model; - -import java.math.BigDecimal; - -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -public class ProductDto { - - private Long id; - - private String title; - - private String description; - - private BigDecimal price; - -} +package com.devonfw.quarkus.productmanagement.service.v1.model; + +import java.math.BigDecimal; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class ProductDto { + + private Long id; + + private String title; + + private String description; + + private BigDecimal price; + +} diff --git a/src/main/java/com/devonfw/quarkus/productmanagement/service/v1/model/ProductSearchCriteriaDto.java b/src/main/java/com/devonfw/quarkus/productmanagement/service/v1/model/ProductSearchCriteriaDto.java index 1ad69ed5..ccf52ea0 100644 --- a/src/main/java/com/devonfw/quarkus/productmanagement/service/v1/model/ProductSearchCriteriaDto.java +++ b/src/main/java/com/devonfw/quarkus/productmanagement/service/v1/model/ProductSearchCriteriaDto.java @@ -1,34 +1,34 @@ -package com.devonfw.quarkus.productmanagement.service.v1.model; - -import java.math.BigDecimal; - -import javax.ws.rs.DefaultValue; -import javax.ws.rs.QueryParam; - -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -public class ProductSearchCriteriaDto { - - @QueryParam("title") - private String title; - - @QueryParam("page") - @DefaultValue("0") - private int pageNumber = 0; - - @QueryParam("size") - @DefaultValue("10") - private int pageSize = 10; - - @QueryParam("priceMin") - private BigDecimal priceMin; - - @QueryParam("priceMax") - private BigDecimal priceMax; - - @QueryParam("price") - private BigDecimal price; -} +package com.devonfw.quarkus.productmanagement.service.v1.model; + +import java.math.BigDecimal; + +import javax.ws.rs.DefaultValue; +import javax.ws.rs.QueryParam; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class ProductSearchCriteriaDto { + + @QueryParam("title") + private String title; + + @QueryParam("page") + @DefaultValue("0") + private int pageNumber = 0; + + @QueryParam("size") + @DefaultValue("10") + private int pageSize = 10; + + @QueryParam("priceMin") + private BigDecimal priceMin; + + @QueryParam("priceMax") + private BigDecimal priceMax; + + @QueryParam("price") + private BigDecimal price; +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 5822b02a..ec3fc7e5 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,66 +1,52 @@ -# Here we put all our configuration values -# we can define profile-specific values using `%.` prefix -# e.g. %dev.quarkus.log.level=DEBUG would only be applied in dev mode - -# Datasource configuration -quarkus.datasource.db-kind=postgresql -quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/demo -quarkus.datasource.username=demo -quarkus.datasource.password=demo - -# Flyway minimal config properties -quarkus.flyway.migrate-at-start=true -quarkus.flyway.baseline-on-migrate=true -quarkus.flyway.baseline-version=0 - -# logging configuration -# which packages should be automatically logged by tkit cdi logger -quarkus.tkit.log.packages=org.tkit,com.devonfw -# you can supress logs from classes by annotations or regex -quarkus.tkit.log.ignore.pattern=.*MapperImpl - - -#identifier of your service when using openTracing, if empty a no-op tracer will be used -#openTelemetry works without these configurations, exporting to different backends. -#Still, there should be some configuration possible in a future quarkus version. -#quarkus.jaeger.service-name=demo-app -#sampling algorithm, const=tracing all or nothing -#quarkus.jaeger.sampler-type=const -#1=trace every single method -#quarkus.jaeger.sampler-param=1 -#quarkus.log.console.format=%d{HH:mm:ss} %-5p traceId=%X{traceId}, parentId=%X{parentId}, spanId=%X{spanId}, sampled=%X{sampled} [%c{2.}] (%t) %s%e%n -#report spans to central aggregator(you must start Jaeger yourself - e.g. using the docker-compose.yaml) -#quarkus.jaeger.endpoint=http://localhost:14268/api/traces - -# all of these are default values, metrics would work just fine if you remove it -quarkus.micrometer.binder-enabled-default=true -# also report metrics from microprofile -quarkus.micrometer.binder.mp-metrics.enabled=true -# implicit metrics from http client -quarkus.micrometer.binder.http-client.enabled=true -# implicit metrics from REST endpoints -quarkus.micrometer.binder.http-server.enabled=true - - -# DEV profile -# in dev mode, use flyway master-data -%quarkus.hibernate-orm.database.generation=none -# during dev, print sql produced by hibernate, disable in prod(default) -%dev.quarkus.hibernate-orm.log.sql=true -# disable json logs for better readability -%dev.quarkus.tkit.log.console.json=false -#if you dont use tkit-json=log but standard quarkus-json-log, use this instead -#%dev.quarkus.log.console.json=false -# if you want to see opentracing values in -%dev.quarkus.log.console.format=%d{HH:mm:ss} %-5p traceId=%X{traceId}, parentId=%X{parentId}, spanId=%X{spanId}, sampled=%X{sampled} [%c{2.}] (%t) %s%e%n - - -# TEST - -%test.quarkus.tkit.log.console.json=false -# Test DB is provided by tkit test containers, URL will be set dynamically -%test.quarkus.datasource.password=demo -%test.quarkus.datasource.username=demo -%test.quarkus.hibernate-orm.database.generation=drop-and-create -%test.quarkus.hibernate-orm.log.sql=true - +# Here we put all our configuration values +# we can define profile-specific values using `%.` prefix +# e.g. %dev.quarkus.log.level=DEBUG would only be applied in dev mode + +# Datasource configuration +quarkus.datasource.db-kind=postgresql +quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/demo +quarkus.datasource.username=demo +quarkus.datasource.password=demo + +# Flyway minimal config properties +quarkus.flyway.migrate-at-start=true +quarkus.flyway.baseline-on-migrate=true +quarkus.flyway.baseline-version=0 + +# logging configuration +# which packages should be automatically logged by tkit cdi logger +quarkus.tkit.log.packages=org.tkit,com.devonfw +# you can supress logs from classes by annotations or regex +quarkus.tkit.log.ignore.pattern=.*MapperImpl + +# Metrics +# all of these are default values, metrics would work just fine if you remove it +quarkus.micrometer.binder-enabled-default=true +# also report metrics from microprofile +quarkus.micrometer.binder.mp-metrics.enabled=true +# implicit metrics from http client +quarkus.micrometer.binder.http-client.enabled=true +# implicit metrics from REST endpoints +quarkus.micrometer.binder.http-server.enabled=true + +# DEV profile +# in dev mode, use flyway master-data +%quarkus.hibernate-orm.database.generation=none +# during dev, print sql produced by hibernate, disable in prod(default) +%dev.quarkus.hibernate-orm.log.sql=true +# disable json logs for better readability +%dev.quarkus.tkit.log.console.json=false +#if you dont use tkit-json=log but standard quarkus-json-log, use this instead +#%dev.quarkus.log.console.json=false +# if you want to see opentracing values in +%dev.quarkus.log.console.format=%d{HH:mm:ss} %-5p traceId=%X{traceId}, parentId=%X{parentId}, spanId=%X{spanId}, sampled=%X{sampled} [%c{2.}] (%t) %s%e%n + + +# TEST +%test.quarkus.tkit.log.console.json=false +# Test DB is provided by tkit test containers, URL will be set dynamically +%test.quarkus.datasource.password=demo +%test.quarkus.datasource.username=demo +%test.quarkus.hibernate-orm.database.generation=drop-and-create +%test.quarkus.hibernate-orm.log.sql=true + diff --git a/src/main/resources/db/migration/V001__Create_schema.sql b/src/main/resources/db/migration/V001__Create_schema.sql index af0c1b3b..560e3001 100644 --- a/src/main/resources/db/migration/V001__Create_schema.sql +++ b/src/main/resources/db/migration/V001__Create_schema.sql @@ -1,10 +1,10 @@ --- *** Product catalog *** -CREATE TABLE Product -( - id BIGSERIAL, - modificationCounter INTEGER NOT NULL, - title VARCHAR (255) NOT NULL, - description VARCHAR (4000), - price DECIMAL (16,2) NOT NULL, - CONSTRAINT PK_Product PRIMARY KEY(id) -); +-- *** Product catalog *** +CREATE TABLE Product +( + id BIGSERIAL, + modificationCounter INTEGER NOT NULL, + title VARCHAR (255) NOT NULL, + description VARCHAR (4000), + price DECIMAL (16,2) NOT NULL, + CONSTRAINT PK_Product PRIMARY KEY(id) +); diff --git a/src/main/resources/db/migration/V002__Master_data.sql b/src/main/resources/db/migration/V002__Master_data.sql index 5fd00a94..204cf812 100644 --- a/src/main/resources/db/migration/V002__Master_data.sql +++ b/src/main/resources/db/migration/V002__Master_data.sql @@ -1,352 +1,352 @@ --- Products 350 entries from https://github.com/etano/productner/blob/master/Product%20Dataset.csv --- Original source: Justifying recommendations using distantly-labeled reviews and fined-grained aspects, Jianmo Ni, Jiacheng Li, Julian McAuley, Empirical Methods in Natural Language Processing (EMNLP), 2019ss -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (0, 1, 'Bose Acoustimass 5 Series III Speaker System - AM53BK', 'Bose Acoustimass 5 Series III Speaker System - AM53BK/ 2 Dual Cube Speakers With Two 2-1/2'' Wide-range Drivers In Each Speaker/ Powerful Bass Module With Two 5-1/2'' Woofers/ 200 Watts Max Power/ Black Finish', 399.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (1, 1, 'Sony Switcher - SBV40S', 'Sony Switcher - SBV40S/ Eliminates Disconnecting And Reconnecting Cables/ Compact Design/ 4 A/V Inputs With S-Video Jacks/ 1 A/V Output With S-Video (Y/C)Jack/ 2 Audio Output', 49.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (2, 1, 'Bose 27028 161 Bookshelf Pair Speakers In White - 161WH', 'Bose 161 Bookshelf Speakers In White - 161WH/ Articulated Array Speaker Design/ High-Excursion Twiddler Drivers/ Magnetically Shielded/ Priced Per Pair/ White Finish', 158.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (3, 1, 'Denon Stereo Tuner - TU1500RD', 'Denon Stereo Tuner - TU1500RD/ RDS Radio Data System/ AM-FM 40 Station Random Memory/ Rotary Tuning Knob/ Dot Matrix FL Display/ Optional Remote', 375.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (4, 1, 'Panasonic Integrated Telephone System - KXTS108W', 'Panasonic Integrated Telephone System - KXTS108W/ 16 Digit LCD With Clock/ Hands Free Speakerphone/ Built-In Data Port/ 10-Station One-Touch Dialing/ 3-Step Ringer Volume/ White Finish', 44.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (5, 1, 'Panasonic Hands-Free Headset - KXTCA86', 'Panasonic Hands-Free Headset - KXTCA86/ Comfort Fit And Fold Design/ Noise Cancelling Microphone/ Standard 2.5mm Connection', 14.95); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (6, 1, 'Panasonic Hands Free Headset - KXTCA92', 'Panasonic Hands Free Headset - KXTCA92/ Comfort Fit With Fold Design/ Noise Cancelling Microphone/ Volume Control/ Mute/ Standard 2.5mm Connection', 25.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (7, 1, 'Cuisinart Convection-Oven-Toaster-Broiler With Exact Heat Sensor - TOB165WH', 'Cuisinart Convection-Oven-Toaster-Broiler With Exact Heat Sensor - TOB165WH/ 0.5 Cubic Foot Oven Capacity/ LED Indicators/ Individual Or Combination Settings/ Always Even Shade Control/ 4 Hour Automatic Shut Off/ Slide-Out Crumb Tray/ Includes Broiling Pan/ White Finish', 149.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (8, 1, 'Frigidaire 24'' White Built-In Dishwasher - FDB130WH', 'Frigidaire 24'' FDB130RGS White Built-In Dishwasher - FDB130WH/ Convection Drying System/ QuietSound Sound Insulation Package/ 2 Wash Levels/ Adjustable Rinse Aid Dispenser/ Self Cleaning Filter/ White Finish', 229.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (9, 1, 'Cuisinart Cordless Electric Kettle - KUA17', 'Cuisinart Cordless Electric Kettle - KUA17/ 1-3/4 Quart Capacity/ Automatic Shut-Off/ Indicator Light/ Splash Guard Spout/ Cord Storage In Base/ Chrome Finish', 70.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (10, 1, 'Omnimount Wall Speaker Mount - 20WLBK', 'Omnimount Wall Speaker Mount - 20WLBK/ Stainless Steel Shafts And All Necessary Hardware Included/ Supports Speakers Up To 20 lbs./ Sold As Single / Black Finish', 39.95); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (11, 1, 'Omnimount Wall Speaker Mount - 20WLWH', 'Omnimount Wall Speaker Mount - 20WLWH/ Stainless Steel Shafts And All Necessary Hardware Included/ Supports Speakers Up To 20 lbs./ Sold as each / White Finish (Photo Showing Black)', 40.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (12, 1, 'Denon Semi-Automatic Turntable - Black Finish - DP29F', 'Denon Semi-Automatic Turntable - DP29F/ Metal Platter/ Built-In RIAA Equalizer/ DC Servo Motor/ 2 Speed 33 + 45 RPM/ Built-In Phono PreAmp', 150.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (13, 1, 'Escort Passport Radar And Laser Detector - Black Finish - 8500', 'Escort Passport X50 Radar And Laser Detector - 8500/ X-Band, K-Band, Ka-Band Operating Bands/ AlGaAs 280 LED Matrix/Text Display Type/ 3-Level Dimming, Plus Dark Mode/ Auto Mute/ City Mode Sensitivity/ Compact Size/ Red Display', 313.95); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (14, 1, 'Sony Compact Disc Player/Recorder - RCDW500C', 'Sony Compact Disc Player/Recorder - RCDW500C/ 5-CD/Dual Deck With 4x High Speed Dubbing/ CD, CD-R, CD-RW, MP3 Playback Capable/ Super Bit Mapping Recording/ High Speed Finalizing', 299.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (15, 1, 'Sanus WMS3B Black Weather Resistant Small Speaker Wall Mount - WMS3B', 'Sanus WMS3B Black Small Speaker Wall Mount - WMS3B/ Holds Up To An 8 Pound Speaker/ Multiple Pivot Points/ Weather Resistant For Indoor/Outdoor Use/ Black Finish/ Priced Per Pair', 29.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (16, 1, 'Sanus WMS3S Silver Weather Resistant Small Speaker Wall Mount - WMS3S', 'Sanus WMS3S Silver Small Speaker Wall Mount - WMS3S/ Holds Up To An 8 Pound Speaker/ Multiple Pivot Points/ Weather Resistant For Indoor/Outdoor Use/ Silver Finish/ Priced Per Pair', 29.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (17, 1, 'Sanus Euro Foundations Satellite Speaker Stand - EFSATB', 'Sanus Euro Foundations Satellite Speaker Stand - EFSATB/ Sturdy Base/ Adjustable Pillar And Floor Spikes/ Includes Three Different Speaker Mounting Methods/ Contemporary European Design/ Satin Powder-Coated Black Finish/ Priced Per Pair', 79.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (18, 1, 'Sanus Euro Foundations Satellite Speaker Stand - EFSATS', 'Sanus Euro Foundations Satellite Speaker Stand - EFSATS/ Sturdy Base/ Adjustable Pillar And Floor Spikes/ Includes Three Different Speaker Mounting Methods/ Contemporary European Design/ Satin Powder-Coated Silver Finish/ Priced Per Pair', 79.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (19, 1, 'Escort Cordless Solo Radar Detector - S2E', 'Escort Cordless Solo Radar Detector - S2E/ S2/ 10 Programmable Features/ High-Efficiency Power Management/ Ultra-Performance Laser Protection/ AutoSensitivity Mode/ High Resolution Graphic LCD Display/ Built-In Earphone Jack', 343.95); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (20, 1, 'Kenwood 6-Disc CD Changer - KDCC669', 'Kenwood 6-Disc CD Changer - KDCC669/ 3-Angle Mounting/ CD, CD-R And CD-RW Playback/ Anti-Vibration Disc Transport/ Compatible With All Kenwood Units With Changer Control', 129.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (21, 1, 'Cuisinart Automatic Brew And Serve Coffeemaker - DTC975BK', 'Cuisinart Automatic Brew And Serve Coffeemaker - DTC975BK/ 12-Cup Double-Wall Insulated Stainless Steel Carafe/ Fully Automatic With 24-Hour Programmability/ Patented Brew-Through And Pour-Through Lid/ Brew Pause Feature/ Automatic Shutoff/ Black And Stainless Steel Finish', 99.95); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (22, 1, 'Sharp Over The Counter Microwave Oven - R1214SS', 'Sharp Over The Counter Microwave Oven - R1214SS/ 1.5 Cubic Foot Capacity/ 1100 Watts/ 24 Automatic Settings/ 2-Color Lighted LCD/ Smart And Easy Sensor Settings/ Auto-Touch Control Panel/ Stainless Steel Finish', 429.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (23, 1, 'Toshiba Rechargeable 5-Hour Battery Pack - MEDB05LX', 'Toshiba Rechargeable 5-Hour Battery Pack - MEDB05LX/ Works With SDP2500 And SDP2600 Portable DVD Players', 149.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (24, 1, 'Sony Super Audio CD Player - SCDCE595', 'Sony Super Audio CD Player - SCDCE595/ Multi-Channel Super Audio CD Playback Capability/ CD/CD-R/CD-RW Playback Capability/ Multi-Channel Direct Stream Digitial Decoder/ Multi-Channel Management System/ SACD Text/CD Text Capability/ ETA LATE JANUARY 2009', 149.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (25, 1, 'Delonghi Twenty Four Seven Coffee Maker In Black - DC50B', 'Delonghi Twenty Four Seven Coffee Maker - DC50B/ 4-Cup Capacity/ Easy-Access, Washable Filter Basket/ Black Finish', 22.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (26, 1, 'Sanus Silver LCD Television Turntable - TVLCDS', 'Sanus Silver LCD Television Turntable - TVLCDS/ Holds 13''-30'' Size Televisions/ 360 Degree Rotation/ Silver Finish', 29.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (27, 1, 'Delonghi Twenty Four Seven Coffee Maker - DC50W', 'Delonghi Twenty Four Seven Coffee Maker - DC50W/ 4-Cup Capacity/ Easy-Access, Washable Filter Basket/ White Finish', 22.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (28, 1, 'Universal IR/RF Remote - MX350', 'Universal IR/RF Remote - MX350/ Controls Up To 10 Components/ Extensive Macro Programming/ Memory Back-Up/ One Hand Ergonomics', 149.95); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (29, 1, 'Universal IR/RF Aeros Remote Control- MX850 - MX850', 'Universal IR/RF Aeros Remote Control- MX850/ Laser Etched Buttons/ Centrally Located Joystick/ Memory Back-Up/ One Hand Ergonomics/ Controls Up To 20 Components', 399.95); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (30, 1, 'Panasonic 5-Pack DVD-RAM Discs - LMAF120LU5', 'Panasonic 5-Pack DVD-RAM Discs - LMAF120LU5/ Slim Cases/ 2-3x Speed/ Single-Sided/ 120 Minute (4.7GB/Non-Cartridge)/ For Video Recording/ 5 Pack', 15.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (31, 1, 'Sanus 13'' - 30'' VisionMount Flat Panel TV Silver Wall Mount - VMFS', 'Sanus 13'' - 30'' VisionMount Flat Panel TV Silver Wall Mount - VMFS/ Supports Up To 40 lbs/ Easy To Install/ Fingertip Virtual Axis Tilting System/ Silver Finish', 39.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (32, 1, 'Weber Performer 22-1/2'' Charcoal Grill - 841001', 'Weber Performer 22-1/2'' Charcoal Grill - 841001/ Push-Button Igniter/ Porcelain-Enameled Bowl And Lid/ Dual-Purpose Themometer/ Crackproof All-Weather Wheels/ Black Lid Finish/ Assembly Required', 329.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (33, 1, 'Sanus 13'' - 30'' Flat Panel TV Black Wall Mount - VM1B', 'Sanus 13'' - 30'' Flat Panel TV Black Wall Mount - VM1B/ Tilt And Swivel Motion/ Rigid Extruded Aluminum Construction/ Supports Up To 50 Lbs/ Black Finish', 69.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (34, 1, 'Sanus 15'' - 40'' Flat Panel TV Silver Wall Mount - VM400S', 'Sanus 15'' - 40'' Flat Panel TV Silver Wall Mount - VM400S/ Virtual Axis Tilt Adjustment System/ Hinged Arm Extend From 3.5'' To 20''/ Durable Powder Coated Silver Finish', 219.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (35, 1, 'Delonghi Oil Filters - FK8', 'Delonghi Oil Filters - FK8/ Made For Use With D895UX/ 3 Pack', 18.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (36, 1, 'Weber Performer 22-1/2'' Charcoal Grill - 848001', 'Weber Performer 22-1/2'' Charcoal Grill - 848001/ Push-Button Igniter/ Porcelain-Enameled Bowl And Lid/ Dual-Purpose Themometer/ Crackproof All-Weather Wheels/ Blue Lid Finish/ Assembly Required', 329.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (37, 1, 'Whirlpool 24'' Built-In Dishwasher - DU1055BK', 'Whirlpool 24'' Built-In Dishwasher - DU1055BK/ 14-Five Piece Place Setting Super Capacity Tub/ 5 Level Direct Feed SheerClean Wash System/ 4 Cycles/ AnyWare Plus Silverware Basket/ Quiet Partner I Sound Package/ Energy Star Qualified/ Black Finish', 397.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (38, 1, 'Whirlpool 24'' Built-In Dishwasher - DU1055SS', 'Whirlpool 24'' Built-In Dishwasher - DU1055SS/ 14-Five Piece Place Setting Super Capacity Tub/ 5 Level Direct Feed SheerClean Wash System/ 4 Cycles/ Soak And Scour Option/ AnyWare Plus Silverware Basket/ Quiet Partner I Sound Package/ Energy Star Qualified/ Black On Stainless Finish', 491.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (39, 1, 'Sony Soft Cyber-Shot Carrying Case - LCSCST', 'Sony Soft Cyber-Shot Carrying Case - LCSCST/ Sturdy Nylon Construction/ Compact And Very Lightweight/ Stylish Black Design', 14.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (40, 1, 'Pioneer XM Digital Satellite Tuner for Pioneer Headunits - GEXP920XM', 'Pioneer XM Digital Satellite Tuner For Pioneer Headunits - GEXP920XM/ SAT Radio Ready/ XM Ready/ Built-In FM Modulator/ 18- Station/ 6- Button Presets/ Magne Mount Installation', 98.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (41, 1, 'Sanus Universal Projector Ceiling Mount - Black Finish - VMPR1B', 'Sanus Universal Projector Ceiling Mount - VMPR1B/ Designed For DLP And LCD Projectors/ Quick Release Mechanism/ 50 Lbs Capacity/ Black Finish', 129.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (42, 1, 'Kenwood iPod Mobile Interface - KCAIP500', 'Kenwood iPod Mobile Interface - KCAIP500/ Compatible With Most Kenwood Receivers/ Text Display, Multiple Search Mode/ Powers And Charges iPod', 49.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (43, 1, 'Pioneer Wired Marine Remote Control Display - CDMR80D', 'Pioneer Wired Marine Remote Control Display - CDMR80D/ Compatible With Pioneer Headunits/ Satellite Radio Text Indications/ ATT (Volume Attenuator) Button', 149.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (44, 1, 'Bose Second Zone Remote - PMC2', 'Bose Second Zone Remote - PMC2/ Controls Lifestyle 38 Or 48 Media Center/ TV, VCR, Cable Box, Satellite Receiver/ Accesses Digitally Stored CDs In UMusic System', 149.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (45, 1, 'Sony DVD-R Recordable Camcorder Media - 3DMR30L1H', 'Sony DVD-R Recordable Camcorder Media 3 Pack - 3DMR30L1H/ 30 Minute, 1.4 GB/ Accucore Technology/ Store Digital Video, Audio And Multimedia Files/ 3 Pack', 9.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (46, 1, 'Sony VAIO Neoprene Laptop Carrying Case - Black Finish - VGPAMC3', 'Sony VAIO Neoprene Laptop Carrying Case - VGPAMC3/ Compatible With VAIO A Series 15'' And FS Series 15.4'' Widescreen Notebooks/ Helps Protect Your Notebook From Scratches, Spills And Dings/ Neoprene Offers Durable And Water-Resistant Protection', 22.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (47, 1, 'Canon Color Ink Tank - CL41CL', 'Canon Color Ink Tank - CL41CL/ Compatible With The Pixma iP1600, MP170 Printers', 24.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (48, 1, 'Canon Cyan Ink Tank - Cyan - CLI8C', 'Canon Cyan Ink Tank - CLI8C/ Compatible With The Pixma iP4200, iP5200, iP5200R, iP6600D, MP500, MP800 Printers', 16.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (49, 1, 'Canon Magenta Ink Tank - Magenta - CLI8M', 'Canon Magenta Ink Tank - CLI8M/ Compatible With The Pixma iP4200, iP5200, iP5200R, iP6600D, MP500, MP800 Printers', 16.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (50, 1, 'Canon Cyan Photo Ink Cartridge - Cyan - CLI8PC', 'Canon Cyan Photo Ink Cartridge - CLI8PC/ Compatible With The Pixma iP6600D Printer', 16.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (51, 1, 'Canon Magenta Photo Ink Cartridge - Magenta - CLI8PM', 'Canon Magenta Photo Ink Cartridge - CLI8PM/ Compatible With The Pixma iP6600D Printer', 16.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (52, 1, 'Canon Yellow Ink Cartridge - Yellow - CLI8Y', 'Canon Yellow Ink Cartridge - CLI8Y/ Compatible With The Pixma iP4200, iP5200, iP5200R, iP6600D, MP500, MP800 Printers', 16.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (53, 1, 'Canon Black Ink Cartridge - Black - PG40BK', 'Canon Black Ink Cartridge - PG40BK/ Compatible With The Pixma iP1600, MP170 Printers', 19.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (54, 1, 'Pioneer Voice Command Pack - Black Finish - CDVC1', 'Pioneer Voice Command Pack - CDVC1/ Microphone And Steering Wheel Remote Control/ Use Your Voice To Control Navigation, Audio, And Video Functions/ Compatible With AVICN2 And AVICN1', 48.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (55, 1, 'Sony VAIO Neoprene Notebook With AC Adapter Case - Black Finish - VGPAMC2', 'Sony VAIO Neoprene Notebook With AC Adapter Case - VGPAMC2/ Helps Protect Your Notebook From Scratches, Spills And Dings/ Neoprene Offers Durable, Water-Resistant Protection/ Fits 17'' Widescreen Notebooks', 24.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (56, 1, 'NetGear ProSafe 24 Port Smart Switch - FS726TP', 'NetGear ProSafe 24 Port Smart Switch - FS726TP/ Two Gigabit Ports Plus Easy Browser/ ProSafe Network Management Software/ Web Based Smart Management Features', 605.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (57, 1, 'Garmin StreetPilot C330 Dash Mount - Black Finish - 0101061300', 'Garmin StreetPilot C330 Dash Mount - 0101061300/ Non-Skid Mount Design/ Fully Portable/ Includes 12/24 Volt Cigarette Lighter Adapter/ Black Finish', 57.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (58, 1, 'Yamaha High Performance Subwoofer - Black Finish - YSTFSW100BK', 'Yamaha High Performance Subwoofer - YSTFSW100BK/ 130 Watts Dynamic Power/ Advanced YST II (Yamaha Active Servo Technology)/ Half Pipe Port/ Powerful 6.5? Multi-Range Driver/ Magnetically Shielded/ 16Hz Ultra Low Frequency Reproduction/ Slim Design/ Black Finish', 150.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (59, 1, 'Netgear ProSafe 16 Port 10/100 Desktop Switch - Purple Finish - FS116P', 'Netgear ProSafe 16 Port 10/100 Desktop Switch - FS116P/ 16 Auto Speed-Sensing 10/100 RJ-45 Ports/ 96 KB Embedded Memory Per Unit', 299.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (60, 1, 'Canon High Capacity Color Ink Cartridge - Color Ink - CL51', 'Canon High Capacity Color Ink Cartridge - CL51/ Compatible With Pixma iP6210D, iP6220D, MP150, MP170 And MP450 Printers', 35.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (61, 1, 'Canon Photo Ink Cartridge - CL52', 'Canon Photo Ink Cartridge - CL52/ Compatible With Pixma iP6210D And iP6220D Printers', 25.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (62, 1, 'Cuisinart Programmable Coffeemaker - Stainless Steel Finish - DCC2000', 'Cuisinart 12-Cup Programmable Coffeemaker - DCC2000/ Fully Programmable/ Removable Coffee Reservoir/ Easy-To-Read Coffee Gauge/ Visible Water Level Indicator/ Removable Drip Tray/ Charcoal Water Filter/ Stainless Steel Finish', 100.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (63, 1, 'Sanus Center Channel Speaker Mount - Black Finish - VMCC1B', 'Sanus Center Channel Speaker Mount - VMCC1B/ Works With Sanus Models VMSA, VMAA18, VMAA26, VMDD26 And VMCM1/ Easy To Install/ Mounting Hardware Included/ Black Finish', 99.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (64, 1, 'Netgear RangeMax Wireless Access Point - White Finish - WPN802NA', 'Netgear RangeMax Wireless Access Point - WPN802NA/ Improves Performance Of Existing Legacy 802.11b And 802.11g Wireless Devices Up To 50 Percent/ Wired Equivalent Privacy (WEP) 64-Bit,128-Bit Encryption/ Wi-Fi Protected Access (WPA, Pre-Shared Key)', 130.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (65, 1, 'Weber Q 300 Liquid Propane Outdoor Grill - 426001', 'Weber Q 300 Liquid Propane Outdoor Grill - 426001/ Liquid Propane Fuel Type/ Two Burners For Direct And Indirect Cooking/ Thermometer Built Into The Lid/ Regulator Hose/ 12-Pound Turkey Capacity/ Cart Included/ Cast Aluminum Finish/ Assembly Required', 349.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (66, 1, 'Sony Lightweight Tripod - Black Finish - VCTR100', 'Sony Lightweight Tripod - VCTR100/ Lightweight And Portable/ Expands From 14'' To 39''/ 3-Way Panhead Function/ Black Finish', 34.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (67, 1, 'Sanus VMAV Black VisionMount Component Wall Shelf VMAVB In Black - VMAVB', 'Sanus VMAV Black VisionMount Component Wall Shelf - VMAVB/ Single Wall Mount Shelf For Audio-Video Component/ Metal V Arm/ Black Finish', 34.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (68, 1, 'Sony PlayStation 2 DUALSHOCK 2 Analog Controller - Emerald Finish - 711719706205', 'Sony PlayStation 2 DUALSHOCK 2 Analog Controller - 711719706205/ Analog Pressure Sensitivity On All Action Buttons/ Built-In DUALSHOCK Vibration Function/ Twin Analog Control Sticks/ Intelligent Self-Calibrating Analog System/ Emerald Finish', 24.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (69, 1, 'Sony PlayStation 2 8MB Memory Card - Black Finish - 711719702702', 'Sony PlayStation 2 8MB Memory Card - 711719702702/ Save And Load High Scores, Positions And Replays/ MagicGate Encryption/ Black Finish', 24.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (70, 1, 'Sony PlayStation 2 8MB Memory Card (2 Pack) - Red/Blue Finish - 711719706700', 'Sony PlayStation 2 8MB Memory Card (2 Pack) - 711719706700/ Save And Load High Scores, Positions And Replays/ MagicGate Encryption/ Red/Blue Finish', 34.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (71, 1, 'Universal RF Series MasterControl Remote Control - RF20', 'Universal RF Series MasterControl Remote Control ? RF20/ Control Up To 10 Components/ 432 MacroPower Buttons/ Customizable LCD Screen/ Pre-Programmed Codes/ Learning Capable/ SimpleSound/ Fully Backlit Keypad/ DVD Guide', 79.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (72, 1, 'Panasonic Network Camera - White Finish - BLC1A', 'Panasonic Network Camera - BLC1A/ Automatic Network Configuration/ Built-In Calendar Timer/ Auto Time Adjustment With NTP/ Up To 10x Digital Zoom/ Multi-Language Interface/ White Finish', 99.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (73, 1, 'Pioneer 6.5'' 2-Way Marine White Speakers - TSMR1640', 'Pioneer 6.5'' 2-Way Marine Speakers - TSMR1640/ 160 Watts Maximum Power Handling (30 Watts Nominal)/ 1-1/8'' Poly-Ether Imide Dome Tweeter With Magnetic Fluid And Equalizer/ Tinsel Lead Wire And Terminals Are Gold-Plated For Extra Protection', 120.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (74, 1, 'Apple USB Modem - White Finish - MA034ZA', 'Apple USB Modem - MA034ZA/ Supports Caller ID, Wake On Ring, Telephone Answering (V.253), Modem On Hold/ V.92 Software Support', 54.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (75, 1, 'Linksys EtherFast 4124 24-Port Ethernet Switch - EF4124', 'Linksys EtherFast 4124 24-Port Ethernet Switch - EF4124/ 24 Autosensing 10/100 Full Duplex, Auto MDI/MDI-X Ports/ Up To 200Mbps/ Address Learning, Aging And Data Flow Control/ Compact Size', 119.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (76, 1, 'Sony DVD Remote Control For PS2 - Black Finish - 711719707608', 'Sony DVD Remote Control For PS2 - 711719707608/ Works As A Full-Featured Standard Controller/ Performs Audio Track Selection, Subtitle Display And Multiangle Options/ Designed To Match The Sleek Look Of PlayStation 2', 19.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (77, 1, 'Nikon 55-200MM Zoom-Nikkor Lens Accessory - 2156', 'Nikon 55-200MM Zoom-Nikkor Lens Accessory - 2156/ 3.6X Zoom/ 55 - 200MM/ Silent Wave Motor/ Two ED Glass Elements/ Focus Mode Switch', 199.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (78, 1, 'Waring Professional Cool-Touch Deep Fryer - Black/Stainless Steel Finish - DF100', 'Waring Professional Cool-Touch Deep Fryer - DF100/ Large Frying Basket/ 60-Minute Timer/ Removable Control Panel/ Unique Heating Element/ Breakaway Cord/ LED Power Indicators', 70.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (79, 1, 'Denon Fully Automatic Analog Turntable - DP300F', 'Denon Fully Automatic Analog Turntable - DP300F/ Removable Headshell/ Automatic Startup/ Built-In Phono Equalizer/ DC Servo Motor And Belt Drive System/ MM Cartridge', 329.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (80, 1, 'Terk Mini Tuner Cartridge For XM Ready Home Products - CNP2000', 'Terk Mini Tuner Cartridge For XM Ready Home Products - CNP2000/ Connects To Any Home Or Portable Audio Product With The XM Ready Logo', 29.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (81, 1, 'Panasonic Plain Paper Fax/Copier With Cordless Phone Answering System - Grey Finish - KXFG2451', 'Panasonic Plain Paper Fax/Copier With Cordless Phone Answering System - KXFG2451/ Automatic Fax/Phone Switching/ 2.4GHz GigaRange Cordless Handset With Handset Speakerphone/ Voice Enhancer Technology/ All-Digital Answering System (18 Min)/ Navigator Key With 2-Line Display', 119.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (82, 1, 'Omnimount Moda 2 Shelf Wall Furniture - MWFS', 'Omnimount Moda 2 Shelf Wall Furniture - MWFS/ Modular Design/ Integrated Cable Management/ Tempered Glass Shelves', 299.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (83, 1, 'Terk Mini Tuner Home Dock For XM Ready Home Products - Black Finish - CNP2000H', 'Terk Mini Tuner Home Dock For XM Ready Home Products - CNP2000H/ Comes Complete With The Docking Station, Protective Cover And A Window Sill Mount Antenna/ Interfaces To Existing And Future XM Ready Products', 30.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (84, 1, 'Denon 5-Disc CD Auto Changer - Black Finish - DCM290', 'Denon 5-Disc CD Auto Changer - DCM290/ CD-R/RW Playback/ Advanced Multilevel Noise Shaping DAC/ Digital Filter/ 3-Mode Random Playback/ Intelligent Disc Scan/ Music Calendar Display/ Black Finish', 249.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (85, 1, 'Denon 5 Disc CD Player - Black Finish - DCM390', 'Denon 5 Disc CD Player - DCM390/ CD-R/RW Playback/ MP3, WMA And HDCD Decoding/ Advanced Multilevel Noise Shaping DAC/ 8 Times Oversampling Digital Filter/ 3 Mode Random Playback/ Intelligent Disc Scan/ 20 Selection Music Calendar Display/ Black Finish', 349.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (86, 1, 'Denon Progressive Scan Universal DVD Player - DVD2930CI', 'Denon Progressive Scan Universal DVD Player - DVD2930CI/ AC 120 Volts/ 60 Hertz/ 45 Watts/ Infrared Pulse Remote Control', 849.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (87, 1, 'Netgear Prosafe 16 Port 10/100 Rackmount Switch - Black Finish - JFS516NA', 'Netgear Prosafe 16 Port 10/100 Rackmount Switch - JFS516NA/ Sixteen Switched Ports Provide Private Bandwidth For PCs, Servers Or Hubs/ Store-And-Forward Packet Switching/ Compatible With All Major Network Software/ Auto Detects Speed And Duplex/ Black Finish', 131.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (88, 1, 'Terk XM Outdoor Home Antenna - Grey Finish - XM6', 'Terk XM Outdoor Home Antenna - XM6/ Universal Mounting Roof, Wall Or Mast/ For Use With Single-Input Receivers/ Connects RG6 Cable For Easy Routing Up To 100 Ft. (Optimal Disatnce 75 Ft.)', 80.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (89, 1, 'Sanus 9'' - 17'' VisionMount Series Under Cabinet Flat Panel TV Silver Wall Mount - VMUC1S', 'Sanus 9'' - 17'' VisionMount Series Under Cabinet Flat Panel TV Silver Wall Mount - VMUC1S/ Tilting Motion/ Swivels Left And Right/ Universal Mounting Bracket/ Easy To Install/ Silver Finish', 99.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (90, 1, 'Sanus 15'' - 40'' VisionMount Flat Panel TV Black Wall Mount - MT25B1', 'Sanus 15'' - 40'' VisionMount Flat Panel TV Black Wall Mount - MT25B1/ Solid Heavy-Gauge Steel Construction/ Durable Powder-Coated Finish/ Virtual Axis Tilt Adjustment System/ Up to 100 Lbs Support/ Black Finish', 99.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (91, 1, 'Garmin GPS Carrying Case - Black Finish - 0101070400', 'Garmin GPS Carrying Case - 0101070400/ Protect Your GPS By Absorbing The Impact From Routine Drops/ Prevent Damage From Scratches And Spills', 30.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (92, 1, 'Tech Craft Avalon Series TV Stand - Black Finish - ABS32', 'Tech Craft Avalon Series TV Stand - ABS32/ 32'' Wide ''Tall Boy'' For Smaller Screen Flat Panels/ Molded Top Gives It An Elegant Appearance/ Framed Doors To Conceal Components/ Black Finish', 249.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (93, 1, 'Tech Craft Avalon Series TV Stand - SWP48', 'Tech Craft Avalon Series TV Stand - SWP48/ 48'' Wide Credenza For Flat Panel TVs And DLPs/ 260 Lbs TV Weight Capacity/ 50 Lbs Shelf Weight Capacity/ Wood Veneer Finish', 299.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (94, 1, 'Sanus 15'' - 40'' VisionMount Flat Panel TV Black Wall Mount - MF110B', 'Sanus 15'' - 40'' VisionMount Flat Panel TV Black Wall Mount - MF110B/ Mounts Within 2.5'' Of Wall/ Holds Up To 100 Lbs/ Powder Coated Black Finish', 179.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (95, 1, 'Garmin Nuvi 360 010-10815-00 Black Replacement Vehicle Suction Cup Mount - 0101081500', 'Garmin Nuvi 360 010-10815-00 Black Replacement Vehicle Suction Cup Mount - 0101081500/ Compatible With The Nuvi 360/ It Is A Replacement/ Black Finish', 39.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (96, 1, 'Garmin Nuvi 360 010-10723-06 Black 12 Volt Adapter Cable - 0101072306', 'Garmin Nuvi 360 010-10723-06 Black 12 Volt Adapter Cable - 0101072306/ Compatible With The Nuvi 350 And 360/ It Is A Replacement/ Black Finish', 47.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (97, 1, 'Garmin Nuvi 660 010-10747-03 Black 12 Volt Adapter Cable - 0101074703', 'Garmin Nuvi 660 010-10747-03 Black 12 Volt Adapter Cable - 0101074703/ Compatible With The Nuvi 660/ Black Finish', 39.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (98, 1, 'Garmin 010-10702-00 Black GA 25MCX Remote GPS Antenna - 0101070200', 'Garmin 010-10702-00 Black GA 25MCX Remote GPS Antenna - 0101070200/ Built-In Magnetic Mount/ Includes A Cable Over 8 Feet Long And MCX Connector', 30.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (99, 1, 'Garmin 010-10823-00 Black Nuvi 660 Vehicle Suction Cup Mount - 0101082300', 'Garmin 010-10823-00 Black Nuvi 660 Vehicle Suction Cup Mount - 0101082300/ Replacement Suction Cup Mount/ Compatible With Nuvi 660/ Black Finish', 46.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (100, 1, 'Universal MRF-350 RF Black Base Station - MRF350', 'Universal MRF-350 RF Black Base Station - MRF350/ No More Pointing/ RF Addressable/ IR Routing/ Expand Operating Range Up To 100 Feet/ Compatible With MX-3000, TX-1000, MX-950 And MX-900 Only/ Black Finish', 250.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (101, 1, 'Bose In-Ear Black Headphones - BOSEIE', 'Bose In-Ear Black Headphones - BOSEIE/ Comfortable In-Ear Design/ TriPort Acoustic Headphone Structure/ S, M And L Removable Silicone Tips/ Carrying Case/ Black Finish', 99.95); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (102, 1, 'Nyko PlayStation 3 Dual Charger AC - 743840830153', 'Nyko PlayStation 3 Dual Charger AC - 743840830153/ Charge 2 Wireless PS3 Controllers From A Standard Wall Outlet/ Collapsable Prongs For Easy Storage/ Charges Other Mini USB Devices', 24.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (103, 1, 'Nyko PlayStation 3 ChargeLink USB Charging Cable - 743840830009', 'Nyko PlayStation 3 ChargeLink USB Charging Cable - 743840830009/ Charge And Play At The Same Time/ Unique Woven Cable Shielding Improves Cable Durability/ 10 Ft Cable', 14.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (104, 1, 'Linksys Wireless-G VPN Broadband Silver Router - WRV54G', 'Linksys Wireless-G VPN Broadband Silver Router - WRV54G/ Built-In VPN Endpoint Capability/ Securely Connect Up To 50 Remote Or Traveling Users To Your Office Network Via VPN/ Hotspot Ready With Subscriber Registration, Authorization And Authentication Functions/ Silver Finish', 149.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (105, 1, 'Bose SL2 Wireless Black Surround Link - SL2WIRELESS', 'Bose SL2 Wireless Black Surround Link - SL2WIRELESS/ Transmitter And Receiver Work On A Radio Frequency Signal Effective From Up To 30 Feet In The Same Room/ Compatible With All Lifestyle Systems, CD-Based Models And All 5.1-Channel Acoustimass Home Entertainment Systems/ Black Finish', 249.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (106, 1, 'Sony Digital Photo Printer Paper 120 Pack - SVMF120P', 'Sony Digital Photo Printer Paper 120 Pack - SVMF120P/ 4'' x 6'' Print Paper With Snap-Off Edges/ Super Coat 2 Protective Lamination/ Water Damage And Fingerprint Resistant Prints/ 120 Sheets Of Paper And Print Ribbon/ For DPPF Series Digital Photo Printers Only', 35.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (107, 1, 'Canon PGI-5BK Black Ink Tank Cartridge - PGI5BK', 'Canon PGI-5BK Black Ink Tank Cartridge - PGI5BK/ Smudge Resistant/ Resists Smearing Caused By Highlighters/ Smudge Resistant/ Pigment Ink Formulation For Long Lasting Prints', 16.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (108, 1, 'Lowepro SlingShot 200 AW Digital Camera Back Pack - SLINGSHOT200AW', 'Lowepro SlingShot 200 AW Digital Camera Back Pack - SLINGSHOT200AW/ Holds A SLR With Attached Compact Zoom Lens Plus 3-4 Extra Lenses Or Flash Unit/ Water-Resistant Micro Fiber/ Ripstop Nylon/ Includes A Built-In Memory Card Puch, Micro Fiber LCD Cloth And Two Organizer Pockets', 89.95); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (109, 1, 'Tech Craft ABS48 Antique Black Avalon Series 48'' TV Stand - ABS48', 'Tech Craft ABS48 Antique Black Avalon Series 48'' TV Stand - ABS48/ For Flat Panels And DLP TV?s/ Molded Top And Shaped Skirt/ Framed Doors/ Antique Black Distressed Finish', 299.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (110, 1, 'Garmin 010-10723-03 Nuvi Suction Cup Mount - 0101072303', 'Garmin 010-10723-03 Nuvi Suction Cup Mount - 0101072303/ Replacement Suction Cup Mount/ Compatible With Garmin Nuvi 300/310/350/360 GPS System/ Black Finish', 39.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (111, 1, 'Weber Stainless Steel Summit S-650 Liquid Propane Grill - 1780001', 'Weber Stainless Steel Summit S-650 Liquid Propane Grill - 1780001/ 6 Stainless Steel Burners/ 60,000 BTU-Per-Hour Input/ 12,000 BTU-Per-Hour Input Side Burner/ 10,600 BTU-Per-Hour Rotisserie Burner/ 8,000 BTU-Per-Hour Input Smoker Burner/ Snap-Jet Individual Burner Ignition System/ 3/8-Inch Diameter Stainless Steel Rod Cooking Grates/ Stainless Steel Flavorizer Bars/ Stainless Steel Finish/ Liquid Propane Model (LP Tank Not Included)/ Assembly Required', 1999.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (112, 1, 'Weber Stainless Steel Genesis S-310 Liquid Propane Grill - 3770001', 'Weber Stainless Steel Genesis S-310 Liquid Propane Grill - 3770001/ 3 Stainless Steel Burners/ 42,000 BTU-Per-Hour Input/ Electronic Crossover Ignition System/ 7MM Diameter Stainless Steel Rod Cooking Grates/ Stainless Steel Flavorizer Bars/ Stainless Steel Finish/ Liquid Propane Model (LP Tank Not Included)/ Assembly Required', 899.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (113, 1, 'Weber Stainless Steel Genesis S320 LP Grill - 3780001', 'Weber 3780001 Stainless Steel Genesis S-320 Liquid Propane Grill - 3780001/ 3 Stainless Steel Burners/ 42,000 BTU-Per-Hour Input/ 12,000 BTU-Per-Hour Input Side Burner/ Electronic Crossover Ignition System/ 7MM Diameter Stainless Steel Rod Cooking Grates/ Stainless Steel Flavorizer Bars/ Stainless Steel Finish/ Liquid Propane Model (LP Tank Not Included)/ Assembly Required', 949.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (114, 1, 'Weber Stainless Steel Genesis S320 Natural Gas Grill - 3880001', 'Weber Stainless Steel Genesis S-320 Natural Gas Grill - 3880001/ 3 Stainless Steel Burners/ 42,000 BTU-Per-Hour Input/ 12,000 BTU-Per-Hour Input Side Burner/ Electronic Crossover Ignition System/ 7MM Diameter Stainless Steel Rod Cooking Grates/ Stainless Steel Flavorizer Bars/ Stainless Steel Finish/ Natural Gas Model/ Assembly Required', 969.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (115, 1, 'Kenwood KCA-IP300V iPod Video Direct Cable - KCAIP300V', 'Kenwood KCA-IP300V iPod Video Direct Cable - KCAIP300V/ iPod Video Direct Cable For DNX7100, DDX7019 And KVT719DVD Indash Monitors', 49.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (116, 1, 'Sony SCPH-98046 PlayStation 3 Blu-Ray DVD Remote Control - 711719804604', 'Sony SCPH-98046 PlayStation 3 Blu-Ray DVD Remote Control - 711719804604/ Full Access To The PlayStation 3 Systems Disc Features/ Can Be Used Without Having To Point Directly At The System', 24.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (117, 1, 'Tripp-Lite PV375 PowerVerter 375-Watt Ultra-Compact Inverter - PV375', 'Tripp-Lite PV375 PowerVerter 375-Watt Ultra-Compact Inverter - PV375/ 12V DC Input/ 120V AC Output/ 2 Outlets/ 375 Watts Continuous Output/ 600 Watts Peak Output/ Convenient Cigarette Lighter Plug', 49.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (118, 1, 'Sirius FMDA25 Wired FM Modulation Relay - FMDA25', 'Sirius FMDA25 Wired FM Modulation Relay - FMDA25/ 2 Ft FM Antenna Cable/ 19 Ft 4 In Mini-Jack Cable', 20.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (119, 1, 'Electrolux Oxygen 3 Canister HEPA H12 Filter - EL012A', 'Electrolux Oxygen 3 Canister HEPA H12 Filter - EL012A/ Retains 99.5% Of Dust And Other Irritants/ 1 Filter Per Package', 19.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (120, 1, 'Fellowes Confetti Cut Shredder - W11C', 'Fellowes Confetti Cut Shredder - W11C/ Shreds Up To 11 Sheets Per Pass/ Safely Shreds Staples And Credit Cards/ 9'' Paper Entry Accepts Any Standard Or Legal Size Document/ Safety Interlock Switch Automatically Powers Off When Shredder Head Is Lifted', 79.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (121, 1, 'Sony VAIO VGP-PRSZ1 SZ Series Docking Station - VGPPRSZ1', 'Sony VAIO VGP-PRSZ1 SZ Series Docking Station - VGPPRSZ1/ Compatible With SZ Series Notebooks/ Expand Connectivity To Your Notebook/ 3 USB 2.0, Gigabit Ethernet, VGA, DVI-D And DC In/ Black Finish', 199.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (122, 1, 'Weber Genesis E-310 Liquid Propane Black Outdoor Grill - 3741001', 'Weber Genesis E-310 Liquid Propane Black Outdoor Grill - 3741001/ 3 Stainless Steel Burners/ 42,000 BTU Per-Hour Input/ Electronic Crossover Ignition System/ Porcelain Enameled Cast Iron Cooking Grates/ 2 Stainless Steel Work Surfaces/ Center Mounted Thermometer/ Cast Aluminum End Caps/ Black Finish/ Liquid Propane Model (LP Tank Not Included)/ Assembly Required', 699.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (123, 1, 'Weber Genesis S-310 Natural Gas Stainless Steel Outdoor Grill - 3870001', 'Weber Genesis S-310 Natural Gas Stainless Steel Outdoor Grill - 3870001/ 3 Stainless Steel Burners/ 42,000 BTU-Per-Hour Input/ Electronic Crossover Ignition System/ Center Mounted Thermometer/ Cast Aluminum End Caps/ 2 Heavy Duty Front Locking Casters/ Stainless Steel Finish/ Assembly Required', 919.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (124, 1, 'DeLonghi Magnifica Super-Automatic Espresso/Coffee Machine - ESAM3300', 'DeLonghi Magnifica Super-Automatic Espresso/Coffee Machine - ESAM3300/ Stainless-Steel Removable Double Boiler/ Instant Reheat/ Removable Water Tank And Bean Container/ Integrated Burr Grinder/ Cappuccino System/ Cup Tray/ Silver Finish', 799.95); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (125, 1, 'Yamaha Silver USB Powered Stereo Speaker - NXU10SIL', 'Yamaha NX-U10 Silver USB Powered Stereo Speaker - NXU10SIL/ 20 Watts Output Power/ PowerStorage Circuit/ SR-Bass (Swing Radiator Bass) Technology/ Magnetic Shielding/ Mac And Windows Compatible/ Silver Finish', 180.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (126, 1, 'Canon FAX-JX200 Inkjet Fax Machine - FAXJX200', 'Canon FAX-JX200 Inkjet Fax Machine - FAXJX200/ Automatic Document Feeder/ Produce B&W Copies With Clear, Sharp Text/ One-Touch Dialing/ Ultra-High Quality (UHQ) Image Processing Technology/ 600 x 600 Dpi Copy Resolution/ White Finish', 78.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (127, 1, 'Weber Genesis E-310 Natural Gas Black Outdoor Grill - 3841001', 'Weber Genesis E-310 Natural Gas Black Outdoor Grill - 3841001/ 3 Stainless Steel Burners/ 42,000 BTU Per-Hour Input/ Electronic Crossover Ignition System/ Porcelain Enameled Cast Iron Cooking Grates/ 2 Stainless Steel Work Surfaces/ Center Mounted Thermometer/ Cast Aluminum End Caps/ Black Finish/ Assembly Required', 719.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (128, 1, 'Weber 3758301 Blue Genesis EP-320 LP Gas Grill - 3758301', 'Weber 3758301 Blue Genesis EP-320 LP Gas Grill - 3758301/ 3 Seamless Stainless Steel Burners/ 42,000 BTU-Per-Hour Input/ Crossover Ignition System/ Stainless Steel Flavorizer Bars And Grates/ Cast Aluminum End Caps/ Centermounted Thermometer/ Blue Finish/ Liquid Propane Model (LP Tank Not Included)/ Assembly Required', 749.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (129, 1, 'Panasonic KX-TG6702B 5.8 GHz FHSS GigaRange Expandable Black Cordless Phone System - KXTG6702B', 'Panasonic KX-TG6702B 5.8 GHz FHSS GigaRange Expandable Black Cordless Phone System - KXTG6702B/ All-Digital Answering System/ LCD Call Counter/ Speakerphone/ Navigator Key/ Up To 8 Handsets With Just One Phone Jack/ Line Status Indicator/ Voice Scramble/ Handset Locator/ Volume Control/ Black Finish', 197.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (130, 1, 'Fellowes MicroShred Shredder - MS450CS', 'Fellowes MS-450CS MicroShred Shredder - MS450CS/ 4.5 Gallons Basket Capacity/ Can Shred Paper, CDs, Credit Cards, Staples, Paper Clips/ Motor Reverse/ Interlock Switch/ Safe Sense/ 7 Sheet Capacity', 189.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (131, 1, 'Sony MRW62E/S1/181 17-In-1 External USB Memory Card Reader - MRW62ES1181', 'Sony MRW62E/S1/181 17-In-1 External USB Memory Card Reader - MRW62ES1181/ Supports 17 Different Memory Card Formats/ Works With Macintosh And Windows Computers/ Easy Hi-Speed USB 2.0 Connection/ Black Finish', 29.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (132, 1, 'Griffin Elevator Brushed Aluminum Laptop Stand - 1093CURV2', 'Griffin Elevator Brushed Aluminum Laptop Stand - 1093CURV2/ Elevates Laptop Screen 5.5'' While Providing Valuable Desktop Real Estate For Your Keyboard And Mouse/ Keeps Laptop Cool With 360 Degrees Of Air Circulation/ Compatible With Mac Or PC Laptop', 39.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (133, 1, 'Escort Passport 9500I Radar And Laser Detector - 9500I', 'Escort Passport 9500I Radar And Laser Detector - 9500I/ 360-Degree Radar And Laser Detection/ Blistering All-Band Protection/ GPS-Powered Truelock Filter/ Immune To The VG-2 ''Detector-Detector''/ Built-In Earphone Jack/ Red Display', 449.95); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (134, 1, 'Panasonic Countertop Microwave Oven In Black - NNSN667BK', 'Panasonic NN-SN667B Countertop Microwave Oven In Black - NNSN667BK/ 1.2 Cubic Foot/ 1300 Watts High Power/ 10 Power Levels/ 5 Cooking Stages/ Quick Minute/ One-Touch Sensor Cooking/ Inverter Turbo Defrost/ Multi-Lingual Menu Action Screen/ Popcorn Key/ Black Finish', 129.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (135, 1, 'Panasonic Countertop Microwave Oven In White - NNSN667WH', 'Panasonic NN-SN667W Countertop Microwave Oven In White - NNSN667WH/ 1.2 Cubic Foot/ 1300 Watts High Power/ 10 Power Levels/ 5 Cooking Stages/ Quick Minute/ One-Touch Sensor Cooking/ Inverter Turbo Defrost/ Multi-Lingual Menu Action Screen/ Popcorn Key/ White Finish', 129.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (136, 1, 'Samsung DLP TV Stand In Black - TR72BX', 'Samsung DLP TV Stand In Black - TR72BX/ Designed To Fit Samsung HLT7288 HLT7288, HL72A650, and HL67A650 Television Sets/ Tempered 6mm Tinted Glass Shelves/ Wide Audio Storage Shelves To Accommodate 4 Or More Components/ Wire Management System/ Easy To Assemble/ High Gloss Black Finish', 369.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (137, 1, 'Sony Black Active Speaker System - SRSA212BK', 'Sony Black Active Speaker System - SRSA212BK/ Designed For Your Portable Audio Or PC/ Built-In Mega Bass/ On/Off Switch With Volume Control/ Magnetically Shielded/ Black Finish', 29.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (138, 1, 'Panasonic Expandable Digital Cordless DECT 6.0 Handset In Silver - KXTGA101S', 'Panasonic Expandable Digital Cordless DECT 6.0 Handset In Silver - KXTGA101S/ Expansion Handset And Charger Select 1000 Series Phone Systems/ Big Buttons/ Built-In Clock With Alarm/ Silver Finish', 39.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (139, 1, 'Tech Craft Dark Cherry Veneto Series TV Stand - SWP60', 'Tech Craft Dark Cherry Veneto Series TV Stand - SWP60/ 60'' Wide Credenza For Flat Panel TV?s And DLP?s/ Center Channel Compartment And Storage/ 260 Lbs TV Capacity/ 50 Lbs Shelf Capacity/ Dark Cherry Wood Veneer Finish', 399.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (140, 1, 'Haier 13'' Silver Tube TV - HTR13', 'Haier 13'' Silver Tube TV - HTR13/ Built-In Atsc/Ntsc Tuner/ Video Noise Reduction/ Multi Picture Modes/ Multilingual Display/ Digital Comb Filter/ Component Video Input/ Front AV Jacks/ Silver Finish', 124.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (141, 1, 'Sony Memory Stick USB Adaptor - MSACUS40', 'Sony Memory Stick USB Adaptor - MSACUS40/ Quickly Transfer Image And Data To A PC/ Transfer Speed Up To 80Mbps/ Compatible With All Memory Stick Media', 29.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (142, 1, 'Sony Clip-On Black Headphones - MDRQ68LW', 'Sony Clip-On Black Headphones - MDRQ68LW/ Lightweight And Thin Body For Stable Fitting/ Retractable Silent Cord/ 3.3 Ft. Cord/ Gold Plated Mini-Plug/ Black Finish', 29.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (143, 1, 'Netgear ProSafe 24-Port Smart Switch - GS724TP', 'Netgear ProSafe 24-Port Smart Switch - GS724TP/ 24 10/100/1000 Ports That Support 802.3af PoE/ 2 Combo Gigabit Copper/SFP Slots/ Web-Based Configuration/ Password Access Control/ Purple Finish', 780.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (144, 1, 'Sharp Over The Counter White Microwave Oven - R1211WH', 'Sharp Over The Counter White Microwave Oven - R1211WH/ 1.5 Cu. Ft. Capacity/ 1100 Watts/ 19 Automatic Settings/ 2-Color Lighted LCD/ Smart And Easy Sensor Settings/ Auto-Touch Control Panel/ White Finish', 269.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (145, 1, 'Monster iFreePlay Cordless Headphones For iPod Shuffle - AISHHPHONE', 'Monster iFreePlay Cordless Headphones For iPod Shuffle - AISHHPHONE/ Wrap-Around Design With No Need For Clips, Armbands Or Pockets/ Easy Access To All iPod Shuffle Controls/ Folds For Compact Storage/ Black With Silver Finish', 48.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (146, 1, 'Canon Black Ink Cartridge - PG50', 'Canon Black Ink Cartridge - PG50/ Pigment Ink Formulation For Long Lasting Prints/ Resists Smearing Caused By Highlighters/ Smudge Resistant/ Ink Remaining Notification Technology/ Crisp Laser Text-Quality Text/ Black Ink', 29.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (147, 1, 'Audiovox Xpress XM Satellite Radio FM Direct Adapter - XMFM1', 'Audiovox Xpress XM Satellite Radio FM Direct Adapter - XMFM1/ Switches Between FM Radio Antenna And Your XM Satellite Radio Receiver', 25.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (148, 1, 'Panasonic NNSD797S Stainless Steel Countertop Microwave Oven - NNSD797SS', 'Panasonic NNSD797S Stainless Steel Countertop Microwave Oven - NNSD797SS/ 1.6 Cu. Ft. Capacity/ 1250W Output Power/ 10 Power Levels/ 5 Cooking Stages/ One-Touch Sensor Cooking Or Heating/ Timer/ Stainless Steel Finish', 199.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (149, 1, 'Apple Mac Mini 1.83GHz Intel Core 2 Duo Computer - MB138LLA', 'Apple Mac Mini 1.83GHz Intel Core 2 Duo Computer - MB138LLA/ 1.83GHz Intel Core 2 Duo/ 1GB Memory/ 80GB Hard Drive/ 24x Combo Drive/ Built-In Speakers/ Four USB 2.0 Ports And One FireWire 400 Port/ Mac OS X v10.5 Leopard', 599.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (150, 1, 'Denon 7.1 Channel Home Theater MultiMedia A/V Receiver With Networking And WiFi - AVR4308CI', 'Denon 7.1 Channel Home Theater MultiMedia AV Receiver With Networking And WiFi In Black - AVR4308CI/ 140 Watts x 7 Channels/ Wi-Fi And Network Capable/ Worlds First Vista Certified Receiver/ HD Radio And XM Ready Tuning/ Dolby TrueHD And DTS-HD Master Audio/ DDSC-HD Digital Dynamic Discrete Surround Circuitry/ Expanded HDMI v1.3a Ports/ Dual Remotes/ Black Finish', 2699.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (151, 1, 'Denon 7.1 Channel Home Theater MultiMedia A/V Receiver With Networking In Black - AVR3808CI', 'Denon 7.1 Channel Home Theater MultiMedia AV Receiver With Networking In Black - AVR3808CI/ 130 Watts x 7 Channels/ Fully Assignable Channels For Bi-Amping/ Rear Panel RS-232C And Ethernet Ports/ Network Capable/ XM Ready Tuning/ Dolby TrueHD And DTS-HD Master Audio/ Expanded HDMI v1.3a Ports/ Dual Remotes/ Black Finish', 1699.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (152, 1, 'Denon X-Space Surround Bar Home Theatre System In Black - DHTFS3', 'Denon X-Space Surround Bar Home Theatre System In Black - DHTFS3/ 22 Watts x 5 (6 Ohms)/ Supports All Audio Formats (Dolby Digital, DTS, Dolby Pro Logic II)/ Slim Design/ Includes Dolby Headphones/ Included Subwoofer Features One-Touch Connection/ Remote Control/ Black Finish', 1199.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (153, 1, 'Apple Wireless Mighty Mouse - MB111LLA', 'Apple Wireless Mighty Mouse - MB111LLA/ Bluetooth Technology/ Laser Tracking Engine/ 360-Degree Innovative Scroll Ball And Button/ Touch-Sensitive Top Shell/ Force-Sensing Side Buttons/ Customizable/ White Finish', 69.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (154, 1, 'Sony PSP 2000 Playstation Portable Gaming System Core 98510 In Piano Black - 711719851004', 'Sony PSP 2000 Playstation Portable Gaming System Core 98510 In Piano Black - 711719851004/ Play Games, Watch Movies On UMD Discs, And Listen To Music All In One Device/ 4.3'' LCD Screen (16:9)/ 480 x 272 Pixel/ Wi-Fi (IEEE 802.11b) For Wireless Networking With Other PSP Owners/ Memory Stick PRO Duo/ 333MHz System Clock Frequency/ Piano Black Finish', 185.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (155, 1, 'Apple Mini-DVI To DVI Adapter - M9321GB', 'Apple Mini-DVI To DVI Adapter - M9321GB/ Compatible With iMac (Intel Core Duo), MacBook And 12'' PowerBook G4/ Connects To An External DVI Monitor Or Projector/ White Finish', 19.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (156, 1, 'Olympus DS40 Digital Voice Recorder - DS40R', 'Olympus DS40 Digital Voice Recorder - DS40R/ 136 Hours 15 Minutes Recording Time In LP Mode/ High-Sensitivity Detachable Stereo Microphone/ Voice Guidance/ Three Modes Of Microphone Sensitivity/ Built-In Variable Control Voice Actuator (VCVA) Function/ Up To 32 Hours Of Continuous Operation', 149.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (157, 1, 'Bose Lifestyle 48 Series IV 43479 Home Entertainment System - LS48IVWH', 'Bose Lifestyle 48 Series IV Home Entertainment System - LS48IVWH/ ADAPTiQ Audio Calibration System/ Acoustimass Module/ Jewel Cube Speakers/ Direct/Reflecting Speaker Technology/ VS-2 Video Enhancer/ Proprietary Videostage 5 Decoding Circuitry/ Digital 5.1 Decoding/ Control Integration/ White Finish', 3999.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (158, 1, 'Sony Black DVD Recorder And VHS Combo Player - RDRVXD655', 'Sony Black DVD Recorder And VHS Combo Player - RDRVXD655/ Multiformat DVD Compatible/ HDMI Output And 720p/1080i Upscaling/ HDTV Tuner/ 4 Video Head Stereo VHS With 19 Micron Heads/ Variable Bit Rate Recording (7 Speeds)/ Progressive Scan Playback/ Dolby Digital And DTS Decoding Playback Compatible/ TV Virtual Surround/ Black Finish', 319.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (159, 1, 'Apple 1GB Silver iPod Shuffle - MB225LLA', 'Apple 1GB Silver 2nd Generation iPod Shuffle - MB225LLA/ Holds Up To 240 Songs/ 12 Hours Of Continuous Playback/ Skip-Free Playback/ Battery Indicator/ Shuffle Switch/ Built-In Clip/ Mac And Windows Compatible/ MB226LLA/ Silver Finish', 49.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (160, 1, 'GE 24'' GSD2400NWW White Built-In Dishwasher - GSD2400WH', 'GE 24'' GSD2400NWW White Built-In Dishwasher - GSD2400WH/ 4-Level PowerScrub Wash System/ HotStart Option/ Piranha Hard Food Disposer/ Heated Dry Option/ Self-Cleaning Filter System/ White Finish', 259.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (161, 1, 'Panasonic Expandable Digital Cordless DECT 6.0 Phone System - KXTG1032S', 'Panasonic Expandable Digital Cordless DECT 6.0 Phone System - KXTG1032S/ Up To 17 Hours Of Talk Time/ Expandable Up To 6 Handsets/ Up To 3-Way Conference Capability/ Light-Up Indicator With Ringer/Message Alert/ Backlit LCD On Handset/ Digital Speakerphone/ 16-Minute All-Digital Answering System/ Silver Finish', 69.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (162, 1, 'Panasonic 2 Line Integrated Corded Phone System - KXTSC14B', 'Panasonic 2 Line Integrated Corded Phone System - KXTSC14B/ 3-Line LCD Display/ Automatic Line Selection/ Call Waiting Caller ID/ 3-Way Conferencing/ Speakerphone/ Navigator Key/ Black Finish', 74.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (163, 1, 'Audiovox XpressEZ XM Satellite Radio Receiver - XMCK5P', 'Audiovox XpressEZ XM Satellite Radio Receiver - XMCK5P/ 10 Programmable Channels/ Universal Connector/ 3-Line Screen Display/ Plug & Play Dock/ Black Finish', 69.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (164, 1, 'Panasonic Integrated White Telephone System With All-Digital Answering System - KXTS620W', 'Panasonic Integrated White Telephone System With All-Digital Answering System - KXTS620W/ 2-Way Recording/ Call Waiting Caller ID/ Speakerphone/ 3-Line LCD/ Data Port/ Ringer Indicator Lamp/ Programmable Tone/Pulse/ Wall Mountable/ White Finish', 69.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (165, 1, 'Tech Craft Veneto Series Black TV Stand - ABS60BK', 'Tech Craft Veneto Series Black TV Stand - ABS60BK/ Supports Up To A 60'' Flat Panel TV/ Molded Top Gives It An Elegant Appearance/ Framed Doors To Conceal Components/ 200 Lbs Top Shelf Capacity/ Black Finish', 399.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (166, 1, 'Skagen Premium Steel Slimline Mesh Womens Watch - 233XSGG', 'Skagen Premium Steel Slimline Mesh Womens Watch - 233XSGG/ Stainless Steel Mesh Band/ Elegant Round Case/ Mother-Of-Pearl Dial/ Chrome Indicators', 110.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (167, 1, 'Canon Color Image Silver Scanner - 8800F', 'Canon Color Image Silver Scanner - 8800F/ Resolution Of Up To 4800 x 9600 Color Dpi/ Enhance Old Photos/ Auto-Image Fix/ USB 2.0 Interface/ Multi-Image Scanning/ Windows And Mac Compatible/ Silver Finish', 199.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (168, 1, 'Sony Black LocationFree Base Station - LFV30', 'Sony Black LocationFree Base Station - LFV30/ Watch TV Wherever You Are/ Compatible With PC Or PSP System/ Programmable On-Screen Home Remote/ Stream Outside Your Home/ User-Friendly/ Black Finish', 199.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (169, 1, 'Linksys Wireless-G Broadband Router - WRT54GL', 'Linksys Wireless-G Broadband Router - WRT54GL/ All-In-One Internet-Sharing Router/ 4-Port Switch/ Push Button Setup Feature/ TKIP And AES Encryption/ Wireless MAC Address Filtering/ Powerful SPI Firewall/ 54Mbps Wireless-G (802.11g) Access Point', 79.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (170, 1, 'Universal RF Base Station - MRF260', 'Universal RF Base Station - MRF260/ Extends The Reception Range Up To 100 Feet Away Through Walls, Floors, Doors, Indoors Or Outdoors/ Programmed To Operate Equipment At Up To 15 Locations/ Black Finish', 149.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (171, 1, 'Chestnut Hill Sound George iPod Music System In White - CHS4001', 'Chestnut Hill Sound George iPod Music System In White - CHS4001/ Playback System For The iPod/ Full Feature Wireless Remote/ Charging Stand Kit/ Bandless AM/FM Radio/ Easy Set Alarm/ Detachable Front Panel/ White Finish/ iPod Sold Separately', 499.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (172, 1, 'Sony Universal Remote Control - RMEZ4', 'Sony Universal Remote Control - RMEZ4/ Easy-To-Use Simplified Functions/ Controls TV And Cable Box/ Compatible With Most Of Major Brands/ Large Buttons For Easy Operation/ 3-Minute Memory Backup/ Comfortable Ergonomic Design/ Silver Finish', 16.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (173, 1, 'Sirius SiriusConnect Home Tuner - SCH1', 'Sirius SiriusConnect Home Tuner - SCH1/ Compact Size/ Analog And Digital Audio Outputs/ Display Indicators/ Connects To Any Sirius-Ready Home Audio Component', 49.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (174, 1, 'Sanus 15'' - 32'' Flat Panel TV Black Wall Mount - MF209B1', 'Sanus 15'' - 32'' Flat Panel TV Black Wall Mount - MF209B1 - MF209B1/ Supports Up To 60 lbs/ Easy To Install/ Virtual Axis 3D Tilting System/ Black Finish', 96.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (175, 1, 'Yamaha High Performance Subwoofer In Black - YSTFSW150BK', 'Yamaha High Performance Subwoofer In Black - YSTFSW150BK/ 130 Watts Dynamic Power/ Advanced YST II (Yamaha Active Servo Technology)/ Linear Port/ Powerful 6.5? Multi-Range Driver/ Magnetically Shielded/ 30 -150 Hz Low Frequency Response/ Down-Firing Active Design/ Best Matching For Front Surround Systems And Micro Component Systems/ Black Finish', 279.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (176, 1, 'Kenwood Sirius Radio Translator For In-Dash Head Units - KCASR50', 'Kenwood Sirius Radio Translator For In-Dash Head Units - KCASR50/ Provides Full Control Of The SIRIUS Radio/ Displays Text On The Stereo And Supplies Power To The Satellite Radio', 60.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (177, 1, 'Linksys Wireless-G PrintServer - WPSM54G', 'Linksys Wireless-G PrintServer - WPSM54G/ Share A Multifunction Printer With Everyone On Your Network (Works With Most USB Printers)/ Allows Full Access To Printing, Faxing, Scanning And Copying Functions/ Connects Your Printer Directly To The Network By 10/100 Wired Ethernet Or 54Mbps Wireless-G', 99.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (178, 1, 'Sirius STILETTO 2 Home Docking Kit - SLH2', 'Sirius STILETTO 2 Home Docking Kit - SLH2/ Stereo Audio Output Connects With Home Audio System Or Speakers/ Headphone Jack/ PC Sync/ Compatible With Stiletto 2 Radios/ Charges Stiletto 2 While Docked/ Black Finish', 49.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (179, 1, 'Microsoft Office Standard 2007 - 02107746', 'Microsoft Office Standard 2007 - 02107746/ Create Documents Faster, More Easily And More Intuitively/ Automatic Document Recovery Tool/ Document Inspector/ Online Tutorials With Step-By-Step Instructions/ Compatible With Windows Vista, Windows XP SP2 And Windows Server 2003 SP1', 399.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (180, 1, 'Jabra Black Bluetooth Headset - BT5010', 'Jabra Black Bluetooth Headset - BT5010/ Up To 10 Hours Of Talk Time And 300 Hours Of Stand-By/ Wind-Noise Reduction Technology/ Vibrating And Visual Alerts/ Colored LED Indicator/ Up To 33-Foot Wireless Range/ Black Finish', 79.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (181, 1, 'Kensington Orbit Optical Trackball Mouse - 64327', 'Kensington Orbit Optical Trackball Mouse - 64327/ DiamondEye Optical Technology For Precise Tracking And Cursor Control/ USB And PS/2 Connectivity For Greater Compatibility/ Windows And Mac Compatible/ Metallic Silver And Black Finish', 38.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (182, 1, 'Sirius Stiletto 2 Vehicle Kit - SLV2', 'Sirius Stiletto 2 Vehicle Kit - SLV2/ Designed For Use With The Sirius Stiletto 2/ Get Direct One-Touch Access To Traffic And Weather/ Built-In FM Transmitter To Play Satellite Radio Through Your Cars Audio System', 49.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (183, 1, 'Denon Networked Audio System With Built-In iPod Dock - S32', 'Denon Networked Audio System With Built-In iPod Dock - S32/ Stream Music Wirelessly/ Buit-In Dock For iPod On Top/ Ability To Decode MP3 And WMA Formats/ High Contrast Graphic LCD/ Multi-Task Jog Wheel On Top/ Built-In Speakers/ Clock With 2 Alarms With Auto Clock Set & Adjust Via Internet/ FM/AM Radio/ WiFi Certified/ Remote Control/ Black Finish', 499.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (184, 1, 'Motorola Portable Bluetooth Car Kit Speaker Phone - T305', 'Motorola Portable Bluetooth Car Kit Speaker Phone - T305/ 2.0 Bluetooth Wireless Technology/ Noise Cancellation Technology/ Loud Sound High Speaker Output/ Convenient Multi-Function Button/ Up To 14 Hours Of Talk Time And 14 Days Of Standby Time/ Mini-USB Connector/ Black Finish', 69.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (185, 1, 'Sony HD-Handycam 3 Meters (10 Feet) HDMI Mini Cable - VMC30MHD', 'Sony HD-Handycam 3 Meters (10 Feet) HDMI Mini Cable - VMC30MHD/ Gold Plating Plug/ HDMI-Compliant High Speed Category 2 Cable/ Support Full HD 1080p/ Digital Audio Transfer/ 3 Meters(10 Feet)/ Black Finish', 69.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (186, 1, 'Klipsch Black Wireless iPod Speaker - ROOMGROOVE', 'Klipsch Black Wireless iPod Speaker - ROOMGROOVE/ Wirelessly Sends CD-Quality Music To/From Other RoomGrooves/ Retractable Dock Charges iPods With 30-Pin Connectors/ Horn-Loaded Technology For Precise High Tones/ Dual High-Output Woofers Deliver Room-Filling Bass/ Black Finish', 299.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (187, 1, 'Logitech QuickCam Communicate STX - 961464', 'Logitech QuickCam Communicate STX - 961464/ 640 x 480 Video Capture/ 1.3 Megapixel Still Image Capture/ Built-In Microphone With RightSound Technology/ 30 Frames Per Second/ Adjustable Base Fits Any Monitor Or Notebook/ USB 2.0 Certified', 49.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (188, 1, 'Sirius Plug And Play Universal Home Kit - SUPH1', 'Sirius Plug And Play Universal Home Kit - SUPH1/ Compatible With All Of The Newest SIRIUS Plug & Play Radios/ Stereo Audio Output For Use Your Home Audio System Or Powered Speakers/ Sleek Compact Design/ High Gloss Black Finish', 49.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (189, 1, 'Belkin Hi-Speed USB 2.0 7-Port Hub - F5U237APLS', 'Belkin Hi-Speed USB 2.0 7-Port Hub - F5U237APLS/ Transfers Data Up To 480Mbps/ Installs Easily With Plug-And-Play Convenience/ Works Seamlessly With All USB 1.1 And USB 2.0 Devices/ Over-Current Detection And Safety/ Mac And PC Compatible/ Silver Finish', 49.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (190, 1, 'Netgear Wireless Access Point - WG102', 'Netgear Wireless Access Point - WG102/ High-Speed IEEE 802.11g, Up To 108 Mbps In Turbo Mode/ Wi-Fi Protected Access (WPA 802.11i-Ready Security)/ Integrated IEEE 802.3af Power Over Ethernet (PoE)/ Block SSID Broadcast/ VPN Pass-Through Support', 186.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (191, 1, 'Logitech diNovo Media Desktop Laser Keyboard And Mouse Combo - 967562', 'Logitech diNovo Media Desktop Laser Keyboard And Mouse Combo - 967562/ Unique Ultra-Flat Keyboard/ Detached Customizable MediaPad/ Precision Rechargeable Laser Mouse/ Tilt Wheel Plus Zoom/ Customizable Hotkeys/ Dedicated Search Buttons/ Bluetooth Wireless Technology Compatible/ Black And Gray Finish', 199.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (192, 1, 'Apple 500GB Time Capsule Wireless Hard Drive - MB276LLA', 'Apple 500GB Time Capsule Wireless Hard Drive - MB276LLA/ 500GB 7200-rpm Serial ATA Server-Grade Hard Disk Drive/ Up To 5x The Performance And 2x The Range With 802.11n/ Wi-Fi Protected Access (WPA/WPA2)/ Wireless Security (WEP) Configurable For 40-Bit And 128-Bit Encryption/ NAT Firewall/ AirPort Utility For Mac And Windows', 299.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (193, 1, 'Apple 1TB Time Capsule Wireless Hard Drive - MB277LLA', 'Apple 1TB Time Capsule Wireless Hard Drive - MB277LLA/ 1TB 7200-rpm Serial ATA Server-Grade Hard Disk Drive/ Up To 5x The Performance And 2x The Range With 802.11n/ Wi-Fi Protected Access (WPA/WPA2)/ Wireless Security (WEP) Configurable For 40-Bit And 128-Bit Encryption/ NAT Firewall/ AirPort Utility For Mac And Windows', 499.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (194, 1, 'Garmin Nuvi Portable Friction Mount - 0101090800', 'Garmin Nuvi Portable Friction Mount - 0101090800/ No Installation Required/ Securely Mounts Your GPS To A Surface In Your Car/ Works With All Garmin Nuvi Portable GPS Units/ Black Finish', 39.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (195, 1, 'Garmin Vehicle Suction Cup Mount - 0101093600', 'Garmin Vehicle Suction Cup Mount - 0101093600/ No Installation Required/ Securely Mounts Your GPS To Dash/ Black Finish', 25.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (196, 1, 'Garmin Suction Cup Mount And 12-Volt Adapter Kit - 0101097900', 'Garmin Suction Cup Mount And 12-Volt Adapter Kit - 0101097900/ Suction Cup Mount And 12-Volt Adapter Included', 30.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (197, 1, 'Pioneer Remote Control With DVD/Audio Controls - CDR55', 'Pioneer Remote Control With DVD/Audio Controls - CDR55/ Hands-Free Wireless Control/ Quick Access For Functions/ Compatible With AVH-P5000DVD, AVH-P4000DVD, AVIC-N4, AVIC-D3, AVH-P4900DVD And AVH-P5900DVD', 19.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (198, 1, 'Pioneer Sirius Bus Interface - CDSB10', 'Pioneer Sirius Bus Interface - CDSB10/ Sirius Connect'' Compatibility/ Replay Function/ Game Alert/ Game Zone', 68.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (199, 1, 'Pioneer HD Radio Tuner - GEXP10HD', 'Pioneer HD Radio Tuner - GEXP10HD/ Compatible With FH-P800BT, FH-P8000BT, DEH-P700BT, DEH-P7000BT, DEH-P600UB, DEH-P6000UB/ ''External Control'' Capable', 100.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (200, 1, 'Sirius Dock And Play Universal Vehicle Kit - SUPV1', 'Sirius Dock And Play Universal Vehicle Kit - SUPV1/ Stereo Audio Output/ Use With Your Home Audio System Or Powered Speakers/ Compatible With Sportster 5, Sportster 4, Sportster 3, Starmate 4, Starmate 3, Stratus 4, Stratus', 49.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (201, 1, 'Electrolux Harmony Series Canister Vacuum - EL6985B', 'Electrolux Harmony Series Canister Vacuum - EL6985B/ Foot-Operated Switch On The Floor Nozel/ Ergonomic Handle Design/ Electronic Dust Bag Indicator/ HEPA H12 Filter/ Telescoping Wand', 299.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (202, 1, 'Sennheiser Rechargeable Nickel-Metal Hydride Battery - BA151', 'Sennheiser Rechargeable Nickel-Metal Hydride Battery - BA151/ Rechargeable Battery For Wireless Sennheiser Headphones', 20.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (203, 1, 'Canon Green Photo Ink Cartridge - CLI8G', 'Canon Green Photo Ink Cartridge - CLI8G/ FINE Technology For Exceptional Sharpness & Detail/ Compatible With Canon Pixma Pro9000', 16.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (204, 1, 'Canon Red Photo Ink Cartridge - CLI8R', 'Canon Red Photo Ink Cartridge - CLI8R/ FINE Technology For Exceptional Sharpness & Detail/ Compatible With Canon Pixma Pro9000', 16.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (205, 1, 'Canon Black Photo Ink Cartridge - CLI8B', 'Canon Black Photo Ink Cartridge - CLI8B/ FINE Technology For Exceptional Sharpness & Detail/ Compatible With Canon Pixma Printers', 16.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (206, 1, 'Netgear ProSafe 5 Port 10/100 Desktop Switch - FS105', 'Netgear ProSafe 5 Port 10/100 Desktop Switch - FS105/ 5 Auto Speed-Sensing 10/100 UTP Ports/ Embedded Memory', 40.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (207, 1, 'Pioneer Premier In-Dash CD/WMA/MP3/AAC Receiver - DEHP400UB', 'Pioneer Premier In-Dash CD/WMA/MP3/AAC Receiver - DEHP400UB/ 50W x 4 Built-In Speaker Power/ 3 RCA Hi-Volt Preouts/ Two-Way Crossover/ Supertuner IIID/ AUX-In Connection/ Rotary Commander Volume Control', 183.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (208, 1, 'Pioneer DEH-2000MP CD/MP3/WMA In-Dash Receiver - DEH2000MP', 'Pioneer DEH-2000MP CD/MP3/WMA In-Dash Receiver - DEH2000MP/ 50W x 4 Built-In Speaker Power/ LED Display/ Built-In Front Auxiliary Input/ Detachable Face Security/ Remote Control/ Rotary Volume Control', 98.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (209, 1, 'Pioneer Premier In-Dash CD/WMA/MP3/AAC Receiver - DEHP500UB', 'Pioneer Premier In-Dash CD/WMA/MP3/AAC Receiver - DEHP500UB/ 50W x 4 Built-In Speaker Power/ 3 RCA Hi-Volt Preouts/ Two-Way Crossover/ Supertuner IIID/ AUX-In Connection/ Rotary Commander Volume Control', 208.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (210, 1, 'Sony 7'' Digital Photo Frame In Black - DPFD70', 'Sony 7'' Digital Photo Frame - DPFD70/ 7'' LCD With 800 x 480 Resolution/ 15:9 Aspect Ratio/ 256MB Internal Memory/ Supports Most Memory Cards/ Variety Of Display Modes/ Auto Image Rotation Feature/ View Mode Button/ Fast Digital Picture Decoding/ Handles Large Data Files/ USB B-Type Connection/ Remote Control/ Black Finish', 139.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (211, 1, 'SIRIUS SiriusConnect Vehicle Kit In Black - SCVDOC1', 'SIRIUS SiriusConnect Vehicle Kit In Black - SCVDOC1/ Compact Design/ Compatible With The Next Generation Of SiriusConnect Interface Adapters/ 3 Interchangeable Adapter Plates/ Black Finish', 59.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (212, 1, 'Linksys Wireless-G Ethernet Bridge - WET54G', 'Linksys Wireless-G Ethernet Bridge - WET54G/ Converts Wired-Ethernet Devices To Wireless-G Network Connectivity/ For Windows, Macintosh, Linux, PlayStation Consoles, Xbox Consoles, Or Anything With An Ethernet Port/ Plug And Play, No Driver Installation Require', 89.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (213, 1, 'Yamaha RX-V363BL 5.1 Channel Digital Home Theater Receiver In Black - RXV363BK', 'Yamaha RX-V363BL 5.1 Channel Digital Home Theater Receiver In Black - RXV363BK/ 500 Watts Powerful Surround Sound (100W x 5)/ iPod And Bluetooth Audio Compatibility/ Dolby Digital, DTS And Dolby Pro Logic II Decoding/ Cinema DSP With 8 DSP Programs/ Compressed Music Enhancer/ 192kHz/24-Bit DACs For All Channels/ Remote Control/ Black Finish', 199.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (214, 1, 'Yamaha All-Weather Pair Speaker System - NSAW390WH', 'Yamaha NS-AW390WH All-Weather Speaker System - NSAW390WH/ 6.5'' High Compliance/ PP Mica Filled Woofers/ Unique Dual 1'' PEI Dome Tweeter Configuration/ Aluminum Speaker Grilles/ Wall Mountable/ White Finish/ Sold As A Pair', 149.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (215, 1, 'Yamaha NS-AW390BL All-Weather Pair Speaker System - NSAW390BK', 'Yamaha NS-AW390BL All-Weather Speaker System - NSAW390BK/ 6.5'' High Compliance/ PP Mica Filled Woofers/ Unique Dual 1'' PEI Dome Tweeter Configuration/ Aluminum Speaker Grilles/ Wall Mountable/ Black Finish/ Sold As A Pair', 149.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (216, 1, 'Yamaha NS-AW190BL All-Weather Pair Speaker System - NSAW190BK', 'Yamaha NS-AW190BL All-Weather Speaker System - NSAW190BK/ 5'' High Compliance/ PP Mica Filled Woofers/ Unique Dual 1/2'' PEI Dome Tweeter Configuration/ Aluminum Speaker Grilles/ Wall Mountable/ Black Finish/ Sold As A Pair', 99.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (217, 1, 'Yamaha 7.2 Channel Black Digital Home Theater Receiver - RXV663BK', 'Yamaha 7.2 Channel Black Digital Home Theater Receiver - RXV663BK/ 4 SCENE Buttons/ XM Ready With XM HD Surround/ SIRIUS Satellite Radio Ready/ YPAO/ iPod Compatibility/ Bluetooth Compatibility/ Multi-Zone Control Compatibility/ On-Screen Display/ Black Finish', 499.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (218, 1, 'Yamaha 7.2 Channel Black Digital Home Theater Receiver - RXV863BK', 'Yamaha 7.2 Channel Black Digital Home Theater Receiver - RXV863BK/ 4 SCENE Buttons/ XM Ready With XM HD Surround/ SIRIUS Satellite Radio Ready/ YPAO/ iPod Compatibility/ Bluetooth Compatibility/ Multi-Zone Control Compatibility/ On-Screen Display/ Black Finish/ CALL FOR LATEST PRICE', 899.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (219, 1, 'Yamaha 5.1 Channel Home Theater In A Box System In Black - YHT390BK', 'Yamaha 5.1 Channel Home Theater In A Box System In Black - YHT390BK/ New Scene, Compressed Music Enhancer/ iPod Compatibility/ 600W Powerful Surround Sound/ Silent Cinema/ 192kHz/24-Bit DACs For All Channels/ Black Finish', 399.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (220, 1, 'Apple MacBook Air SuperDrive - MB397GA', 'Apple MacBook Air SuperDrive - MB397GA/ Compact And Portable Slot-Loading 8x SuperDrive/ Connect To MacBook Air USB Slot/ Play And Burn Both CDs And DVDs/ Watch DVD Movie, Install Software, Or Create Backup Discs', 99.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (221, 1, 'Monster Mini-To-Mini iCable For Car - AICMINIIP3S', 'Monster Mini-To-Mini iCable For Car - AICMINIIP3S/ 3 Ft. Cable/ 1/8 Mini-Jack Input For Car Stereo/ Dual Balanced High-Purity Copper Conductors And 24k Gold/ Xtra Low Noise DoubleHelix Construction/ Compatible With Apple iPod, iPhone, And Portable MP3 Player/ White Finish', 15.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (222, 1, 'TomTom GPS Mount And USB Car Charger - 9N00101', 'TomTom GPS Mount And USB Car Charger - 9N00101/ Extra Holder And Car Charger Convenient For Multi-Vehicles User/ No Need To Transfer Holder From One Car To Another/ Easy Installation/ Compatible With TomTom ONE/ Black Finish', 39.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (223, 1, 'Denon Blu-ray Disc DVD/CD Player - DVD3800BDCI', 'Denon Blu-ray Disc DVD/CD Player - DVD3800BDCI/ 10-Bit Realta HQV Video Processor/ 1080p/24fps Output And Multi-Cadence Detection/ HDMI 1.3a Output With 36-Bit Deep Color Support/ Dual 32-Bit Floating Point DSP/ Multi-Layered Construction With Dual-Layered Top Shields And Triple-Layered Bottom/ Suppress Vibration Hybrid (S.V.H.) Loader/ Black Finish', 1999.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (224, 1, 'TomTom GPS Mount And USB Car Charger - 9S00006', 'TomTom GPS Mount And USB Car Charger - 9S00006/ Extra Holder And Car Charger Convenient For Multi-Vehicles User/ No Need To Transfer Holder From One Car To Another/ Easy Installation/ Compatible With TomTom ONE XL/ Black Finish', 28.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (225, 1, 'Bracketron iPod Docking Kit - IPM202BL', 'Bracketron iPod Docking Kit - IPM202BL/ Compatible With All Generation iPods Including iPod Mini, iPod Nano And Apple iPhone/ Wings Adjustable Up To 2.5''/ Black Finish', 14.95); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (226, 1, 'Boston Acoustics Solo AM/FM Large Display Clock Radio - HSOLOMDNT', 'Boston Acoustics Solo AM/FM Large Display Clock Radio - HSOLOMDNT/ Rotating Clock Face/ Precision Tuner/ 3 1/2? Full-Range Speaker/ Auxiliary Input/ High Contrast LCD Display/ 360� Snooze Bar/ Grey Finish', 99.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (227, 1, 'Panasonic 5.8 GHz Black Expandable Digital Cordless Phone System - KXTG4323B', 'Panasonic 5.8 GHz Black Expandable Digital Cordless Phone System - KXTG4323B/ Include 3 Handsets/ Expandable Up To 4 Handsets/ Digital Answering Machine System/ Ringer ID/ Call Waiting Caller ID/ Voicemail/ Hold/ Mute/ Clock/ Alarm/ LED Lighting/ Speakerphone/ Intercom/ 11 Days Standby/ 5 Hours Talk Time/ Black Finish', 79.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (228, 1, 'Sony Silver Digital Voice Recorder - ICDB600', 'Sony Silver Digital Voice Recorder - ICDB600/ 512MB Built-In Flash Memory/ Up To 300 Hours Of Recording Time/ 3 Recording Modes/ 4 Message Folders/ Large LCD Display/ Voice Operated Recording/ 250mW Speaker Output/ Date and Time Stamp/ Silver Finish', 39.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (229, 1, 'Motorola MotoRokr Portable Bluetooth Car Kit Speaker Phone - T505', 'Motorola MotoRokr Portable Bluetooth Car Kit Speaker Phone - T505/ 2.0 Bluetooth Wireless Technology/ Noise Cancellation Technology/ Loud Sound High Speaker Output/ Audio CallerID/ StationFinder/ Convenient Multi-Function Button/ Long Battery Life/ Mini-USB Connector/ Black Finish', 129.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (230, 1, 'Samsung Hi Definition Conversion DVD Player - DVD1080P8', 'Samsung Hi Definition Conversion DVD Player - DVD1080P8/ Progressive Scan/ HD Upconversion/ Digital-To-Analog Converter/ Dolby Digital Surround Sound/ Child Protection/ HDMI Output/ Black Finish', 79.90); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (231, 1, 'Boston Acoustics Duo-I AM/FM Clock Radio With iPod Dock - HDUOIMDNT', 'Boston Acoustics Duo-I AM/FM Clock Radio With iPod Dock - HDUOIMDNT/ Integrated iPod Dock/ Precision AM/FM Stereo Tuner/ 3 1/2'' Dual High Performance Full-Range Speakers/ BassTrac Audio Processing/ 2 Auxiliary Inputs/ High Contrast Display/ 10 FM & 5 AM Station Presets/ 360� Snooze Bar/ Remote Control Included/ Grey Finish', 199.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (232, 1, 'Panasonic Black DVD Home Theater Sound System - SCPT660', 'Panasonic Black DVD Home Theater Sound System - SCPT660/ Kelton Subwoofer/ Bamboo Diaphragm Center Speakers/ 1080p Up-Conversion/ Integrated Universal Dock And On-Screen Display For iPod/ iPod Video Playback/ Whisper-Mode Surround/ Built-In Dolby Digital And DTS Decoder/ High Speed 5-DVD/CD Changer/ Black Finish', 289.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (233, 1, 'Weber Summit E-620 Copper Liquid Propane Gas Outdoor Grill - 1752001', 'Weber Summit E-620 Copper Liquid Propane Gas Outdoor Grill - 1752001/ 6 Stainless Steel Burners/ 60,000 BTU-Per-Hour Input/ Snap-Jet Individual Burner Ignition System/ 838 Sq. In. Total Cooking Area/ Porcelain-Enameled Shroud/ Center-Mounted Thermometer/ Copper Finish/ Liquid Propane Model (LP Tank Not Included)/ Assembly Required', 1899.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (234, 1, 'Logitech Harmony One Advanced Universal Remote Control - HARMONY1', 'Logitech Harmony One Advanced Universal Remote Control - HARMONY1/ One-Touch Access To Your Entertainment/ Replaces Up To 15 Remotes/ Full-Color Touch Screen/ Sculpted, Backlighted Buttons In Logical Zones/ Ergonomic Design/ Rechargeable/ Guided Online Setup/ World?s Largest AV Control Database/915-000035', 249.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (235, 1, 'Z-Line Portland Black TV Stand - ZL2344MU', 'Z-Line Portland Black TV Stand - ZL2344MU/ Accommodates Most Flat Panel LCD/Plasma TVs Up To 50''/ Durable Black Glossy Powder Coat Metal Frame/ Tempered Black Safety Glass Shelves/ Chrome Cylinder Glass Supports/ Swivel Mount/ Wire Management/ Holds 65 lbs Per Shelf/ Distance Between Shelves- 8.25'' (Bottom to Middle) and 7'' (Middle to the bar below the top shelf)/ Black Finish', 399.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (236, 1, 'Sony Black USB Stereo Turntable System - PSLX300USB', 'Sony Black USB Stereo Turntable System - PSLX300USB/ Transfer Classic Vinyl To PC, Walkman, Or MP3 Player/ USB And RCA Audio Output/ 45 Rpm Record Playback/ Belt Drive System/ Dust Cover/ Black Finish', 149.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (237, 1, 'Sony Digital SLR Camera With Lens Kit - DSLRA200W', 'Sony Alpha Digital SLR Camera With Lens Kit - DSLRA200W/ 10.2 Megapixels/ 2.7'' Clear Photo LCD Screen/ Super SteadyShot In-Camera Image Stabilization/ Continuous Burst Mode/ Bionz Image Processor/ ISO Sensitivity/ 9-Point Center Cross AF Sensor/ Scene Selection Modes/ DT 18-70mm f3.5 Zoom Lens And 75-300mm f4.5-5.6 Compact Super Telephoto Zoom Lens Included/ Black Finish', 849.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (238, 1, 'Nyko Charge Base 2 Charger For PlayStation 3 Controller - 743840830535', 'Nyko Charge Base 2 Charger For PlayStation 3 Controller - 743840830535/ Compact Design/ Rapidly Charges Two PS3 Controllers Simultaneously/ Includes Two USB Charge Adaptors', 34.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (239, 1, 'Sony Remote Control Tripod - VCT60AV', 'Sony Remote Control Tripod - VCT60AV/ A/V Remote Connector/ 4 Stage Leg Extension/ Extends From 18.9'' To 57.6'' In Height/ Guide Frame Feature/ Available Vertical Position/ Supplied Carrying Case/ Black Finish', 99.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (240, 1, 'Klipsch Groove PM20 Computer Speakers - GROOVEPM20BK', 'Klipsch Groove PM20 Computer Speakers - GROOVEPM20BK/ 6 Ohms Nominal Impedance/ 3Full-Range 2.5? Fiber Composite Driver/ Overload Protection/ System-Specific Loudness Contour/ Black Finish', 99.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (241, 1, 'Weber Gas Barbecue Rotisserie - 7519', 'Weber Gas Barbecue Rotisserie - 7519/ Fits Genesis E-300, S-300 Gas Grills/ Heavy-Duty Electric Motor/ Counterbalance For Smooth Turning', 80.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (242, 1, 'Weber Cast Iron Griddle - 7531', 'Weber Cast Iron Griddle - 7531/ Heavy-Duty Cast Iron Griddle/ Fits Weber Genesis Silver A & Spirit 500 Gas Grills', 44.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (243, 1, 'Weber Cast Iron Griddle - 7542', 'Weber Cast Iron Griddle - 7542/ Heavy-Duty Cast Iron Griddle/ Two-Sided For Cooking A Variety Of Foods/ Fits Several Weber Grills', 44.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (244, 1, 'Sony 5.1 Channel Black A/V Receiver - STRDG520', 'Sony 5.1 Channel Black A/V Receiver - STRDG520/ 100 Watts X 5 Power/ 1080p HDMI Pass Through/ Accepts 1080/60p And 24p Video Signal Via HDMI/ Dolby Digital, Dolby Pro Logic, Dolby Pro Logic II, Digital Cinema Sound And Dts Decoding/ Black Finish', 199.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (245, 1, 'Sony Alpha DSLR Black Camera Body With 18-70mm Zoom Lens - DSLRA300K', 'Sony Alpha DSLR Black Camera Body With 18-70mm Zoom Lens - DSLRA300K/ 10.2 MP Super HAD CCD/ Tiltable 2.7 Clear Photo LCD Plus Screen/ Smart Teleconverter 2X Zoom/ Expanded ISO Sensitivity/ Super SteadyShot In-Camera Image Stabilization/ Anti-Dust Technology/ 9-Point Center Cross AF Sensor/ Index and Slide Show Display/ Black Finish', 599.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (246, 1, 'Polk Audio CSI A4 Black Center Channel Loudspeaker - CSIA4BK', 'Polk Audio CSI A4 Black Center Channel Loudspeaker - CSIA4BK/ 1'' Silk/Polymer Dome Tweeter/ Dual 5-1/4'' Mid/Woofers/ Magnetic Shielding/ All-MDF Construction/ Acoustically Inert Stamped Driver Baskets/ Floating Anti-Diffraction Grilles/ Dual Bi-Ampable Gold-Plated 5-Way Binding Post Inputs/ Black Finish/ Sold As A Single', 279.95); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (247, 1, 'Polk Audio CSI A4 Cherry Center Channel Loudspeaker - CSIA4CH', 'Polk Audio CSI A4 Cherry Center Channel Loudspeaker - CSIA4CH/ 1'' Silk/Polymer Dome Tweeter/ Dual 5-1/4'' Mid/Woofers/ Magnetic Shielding/ All-MDF Construction/ Acoustically Inert Stamped Driver Baskets/ Floating Anti-Diffraction Grilles/ Dual Bi-Ampable Gold-Plated 5-Way Binding Post Inputs/ Cherry Finish/ Sold As A Single', 279.95); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (248, 1, 'Polk Audio CSI A6 Black Center Channel Loudspeaker - CSIA6BK', 'Polk Audio CSI A6 Black Center Channel Loudspeaker - CSIA6BK/ Dual 6-1/2'' Mid/Woofers/ 1'' Silk/Polymer Dome Tweeter/ Dual Rear PowerPort Bass Venting/ Magnetic Shielding/ Mylar Bypass Capacitors/ Acoustic Resonance Control (ARC Port) Technology/ Dual Bi-Ampable Gold-Plated 5-Way Binding Post Inputs/ Butyl Rubber Surrounds/ Floating Anti-Diffraction Grilles/ All-MDF Construction/ Black Finish/ Sold As A Single', 449.95); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (249, 1, 'Polk Audio 5.1 Channel Black Home Theater Speaker System - RM705BK', 'Polk Audio 5.1 Channel Black Home Theater Speaker System - RM705BK/ Heavy-Duty Non-Resonant Composite Enclosures/ Downward Firing Powered 8'' Subwoofer/ Built-In Subwoofer Power Amp With Active Crossover/ Three-Sided Cabinet Design/ Magnetically Shielded/ Black Finish', 499.95); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (250, 1, 'Sony 3.1 Channel Home Theater Surround System In Black - HTCT100', 'Sony 3.1 Channel Home Theater Surround System In Black - HTCT100/ HDMI Active Intelligence/ LPCM Playback/ 3.1 Channel/ S-Force Surround/ BRAVIA� Sync/ Digital Media Port/ Black Finish/ ETA MID JANUARY 2009', 299.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (251, 1, 'Polk Audio Black 10'' Powered Subwoofer - PSW110BK', 'Polk Audio PSW110 Black 10'' Powered Subwoofer - PSW110BK/ 100 Watts Continuous Average Output/ 200 Watts Dynamic Power Output/ 10'' Dynamic Balance Composite Woofer Driver/ Klippel Optimized Woofer/ High Current Class A/B Amplifiers/ Downward Firing Port/ Line And Speaker Level Inputs/ Non-Resonant MDF Construction/ Black Finish', 299.95); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (252, 1, 'Twenty20 VholdR Mount Adhesive - 2200MA', 'Twenty20 VholdR Mount Adhesive - 2200MA/ Removable/ Resists Water, Heat And Cold', 6.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (253, 1, 'Weber Premium Black Grill Cover - 7550', 'Weber Premium Black Grill Cover - 7550/ Heavy-Duty Vinyl/ Compatible With Spirit E-200 Series, Spirit 500 And Genesis Silver A Gas Grills/ Black Finish', 40.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (254, 1, 'Sony Black Earbud Style Headphones - MDREX55BK', 'Sony MDREX55BLK Black Earbud Style Headphones - MDREX55BK/ 9mm EX Driver Provides Comfort Fit And Deep Bass Sound/ Soft Fitting Silicon Housing/ 3 Sizes Earbuds/ Carrying Pouch/ Black Finish', 39.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (255, 1, 'Hoover EmPower Bagless Upright Vacuum - U5269', 'Hoover EmPower Bagless Upright Vacuum - U5269/ Hush Mode/ Power Boost/ No Assembly Required/ Folding Handle For Easy Storage/ Allergen Filter/ 12 Amp Motor/ Tools Included/ Green Finish', 99.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (256, 1, 'Panasonic DECT 6.0 Expandable Digital Cordless Phone With All-Digital Answering System - KXTG9344T', 'Panasonic DECT 6.0 Expandable Digital Cordless Phone With All-Digital Answering System - KXTG9344T/ 4 Handsets System/ Up To 6 Multi-Handset Capability/ Digital Answering Machine System/ Ringer ID/ Call Waiting Caller ID/ Voicemail/ Hold/ Voice Menu/ Marker Message/ Mute/ Clock/ Alarm/ LED Lighting/ Night Mode/ Call Block/ Speakerphone/ 11 Days Standby/ 5 Hours Talk Time/ Black Metallic Finish', 139.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (257, 1, 'LaCie 500GB d2 Quadra External Hard Drive - 301825U', 'LaCie 500GB d2 Quadra External Hard Drive - 301825U/ Quadruple Interface For Full PC And Mac Compatibility/ Interface Bandwidth Up To 3Gbits/s (eSATA)/ Advanced Aluminum Heat Sink Design Cooling System For Quiet Operation/ 7200 Rotational Speed (rpm)/ 16MB Cache/ Compatible With Time Machine', 159.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (258, 1, 'Panasonic DECT 6.0 Black Expandable Digital Cordless Phone - KXTG9361B', 'Panasonic DECT 6.0 Black Expandable Digital Cordless Phone - KXTG9361B/ Drop And Splash Resistant/ Multi-Handset Capability/ Ringer ID/ Call Waiting Caller ID/ Voicemail/ Hold/ Mute/ Clock/ Alarm/ LED Lighting/ Night Mode/ Call Block/ Speakerphone/ 11 Days Standby/ 5 Hours Talk Time/ Black Finish', 48.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (259, 1, 'Sony 1GB Memory Stick PRO Duo Mark 2 Media Card - MSMT1G', 'Sony 1GB Memory Stick PRO Duo Mark 2 Media Card - MSMT1G/ 160 Mbps Transfer Speed/ 940MB Actual Capacity', 19.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (260, 1, 'Sony 2GB Memory Stick PRO Duo Mark 2 Media Card - MSMT2G', 'Sony 2GB Memory Stick PRO Duo Mark 2 Media Card - MSMT2G/ 160 Mbps Transfer Speed/ 1.85GB Actual Capacity', 29.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (261, 1, 'Pioneer Black Premier Single CD Receiver - DEHP700BT', 'Pioneer Black Premier Single CD Receiver - DEHP700BT/ Built-In Bluetooth Solution/ USB Direct Control For iPod/ Advanced Sound Retriever/ 3 RCA Hi-Volt Preouts/ Two-Way Crossover/ Built-In MOSFET 50 W x 4 Amplifier/ Supertuner IIID/ Amplifier Off Mode/ Display Off Mode', 308.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (262, 1, 'TomTom ONE 130S Car GPS Navigation System - 1EE005202', 'TomTom ONE 130S Car GPS Navigation System - 1EE005202/ 3.5'' LCD Anti-Glare Touch Screen/ Pre-Installed Maps/ Internal Lithium-Ion Battery/ Car Speed Linked Volume/ Automatic Day/Night Mode/ QuickGPSfix/ Text-To-Speech Included', 246.95); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (263, 1, 'TomTom ONE XL 330 Car GPS Navigation System - 1EG005200', 'TomTom ONE XL 330 Car GPS Navigation System - 1EG005200/ 4.3'' LCD Anti-Glare Touch Screen/ Pre-Installed Maps/ Internal Lithium-Ion Battery/ Car Speed Linked Volume/ Automatic Day/Night Mode/ QuickGPSfix', 246.95); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (264, 1, 'TomTom ONE XL 330S Car GPS Navigation System - 1EG005201', 'TomTom ONE XL 330S Car GPS Navigation System - 1EG005201/ 4.3'' LCD Anti-Glare Touch Screen/ Pre-Installed Maps/ Internal Lithium-Ion Battery/ Car Speed Linked Volume/ Automatic Day/Night Mode/ QuickGPSfix/ Text-To-Speech Included', 296.95); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (265, 1, 'Sony Black Camcorder Tripod - VCT80AV', 'Sony Black Camcorder Tripod - VCT80AV/ 3 Stage Leg Extension/ Extends From 24.88'' To 65.88'' In Height/ Guide Frame Feature/ Available Vertical Position/ For A/V Remote Connector/ Supplied Carrying Case/ Black Finish', 180.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (266, 1, 'Sony 7.1 Channel Black A/V Receiver - STRDG820', 'Sony 7.1 Channel Black A/V Receiver - STRDG820/ 770 Watts Total Power (110W x 7)/ Accepting Resolutions Up To 1080p Via HDMI/ Digital Cinema Auto Calibration/ BRAVIA Sync/ Digital Cinema Sound/ Dolby Digital, Dolby Digital EX, Dolby Pro Logic II, Dolby Pro Logic IIx, Dts, Dts-ES, Dts 96/24, Dts NEO:6 Decoding/ Black Finish', 399.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (267, 1, 'Sony Splash Resistant Shower Radio - ICFS79W', 'Sony Multi Band Digital Tuner Shower Radio - ICFS79W/ Splash Resistant/ AM/FM/Weather Band Reception/ Easy One Button Weather Band Select/ Built-In Digital Clock/ Selectable Automatic-Off Timer/ Quartz Synthesized Tuner/ Built-In Antennas', 49.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (268, 1, 'Samsung Black Combo DVD/VHS Player - DVDV9800', 'Samsung Black Combo DVD/VHS Player - DVDV9800/ Progressive Scan/ 1080p Up-Conversion Via HDMI/ 10Bit / 54MHz Digital-To-Analog Converter/ 4-Head Hi-Fi VCR/ Black Finish/ No Tuner', 98.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (269, 1, 'Omnimount Stellar Series Audio Tower - G303DARK', 'Omnimount Stellar Series Audio Tower - G303DARK/ Designed For Large Audio Components/ Supports Tabletop Flat Panels/ Three ?Floating? Shelf Design/ Integrated Cable Management/ Black Finish', 299.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (270, 1, 'Weber Q 320 Liquid Propane Table And Outdoor Grill - 586002', 'Weber Q 320 Liquid Propane Table And Outdoor Grill - 586002/ 462 Sq. In. Total Cooking Area/ 21,700 BTU Stainless Steel Burners/ Porcelain-Enameled Cast-Iron Cooking Grate/ Cast-Aluminum Lid And Body/ Electronic Ignition/ Grill Out Handle Light/ Folding Work Tables With Tool Holders/ Removable Catch Pan/ Built-In Thermometer/ Stationary Cart Included/ Black And Aluminum Finish/ Assembly Required', 379.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (271, 1, 'Sony Black Component Home Theater System - HT7200DH', 'Sony Black Component Home Theater System - HT7200DH/ 900 Watts/ 5.1 Channels/ HDMI 1080p Output DVD Player/ HDMI Active Intellegence AV Receiver/ 5 Satellite Speakers/ XM Ready/ Black Finish', 499.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (272, 1, 'TomTom Black Carry Case - 9UEA01700', 'TomTom Black Carry Case - 9UEA01700/ Specifically Designed For TomTom ONE 130 GPS/ Durable And Compact Protective Hardcover Material/ Wrist Strap/ Black Finish', 19.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (273, 1, 'Mitsubishi 835 Diamond Series 73'' 1080p DLP Rear Projection HDTV - WD73835', 'Mitsubishi 835 Diamond Series 73'' 1080p DLP Rear Projection HDTV - WD73835/ 1920 x 1080 Full HD Resolution/ 6-Color Processor/ Smooth 120Hz/ x.v.Color/ Plush1080p 12-Bit Digital Video Processing/ Color 4D Video Noise Reduction/ 3D Ready/ NetCommand/ DeepField Imager/ Black Finish', 3499.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (274, 1, 'Sony Black DVD Recorder And VHS Combo Player - RDRVX560', 'Sony Black DVD Recorder And VHS Combo Player - RDRVX560/ Multiformat DVD Compatible/ HDMI Output With 1080p,1080i,720p Upscaling/ USB One Touch Dubbing/ 4 Video Head Stereo VHS With 19 Micron Heads/ Virtual Surround Sound For DVD With Stereo TV Speakers/ Black Finish', 219.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (275, 1, 'Uniden DECT 6.0 Digital Accessory Handset - DCX300', 'Uniden DECT 6.0 Digital Accessory Handset - DCX300/ DECT 6.0 Interference Free Cordless Frequency/ Large Color Display/ Blue Backlit Keypad/ Handset Speakerphone/ Intercom or Call Transfer Between Handsets/ Polyphonic Ring Tones/ Advanced Phonebook Features/ Last 5 Number Redial/ Piano Black Finish', 34.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (276, 1, 'Sony DVD Recorder In Black - RDRGX360', 'Sony DVD Recorder In Black - RDRGX360/ 1080p/1080i/720p Upscaling For DVD/ USB One Touch Dubbing/ Line Input Recording/ BRAVIA Sync/ DVD+R Double Layer Recording/ Dolby Digital Decoding Playback Compatible/ Black Finish', 179.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (277, 1, 'Sennheisser Hi-Fi Wireless Headphone - RS130', 'Sennheisser Hi-Fi Wireless Headphone - RS130/ Switchable SRS Surround Sound Mode/ Intelligent Auto-Tuning/ Memory Function/ Self-Learning Automatic Level Control/ Black Finish', 159.95); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (278, 1, 'BlueAnt Black Bluetooth Headset - Z9I', 'BlueAnt Black Bluetooth Headset - Z9I/ Pairs With 5 Devices/ Bluetooth Version 2.0 Technology/ Dual Microphones For Pure Speech/ Revolutionary Voice Isolation Technology/ Automatic Connection And Reconnection With Notification/ Firmware Upgrade Via USB On Your PC/ Up To 5.5 Hours Talk Time/ 200 Hours Standby Time/ Gloss Black Finish', 99.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (279, 1, 'Escort Passport 9500CI Radar Detector - 9500CI', 'Escort Passport 9500CI Radar Detector - 9500CI/ 360 Degree Protection/ Completely Undetectable To All Detector Scanners/ Variable-Speed Radar Performance/ GPS-Powered Truelock Filter/ Adaptive Signal Processing/ Speed Alert/ Crystal-Clear Voice Alerts/ 280 LED Matrix Blue Display/ 5 Levels Of Brightness Control/ Black Finish/ Price Includes Installation', 1995.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (280, 1, 'Sony Black 5.1 Channel Home Theater System - HTDDWG700', 'Sony Black 5.1 Channel Home Theater System - HTDDWG700/ 5.1 Channel/ 900 Watts Power/ Portable Audio Enhancer With Front Audio Input/ iPod Cradle/ Digital Cinema Auto Calibration/ BRAVIA Sync/ Digital Media Port/ Black Finish', 199.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (281, 1, 'Denon Multi-Channel Digital Surround Sound Speaker System - DHTFS5', 'Denon Multi-Channel Digital Surround Sound Speaker System - DHTFS5/ Multiple Amplifier Channels/ Dolby Pro Logic II, Dolby Digital And DTS Surround/ Balanced Loudspeaker Drivers/ X-Space Surround Technology/ Night Mode/ Remote Control Included/ Black Finish', 499.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (282, 1, 'Danby White Countertop Dishwasher - DDW497WH', 'Danby White Countertop Dishwasher - DDW497WH/ 4 Place Settings/ Quick Connect To Any Kitchen Tap/ Automatic Detergent And Rinse Agent Dispenser/ Quiet Operation/ 5 Wash Cycles/ Durable Stainless Steel Spray Arm And Interior/ White Finish', 222.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (283, 1, 'Canon KP-36IP Color Ink & Paper Set - 7737A001', 'Canon KP-36IP Color Ink & Paper Set - 7737A001/ 36 Sheets Of 4'' x 6'' Photo Paper/ Ink Cartridge For Compatible Canon Dye Sublimation Printer', 12.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (284, 1, 'Linksys Ultra RangePlus Wireless-N Broadband Router - WRT160N', 'Linksys Ultra RangePlus Wireless-N Broadband Router - WRT160N/ Internet-Sharing Router/ 4-Port Switch/ Enhanced Wireless Access Point/ MIMO Technology/ Faster Than Wireless-G/ Protected By Wireless Encryption/ Powerful SPI Firewall/ 2 Antennas/ Glossy Black Finish', 79.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (285, 1, 'Pioneer USB iPod Interface Cable - CDIU230V', 'Pioneer USB iPod Interface Cable - CDIU230V/ Compatible With AVIC-F700BT And AVIC-F900BT Navigation Receivers', 48.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (286, 1, 'Canon White Selphy CP760 Compact Photo Printer - 2565B001', 'Canon White Selphy CP760 Compact Photo Printer - 2565B001/ 2.5'' TFT Display/ Portrait Image Optimize/ Print Water-Resistant Photos/ Print Directly From Your Memory Cards Or Bluetooth-Enabled Devices/ Big Buttons/ Automatic Red-Eye Correction/ White Finish', 95.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (287, 1, 'Sony 2GB Memory Stick Micro (M2) - MSA2GU2', 'Sony MSA2GD 2GB Memory Stick Micro (M2) - MSA2GU2/ Ultra-Small Size/ 2GB Storage Capacity With 1.85GB Available/ Designed For Use In Compatible Small Devices Such As Mobile Phone/ Dual Operating Voltage/ M2 Duo Adaptor Included/ Black Finish', 29.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (288, 1, 'Panasonic DECT 6.0 Silver Digital Cordless Handset - KXTGA630S', 'Panasonic DECT 6.0 Silver Digital Cordless Handset - KXTGA630S/ For Use With Panasonic 6300 And 9300 Series Phone Systems/ DECT 6.0 Technology/ 60 Channels/ Call Waiting Caller ID/ 1.4'' Amber Backlit LCD Display/ Wall Mountable/ 11 Days Standby Time/ 5 Hours Talk Time/ Silver Finish', 29.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (289, 1, 'Polk Audio White Round Two-Way In-Wall Loudspeaker - TC60I', 'Polk Audio White Round Two-Way In-Wall Loudspeaker - TC60I/ Dynamic Balance Polymer Composite Driver/ Aimable 1'' Silk Dome Tweeter With Neodymium Magnet/ 15-Degree Offset Drive Unit/ Wide Dispersion Design/ Durable, Moisture Resistant Materials/ Infinite Baffle Tuning/ Paintable, Powder-Coated Aluminum Grilles/ Conveniently Accessible Front Panel Controls/ Each Speaker Sold Seperately/ White Finish', 299.95); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (290, 1, 'Toshiba Black DVD/VCR Combinaton Player - SDV296', 'Toshiba Black DVD/VCR Combinaton Player - SDV296/ Progressive Scan DVD Player/ One Touch Recording For The VCR/ ColorStream Pro Progressive Scan Component Video Outputs/ Simultaneous DVD Playback And VHS Record/ JPEG Viewer/ Black Finish', 89.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (291, 1, 'Samsung 19'' Black Flat Panel Series 6 LCD HDTV - LN19A650', 'Samsung 19'' Black Flat Panel Series 6 LCD HDTV - LN19A650/ 1440 x 900 True 720p Resolution/ 3,000:1 Dynamic Contrast Ratio/ SRS TruSurround XT/ Built-In Digital Tuner (ATSC/Clear QAM)/ Wide Color Enhancer/ 8ms Response Time/ Touch Of Color Design/ Black With Red Finish', 499.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (292, 1, 'Samsung 22'' Black Flat Panel Series 6 LCD HDTV - LN22A650', 'Samsung 22'' Black Flat Panel Series 6 LCD HDTV - LN22A650/ 1680 x 1050 True 720p Resolution/ 5,000:1 Dynamic Contrast Ratio/ SRS TruSurround XT/ Built-In Digital Tuner (ATSC/Clear QAM)/ Wide Color Enhancer/ 8ms Response Time/ Touch Of Color Design/ Black With Red Finish', 599.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (293, 1, 'Canon Deluxe Burgundy Leather Case - 2350B001', 'Canon Deluxe Burgundy Leather Case - 2350B001/ Genuine Leather Case/ Designed For The PowerShot SD770 IS, SD1100 And SD1000/ Burgundy Finish', 18.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (294, 1, 'Canon Deluxe Black Digital Camera Case - 2595B002', 'Canon Deluxe Black Digital Camera Case - 2595B002/ Soft Nylon Case/ Flip-Down Cover/ Belt Loop Attachment For Hands-Free Convenience/ Compatible With Canon PowerShot A Series/ Black Finish', 13.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (295, 1, 'Griffin iPod RoadTrip With SmartScan - 4040RDTRPB', 'Griffin iPod RoadTrip With SmartScan - 4040RDTRPB/ Play Music From Your iPod On Your Car?s Stereo System As It Charges/ Switch Quickly Between Pre-Sets/ SmartSound Plus Technology Delivers Clear Sound Under Real-World Conditions/ Flexible Steel Neck/ Black Finish', 89.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (296, 1, 'Denon Black Home Theater Surround Sound Receiver - AVR1709', 'Denon Black AVR-1709 Home Theater Surround Sound Receiver - AVR1709/ 80 Watts Per Channel/ 7 Channels/ HDMI V1.3A Video Switching/ Dolby Digital Surround EX, Dolby Pro Logic IIx, DTS ES 6.1, DTS Neo:6 Decoding/ Audyssey MultEQ, Dynamic Volume And Dynamic EQ/ Video Up-Conversion/ Black Finish', 449.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (297, 1, 'Denon Black AVR-1609 Home Theater Surround Sound Receiver - AVR1609', 'Denon Black AVR-1609 Home Theater Surround Sound Receiver - AVR1609/ 75 Watts Per Channel/ 7 Channels/ HDMI V1.3A Video Switching/ Dolby Digital Surround EX, Dolby Pro Logic IIx, DTS ES 6.1, DTS Neo:6 Decoding/ Audyssey MultEQ, Dynamic Volume And Dynamic EQ/ Sirius Satellite Radio Ready/ Network And Digital Media Connectivity/ Black Finish', 349.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (298, 1, 'Sony Bud Style Headphones In Silver - MDRED12LPSLV', 'Sony Bud Style Headphones In Silver - MDRED12LPSLV/ 16mm Drivers/ Crisp Sound/ Neodymium Magnets Offer Powerful Sound Reproduction/ Convenient Cord Slider Reduces Tangles/ 3.9 Ft. Cord Length/ Frequency Response Of 8-22,000Hz/ Silver Finish', 14.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (299, 1, 'Sony Bud Style Headphones In Red - MDRED12LPRED', 'Sony Bud Style Headphones In Red - MDRED12LPRED/ 16mm Drivers/ Crisp Sound/ Neodymium Magnets Offer Powerful Sound Reproduction/ Convenient Cord Slider Reduces Tangles/ 3.9 Ft. Cord Length/ Frequency Response Of 8-22,000Hz/ Red Finish', 14.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (300, 1, 'Sony EX Ear Bud Headphones In Black - MDREX32LPBLK', 'Sony EX Ear Bud Headphones In Black - MDREX32LPBLK/ 9mm Drivers/ Deep Bass Sound/ Neodymium (400kJ/m3) Magnets Offer Powerful Bass Sound Reproduction/ 3.9 Ft. Cord Length/ Frequency Response Of 6-23,000Hz/ Black Finish', 24.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (301, 1, 'Sony EX Ear Bud Headphones In White - MDREX32LPWHI', 'Sony EX Ear Bud Headphones In White - MDREX32LPWHI/ 9mm Drivers/ Deep Bass Sound/ Neodymium (400kJ/m3) Magnets Offer Powerful Bass Sound Reproduction/ 3.9 Ft. Cord Length/ Frequency Response Of 6-23,000Hz/ White Finish', 24.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (302, 1, 'Griffin iPhone SmartTalk - 3016SMRTLKB', 'Griffin iPhone SmartTalk - 3016SMRTLKB/ Adds A Microphone And An iPhone Control Button To Your Favorite Earphones/ Play, Pause And Skip Through Your Tunes/ High-Sensitivity Microphone For Crystal-Clear Phone Conversations/ 30'' Cable Sheathed In Nylon Braiding', 19.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (303, 1, 'Logitech Driving Force Pro Steering Wheel With Pedals Set For Sony Playstation 2 - 9632930403', 'Logitech Driving Force Pro Steering Wheel With Pedals Set For Sony Playstation 2 - 9632930403/ Comfortable Soft Full Rubber Wheel/ Realistically Turn Through 2.5 Times Wheel Rotation/ 900 Degrees Of wheel Steering/ State-Of-The-Art Force Feedback Technology/ Stick Shifter/ Responsive Gas And Brake Pedals/ Black Finish', 129.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (304, 1, 'Monster iCarPlay Wireless 250 FM Transmitter With AutoScan for iPod And iPhone - AIPFMCH250', 'Monster iCarPlay Wireless 250 FM Transmitter With AutoScan For iPod And iPhone - AIPFMCH250/ Plays iPod Or iPhone Music Over Any Car Stereo/ Vibrant Sound/ Works With Any FM Car Radio/ 3 Programmable Presets/ FM Stations Range From 88.1 To 107.9/ Easy To Use/ Convenient Charging While You Drive/ Black Finish', 100.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (305, 1, 'D-Link Broadband Cable Modem - DCM202', 'D-Link Broadband Cable Modem - DCM202/ DOCSIS 2.0 CableLabs Certified/ High-Speed Internet Connectivity/ Always On And Always Connected/ Ethernet Or USB Connectivity/ Front Panel LED Indicator Lights/ Grey Finish', 79.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (306, 1, 'LaCie USB 2.0 Floppy Disk Drive - 706018', 'LaCie USB 2.0 Floppy Disk Drive - 706018/ Ultra-Thin Portable Design/ Compatible With Windows And Mac OS/ Plug And Play/ USB Powered/ 250 - 500 kbps Transfer Rate/ Silver Finish', 49.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (307, 1, 'Toshiba XDE Black 1080p Upconversion Extended Detail DVD Player - XDE500', 'Toshiba XDE Black 1080p Upconversion Extended Detail DVD Player - XDE500/ Full 1080p Upconversion With 24 Frames Per Second/ Detail Enhancement/ Intelligent Color/ Contrast Enhancement/ DivX Certified/ Black Finish', 99.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (308, 1, 'Griffin Black iPhone 3G Wave Case - 8227IP2WVB', 'Griffin Black iPhone 3G Wave Case - 8227IP2WVB/ Elegtant Wave-Shaped Closures/ Durable Polycarbonate Protection/ Rigid Touchscreen Protector/ Full Access To All Ports And Controls/ Black Finish', 24.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (309, 1, 'iHome iPod & iPhone Clock Radio & Audio System - IP99BR', 'iHome iP99 iPod & iPhone Clock Radio & Audio System - IP99BR/ Universal Dock For iPhone/ Auto-Set Clock/ Programmable Snooze/ Charges iPod Or iPhone While Docked/ Reason8 Speaker Chambers/ Line In Jack/ Full Function Remote Control Included/ Dual Alarm Clock/ Extra-Large LCD Display/ Black Finish (iPhone Not Included)', 149.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (310, 1, 'Transcend 8GB SDHC Card And Compact Card Reader - TS8GSDHC6S5W', 'Transcend 8GB SDHC Card And Compact Card Reader - TS8GSDHC6S5W/ SDHC Card Is Class 6 Compliant And Compatible With All SDHC-Labeled Host Devices/ Card Reader Is Fully Compatible With Hi Speed USB 2.0, Up To 480Mb/s And Supports SDHC Memory Cards', 26.30); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (311, 1, 'Denon 7.1 Channel AV Receiver With Network Client Compatible D-Dock Port In Black - AVR2809CI', 'Denon 7.1 Channel AV Home Theater Surround Receiver With Network Client Compatible D-Dock Port In Black - AVR2809CI/ 110 Watts x 7 Channels/ 1080p Upscaling/ PC Setup And Control Capability Via RS-232C/ Network Capable/ XM Satellite Radio Ready/ Dolby TrueHD And DTS-HD Master Audio/ HDMI 1.3a Repeater Inputs-Outputs/ Dual Remotes/ Black Finish', 1199.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (312, 1, 'LaCie Little Disk 320GB Black Portable Hard Drive - 301829', 'LaCie Little Disk 320GB Black Portable Hard Drive - 301829/ Compact, Thin And Lightweight Design/ Back Up, Synchronize And Secure Files And Settings/ Extractable Integrated USB Cable And Protective Cap/ Hi-Speed USB 2.0/ PC And Mac Compatible/ Black Finish', 119.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (313, 1, 'LaCie Little Disk 250GB Black Portable Hard Drive - 301278', 'LaCie Little Disk 250GB Black Portable Hard Drive - 301278/ Compact, Thin And Lightweight Design/ Back Up, Synchronize And Secure Files And Settings/ Extractable Integrated USB Cable And Protective Cap/ Hi-Speed USB 2.0/ PC And Mac Compatible/ Black Finish', 99.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (314, 1, 'AppleCare Protection Plan For iPod Touch Or iPod Classic - MB591LLA', 'AppleCare Protection Plan For iPod Touch Or iPod Classic - MB591LLA/ Extends Your Service Coverage To Up To Two Years/ Includes Both Phone And In Store Techinical Support', 59.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (315, 1, 'Nikon CoolPix S610 10 Megapixel Black Digital Camera - COOLPIXS610BK', 'Nikon CoolPix S610 10 Megapixel Black Digital Camera - COOLPIXS610BK/ 10.0 Megapixels/ 4x Zoom-NIKKOR Lens/ 3.0'' High-Resolution Wide-Viewing Angle LCD Monitor/ Scene Auto Selector/ Active Child Mode/ Smile And Food Mode/ Face-Priority AF/ In-Camera Red-Eye Fix/ D-Lighting/ Midnight Black Finish', 249.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (316, 1, 'Sony VAIO Black USB Docking Station - VGPUPR1', 'Sony VAIO Black USB Docking Station - VGPUPR1/ Perfect For The Constant Traveler Or Mobile Professional/ Easily Connect All Of Necessary Peripherals/ VGA Port/ 4 USB Ports/ Ethernet Port/ Headphone And Microphone Ports/ Compatible With VAIO CR Series, FZ Series, FW Series, NR Series And AR Series Notebooks/ Black Finish', 199.99); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (317, 1, 'Nikon SB-900 AF Speedlight In Black - SB900', 'Nikon AF Speedlight In Black - SB900/ Wireless Commander Mode/ Control Up To Three Remote/ 3 Light Distribution Patterns/ Flash Tube Overheat Protection/ Drip-Proof Mounting Foot Cover (Water Guard)/ Color Gel Filter Identification/ Black Finish', 499.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (318, 1, 'Denon D-M37 Black CD/AM/FM Micro System - DM37SBK', 'Denon D-M37 Black CD/AM/FM Micro System - DM37SBK/ 30 Watts x 2 Amplifier/ Precision Burr-Brown Audiophile Quality DACs/ MP3 And WMA Tracks Playback Capability/ European Engineered Loudspeakers/ 120mm Long-Throw D.D.L Double-Layered Cone Woofer/ 25mm Soft Dome Tweeter With Extended Response/ Triadic Noise Reduction Concept/ Portable Player Connectivity/ Black Finish', 399.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (319, 1, 'Griffin iPhone 3G Black Elan Form Hard-Shell Leather Case - 8223IP2EFRMB', 'Griffin iPhone 3G Black Elan Form Hard-Shell Leather Case - 8223IP2EFRMB/ Top-Grain Outer Shell Crafted From Hand-Matched Leather/ Protective Polycarbonate Inner Shell/ Easy Access To Controls/ Includes Stiff Polycarbonate Screen Protector & Premium Cleaning Cloth/ Black Finish (iPhone Not Included)', 24.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (320, 1, 'Speck Black ToughSkin Case For iPhone 3G - IPH3GBLKTS', 'Speck Black ToughSkin Case For iPhone 3G - IPH3GBLKTS/ Tough, Textured And Ruggedized Protection/ Bottom Hinges Open To Allow Docking/ Thicker Corners For Extra Protection/ Removable Rotating Belt Clip/ Lightweight Design/ Easy Access To All Ports & Controls/ Black Finish (iPhone Not Included)', 34.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (321, 1, 'Canon PIXMA iP2600 Photo Printer - IP2600', 'Canon PIXMA Photo Printer - IP2600/ 4800 x 1200 Color dpi/ Spectacular Resolution/ Fast Photo Printing/ FINE Technology/ 1,472 Precision Nozzles/ Auto Image Fix/ Easy-PhotoPrint EX Software/ 4 In 1 Or 2 In 1 Printing/ Energy Star Qualified/ Borderless 4'' x 6'' Print Approx. 55 Seconds/ Windows And Mac Compatible', 49.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (322, 1, 'Klipsch 5.25'' THX Ultra2 In-Ceiling White Loudspeaker - KS7502THX', 'Klipsch 5.25'' THX Ultra2 In-Ceiling White Loudspeaker - KS7502THX/ 100W Continuous/400W Peak Power Handling/ Dual 1'' Titanium Diaphragm Compression Drivers Mated To WDST Tractrix Horn Array/ Dual 5.25'' High-Output Cerametallic Cone Woofers/ MDF And Aluminum Motorboard/ABS Shell Enclosure/ White Finish/ Price Per Speaker', 1000.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (323, 1, 'Canon PIXMA Photo All-In-One Printer - MP620', 'Canon PIXMA Photo All-In-One Printer - MP620/ High Performance Printer And Copier, Scanner/ Easy Scroll Wheel/ Dual Paper Trays/ 2.5'' High Definition LCD Display/ Maximum 9600 x 2400 Color Dpi/ Automatic Image Optimization/ Quick Start/ Wi-Fi Ready/ Built-In Media Card Slot/ ENERGY STAR Qualified', 149.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (324, 1, 'TiVo HD XL Black Digital Video Recorder - TCD658000', 'TiVo HD XL Black Digital Video Recorder - TCD658000/ Search, Record And Watch Shows In HD/ Save Up To 150 Hours Of HD Programming At A Time/ Control Cable TV With Pause, Rewind, Fast-Forward, And Slow-Motion/ Record Two Shows At Once In HD/ Digital Transition Ready/ Backlit Remote Control/ Netflix Instant Streaming/ TiVo Service Required And Sold Separately', 599.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (325, 1, 'Apple 8GB Black 2nd Generation iPod Touch - MB528LLA', 'Apple 8GB Black 2nd Generation iPod Touch - MB528LLA/ Holds Up To 1,750 Songs In 128-Kbps AAC Format, 10,000 iPod-Viewable Photos And 10 Hours Of Video/ Wi-Fi (802.11b/g)/ Nike + iPod Support Built-In/ Maps Location-Based Service/ 3.5'' (Diagonal) Widescreen Multi-Touch Display/ 480x320-Pixel Resolution/ 480p And 576p Component TV Out/ Mac And Windows Compatible/ Black Finish', 229.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (326, 1, 'Apple 16GB Black 2nd Generation iPod Touch - MB531LLA', 'Apple 16GB Black 2nd Generation iPod Touch - MB531LLA/ Holds Up To 3,500 Songs In 128-Kbps AAC Format, 20,000 iPod-Viewable Photos And 20 Hours Of Video/ Wi-Fi (802.11b/g)/ Nike + iPod Support Built-In/ Maps Location-Based Service/ 3.5'' (Diagonal) Widescreen Multi-Touch Display/ 480x320-Pixel Resolution/ 480p And 576p Component TV Out/ Mac And Windows Compatible/ Black Finish', 299.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (327, 1, 'Apple 32GB Black 2nd Generation iPod Touch - MB533LLA', 'Apple 32GB Black 2nd Generation iPod Touch - MB533LLA/ Holds Up To 7,000 Songs In 128-Kbps AAC Format, 25,000 iPod-Viewable Photos And 40 Hours Of Video/ Wi-Fi (802.11b/g)/ Nike + iPod Support Built-In/ Maps Location-Based Service/ 3.5'' (Diagonal) Widescreen Multi-Touch Display/ 480x320-Pixel Resolution/ 480p And 576p Component TV Out/ Mac And Windows Compatible/ Black Finish', 399.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (328, 1, 'Apple 8GB Silver 4th Generation iPod Nano - MB598LLA', 'Apple 8GB Silver 4th Generation iPod Nano - MB598LLA/ Holds Up To 2,000 Songs In 128-Kbps AAC Format, 7,000 iPod-Viewable Photos And 8 Hours Of Video/ 2'' (Diagonal) Liquid Crystal Display With Blue-White LED Backlight/ 320-By-240-Pixel Resolution/ Give It A Shake To Shuffle Your Music/ Turn It Sideways To View Cover Flow/ Mac And Windows Compatible/ Silver Finish', 144.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (329, 1, 'Apple 8GB Blue 4th Generation iPod Nano - MB732LLA', 'Apple 8GB Blue 4th Generation iPod Nano - MB732LLA/ Holds Up To 2,000 Songs In 128-Kbps AAC Format, 7,000 iPod-Viewable Photos And 8 Hours Of Video/ 2'' (Diagonal) Liquid Crystal Display With Blue-White LED Backlight/ 320-By-240-Pixel Resolution/ Give It A Shake To Shuffle Your Music/ Turn It Sideways To View Cover Flow/ Mac And Windows Compatible/ Blue Finish', 149.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (330, 1, 'Apple 8GB Pink 4th Generation iPod Nano - MB735LLA', 'Apple 8GB Pink 4th Generation iPod Nano - MB735LLA/ Holds Up To 2,000 Songs In 128-Kbps AAC Format, 7,000 iPod-Viewable Photos And 8 Hours Of Video/ 2'' (Diagonal) Liquid Crystal Display With Blue-White LED Backlight/ 320-By-240-Pixel Resolution/ Give It A Shake To Shuffle Your Music/ Turn It Sideways To View Cover Flow/ Mac And Windows Compatible/ Pink Finish', 144.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (331, 1, 'Apple 8GB Purple 4th Generation iPod Nano - MB739LLA', 'Apple 8GB Purple 4th Generation iPod Nano - MB739LLA/ Holds Up To 2,000 Songs In 128-Kbps AAC Format, 7,000 iPod-Viewable Photos And 8 Hours Of Video/ 2'' (Diagonal) Liquid Crystal Display With Blue-White LED Backlight/ 320-By-240-Pixel Resolution/ Give It A Shake To Shuffle Your Music/ Turn It Sideways To View Cover Flow/ Mac And Windows Compatible/ Purple Finish', 149.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (332, 1, 'Apple 8GB Green 4th Generation iPod Nano - MB745LLA', 'Apple 8GB Green 4th Generation iPod Nano - MB745LLA/ Holds Up To 2,000 Songs In 128-Kbps AAC Format, 7,000 iPod-Viewable Photos And 8 Hours Of Video/ 2'' (Diagonal) Liquid Crystal Display With Blue-White LED Backlight/ 320-By-240-Pixel Resolution/ Give It A Shake To Shuffle Your Music/ Turn It Sideways To View Cover Flow/ Mac And Windows Compatible/ Green Finish', 149.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (333, 1, 'Apple 8GB Black 4th Generation iPod Nano - MB754LLA', 'Apple 8GB Black 4th Generation iPod Nano - MB754LLA/ Holds Up To 2,000 Songs In 128-Kbps AAC Format, 7,000 iPod-Viewable Photos And 8 Hours Of Video/ 2'' (Diagonal) Liquid Crystal Display With Blue-White LED Backlight/ 320-By-240-Pixel Resolution/ Give It A Shake To Shuffle Your Music/ Turn It Sideways To View Cover Flow/ Mac And Windows Compatible/ Black Finish', 144.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (334, 1, 'Apple 1GB Pink 2nd Generation iPod Shuffle - MB811LLA', 'Apple 1GB Pink 2nd Generation iPod Shuffle - MB811LLA/ Holds Up To 240 Songs In 128-Kbps AAC Format/ 12 Hours Of Continuous Playback/ Skip-Free Playback/ Battery Indicator/ Shuffle Switch/ Built-In Clip/ Mac And Windows Compatible/ Pink Finish', 49.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (335, 1, 'Sony BRAVIA Black SXRD 1080p Home Theater Front Projector - VPLHW10', 'Sony BRAVIA Black SXRD 1080p Home Theater Front Projector - VPLHW10/ SXRD 1920 x 1080p Full HD Panels/ 30,000:1 Dynamic Contrast Ratio/ Fully Digital Signal Processing/ 200Watts Ultra-High-Pressure Lamp/ Whisper-Quiet Fan Noise And Noise Reduction Function/ Two HDMI Inputs/ BRAVIA Theatre Sync/ Remote Commander/ Black Finish', 3499.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (336, 1, 'Canon PIXMA Black Photo Printer - IP4600', 'Canon PIXMA Black Photo Printer - IP4600/ Premium Printer With Individual Ink Tanks And Built-In Auto Duplex/ Print 4'' x 6'' Photo In 20 Seconds/ Dual Paper Trays/ Maximum 9600 x 2400 Color Dpi/ Automatic Image Optimization/ ENERGY STAR Qualified/ Black Finish', 99.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (337, 1, 'Canon PIXMA Photo All-In-One Printer - MP980', 'Canon PIXMA Photo All-In-One Printer - MP980/ High Performance Wireless Printer, Copier And Scanner/ Easy Scroll Wheel/ 3.5'' High Definition LCD Display/ Maximum 9600 x 2400 Color Dpi/ Six Individual Inks Tanks/ Auto Duplex Print/ Smart Copying/ Automatic Image Optimization/ No Warm-Up/ ENERGY STAR Qualified', 299.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (338, 1, 'Nintendo DS Lite Cobalt/Black Portable Gaming System - NDSUSGBMKB', 'Nintendo DS Lite Cobalt/Black Portable Gaming System - NDSUSGBMKB/ Dual 3'' TFT Color LCD Touchscreens/ Slimmer Design/ Dual Slot Compatibility (DS Lite/Game Boy Advance Game Paks)/ Twin Ultra Bright LCD Screens/ Up To 19 Hours Continuous Gameplay/ Nintendo Wi-Fi Connection/ Impressive 3D Graphics/ Dual Stereo Speakers/ Cobalt and Black Finish', 139.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (339, 1, 'Nintendo DS Lite Onyx Black Portable Gaming System - NDSUSGSKB', 'Nintendo DS Lite Onyx Black Portable Gaming System - NDSUSGSKB/ Dual 3'' TFT Color LCD Touchscreens/ Slimmer Design/ Dual Slot Compatibility (DS Lite/Game Boy Advance Game Paks)/ Twin Ultra Bright LCD Screens/ Up To 19 Hours Continuous Gameplay/ Nintendo Wi-Fi Connection/ Impressive 3D Graphics/ Dual Stereo Speakers/ Onyx Black Finish', 139.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (340, 1, 'Nintendo DS Lite Metallic Silver Portable Gaming System - NDSUSGSVB', 'Nintendo DS Lite Metallic Silver Portable Gaming System - NDSUSGSVB/ Dual 3'' TFT Color LCD Touchscreens/ Slimmer Design/ Dual Slot Compatibility (DS Lite/Game Boy Advance Game Paks)/ Twin Ultra Bright LCD Screens/ Up To 19 Hours Continuous Gameplay/ Nintendo Wi-Fi Connection/ Impressive 3D Graphics/ Dual Stereo Speakers/ Metallic Silver Finish', 139.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (341, 1, 'Nintendo DS Lite Metallic Rose Portable Gaming System - NDSUSGSZPB', 'Nintendo DS Lite Metallic Rose Portable Gaming System - NDSUSGSZPB/ Dual 3'' TFT Color LCD Touchscreens/ Slimmer Design/ Dual Slot Compatibility (DS Lite/Game Boy Advance Game Paks)/ Twin Ultra Bright LCD Screens/ Up To 19 Hours Continuous Gameplay/ Nintendo Wi-Fi Connection/ Impressive 3D Graphics/ Dual Stereo Speakers/ Metallic Rose Finish', 139.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (342, 1, 'Case Logic Vertical Universal Leather BlackBerry Case - CLP104BB', 'Case Logic Vertical Universal Leather BlackBerry Case - CLP104BB/ 360 Degree Swivel Belt Clip/ Magnetic Closure/ Soft Internal Lining/ Expandable Elastic Sides/ Compatible With Most BlackBerrys/ Leather Fabric/ Black Finish', 15.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (343, 1, 'Nintendo DS Lite Crimson/Black Portable Gaming System - NDSUSGSRMKB', 'Nintendo DS Lite Crimson/Black Portable Gaming System - NDSUSGSRMKB/ Dual 3'' TFT Color LCD Touchscreens/ Slimmer Design/ Dual Slot Compatibility (DS Lite/Game Boy Advance Game Paks)/ Twin Ultra Bright LCD Screens/ Up To 19 Hours Continuous Gameplay/ Nintendo Wi-Fi Connection/ Impressive 3D Graphics/ Dual Stereo Speakers/ Crimson/Black Finish', 139.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (344, 1, 'BlueAnt Bluetooth Voice Control Headset - V1', 'BlueAnt Bluetooth Voice Control Headset - V1/ Voice Control User Interface/ Voice Isolation Technology/ Dual Microphones/ Pairs With Up To 8 Bluetooth Devices/ Up To 5 Hours Talk-Time/ 3 Charging Options', 119.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (345, 1, 'Netgear Prosafe 5 Port Gigabit Ethernet Desktop Switch - GS105NA', 'Netgear Prosafe 5 Port Gigabit Ethernet Desktop Switch - GS105NA/ Auto-Switching Ethernet Connection/ Supports Windows And Macintosh Platforms/ Dual Color LEDs/ AutoUplink Technology/ Compact Metal Case/ Fanless Design/ Plug-And-Play Installation', 55.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (346, 1, 'Jabra Bluetooth Headset - BT2070', 'Jabra Bluetooth Headset - BT2070/ Up To 5.5 Hours Talk Time/ Up To 200 Hours Standby Time/ Earhook Included/ Bluetooth 2.0+ EDR & eSCO Technology/ Auto-Pairing/ Discreet Light/ Answer/End, Redial And Voice Dial Features/ USB Micro-B, 5-Pin Charging Plug', 49.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (347, 1, 'Canon Printer Ink Cartridge 4 Colors Pack - 2946B004', 'Canon Printer Ink Cartridge 4 Colors Pack - 2946B004/ FINE Technology For Exceptional Sharpness And Detail/ Compatible With PIXMA iP3600, PIXMA iP4600, PIXMA MP620 And PIXMA MP980/ Includes 4 Ink Tanks (Black, Cyan, Magenta, Yellow)', 47.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (348, 1, 'Canon PIXMA Photo All-In-One Printer - MP480', 'Canon PIXMA Photo All-In-One Printer - MP480/ High Performance Printer, Copier And Scanner/ 1.8'' TFT Display/ Maximum 2400 x 4800 Color Dpi/ Smart Scanning/ Quick Start/ Built-In Media Card Slot/ ENERGY STAR Qualified', 99.00); -INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (349, 1, 'Sanus 30'' - 58'' VisionMount Flat Panel TV Black Tilting Wall Mount - LT25B1', 'Sanus 30'' - 58'' VisionMount Flat Panel TV Black Tilting Wall Mount - LT25B1/ Lateral Shift Adjustment/ Virtual Axis/ Height and Level Adjustments/ ClickStand/ ClickFit System/ Open Wall Plate/ Black Finish', 199.00); +-- Products 350 entries from https://github.com/etano/productner/blob/master/Product%20Dataset.csv +-- Original source: Justifying recommendations using distantly-labeled reviews and fined-grained aspects, Jianmo Ni, Jiacheng Li, Julian McAuley, Empirical Methods in Natural Language Processing (EMNLP), 2019ss +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (0, 1, 'Bose Acoustimass 5 Series III Speaker System - AM53BK', 'Bose Acoustimass 5 Series III Speaker System - AM53BK/ 2 Dual Cube Speakers With Two 2-1/2'' Wide-range Drivers In Each Speaker/ Powerful Bass Module With Two 5-1/2'' Woofers/ 200 Watts Max Power/ Black Finish', 399.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (1, 1, 'Sony Switcher - SBV40S', 'Sony Switcher - SBV40S/ Eliminates Disconnecting And Reconnecting Cables/ Compact Design/ 4 A/V Inputs With S-Video Jacks/ 1 A/V Output With S-Video (Y/C)Jack/ 2 Audio Output', 49.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (2, 1, 'Bose 27028 161 Bookshelf Pair Speakers In White - 161WH', 'Bose 161 Bookshelf Speakers In White - 161WH/ Articulated Array Speaker Design/ High-Excursion Twiddler Drivers/ Magnetically Shielded/ Priced Per Pair/ White Finish', 158.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (3, 1, 'Denon Stereo Tuner - TU1500RD', 'Denon Stereo Tuner - TU1500RD/ RDS Radio Data System/ AM-FM 40 Station Random Memory/ Rotary Tuning Knob/ Dot Matrix FL Display/ Optional Remote', 375.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (4, 1, 'Panasonic Integrated Telephone System - KXTS108W', 'Panasonic Integrated Telephone System - KXTS108W/ 16 Digit LCD With Clock/ Hands Free Speakerphone/ Built-In Data Port/ 10-Station One-Touch Dialing/ 3-Step Ringer Volume/ White Finish', 44.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (5, 1, 'Panasonic Hands-Free Headset - KXTCA86', 'Panasonic Hands-Free Headset - KXTCA86/ Comfort Fit And Fold Design/ Noise Cancelling Microphone/ Standard 2.5mm Connection', 14.95); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (6, 1, 'Panasonic Hands Free Headset - KXTCA92', 'Panasonic Hands Free Headset - KXTCA92/ Comfort Fit With Fold Design/ Noise Cancelling Microphone/ Volume Control/ Mute/ Standard 2.5mm Connection', 25.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (7, 1, 'Cuisinart Convection-Oven-Toaster-Broiler With Exact Heat Sensor - TOB165WH', 'Cuisinart Convection-Oven-Toaster-Broiler With Exact Heat Sensor - TOB165WH/ 0.5 Cubic Foot Oven Capacity/ LED Indicators/ Individual Or Combination Settings/ Always Even Shade Control/ 4 Hour Automatic Shut Off/ Slide-Out Crumb Tray/ Includes Broiling Pan/ White Finish', 149.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (8, 1, 'Frigidaire 24'' White Built-In Dishwasher - FDB130WH', 'Frigidaire 24'' FDB130RGS White Built-In Dishwasher - FDB130WH/ Convection Drying System/ QuietSound Sound Insulation Package/ 2 Wash Levels/ Adjustable Rinse Aid Dispenser/ Self Cleaning Filter/ White Finish', 229.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (9, 1, 'Cuisinart Cordless Electric Kettle - KUA17', 'Cuisinart Cordless Electric Kettle - KUA17/ 1-3/4 Quart Capacity/ Automatic Shut-Off/ Indicator Light/ Splash Guard Spout/ Cord Storage In Base/ Chrome Finish', 70.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (10, 1, 'Omnimount Wall Speaker Mount - 20WLBK', 'Omnimount Wall Speaker Mount - 20WLBK/ Stainless Steel Shafts And All Necessary Hardware Included/ Supports Speakers Up To 20 lbs./ Sold As Single / Black Finish', 39.95); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (11, 1, 'Omnimount Wall Speaker Mount - 20WLWH', 'Omnimount Wall Speaker Mount - 20WLWH/ Stainless Steel Shafts And All Necessary Hardware Included/ Supports Speakers Up To 20 lbs./ Sold as each / White Finish (Photo Showing Black)', 40.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (12, 1, 'Denon Semi-Automatic Turntable - Black Finish - DP29F', 'Denon Semi-Automatic Turntable - DP29F/ Metal Platter/ Built-In RIAA Equalizer/ DC Servo Motor/ 2 Speed 33 + 45 RPM/ Built-In Phono PreAmp', 150.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (13, 1, 'Escort Passport Radar And Laser Detector - Black Finish - 8500', 'Escort Passport X50 Radar And Laser Detector - 8500/ X-Band, K-Band, Ka-Band Operating Bands/ AlGaAs 280 LED Matrix/Text Display Type/ 3-Level Dimming, Plus Dark Mode/ Auto Mute/ City Mode Sensitivity/ Compact Size/ Red Display', 313.95); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (14, 1, 'Sony Compact Disc Player/Recorder - RCDW500C', 'Sony Compact Disc Player/Recorder - RCDW500C/ 5-CD/Dual Deck With 4x High Speed Dubbing/ CD, CD-R, CD-RW, MP3 Playback Capable/ Super Bit Mapping Recording/ High Speed Finalizing', 299.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (15, 1, 'Sanus WMS3B Black Weather Resistant Small Speaker Wall Mount - WMS3B', 'Sanus WMS3B Black Small Speaker Wall Mount - WMS3B/ Holds Up To An 8 Pound Speaker/ Multiple Pivot Points/ Weather Resistant For Indoor/Outdoor Use/ Black Finish/ Priced Per Pair', 29.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (16, 1, 'Sanus WMS3S Silver Weather Resistant Small Speaker Wall Mount - WMS3S', 'Sanus WMS3S Silver Small Speaker Wall Mount - WMS3S/ Holds Up To An 8 Pound Speaker/ Multiple Pivot Points/ Weather Resistant For Indoor/Outdoor Use/ Silver Finish/ Priced Per Pair', 29.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (17, 1, 'Sanus Euro Foundations Satellite Speaker Stand - EFSATB', 'Sanus Euro Foundations Satellite Speaker Stand - EFSATB/ Sturdy Base/ Adjustable Pillar And Floor Spikes/ Includes Three Different Speaker Mounting Methods/ Contemporary European Design/ Satin Powder-Coated Black Finish/ Priced Per Pair', 79.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (18, 1, 'Sanus Euro Foundations Satellite Speaker Stand - EFSATS', 'Sanus Euro Foundations Satellite Speaker Stand - EFSATS/ Sturdy Base/ Adjustable Pillar And Floor Spikes/ Includes Three Different Speaker Mounting Methods/ Contemporary European Design/ Satin Powder-Coated Silver Finish/ Priced Per Pair', 79.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (19, 1, 'Escort Cordless Solo Radar Detector - S2E', 'Escort Cordless Solo Radar Detector - S2E/ S2/ 10 Programmable Features/ High-Efficiency Power Management/ Ultra-Performance Laser Protection/ AutoSensitivity Mode/ High Resolution Graphic LCD Display/ Built-In Earphone Jack', 343.95); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (20, 1, 'Kenwood 6-Disc CD Changer - KDCC669', 'Kenwood 6-Disc CD Changer - KDCC669/ 3-Angle Mounting/ CD, CD-R And CD-RW Playback/ Anti-Vibration Disc Transport/ Compatible With All Kenwood Units With Changer Control', 129.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (21, 1, 'Cuisinart Automatic Brew And Serve Coffeemaker - DTC975BK', 'Cuisinart Automatic Brew And Serve Coffeemaker - DTC975BK/ 12-Cup Double-Wall Insulated Stainless Steel Carafe/ Fully Automatic With 24-Hour Programmability/ Patented Brew-Through And Pour-Through Lid/ Brew Pause Feature/ Automatic Shutoff/ Black And Stainless Steel Finish', 99.95); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (22, 1, 'Sharp Over The Counter Microwave Oven - R1214SS', 'Sharp Over The Counter Microwave Oven - R1214SS/ 1.5 Cubic Foot Capacity/ 1100 Watts/ 24 Automatic Settings/ 2-Color Lighted LCD/ Smart And Easy Sensor Settings/ Auto-Touch Control Panel/ Stainless Steel Finish', 429.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (23, 1, 'Toshiba Rechargeable 5-Hour Battery Pack - MEDB05LX', 'Toshiba Rechargeable 5-Hour Battery Pack - MEDB05LX/ Works With SDP2500 And SDP2600 Portable DVD Players', 149.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (24, 1, 'Sony Super Audio CD Player - SCDCE595', 'Sony Super Audio CD Player - SCDCE595/ Multi-Channel Super Audio CD Playback Capability/ CD/CD-R/CD-RW Playback Capability/ Multi-Channel Direct Stream Digitial Decoder/ Multi-Channel Management System/ SACD Text/CD Text Capability/ ETA LATE JANUARY 2009', 149.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (25, 1, 'Delonghi Twenty Four Seven Coffee Maker In Black - DC50B', 'Delonghi Twenty Four Seven Coffee Maker - DC50B/ 4-Cup Capacity/ Easy-Access, Washable Filter Basket/ Black Finish', 22.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (26, 1, 'Sanus Silver LCD Television Turntable - TVLCDS', 'Sanus Silver LCD Television Turntable - TVLCDS/ Holds 13''-30'' Size Televisions/ 360 Degree Rotation/ Silver Finish', 29.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (27, 1, 'Delonghi Twenty Four Seven Coffee Maker - DC50W', 'Delonghi Twenty Four Seven Coffee Maker - DC50W/ 4-Cup Capacity/ Easy-Access, Washable Filter Basket/ White Finish', 22.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (28, 1, 'Universal IR/RF Remote - MX350', 'Universal IR/RF Remote - MX350/ Controls Up To 10 Components/ Extensive Macro Programming/ Memory Back-Up/ One Hand Ergonomics', 149.95); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (29, 1, 'Universal IR/RF Aeros Remote Control- MX850 - MX850', 'Universal IR/RF Aeros Remote Control- MX850/ Laser Etched Buttons/ Centrally Located Joystick/ Memory Back-Up/ One Hand Ergonomics/ Controls Up To 20 Components', 399.95); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (30, 1, 'Panasonic 5-Pack DVD-RAM Discs - LMAF120LU5', 'Panasonic 5-Pack DVD-RAM Discs - LMAF120LU5/ Slim Cases/ 2-3x Speed/ Single-Sided/ 120 Minute (4.7GB/Non-Cartridge)/ For Video Recording/ 5 Pack', 15.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (31, 1, 'Sanus 13'' - 30'' VisionMount Flat Panel TV Silver Wall Mount - VMFS', 'Sanus 13'' - 30'' VisionMount Flat Panel TV Silver Wall Mount - VMFS/ Supports Up To 40 lbs/ Easy To Install/ Fingertip Virtual Axis Tilting System/ Silver Finish', 39.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (32, 1, 'Weber Performer 22-1/2'' Charcoal Grill - 841001', 'Weber Performer 22-1/2'' Charcoal Grill - 841001/ Push-Button Igniter/ Porcelain-Enameled Bowl And Lid/ Dual-Purpose Themometer/ Crackproof All-Weather Wheels/ Black Lid Finish/ Assembly Required', 329.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (33, 1, 'Sanus 13'' - 30'' Flat Panel TV Black Wall Mount - VM1B', 'Sanus 13'' - 30'' Flat Panel TV Black Wall Mount - VM1B/ Tilt And Swivel Motion/ Rigid Extruded Aluminum Construction/ Supports Up To 50 Lbs/ Black Finish', 69.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (34, 1, 'Sanus 15'' - 40'' Flat Panel TV Silver Wall Mount - VM400S', 'Sanus 15'' - 40'' Flat Panel TV Silver Wall Mount - VM400S/ Virtual Axis Tilt Adjustment System/ Hinged Arm Extend From 3.5'' To 20''/ Durable Powder Coated Silver Finish', 219.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (35, 1, 'Delonghi Oil Filters - FK8', 'Delonghi Oil Filters - FK8/ Made For Use With D895UX/ 3 Pack', 18.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (36, 1, 'Weber Performer 22-1/2'' Charcoal Grill - 848001', 'Weber Performer 22-1/2'' Charcoal Grill - 848001/ Push-Button Igniter/ Porcelain-Enameled Bowl And Lid/ Dual-Purpose Themometer/ Crackproof All-Weather Wheels/ Blue Lid Finish/ Assembly Required', 329.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (37, 1, 'Whirlpool 24'' Built-In Dishwasher - DU1055BK', 'Whirlpool 24'' Built-In Dishwasher - DU1055BK/ 14-Five Piece Place Setting Super Capacity Tub/ 5 Level Direct Feed SheerClean Wash System/ 4 Cycles/ AnyWare Plus Silverware Basket/ Quiet Partner I Sound Package/ Energy Star Qualified/ Black Finish', 397.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (38, 1, 'Whirlpool 24'' Built-In Dishwasher - DU1055SS', 'Whirlpool 24'' Built-In Dishwasher - DU1055SS/ 14-Five Piece Place Setting Super Capacity Tub/ 5 Level Direct Feed SheerClean Wash System/ 4 Cycles/ Soak And Scour Option/ AnyWare Plus Silverware Basket/ Quiet Partner I Sound Package/ Energy Star Qualified/ Black On Stainless Finish', 491.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (39, 1, 'Sony Soft Cyber-Shot Carrying Case - LCSCST', 'Sony Soft Cyber-Shot Carrying Case - LCSCST/ Sturdy Nylon Construction/ Compact And Very Lightweight/ Stylish Black Design', 14.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (40, 1, 'Pioneer XM Digital Satellite Tuner for Pioneer Headunits - GEXP920XM', 'Pioneer XM Digital Satellite Tuner For Pioneer Headunits - GEXP920XM/ SAT Radio Ready/ XM Ready/ Built-In FM Modulator/ 18- Station/ 6- Button Presets/ Magne Mount Installation', 98.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (41, 1, 'Sanus Universal Projector Ceiling Mount - Black Finish - VMPR1B', 'Sanus Universal Projector Ceiling Mount - VMPR1B/ Designed For DLP And LCD Projectors/ Quick Release Mechanism/ 50 Lbs Capacity/ Black Finish', 129.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (42, 1, 'Kenwood iPod Mobile Interface - KCAIP500', 'Kenwood iPod Mobile Interface - KCAIP500/ Compatible With Most Kenwood Receivers/ Text Display, Multiple Search Mode/ Powers And Charges iPod', 49.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (43, 1, 'Pioneer Wired Marine Remote Control Display - CDMR80D', 'Pioneer Wired Marine Remote Control Display - CDMR80D/ Compatible With Pioneer Headunits/ Satellite Radio Text Indications/ ATT (Volume Attenuator) Button', 149.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (44, 1, 'Bose Second Zone Remote - PMC2', 'Bose Second Zone Remote - PMC2/ Controls Lifestyle 38 Or 48 Media Center/ TV, VCR, Cable Box, Satellite Receiver/ Accesses Digitally Stored CDs In UMusic System', 149.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (45, 1, 'Sony DVD-R Recordable Camcorder Media - 3DMR30L1H', 'Sony DVD-R Recordable Camcorder Media 3 Pack - 3DMR30L1H/ 30 Minute, 1.4 GB/ Accucore Technology/ Store Digital Video, Audio And Multimedia Files/ 3 Pack', 9.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (46, 1, 'Sony VAIO Neoprene Laptop Carrying Case - Black Finish - VGPAMC3', 'Sony VAIO Neoprene Laptop Carrying Case - VGPAMC3/ Compatible With VAIO A Series 15'' And FS Series 15.4'' Widescreen Notebooks/ Helps Protect Your Notebook From Scratches, Spills And Dings/ Neoprene Offers Durable And Water-Resistant Protection', 22.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (47, 1, 'Canon Color Ink Tank - CL41CL', 'Canon Color Ink Tank - CL41CL/ Compatible With The Pixma iP1600, MP170 Printers', 24.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (48, 1, 'Canon Cyan Ink Tank - Cyan - CLI8C', 'Canon Cyan Ink Tank - CLI8C/ Compatible With The Pixma iP4200, iP5200, iP5200R, iP6600D, MP500, MP800 Printers', 16.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (49, 1, 'Canon Magenta Ink Tank - Magenta - CLI8M', 'Canon Magenta Ink Tank - CLI8M/ Compatible With The Pixma iP4200, iP5200, iP5200R, iP6600D, MP500, MP800 Printers', 16.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (50, 1, 'Canon Cyan Photo Ink Cartridge - Cyan - CLI8PC', 'Canon Cyan Photo Ink Cartridge - CLI8PC/ Compatible With The Pixma iP6600D Printer', 16.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (51, 1, 'Canon Magenta Photo Ink Cartridge - Magenta - CLI8PM', 'Canon Magenta Photo Ink Cartridge - CLI8PM/ Compatible With The Pixma iP6600D Printer', 16.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (52, 1, 'Canon Yellow Ink Cartridge - Yellow - CLI8Y', 'Canon Yellow Ink Cartridge - CLI8Y/ Compatible With The Pixma iP4200, iP5200, iP5200R, iP6600D, MP500, MP800 Printers', 16.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (53, 1, 'Canon Black Ink Cartridge - Black - PG40BK', 'Canon Black Ink Cartridge - PG40BK/ Compatible With The Pixma iP1600, MP170 Printers', 19.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (54, 1, 'Pioneer Voice Command Pack - Black Finish - CDVC1', 'Pioneer Voice Command Pack - CDVC1/ Microphone And Steering Wheel Remote Control/ Use Your Voice To Control Navigation, Audio, And Video Functions/ Compatible With AVICN2 And AVICN1', 48.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (55, 1, 'Sony VAIO Neoprene Notebook With AC Adapter Case - Black Finish - VGPAMC2', 'Sony VAIO Neoprene Notebook With AC Adapter Case - VGPAMC2/ Helps Protect Your Notebook From Scratches, Spills And Dings/ Neoprene Offers Durable, Water-Resistant Protection/ Fits 17'' Widescreen Notebooks', 24.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (56, 1, 'NetGear ProSafe 24 Port Smart Switch - FS726TP', 'NetGear ProSafe 24 Port Smart Switch - FS726TP/ Two Gigabit Ports Plus Easy Browser/ ProSafe Network Management Software/ Web Based Smart Management Features', 605.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (57, 1, 'Garmin StreetPilot C330 Dash Mount - Black Finish - 0101061300', 'Garmin StreetPilot C330 Dash Mount - 0101061300/ Non-Skid Mount Design/ Fully Portable/ Includes 12/24 Volt Cigarette Lighter Adapter/ Black Finish', 57.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (58, 1, 'Yamaha High Performance Subwoofer - Black Finish - YSTFSW100BK', 'Yamaha High Performance Subwoofer - YSTFSW100BK/ 130 Watts Dynamic Power/ Advanced YST II (Yamaha Active Servo Technology)/ Half Pipe Port/ Powerful 6.5? Multi-Range Driver/ Magnetically Shielded/ 16Hz Ultra Low Frequency Reproduction/ Slim Design/ Black Finish', 150.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (59, 1, 'Netgear ProSafe 16 Port 10/100 Desktop Switch - Purple Finish - FS116P', 'Netgear ProSafe 16 Port 10/100 Desktop Switch - FS116P/ 16 Auto Speed-Sensing 10/100 RJ-45 Ports/ 96 KB Embedded Memory Per Unit', 299.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (60, 1, 'Canon High Capacity Color Ink Cartridge - Color Ink - CL51', 'Canon High Capacity Color Ink Cartridge - CL51/ Compatible With Pixma iP6210D, iP6220D, MP150, MP170 And MP450 Printers', 35.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (61, 1, 'Canon Photo Ink Cartridge - CL52', 'Canon Photo Ink Cartridge - CL52/ Compatible With Pixma iP6210D And iP6220D Printers', 25.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (62, 1, 'Cuisinart Programmable Coffeemaker - Stainless Steel Finish - DCC2000', 'Cuisinart 12-Cup Programmable Coffeemaker - DCC2000/ Fully Programmable/ Removable Coffee Reservoir/ Easy-To-Read Coffee Gauge/ Visible Water Level Indicator/ Removable Drip Tray/ Charcoal Water Filter/ Stainless Steel Finish', 100.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (63, 1, 'Sanus Center Channel Speaker Mount - Black Finish - VMCC1B', 'Sanus Center Channel Speaker Mount - VMCC1B/ Works With Sanus Models VMSA, VMAA18, VMAA26, VMDD26 And VMCM1/ Easy To Install/ Mounting Hardware Included/ Black Finish', 99.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (64, 1, 'Netgear RangeMax Wireless Access Point - White Finish - WPN802NA', 'Netgear RangeMax Wireless Access Point - WPN802NA/ Improves Performance Of Existing Legacy 802.11b And 802.11g Wireless Devices Up To 50 Percent/ Wired Equivalent Privacy (WEP) 64-Bit,128-Bit Encryption/ Wi-Fi Protected Access (WPA, Pre-Shared Key)', 130.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (65, 1, 'Weber Q 300 Liquid Propane Outdoor Grill - 426001', 'Weber Q 300 Liquid Propane Outdoor Grill - 426001/ Liquid Propane Fuel Type/ Two Burners For Direct And Indirect Cooking/ Thermometer Built Into The Lid/ Regulator Hose/ 12-Pound Turkey Capacity/ Cart Included/ Cast Aluminum Finish/ Assembly Required', 349.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (66, 1, 'Sony Lightweight Tripod - Black Finish - VCTR100', 'Sony Lightweight Tripod - VCTR100/ Lightweight And Portable/ Expands From 14'' To 39''/ 3-Way Panhead Function/ Black Finish', 34.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (67, 1, 'Sanus VMAV Black VisionMount Component Wall Shelf VMAVB In Black - VMAVB', 'Sanus VMAV Black VisionMount Component Wall Shelf - VMAVB/ Single Wall Mount Shelf For Audio-Video Component/ Metal V Arm/ Black Finish', 34.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (68, 1, 'Sony PlayStation 2 DUALSHOCK 2 Analog Controller - Emerald Finish - 711719706205', 'Sony PlayStation 2 DUALSHOCK 2 Analog Controller - 711719706205/ Analog Pressure Sensitivity On All Action Buttons/ Built-In DUALSHOCK Vibration Function/ Twin Analog Control Sticks/ Intelligent Self-Calibrating Analog System/ Emerald Finish', 24.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (69, 1, 'Sony PlayStation 2 8MB Memory Card - Black Finish - 711719702702', 'Sony PlayStation 2 8MB Memory Card - 711719702702/ Save And Load High Scores, Positions And Replays/ MagicGate Encryption/ Black Finish', 24.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (70, 1, 'Sony PlayStation 2 8MB Memory Card (2 Pack) - Red/Blue Finish - 711719706700', 'Sony PlayStation 2 8MB Memory Card (2 Pack) - 711719706700/ Save And Load High Scores, Positions And Replays/ MagicGate Encryption/ Red/Blue Finish', 34.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (71, 1, 'Universal RF Series MasterControl Remote Control - RF20', 'Universal RF Series MasterControl Remote Control ? RF20/ Control Up To 10 Components/ 432 MacroPower Buttons/ Customizable LCD Screen/ Pre-Programmed Codes/ Learning Capable/ SimpleSound/ Fully Backlit Keypad/ DVD Guide', 79.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (72, 1, 'Panasonic Network Camera - White Finish - BLC1A', 'Panasonic Network Camera - BLC1A/ Automatic Network Configuration/ Built-In Calendar Timer/ Auto Time Adjustment With NTP/ Up To 10x Digital Zoom/ Multi-Language Interface/ White Finish', 99.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (73, 1, 'Pioneer 6.5'' 2-Way Marine White Speakers - TSMR1640', 'Pioneer 6.5'' 2-Way Marine Speakers - TSMR1640/ 160 Watts Maximum Power Handling (30 Watts Nominal)/ 1-1/8'' Poly-Ether Imide Dome Tweeter With Magnetic Fluid And Equalizer/ Tinsel Lead Wire And Terminals Are Gold-Plated For Extra Protection', 120.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (74, 1, 'Apple USB Modem - White Finish - MA034ZA', 'Apple USB Modem - MA034ZA/ Supports Caller ID, Wake On Ring, Telephone Answering (V.253), Modem On Hold/ V.92 Software Support', 54.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (75, 1, 'Linksys EtherFast 4124 24-Port Ethernet Switch - EF4124', 'Linksys EtherFast 4124 24-Port Ethernet Switch - EF4124/ 24 Autosensing 10/100 Full Duplex, Auto MDI/MDI-X Ports/ Up To 200Mbps/ Address Learning, Aging And Data Flow Control/ Compact Size', 119.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (76, 1, 'Sony DVD Remote Control For PS2 - Black Finish - 711719707608', 'Sony DVD Remote Control For PS2 - 711719707608/ Works As A Full-Featured Standard Controller/ Performs Audio Track Selection, Subtitle Display And Multiangle Options/ Designed To Match The Sleek Look Of PlayStation 2', 19.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (77, 1, 'Nikon 55-200MM Zoom-Nikkor Lens Accessory - 2156', 'Nikon 55-200MM Zoom-Nikkor Lens Accessory - 2156/ 3.6X Zoom/ 55 - 200MM/ Silent Wave Motor/ Two ED Glass Elements/ Focus Mode Switch', 199.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (78, 1, 'Waring Professional Cool-Touch Deep Fryer - Black/Stainless Steel Finish - DF100', 'Waring Professional Cool-Touch Deep Fryer - DF100/ Large Frying Basket/ 60-Minute Timer/ Removable Control Panel/ Unique Heating Element/ Breakaway Cord/ LED Power Indicators', 70.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (79, 1, 'Denon Fully Automatic Analog Turntable - DP300F', 'Denon Fully Automatic Analog Turntable - DP300F/ Removable Headshell/ Automatic Startup/ Built-In Phono Equalizer/ DC Servo Motor And Belt Drive System/ MM Cartridge', 329.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (80, 1, 'Terk Mini Tuner Cartridge For XM Ready Home Products - CNP2000', 'Terk Mini Tuner Cartridge For XM Ready Home Products - CNP2000/ Connects To Any Home Or Portable Audio Product With The XM Ready Logo', 29.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (81, 1, 'Panasonic Plain Paper Fax/Copier With Cordless Phone Answering System - Grey Finish - KXFG2451', 'Panasonic Plain Paper Fax/Copier With Cordless Phone Answering System - KXFG2451/ Automatic Fax/Phone Switching/ 2.4GHz GigaRange Cordless Handset With Handset Speakerphone/ Voice Enhancer Technology/ All-Digital Answering System (18 Min)/ Navigator Key With 2-Line Display', 119.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (82, 1, 'Omnimount Moda 2 Shelf Wall Furniture - MWFS', 'Omnimount Moda 2 Shelf Wall Furniture - MWFS/ Modular Design/ Integrated Cable Management/ Tempered Glass Shelves', 299.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (83, 1, 'Terk Mini Tuner Home Dock For XM Ready Home Products - Black Finish - CNP2000H', 'Terk Mini Tuner Home Dock For XM Ready Home Products - CNP2000H/ Comes Complete With The Docking Station, Protective Cover And A Window Sill Mount Antenna/ Interfaces To Existing And Future XM Ready Products', 30.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (84, 1, 'Denon 5-Disc CD Auto Changer - Black Finish - DCM290', 'Denon 5-Disc CD Auto Changer - DCM290/ CD-R/RW Playback/ Advanced Multilevel Noise Shaping DAC/ Digital Filter/ 3-Mode Random Playback/ Intelligent Disc Scan/ Music Calendar Display/ Black Finish', 249.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (85, 1, 'Denon 5 Disc CD Player - Black Finish - DCM390', 'Denon 5 Disc CD Player - DCM390/ CD-R/RW Playback/ MP3, WMA And HDCD Decoding/ Advanced Multilevel Noise Shaping DAC/ 8 Times Oversampling Digital Filter/ 3 Mode Random Playback/ Intelligent Disc Scan/ 20 Selection Music Calendar Display/ Black Finish', 349.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (86, 1, 'Denon Progressive Scan Universal DVD Player - DVD2930CI', 'Denon Progressive Scan Universal DVD Player - DVD2930CI/ AC 120 Volts/ 60 Hertz/ 45 Watts/ Infrared Pulse Remote Control', 849.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (87, 1, 'Netgear Prosafe 16 Port 10/100 Rackmount Switch - Black Finish - JFS516NA', 'Netgear Prosafe 16 Port 10/100 Rackmount Switch - JFS516NA/ Sixteen Switched Ports Provide Private Bandwidth For PCs, Servers Or Hubs/ Store-And-Forward Packet Switching/ Compatible With All Major Network Software/ Auto Detects Speed And Duplex/ Black Finish', 131.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (88, 1, 'Terk XM Outdoor Home Antenna - Grey Finish - XM6', 'Terk XM Outdoor Home Antenna - XM6/ Universal Mounting Roof, Wall Or Mast/ For Use With Single-Input Receivers/ Connects RG6 Cable For Easy Routing Up To 100 Ft. (Optimal Disatnce 75 Ft.)', 80.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (89, 1, 'Sanus 9'' - 17'' VisionMount Series Under Cabinet Flat Panel TV Silver Wall Mount - VMUC1S', 'Sanus 9'' - 17'' VisionMount Series Under Cabinet Flat Panel TV Silver Wall Mount - VMUC1S/ Tilting Motion/ Swivels Left And Right/ Universal Mounting Bracket/ Easy To Install/ Silver Finish', 99.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (90, 1, 'Sanus 15'' - 40'' VisionMount Flat Panel TV Black Wall Mount - MT25B1', 'Sanus 15'' - 40'' VisionMount Flat Panel TV Black Wall Mount - MT25B1/ Solid Heavy-Gauge Steel Construction/ Durable Powder-Coated Finish/ Virtual Axis Tilt Adjustment System/ Up to 100 Lbs Support/ Black Finish', 99.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (91, 1, 'Garmin GPS Carrying Case - Black Finish - 0101070400', 'Garmin GPS Carrying Case - 0101070400/ Protect Your GPS By Absorbing The Impact From Routine Drops/ Prevent Damage From Scratches And Spills', 30.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (92, 1, 'Tech Craft Avalon Series TV Stand - Black Finish - ABS32', 'Tech Craft Avalon Series TV Stand - ABS32/ 32'' Wide ''Tall Boy'' For Smaller Screen Flat Panels/ Molded Top Gives It An Elegant Appearance/ Framed Doors To Conceal Components/ Black Finish', 249.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (93, 1, 'Tech Craft Avalon Series TV Stand - SWP48', 'Tech Craft Avalon Series TV Stand - SWP48/ 48'' Wide Credenza For Flat Panel TVs And DLPs/ 260 Lbs TV Weight Capacity/ 50 Lbs Shelf Weight Capacity/ Wood Veneer Finish', 299.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (94, 1, 'Sanus 15'' - 40'' VisionMount Flat Panel TV Black Wall Mount - MF110B', 'Sanus 15'' - 40'' VisionMount Flat Panel TV Black Wall Mount - MF110B/ Mounts Within 2.5'' Of Wall/ Holds Up To 100 Lbs/ Powder Coated Black Finish', 179.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (95, 1, 'Garmin Nuvi 360 010-10815-00 Black Replacement Vehicle Suction Cup Mount - 0101081500', 'Garmin Nuvi 360 010-10815-00 Black Replacement Vehicle Suction Cup Mount - 0101081500/ Compatible With The Nuvi 360/ It Is A Replacement/ Black Finish', 39.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (96, 1, 'Garmin Nuvi 360 010-10723-06 Black 12 Volt Adapter Cable - 0101072306', 'Garmin Nuvi 360 010-10723-06 Black 12 Volt Adapter Cable - 0101072306/ Compatible With The Nuvi 350 And 360/ It Is A Replacement/ Black Finish', 47.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (97, 1, 'Garmin Nuvi 660 010-10747-03 Black 12 Volt Adapter Cable - 0101074703', 'Garmin Nuvi 660 010-10747-03 Black 12 Volt Adapter Cable - 0101074703/ Compatible With The Nuvi 660/ Black Finish', 39.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (98, 1, 'Garmin 010-10702-00 Black GA 25MCX Remote GPS Antenna - 0101070200', 'Garmin 010-10702-00 Black GA 25MCX Remote GPS Antenna - 0101070200/ Built-In Magnetic Mount/ Includes A Cable Over 8 Feet Long And MCX Connector', 30.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (99, 1, 'Garmin 010-10823-00 Black Nuvi 660 Vehicle Suction Cup Mount - 0101082300', 'Garmin 010-10823-00 Black Nuvi 660 Vehicle Suction Cup Mount - 0101082300/ Replacement Suction Cup Mount/ Compatible With Nuvi 660/ Black Finish', 46.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (100, 1, 'Universal MRF-350 RF Black Base Station - MRF350', 'Universal MRF-350 RF Black Base Station - MRF350/ No More Pointing/ RF Addressable/ IR Routing/ Expand Operating Range Up To 100 Feet/ Compatible With MX-3000, TX-1000, MX-950 And MX-900 Only/ Black Finish', 250.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (101, 1, 'Bose In-Ear Black Headphones - BOSEIE', 'Bose In-Ear Black Headphones - BOSEIE/ Comfortable In-Ear Design/ TriPort Acoustic Headphone Structure/ S, M And L Removable Silicone Tips/ Carrying Case/ Black Finish', 99.95); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (102, 1, 'Nyko PlayStation 3 Dual Charger AC - 743840830153', 'Nyko PlayStation 3 Dual Charger AC - 743840830153/ Charge 2 Wireless PS3 Controllers From A Standard Wall Outlet/ Collapsable Prongs For Easy Storage/ Charges Other Mini USB Devices', 24.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (103, 1, 'Nyko PlayStation 3 ChargeLink USB Charging Cable - 743840830009', 'Nyko PlayStation 3 ChargeLink USB Charging Cable - 743840830009/ Charge And Play At The Same Time/ Unique Woven Cable Shielding Improves Cable Durability/ 10 Ft Cable', 14.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (104, 1, 'Linksys Wireless-G VPN Broadband Silver Router - WRV54G', 'Linksys Wireless-G VPN Broadband Silver Router - WRV54G/ Built-In VPN Endpoint Capability/ Securely Connect Up To 50 Remote Or Traveling Users To Your Office Network Via VPN/ Hotspot Ready With Subscriber Registration, Authorization And Authentication Functions/ Silver Finish', 149.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (105, 1, 'Bose SL2 Wireless Black Surround Link - SL2WIRELESS', 'Bose SL2 Wireless Black Surround Link - SL2WIRELESS/ Transmitter And Receiver Work On A Radio Frequency Signal Effective From Up To 30 Feet In The Same Room/ Compatible With All Lifestyle Systems, CD-Based Models And All 5.1-Channel Acoustimass Home Entertainment Systems/ Black Finish', 249.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (106, 1, 'Sony Digital Photo Printer Paper 120 Pack - SVMF120P', 'Sony Digital Photo Printer Paper 120 Pack - SVMF120P/ 4'' x 6'' Print Paper With Snap-Off Edges/ Super Coat 2 Protective Lamination/ Water Damage And Fingerprint Resistant Prints/ 120 Sheets Of Paper And Print Ribbon/ For DPPF Series Digital Photo Printers Only', 35.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (107, 1, 'Canon PGI-5BK Black Ink Tank Cartridge - PGI5BK', 'Canon PGI-5BK Black Ink Tank Cartridge - PGI5BK/ Smudge Resistant/ Resists Smearing Caused By Highlighters/ Smudge Resistant/ Pigment Ink Formulation For Long Lasting Prints', 16.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (108, 1, 'Lowepro SlingShot 200 AW Digital Camera Back Pack - SLINGSHOT200AW', 'Lowepro SlingShot 200 AW Digital Camera Back Pack - SLINGSHOT200AW/ Holds A SLR With Attached Compact Zoom Lens Plus 3-4 Extra Lenses Or Flash Unit/ Water-Resistant Micro Fiber/ Ripstop Nylon/ Includes A Built-In Memory Card Puch, Micro Fiber LCD Cloth And Two Organizer Pockets', 89.95); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (109, 1, 'Tech Craft ABS48 Antique Black Avalon Series 48'' TV Stand - ABS48', 'Tech Craft ABS48 Antique Black Avalon Series 48'' TV Stand - ABS48/ For Flat Panels And DLP TV?s/ Molded Top And Shaped Skirt/ Framed Doors/ Antique Black Distressed Finish', 299.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (110, 1, 'Garmin 010-10723-03 Nuvi Suction Cup Mount - 0101072303', 'Garmin 010-10723-03 Nuvi Suction Cup Mount - 0101072303/ Replacement Suction Cup Mount/ Compatible With Garmin Nuvi 300/310/350/360 GPS System/ Black Finish', 39.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (111, 1, 'Weber Stainless Steel Summit S-650 Liquid Propane Grill - 1780001', 'Weber Stainless Steel Summit S-650 Liquid Propane Grill - 1780001/ 6 Stainless Steel Burners/ 60,000 BTU-Per-Hour Input/ 12,000 BTU-Per-Hour Input Side Burner/ 10,600 BTU-Per-Hour Rotisserie Burner/ 8,000 BTU-Per-Hour Input Smoker Burner/ Snap-Jet Individual Burner Ignition System/ 3/8-Inch Diameter Stainless Steel Rod Cooking Grates/ Stainless Steel Flavorizer Bars/ Stainless Steel Finish/ Liquid Propane Model (LP Tank Not Included)/ Assembly Required', 1999.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (112, 1, 'Weber Stainless Steel Genesis S-310 Liquid Propane Grill - 3770001', 'Weber Stainless Steel Genesis S-310 Liquid Propane Grill - 3770001/ 3 Stainless Steel Burners/ 42,000 BTU-Per-Hour Input/ Electronic Crossover Ignition System/ 7MM Diameter Stainless Steel Rod Cooking Grates/ Stainless Steel Flavorizer Bars/ Stainless Steel Finish/ Liquid Propane Model (LP Tank Not Included)/ Assembly Required', 899.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (113, 1, 'Weber Stainless Steel Genesis S320 LP Grill - 3780001', 'Weber 3780001 Stainless Steel Genesis S-320 Liquid Propane Grill - 3780001/ 3 Stainless Steel Burners/ 42,000 BTU-Per-Hour Input/ 12,000 BTU-Per-Hour Input Side Burner/ Electronic Crossover Ignition System/ 7MM Diameter Stainless Steel Rod Cooking Grates/ Stainless Steel Flavorizer Bars/ Stainless Steel Finish/ Liquid Propane Model (LP Tank Not Included)/ Assembly Required', 949.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (114, 1, 'Weber Stainless Steel Genesis S320 Natural Gas Grill - 3880001', 'Weber Stainless Steel Genesis S-320 Natural Gas Grill - 3880001/ 3 Stainless Steel Burners/ 42,000 BTU-Per-Hour Input/ 12,000 BTU-Per-Hour Input Side Burner/ Electronic Crossover Ignition System/ 7MM Diameter Stainless Steel Rod Cooking Grates/ Stainless Steel Flavorizer Bars/ Stainless Steel Finish/ Natural Gas Model/ Assembly Required', 969.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (115, 1, 'Kenwood KCA-IP300V iPod Video Direct Cable - KCAIP300V', 'Kenwood KCA-IP300V iPod Video Direct Cable - KCAIP300V/ iPod Video Direct Cable For DNX7100, DDX7019 And KVT719DVD Indash Monitors', 49.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (116, 1, 'Sony SCPH-98046 PlayStation 3 Blu-Ray DVD Remote Control - 711719804604', 'Sony SCPH-98046 PlayStation 3 Blu-Ray DVD Remote Control - 711719804604/ Full Access To The PlayStation 3 Systems Disc Features/ Can Be Used Without Having To Point Directly At The System', 24.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (117, 1, 'Tripp-Lite PV375 PowerVerter 375-Watt Ultra-Compact Inverter - PV375', 'Tripp-Lite PV375 PowerVerter 375-Watt Ultra-Compact Inverter - PV375/ 12V DC Input/ 120V AC Output/ 2 Outlets/ 375 Watts Continuous Output/ 600 Watts Peak Output/ Convenient Cigarette Lighter Plug', 49.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (118, 1, 'Sirius FMDA25 Wired FM Modulation Relay - FMDA25', 'Sirius FMDA25 Wired FM Modulation Relay - FMDA25/ 2 Ft FM Antenna Cable/ 19 Ft 4 In Mini-Jack Cable', 20.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (119, 1, 'Electrolux Oxygen 3 Canister HEPA H12 Filter - EL012A', 'Electrolux Oxygen 3 Canister HEPA H12 Filter - EL012A/ Retains 99.5% Of Dust And Other Irritants/ 1 Filter Per Package', 19.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (120, 1, 'Fellowes Confetti Cut Shredder - W11C', 'Fellowes Confetti Cut Shredder - W11C/ Shreds Up To 11 Sheets Per Pass/ Safely Shreds Staples And Credit Cards/ 9'' Paper Entry Accepts Any Standard Or Legal Size Document/ Safety Interlock Switch Automatically Powers Off When Shredder Head Is Lifted', 79.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (121, 1, 'Sony VAIO VGP-PRSZ1 SZ Series Docking Station - VGPPRSZ1', 'Sony VAIO VGP-PRSZ1 SZ Series Docking Station - VGPPRSZ1/ Compatible With SZ Series Notebooks/ Expand Connectivity To Your Notebook/ 3 USB 2.0, Gigabit Ethernet, VGA, DVI-D And DC In/ Black Finish', 199.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (122, 1, 'Weber Genesis E-310 Liquid Propane Black Outdoor Grill - 3741001', 'Weber Genesis E-310 Liquid Propane Black Outdoor Grill - 3741001/ 3 Stainless Steel Burners/ 42,000 BTU Per-Hour Input/ Electronic Crossover Ignition System/ Porcelain Enameled Cast Iron Cooking Grates/ 2 Stainless Steel Work Surfaces/ Center Mounted Thermometer/ Cast Aluminum End Caps/ Black Finish/ Liquid Propane Model (LP Tank Not Included)/ Assembly Required', 699.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (123, 1, 'Weber Genesis S-310 Natural Gas Stainless Steel Outdoor Grill - 3870001', 'Weber Genesis S-310 Natural Gas Stainless Steel Outdoor Grill - 3870001/ 3 Stainless Steel Burners/ 42,000 BTU-Per-Hour Input/ Electronic Crossover Ignition System/ Center Mounted Thermometer/ Cast Aluminum End Caps/ 2 Heavy Duty Front Locking Casters/ Stainless Steel Finish/ Assembly Required', 919.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (124, 1, 'DeLonghi Magnifica Super-Automatic Espresso/Coffee Machine - ESAM3300', 'DeLonghi Magnifica Super-Automatic Espresso/Coffee Machine - ESAM3300/ Stainless-Steel Removable Double Boiler/ Instant Reheat/ Removable Water Tank And Bean Container/ Integrated Burr Grinder/ Cappuccino System/ Cup Tray/ Silver Finish', 799.95); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (125, 1, 'Yamaha Silver USB Powered Stereo Speaker - NXU10SIL', 'Yamaha NX-U10 Silver USB Powered Stereo Speaker - NXU10SIL/ 20 Watts Output Power/ PowerStorage Circuit/ SR-Bass (Swing Radiator Bass) Technology/ Magnetic Shielding/ Mac And Windows Compatible/ Silver Finish', 180.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (126, 1, 'Canon FAX-JX200 Inkjet Fax Machine - FAXJX200', 'Canon FAX-JX200 Inkjet Fax Machine - FAXJX200/ Automatic Document Feeder/ Produce B&W Copies With Clear, Sharp Text/ One-Touch Dialing/ Ultra-High Quality (UHQ) Image Processing Technology/ 600 x 600 Dpi Copy Resolution/ White Finish', 78.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (127, 1, 'Weber Genesis E-310 Natural Gas Black Outdoor Grill - 3841001', 'Weber Genesis E-310 Natural Gas Black Outdoor Grill - 3841001/ 3 Stainless Steel Burners/ 42,000 BTU Per-Hour Input/ Electronic Crossover Ignition System/ Porcelain Enameled Cast Iron Cooking Grates/ 2 Stainless Steel Work Surfaces/ Center Mounted Thermometer/ Cast Aluminum End Caps/ Black Finish/ Assembly Required', 719.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (128, 1, 'Weber 3758301 Blue Genesis EP-320 LP Gas Grill - 3758301', 'Weber 3758301 Blue Genesis EP-320 LP Gas Grill - 3758301/ 3 Seamless Stainless Steel Burners/ 42,000 BTU-Per-Hour Input/ Crossover Ignition System/ Stainless Steel Flavorizer Bars And Grates/ Cast Aluminum End Caps/ Centermounted Thermometer/ Blue Finish/ Liquid Propane Model (LP Tank Not Included)/ Assembly Required', 749.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (129, 1, 'Panasonic KX-TG6702B 5.8 GHz FHSS GigaRange Expandable Black Cordless Phone System - KXTG6702B', 'Panasonic KX-TG6702B 5.8 GHz FHSS GigaRange Expandable Black Cordless Phone System - KXTG6702B/ All-Digital Answering System/ LCD Call Counter/ Speakerphone/ Navigator Key/ Up To 8 Handsets With Just One Phone Jack/ Line Status Indicator/ Voice Scramble/ Handset Locator/ Volume Control/ Black Finish', 197.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (130, 1, 'Fellowes MicroShred Shredder - MS450CS', 'Fellowes MS-450CS MicroShred Shredder - MS450CS/ 4.5 Gallons Basket Capacity/ Can Shred Paper, CDs, Credit Cards, Staples, Paper Clips/ Motor Reverse/ Interlock Switch/ Safe Sense/ 7 Sheet Capacity', 189.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (131, 1, 'Sony MRW62E/S1/181 17-In-1 External USB Memory Card Reader - MRW62ES1181', 'Sony MRW62E/S1/181 17-In-1 External USB Memory Card Reader - MRW62ES1181/ Supports 17 Different Memory Card Formats/ Works With Macintosh And Windows Computers/ Easy Hi-Speed USB 2.0 Connection/ Black Finish', 29.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (132, 1, 'Griffin Elevator Brushed Aluminum Laptop Stand - 1093CURV2', 'Griffin Elevator Brushed Aluminum Laptop Stand - 1093CURV2/ Elevates Laptop Screen 5.5'' While Providing Valuable Desktop Real Estate For Your Keyboard And Mouse/ Keeps Laptop Cool With 360 Degrees Of Air Circulation/ Compatible With Mac Or PC Laptop', 39.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (133, 1, 'Escort Passport 9500I Radar And Laser Detector - 9500I', 'Escort Passport 9500I Radar And Laser Detector - 9500I/ 360-Degree Radar And Laser Detection/ Blistering All-Band Protection/ GPS-Powered Truelock Filter/ Immune To The VG-2 ''Detector-Detector''/ Built-In Earphone Jack/ Red Display', 449.95); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (134, 1, 'Panasonic Countertop Microwave Oven In Black - NNSN667BK', 'Panasonic NN-SN667B Countertop Microwave Oven In Black - NNSN667BK/ 1.2 Cubic Foot/ 1300 Watts High Power/ 10 Power Levels/ 5 Cooking Stages/ Quick Minute/ One-Touch Sensor Cooking/ Inverter Turbo Defrost/ Multi-Lingual Menu Action Screen/ Popcorn Key/ Black Finish', 129.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (135, 1, 'Panasonic Countertop Microwave Oven In White - NNSN667WH', 'Panasonic NN-SN667W Countertop Microwave Oven In White - NNSN667WH/ 1.2 Cubic Foot/ 1300 Watts High Power/ 10 Power Levels/ 5 Cooking Stages/ Quick Minute/ One-Touch Sensor Cooking/ Inverter Turbo Defrost/ Multi-Lingual Menu Action Screen/ Popcorn Key/ White Finish', 129.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (136, 1, 'Samsung DLP TV Stand In Black - TR72BX', 'Samsung DLP TV Stand In Black - TR72BX/ Designed To Fit Samsung HLT7288 HLT7288, HL72A650, and HL67A650 Television Sets/ Tempered 6mm Tinted Glass Shelves/ Wide Audio Storage Shelves To Accommodate 4 Or More Components/ Wire Management System/ Easy To Assemble/ High Gloss Black Finish', 369.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (137, 1, 'Sony Black Active Speaker System - SRSA212BK', 'Sony Black Active Speaker System - SRSA212BK/ Designed For Your Portable Audio Or PC/ Built-In Mega Bass/ On/Off Switch With Volume Control/ Magnetically Shielded/ Black Finish', 29.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (138, 1, 'Panasonic Expandable Digital Cordless DECT 6.0 Handset In Silver - KXTGA101S', 'Panasonic Expandable Digital Cordless DECT 6.0 Handset In Silver - KXTGA101S/ Expansion Handset And Charger Select 1000 Series Phone Systems/ Big Buttons/ Built-In Clock With Alarm/ Silver Finish', 39.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (139, 1, 'Tech Craft Dark Cherry Veneto Series TV Stand - SWP60', 'Tech Craft Dark Cherry Veneto Series TV Stand - SWP60/ 60'' Wide Credenza For Flat Panel TV?s And DLP?s/ Center Channel Compartment And Storage/ 260 Lbs TV Capacity/ 50 Lbs Shelf Capacity/ Dark Cherry Wood Veneer Finish', 399.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (140, 1, 'Haier 13'' Silver Tube TV - HTR13', 'Haier 13'' Silver Tube TV - HTR13/ Built-In Atsc/Ntsc Tuner/ Video Noise Reduction/ Multi Picture Modes/ Multilingual Display/ Digital Comb Filter/ Component Video Input/ Front AV Jacks/ Silver Finish', 124.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (141, 1, 'Sony Memory Stick USB Adaptor - MSACUS40', 'Sony Memory Stick USB Adaptor - MSACUS40/ Quickly Transfer Image And Data To A PC/ Transfer Speed Up To 80Mbps/ Compatible With All Memory Stick Media', 29.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (142, 1, 'Sony Clip-On Black Headphones - MDRQ68LW', 'Sony Clip-On Black Headphones - MDRQ68LW/ Lightweight And Thin Body For Stable Fitting/ Retractable Silent Cord/ 3.3 Ft. Cord/ Gold Plated Mini-Plug/ Black Finish', 29.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (143, 1, 'Netgear ProSafe 24-Port Smart Switch - GS724TP', 'Netgear ProSafe 24-Port Smart Switch - GS724TP/ 24 10/100/1000 Ports That Support 802.3af PoE/ 2 Combo Gigabit Copper/SFP Slots/ Web-Based Configuration/ Password Access Control/ Purple Finish', 780.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (144, 1, 'Sharp Over The Counter White Microwave Oven - R1211WH', 'Sharp Over The Counter White Microwave Oven - R1211WH/ 1.5 Cu. Ft. Capacity/ 1100 Watts/ 19 Automatic Settings/ 2-Color Lighted LCD/ Smart And Easy Sensor Settings/ Auto-Touch Control Panel/ White Finish', 269.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (145, 1, 'Monster iFreePlay Cordless Headphones For iPod Shuffle - AISHHPHONE', 'Monster iFreePlay Cordless Headphones For iPod Shuffle - AISHHPHONE/ Wrap-Around Design With No Need For Clips, Armbands Or Pockets/ Easy Access To All iPod Shuffle Controls/ Folds For Compact Storage/ Black With Silver Finish', 48.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (146, 1, 'Canon Black Ink Cartridge - PG50', 'Canon Black Ink Cartridge - PG50/ Pigment Ink Formulation For Long Lasting Prints/ Resists Smearing Caused By Highlighters/ Smudge Resistant/ Ink Remaining Notification Technology/ Crisp Laser Text-Quality Text/ Black Ink', 29.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (147, 1, 'Audiovox Xpress XM Satellite Radio FM Direct Adapter - XMFM1', 'Audiovox Xpress XM Satellite Radio FM Direct Adapter - XMFM1/ Switches Between FM Radio Antenna And Your XM Satellite Radio Receiver', 25.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (148, 1, 'Panasonic NNSD797S Stainless Steel Countertop Microwave Oven - NNSD797SS', 'Panasonic NNSD797S Stainless Steel Countertop Microwave Oven - NNSD797SS/ 1.6 Cu. Ft. Capacity/ 1250W Output Power/ 10 Power Levels/ 5 Cooking Stages/ One-Touch Sensor Cooking Or Heating/ Timer/ Stainless Steel Finish', 199.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (149, 1, 'Apple Mac Mini 1.83GHz Intel Core 2 Duo Computer - MB138LLA', 'Apple Mac Mini 1.83GHz Intel Core 2 Duo Computer - MB138LLA/ 1.83GHz Intel Core 2 Duo/ 1GB Memory/ 80GB Hard Drive/ 24x Combo Drive/ Built-In Speakers/ Four USB 2.0 Ports And One FireWire 400 Port/ Mac OS X v10.5 Leopard', 599.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (150, 1, 'Denon 7.1 Channel Home Theater MultiMedia A/V Receiver With Networking And WiFi - AVR4308CI', 'Denon 7.1 Channel Home Theater MultiMedia AV Receiver With Networking And WiFi In Black - AVR4308CI/ 140 Watts x 7 Channels/ Wi-Fi And Network Capable/ Worlds First Vista Certified Receiver/ HD Radio And XM Ready Tuning/ Dolby TrueHD And DTS-HD Master Audio/ DDSC-HD Digital Dynamic Discrete Surround Circuitry/ Expanded HDMI v1.3a Ports/ Dual Remotes/ Black Finish', 2699.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (151, 1, 'Denon 7.1 Channel Home Theater MultiMedia A/V Receiver With Networking In Black - AVR3808CI', 'Denon 7.1 Channel Home Theater MultiMedia AV Receiver With Networking In Black - AVR3808CI/ 130 Watts x 7 Channels/ Fully Assignable Channels For Bi-Amping/ Rear Panel RS-232C And Ethernet Ports/ Network Capable/ XM Ready Tuning/ Dolby TrueHD And DTS-HD Master Audio/ Expanded HDMI v1.3a Ports/ Dual Remotes/ Black Finish', 1699.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (152, 1, 'Denon X-Space Surround Bar Home Theatre System In Black - DHTFS3', 'Denon X-Space Surround Bar Home Theatre System In Black - DHTFS3/ 22 Watts x 5 (6 Ohms)/ Supports All Audio Formats (Dolby Digital, DTS, Dolby Pro Logic II)/ Slim Design/ Includes Dolby Headphones/ Included Subwoofer Features One-Touch Connection/ Remote Control/ Black Finish', 1199.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (153, 1, 'Apple Wireless Mighty Mouse - MB111LLA', 'Apple Wireless Mighty Mouse - MB111LLA/ Bluetooth Technology/ Laser Tracking Engine/ 360-Degree Innovative Scroll Ball And Button/ Touch-Sensitive Top Shell/ Force-Sensing Side Buttons/ Customizable/ White Finish', 69.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (154, 1, 'Sony PSP 2000 Playstation Portable Gaming System Core 98510 In Piano Black - 711719851004', 'Sony PSP 2000 Playstation Portable Gaming System Core 98510 In Piano Black - 711719851004/ Play Games, Watch Movies On UMD Discs, And Listen To Music All In One Device/ 4.3'' LCD Screen (16:9)/ 480 x 272 Pixel/ Wi-Fi (IEEE 802.11b) For Wireless Networking With Other PSP Owners/ Memory Stick PRO Duo/ 333MHz System Clock Frequency/ Piano Black Finish', 185.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (155, 1, 'Apple Mini-DVI To DVI Adapter - M9321GB', 'Apple Mini-DVI To DVI Adapter - M9321GB/ Compatible With iMac (Intel Core Duo), MacBook And 12'' PowerBook G4/ Connects To An External DVI Monitor Or Projector/ White Finish', 19.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (156, 1, 'Olympus DS40 Digital Voice Recorder - DS40R', 'Olympus DS40 Digital Voice Recorder - DS40R/ 136 Hours 15 Minutes Recording Time In LP Mode/ High-Sensitivity Detachable Stereo Microphone/ Voice Guidance/ Three Modes Of Microphone Sensitivity/ Built-In Variable Control Voice Actuator (VCVA) Function/ Up To 32 Hours Of Continuous Operation', 149.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (157, 1, 'Bose Lifestyle 48 Series IV 43479 Home Entertainment System - LS48IVWH', 'Bose Lifestyle 48 Series IV Home Entertainment System - LS48IVWH/ ADAPTiQ Audio Calibration System/ Acoustimass Module/ Jewel Cube Speakers/ Direct/Reflecting Speaker Technology/ VS-2 Video Enhancer/ Proprietary Videostage 5 Decoding Circuitry/ Digital 5.1 Decoding/ Control Integration/ White Finish', 3999.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (158, 1, 'Sony Black DVD Recorder And VHS Combo Player - RDRVXD655', 'Sony Black DVD Recorder And VHS Combo Player - RDRVXD655/ Multiformat DVD Compatible/ HDMI Output And 720p/1080i Upscaling/ HDTV Tuner/ 4 Video Head Stereo VHS With 19 Micron Heads/ Variable Bit Rate Recording (7 Speeds)/ Progressive Scan Playback/ Dolby Digital And DTS Decoding Playback Compatible/ TV Virtual Surround/ Black Finish', 319.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (159, 1, 'Apple 1GB Silver iPod Shuffle - MB225LLA', 'Apple 1GB Silver 2nd Generation iPod Shuffle - MB225LLA/ Holds Up To 240 Songs/ 12 Hours Of Continuous Playback/ Skip-Free Playback/ Battery Indicator/ Shuffle Switch/ Built-In Clip/ Mac And Windows Compatible/ MB226LLA/ Silver Finish', 49.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (160, 1, 'GE 24'' GSD2400NWW White Built-In Dishwasher - GSD2400WH', 'GE 24'' GSD2400NWW White Built-In Dishwasher - GSD2400WH/ 4-Level PowerScrub Wash System/ HotStart Option/ Piranha Hard Food Disposer/ Heated Dry Option/ Self-Cleaning Filter System/ White Finish', 259.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (161, 1, 'Panasonic Expandable Digital Cordless DECT 6.0 Phone System - KXTG1032S', 'Panasonic Expandable Digital Cordless DECT 6.0 Phone System - KXTG1032S/ Up To 17 Hours Of Talk Time/ Expandable Up To 6 Handsets/ Up To 3-Way Conference Capability/ Light-Up Indicator With Ringer/Message Alert/ Backlit LCD On Handset/ Digital Speakerphone/ 16-Minute All-Digital Answering System/ Silver Finish', 69.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (162, 1, 'Panasonic 2 Line Integrated Corded Phone System - KXTSC14B', 'Panasonic 2 Line Integrated Corded Phone System - KXTSC14B/ 3-Line LCD Display/ Automatic Line Selection/ Call Waiting Caller ID/ 3-Way Conferencing/ Speakerphone/ Navigator Key/ Black Finish', 74.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (163, 1, 'Audiovox XpressEZ XM Satellite Radio Receiver - XMCK5P', 'Audiovox XpressEZ XM Satellite Radio Receiver - XMCK5P/ 10 Programmable Channels/ Universal Connector/ 3-Line Screen Display/ Plug & Play Dock/ Black Finish', 69.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (164, 1, 'Panasonic Integrated White Telephone System With All-Digital Answering System - KXTS620W', 'Panasonic Integrated White Telephone System With All-Digital Answering System - KXTS620W/ 2-Way Recording/ Call Waiting Caller ID/ Speakerphone/ 3-Line LCD/ Data Port/ Ringer Indicator Lamp/ Programmable Tone/Pulse/ Wall Mountable/ White Finish', 69.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (165, 1, 'Tech Craft Veneto Series Black TV Stand - ABS60BK', 'Tech Craft Veneto Series Black TV Stand - ABS60BK/ Supports Up To A 60'' Flat Panel TV/ Molded Top Gives It An Elegant Appearance/ Framed Doors To Conceal Components/ 200 Lbs Top Shelf Capacity/ Black Finish', 399.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (166, 1, 'Skagen Premium Steel Slimline Mesh Womens Watch - 233XSGG', 'Skagen Premium Steel Slimline Mesh Womens Watch - 233XSGG/ Stainless Steel Mesh Band/ Elegant Round Case/ Mother-Of-Pearl Dial/ Chrome Indicators', 110.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (167, 1, 'Canon Color Image Silver Scanner - 8800F', 'Canon Color Image Silver Scanner - 8800F/ Resolution Of Up To 4800 x 9600 Color Dpi/ Enhance Old Photos/ Auto-Image Fix/ USB 2.0 Interface/ Multi-Image Scanning/ Windows And Mac Compatible/ Silver Finish', 199.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (168, 1, 'Sony Black LocationFree Base Station - LFV30', 'Sony Black LocationFree Base Station - LFV30/ Watch TV Wherever You Are/ Compatible With PC Or PSP System/ Programmable On-Screen Home Remote/ Stream Outside Your Home/ User-Friendly/ Black Finish', 199.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (169, 1, 'Linksys Wireless-G Broadband Router - WRT54GL', 'Linksys Wireless-G Broadband Router - WRT54GL/ All-In-One Internet-Sharing Router/ 4-Port Switch/ Push Button Setup Feature/ TKIP And AES Encryption/ Wireless MAC Address Filtering/ Powerful SPI Firewall/ 54Mbps Wireless-G (802.11g) Access Point', 79.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (170, 1, 'Universal RF Base Station - MRF260', 'Universal RF Base Station - MRF260/ Extends The Reception Range Up To 100 Feet Away Through Walls, Floors, Doors, Indoors Or Outdoors/ Programmed To Operate Equipment At Up To 15 Locations/ Black Finish', 149.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (171, 1, 'Chestnut Hill Sound George iPod Music System In White - CHS4001', 'Chestnut Hill Sound George iPod Music System In White - CHS4001/ Playback System For The iPod/ Full Feature Wireless Remote/ Charging Stand Kit/ Bandless AM/FM Radio/ Easy Set Alarm/ Detachable Front Panel/ White Finish/ iPod Sold Separately', 499.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (172, 1, 'Sony Universal Remote Control - RMEZ4', 'Sony Universal Remote Control - RMEZ4/ Easy-To-Use Simplified Functions/ Controls TV And Cable Box/ Compatible With Most Of Major Brands/ Large Buttons For Easy Operation/ 3-Minute Memory Backup/ Comfortable Ergonomic Design/ Silver Finish', 16.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (173, 1, 'Sirius SiriusConnect Home Tuner - SCH1', 'Sirius SiriusConnect Home Tuner - SCH1/ Compact Size/ Analog And Digital Audio Outputs/ Display Indicators/ Connects To Any Sirius-Ready Home Audio Component', 49.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (174, 1, 'Sanus 15'' - 32'' Flat Panel TV Black Wall Mount - MF209B1', 'Sanus 15'' - 32'' Flat Panel TV Black Wall Mount - MF209B1 - MF209B1/ Supports Up To 60 lbs/ Easy To Install/ Virtual Axis 3D Tilting System/ Black Finish', 96.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (175, 1, 'Yamaha High Performance Subwoofer In Black - YSTFSW150BK', 'Yamaha High Performance Subwoofer In Black - YSTFSW150BK/ 130 Watts Dynamic Power/ Advanced YST II (Yamaha Active Servo Technology)/ Linear Port/ Powerful 6.5? Multi-Range Driver/ Magnetically Shielded/ 30 -150 Hz Low Frequency Response/ Down-Firing Active Design/ Best Matching For Front Surround Systems And Micro Component Systems/ Black Finish', 279.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (176, 1, 'Kenwood Sirius Radio Translator For In-Dash Head Units - KCASR50', 'Kenwood Sirius Radio Translator For In-Dash Head Units - KCASR50/ Provides Full Control Of The SIRIUS Radio/ Displays Text On The Stereo And Supplies Power To The Satellite Radio', 60.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (177, 1, 'Linksys Wireless-G PrintServer - WPSM54G', 'Linksys Wireless-G PrintServer - WPSM54G/ Share A Multifunction Printer With Everyone On Your Network (Works With Most USB Printers)/ Allows Full Access To Printing, Faxing, Scanning And Copying Functions/ Connects Your Printer Directly To The Network By 10/100 Wired Ethernet Or 54Mbps Wireless-G', 99.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (178, 1, 'Sirius STILETTO 2 Home Docking Kit - SLH2', 'Sirius STILETTO 2 Home Docking Kit - SLH2/ Stereo Audio Output Connects With Home Audio System Or Speakers/ Headphone Jack/ PC Sync/ Compatible With Stiletto 2 Radios/ Charges Stiletto 2 While Docked/ Black Finish', 49.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (179, 1, 'Microsoft Office Standard 2007 - 02107746', 'Microsoft Office Standard 2007 - 02107746/ Create Documents Faster, More Easily And More Intuitively/ Automatic Document Recovery Tool/ Document Inspector/ Online Tutorials With Step-By-Step Instructions/ Compatible With Windows Vista, Windows XP SP2 And Windows Server 2003 SP1', 399.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (180, 1, 'Jabra Black Bluetooth Headset - BT5010', 'Jabra Black Bluetooth Headset - BT5010/ Up To 10 Hours Of Talk Time And 300 Hours Of Stand-By/ Wind-Noise Reduction Technology/ Vibrating And Visual Alerts/ Colored LED Indicator/ Up To 33-Foot Wireless Range/ Black Finish', 79.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (181, 1, 'Kensington Orbit Optical Trackball Mouse - 64327', 'Kensington Orbit Optical Trackball Mouse - 64327/ DiamondEye Optical Technology For Precise Tracking And Cursor Control/ USB And PS/2 Connectivity For Greater Compatibility/ Windows And Mac Compatible/ Metallic Silver And Black Finish', 38.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (182, 1, 'Sirius Stiletto 2 Vehicle Kit - SLV2', 'Sirius Stiletto 2 Vehicle Kit - SLV2/ Designed For Use With The Sirius Stiletto 2/ Get Direct One-Touch Access To Traffic And Weather/ Built-In FM Transmitter To Play Satellite Radio Through Your Cars Audio System', 49.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (183, 1, 'Denon Networked Audio System With Built-In iPod Dock - S32', 'Denon Networked Audio System With Built-In iPod Dock - S32/ Stream Music Wirelessly/ Buit-In Dock For iPod On Top/ Ability To Decode MP3 And WMA Formats/ High Contrast Graphic LCD/ Multi-Task Jog Wheel On Top/ Built-In Speakers/ Clock With 2 Alarms With Auto Clock Set & Adjust Via Internet/ FM/AM Radio/ WiFi Certified/ Remote Control/ Black Finish', 499.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (184, 1, 'Motorola Portable Bluetooth Car Kit Speaker Phone - T305', 'Motorola Portable Bluetooth Car Kit Speaker Phone - T305/ 2.0 Bluetooth Wireless Technology/ Noise Cancellation Technology/ Loud Sound High Speaker Output/ Convenient Multi-Function Button/ Up To 14 Hours Of Talk Time And 14 Days Of Standby Time/ Mini-USB Connector/ Black Finish', 69.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (185, 1, 'Sony HD-Handycam 3 Meters (10 Feet) HDMI Mini Cable - VMC30MHD', 'Sony HD-Handycam 3 Meters (10 Feet) HDMI Mini Cable - VMC30MHD/ Gold Plating Plug/ HDMI-Compliant High Speed Category 2 Cable/ Support Full HD 1080p/ Digital Audio Transfer/ 3 Meters(10 Feet)/ Black Finish', 69.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (186, 1, 'Klipsch Black Wireless iPod Speaker - ROOMGROOVE', 'Klipsch Black Wireless iPod Speaker - ROOMGROOVE/ Wirelessly Sends CD-Quality Music To/From Other RoomGrooves/ Retractable Dock Charges iPods With 30-Pin Connectors/ Horn-Loaded Technology For Precise High Tones/ Dual High-Output Woofers Deliver Room-Filling Bass/ Black Finish', 299.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (187, 1, 'Logitech QuickCam Communicate STX - 961464', 'Logitech QuickCam Communicate STX - 961464/ 640 x 480 Video Capture/ 1.3 Megapixel Still Image Capture/ Built-In Microphone With RightSound Technology/ 30 Frames Per Second/ Adjustable Base Fits Any Monitor Or Notebook/ USB 2.0 Certified', 49.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (188, 1, 'Sirius Plug And Play Universal Home Kit - SUPH1', 'Sirius Plug And Play Universal Home Kit - SUPH1/ Compatible With All Of The Newest SIRIUS Plug & Play Radios/ Stereo Audio Output For Use Your Home Audio System Or Powered Speakers/ Sleek Compact Design/ High Gloss Black Finish', 49.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (189, 1, 'Belkin Hi-Speed USB 2.0 7-Port Hub - F5U237APLS', 'Belkin Hi-Speed USB 2.0 7-Port Hub - F5U237APLS/ Transfers Data Up To 480Mbps/ Installs Easily With Plug-And-Play Convenience/ Works Seamlessly With All USB 1.1 And USB 2.0 Devices/ Over-Current Detection And Safety/ Mac And PC Compatible/ Silver Finish', 49.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (190, 1, 'Netgear Wireless Access Point - WG102', 'Netgear Wireless Access Point - WG102/ High-Speed IEEE 802.11g, Up To 108 Mbps In Turbo Mode/ Wi-Fi Protected Access (WPA 802.11i-Ready Security)/ Integrated IEEE 802.3af Power Over Ethernet (PoE)/ Block SSID Broadcast/ VPN Pass-Through Support', 186.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (191, 1, 'Logitech diNovo Media Desktop Laser Keyboard And Mouse Combo - 967562', 'Logitech diNovo Media Desktop Laser Keyboard And Mouse Combo - 967562/ Unique Ultra-Flat Keyboard/ Detached Customizable MediaPad/ Precision Rechargeable Laser Mouse/ Tilt Wheel Plus Zoom/ Customizable Hotkeys/ Dedicated Search Buttons/ Bluetooth Wireless Technology Compatible/ Black And Gray Finish', 199.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (192, 1, 'Apple 500GB Time Capsule Wireless Hard Drive - MB276LLA', 'Apple 500GB Time Capsule Wireless Hard Drive - MB276LLA/ 500GB 7200-rpm Serial ATA Server-Grade Hard Disk Drive/ Up To 5x The Performance And 2x The Range With 802.11n/ Wi-Fi Protected Access (WPA/WPA2)/ Wireless Security (WEP) Configurable For 40-Bit And 128-Bit Encryption/ NAT Firewall/ AirPort Utility For Mac And Windows', 299.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (193, 1, 'Apple 1TB Time Capsule Wireless Hard Drive - MB277LLA', 'Apple 1TB Time Capsule Wireless Hard Drive - MB277LLA/ 1TB 7200-rpm Serial ATA Server-Grade Hard Disk Drive/ Up To 5x The Performance And 2x The Range With 802.11n/ Wi-Fi Protected Access (WPA/WPA2)/ Wireless Security (WEP) Configurable For 40-Bit And 128-Bit Encryption/ NAT Firewall/ AirPort Utility For Mac And Windows', 499.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (194, 1, 'Garmin Nuvi Portable Friction Mount - 0101090800', 'Garmin Nuvi Portable Friction Mount - 0101090800/ No Installation Required/ Securely Mounts Your GPS To A Surface In Your Car/ Works With All Garmin Nuvi Portable GPS Units/ Black Finish', 39.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (195, 1, 'Garmin Vehicle Suction Cup Mount - 0101093600', 'Garmin Vehicle Suction Cup Mount - 0101093600/ No Installation Required/ Securely Mounts Your GPS To Dash/ Black Finish', 25.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (196, 1, 'Garmin Suction Cup Mount And 12-Volt Adapter Kit - 0101097900', 'Garmin Suction Cup Mount And 12-Volt Adapter Kit - 0101097900/ Suction Cup Mount And 12-Volt Adapter Included', 30.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (197, 1, 'Pioneer Remote Control With DVD/Audio Controls - CDR55', 'Pioneer Remote Control With DVD/Audio Controls - CDR55/ Hands-Free Wireless Control/ Quick Access For Functions/ Compatible With AVH-P5000DVD, AVH-P4000DVD, AVIC-N4, AVIC-D3, AVH-P4900DVD And AVH-P5900DVD', 19.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (198, 1, 'Pioneer Sirius Bus Interface - CDSB10', 'Pioneer Sirius Bus Interface - CDSB10/ Sirius Connect'' Compatibility/ Replay Function/ Game Alert/ Game Zone', 68.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (199, 1, 'Pioneer HD Radio Tuner - GEXP10HD', 'Pioneer HD Radio Tuner - GEXP10HD/ Compatible With FH-P800BT, FH-P8000BT, DEH-P700BT, DEH-P7000BT, DEH-P600UB, DEH-P6000UB/ ''External Control'' Capable', 100.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (200, 1, 'Sirius Dock And Play Universal Vehicle Kit - SUPV1', 'Sirius Dock And Play Universal Vehicle Kit - SUPV1/ Stereo Audio Output/ Use With Your Home Audio System Or Powered Speakers/ Compatible With Sportster 5, Sportster 4, Sportster 3, Starmate 4, Starmate 3, Stratus 4, Stratus', 49.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (201, 1, 'Electrolux Harmony Series Canister Vacuum - EL6985B', 'Electrolux Harmony Series Canister Vacuum - EL6985B/ Foot-Operated Switch On The Floor Nozel/ Ergonomic Handle Design/ Electronic Dust Bag Indicator/ HEPA H12 Filter/ Telescoping Wand', 299.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (202, 1, 'Sennheiser Rechargeable Nickel-Metal Hydride Battery - BA151', 'Sennheiser Rechargeable Nickel-Metal Hydride Battery - BA151/ Rechargeable Battery For Wireless Sennheiser Headphones', 20.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (203, 1, 'Canon Green Photo Ink Cartridge - CLI8G', 'Canon Green Photo Ink Cartridge - CLI8G/ FINE Technology For Exceptional Sharpness & Detail/ Compatible With Canon Pixma Pro9000', 16.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (204, 1, 'Canon Red Photo Ink Cartridge - CLI8R', 'Canon Red Photo Ink Cartridge - CLI8R/ FINE Technology For Exceptional Sharpness & Detail/ Compatible With Canon Pixma Pro9000', 16.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (205, 1, 'Canon Black Photo Ink Cartridge - CLI8B', 'Canon Black Photo Ink Cartridge - CLI8B/ FINE Technology For Exceptional Sharpness & Detail/ Compatible With Canon Pixma Printers', 16.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (206, 1, 'Netgear ProSafe 5 Port 10/100 Desktop Switch - FS105', 'Netgear ProSafe 5 Port 10/100 Desktop Switch - FS105/ 5 Auto Speed-Sensing 10/100 UTP Ports/ Embedded Memory', 40.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (207, 1, 'Pioneer Premier In-Dash CD/WMA/MP3/AAC Receiver - DEHP400UB', 'Pioneer Premier In-Dash CD/WMA/MP3/AAC Receiver - DEHP400UB/ 50W x 4 Built-In Speaker Power/ 3 RCA Hi-Volt Preouts/ Two-Way Crossover/ Supertuner IIID/ AUX-In Connection/ Rotary Commander Volume Control', 183.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (208, 1, 'Pioneer DEH-2000MP CD/MP3/WMA In-Dash Receiver - DEH2000MP', 'Pioneer DEH-2000MP CD/MP3/WMA In-Dash Receiver - DEH2000MP/ 50W x 4 Built-In Speaker Power/ LED Display/ Built-In Front Auxiliary Input/ Detachable Face Security/ Remote Control/ Rotary Volume Control', 98.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (209, 1, 'Pioneer Premier In-Dash CD/WMA/MP3/AAC Receiver - DEHP500UB', 'Pioneer Premier In-Dash CD/WMA/MP3/AAC Receiver - DEHP500UB/ 50W x 4 Built-In Speaker Power/ 3 RCA Hi-Volt Preouts/ Two-Way Crossover/ Supertuner IIID/ AUX-In Connection/ Rotary Commander Volume Control', 208.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (210, 1, 'Sony 7'' Digital Photo Frame In Black - DPFD70', 'Sony 7'' Digital Photo Frame - DPFD70/ 7'' LCD With 800 x 480 Resolution/ 15:9 Aspect Ratio/ 256MB Internal Memory/ Supports Most Memory Cards/ Variety Of Display Modes/ Auto Image Rotation Feature/ View Mode Button/ Fast Digital Picture Decoding/ Handles Large Data Files/ USB B-Type Connection/ Remote Control/ Black Finish', 139.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (211, 1, 'SIRIUS SiriusConnect Vehicle Kit In Black - SCVDOC1', 'SIRIUS SiriusConnect Vehicle Kit In Black - SCVDOC1/ Compact Design/ Compatible With The Next Generation Of SiriusConnect Interface Adapters/ 3 Interchangeable Adapter Plates/ Black Finish', 59.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (212, 1, 'Linksys Wireless-G Ethernet Bridge - WET54G', 'Linksys Wireless-G Ethernet Bridge - WET54G/ Converts Wired-Ethernet Devices To Wireless-G Network Connectivity/ For Windows, Macintosh, Linux, PlayStation Consoles, Xbox Consoles, Or Anything With An Ethernet Port/ Plug And Play, No Driver Installation Require', 89.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (213, 1, 'Yamaha RX-V363BL 5.1 Channel Digital Home Theater Receiver In Black - RXV363BK', 'Yamaha RX-V363BL 5.1 Channel Digital Home Theater Receiver In Black - RXV363BK/ 500 Watts Powerful Surround Sound (100W x 5)/ iPod And Bluetooth Audio Compatibility/ Dolby Digital, DTS And Dolby Pro Logic II Decoding/ Cinema DSP With 8 DSP Programs/ Compressed Music Enhancer/ 192kHz/24-Bit DACs For All Channels/ Remote Control/ Black Finish', 199.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (214, 1, 'Yamaha All-Weather Pair Speaker System - NSAW390WH', 'Yamaha NS-AW390WH All-Weather Speaker System - NSAW390WH/ 6.5'' High Compliance/ PP Mica Filled Woofers/ Unique Dual 1'' PEI Dome Tweeter Configuration/ Aluminum Speaker Grilles/ Wall Mountable/ White Finish/ Sold As A Pair', 149.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (215, 1, 'Yamaha NS-AW390BL All-Weather Pair Speaker System - NSAW390BK', 'Yamaha NS-AW390BL All-Weather Speaker System - NSAW390BK/ 6.5'' High Compliance/ PP Mica Filled Woofers/ Unique Dual 1'' PEI Dome Tweeter Configuration/ Aluminum Speaker Grilles/ Wall Mountable/ Black Finish/ Sold As A Pair', 149.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (216, 1, 'Yamaha NS-AW190BL All-Weather Pair Speaker System - NSAW190BK', 'Yamaha NS-AW190BL All-Weather Speaker System - NSAW190BK/ 5'' High Compliance/ PP Mica Filled Woofers/ Unique Dual 1/2'' PEI Dome Tweeter Configuration/ Aluminum Speaker Grilles/ Wall Mountable/ Black Finish/ Sold As A Pair', 99.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (217, 1, 'Yamaha 7.2 Channel Black Digital Home Theater Receiver - RXV663BK', 'Yamaha 7.2 Channel Black Digital Home Theater Receiver - RXV663BK/ 4 SCENE Buttons/ XM Ready With XM HD Surround/ SIRIUS Satellite Radio Ready/ YPAO/ iPod Compatibility/ Bluetooth Compatibility/ Multi-Zone Control Compatibility/ On-Screen Display/ Black Finish', 499.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (218, 1, 'Yamaha 7.2 Channel Black Digital Home Theater Receiver - RXV863BK', 'Yamaha 7.2 Channel Black Digital Home Theater Receiver - RXV863BK/ 4 SCENE Buttons/ XM Ready With XM HD Surround/ SIRIUS Satellite Radio Ready/ YPAO/ iPod Compatibility/ Bluetooth Compatibility/ Multi-Zone Control Compatibility/ On-Screen Display/ Black Finish/ CALL FOR LATEST PRICE', 899.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (219, 1, 'Yamaha 5.1 Channel Home Theater In A Box System In Black - YHT390BK', 'Yamaha 5.1 Channel Home Theater In A Box System In Black - YHT390BK/ New Scene, Compressed Music Enhancer/ iPod Compatibility/ 600W Powerful Surround Sound/ Silent Cinema/ 192kHz/24-Bit DACs For All Channels/ Black Finish', 399.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (220, 1, 'Apple MacBook Air SuperDrive - MB397GA', 'Apple MacBook Air SuperDrive - MB397GA/ Compact And Portable Slot-Loading 8x SuperDrive/ Connect To MacBook Air USB Slot/ Play And Burn Both CDs And DVDs/ Watch DVD Movie, Install Software, Or Create Backup Discs', 99.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (221, 1, 'Monster Mini-To-Mini iCable For Car - AICMINIIP3S', 'Monster Mini-To-Mini iCable For Car - AICMINIIP3S/ 3 Ft. Cable/ 1/8 Mini-Jack Input For Car Stereo/ Dual Balanced High-Purity Copper Conductors And 24k Gold/ Xtra Low Noise DoubleHelix Construction/ Compatible With Apple iPod, iPhone, And Portable MP3 Player/ White Finish', 15.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (222, 1, 'TomTom GPS Mount And USB Car Charger - 9N00101', 'TomTom GPS Mount And USB Car Charger - 9N00101/ Extra Holder And Car Charger Convenient For Multi-Vehicles User/ No Need To Transfer Holder From One Car To Another/ Easy Installation/ Compatible With TomTom ONE/ Black Finish', 39.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (223, 1, 'Denon Blu-ray Disc DVD/CD Player - DVD3800BDCI', 'Denon Blu-ray Disc DVD/CD Player - DVD3800BDCI/ 10-Bit Realta HQV Video Processor/ 1080p/24fps Output And Multi-Cadence Detection/ HDMI 1.3a Output With 36-Bit Deep Color Support/ Dual 32-Bit Floating Point DSP/ Multi-Layered Construction With Dual-Layered Top Shields And Triple-Layered Bottom/ Suppress Vibration Hybrid (S.V.H.) Loader/ Black Finish', 1999.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (224, 1, 'TomTom GPS Mount And USB Car Charger - 9S00006', 'TomTom GPS Mount And USB Car Charger - 9S00006/ Extra Holder And Car Charger Convenient For Multi-Vehicles User/ No Need To Transfer Holder From One Car To Another/ Easy Installation/ Compatible With TomTom ONE XL/ Black Finish', 28.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (225, 1, 'Bracketron iPod Docking Kit - IPM202BL', 'Bracketron iPod Docking Kit - IPM202BL/ Compatible With All Generation iPods Including iPod Mini, iPod Nano And Apple iPhone/ Wings Adjustable Up To 2.5''/ Black Finish', 14.95); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (226, 1, 'Boston Acoustics Solo AM/FM Large Display Clock Radio - HSOLOMDNT', 'Boston Acoustics Solo AM/FM Large Display Clock Radio - HSOLOMDNT/ Rotating Clock Face/ Precision Tuner/ 3 1/2? Full-Range Speaker/ Auxiliary Input/ High Contrast LCD Display/ 360� Snooze Bar/ Grey Finish', 99.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (227, 1, 'Panasonic 5.8 GHz Black Expandable Digital Cordless Phone System - KXTG4323B', 'Panasonic 5.8 GHz Black Expandable Digital Cordless Phone System - KXTG4323B/ Include 3 Handsets/ Expandable Up To 4 Handsets/ Digital Answering Machine System/ Ringer ID/ Call Waiting Caller ID/ Voicemail/ Hold/ Mute/ Clock/ Alarm/ LED Lighting/ Speakerphone/ Intercom/ 11 Days Standby/ 5 Hours Talk Time/ Black Finish', 79.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (228, 1, 'Sony Silver Digital Voice Recorder - ICDB600', 'Sony Silver Digital Voice Recorder - ICDB600/ 512MB Built-In Flash Memory/ Up To 300 Hours Of Recording Time/ 3 Recording Modes/ 4 Message Folders/ Large LCD Display/ Voice Operated Recording/ 250mW Speaker Output/ Date and Time Stamp/ Silver Finish', 39.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (229, 1, 'Motorola MotoRokr Portable Bluetooth Car Kit Speaker Phone - T505', 'Motorola MotoRokr Portable Bluetooth Car Kit Speaker Phone - T505/ 2.0 Bluetooth Wireless Technology/ Noise Cancellation Technology/ Loud Sound High Speaker Output/ Audio CallerID/ StationFinder/ Convenient Multi-Function Button/ Long Battery Life/ Mini-USB Connector/ Black Finish', 129.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (230, 1, 'Samsung Hi Definition Conversion DVD Player - DVD1080P8', 'Samsung Hi Definition Conversion DVD Player - DVD1080P8/ Progressive Scan/ HD Upconversion/ Digital-To-Analog Converter/ Dolby Digital Surround Sound/ Child Protection/ HDMI Output/ Black Finish', 79.90); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (231, 1, 'Boston Acoustics Duo-I AM/FM Clock Radio With iPod Dock - HDUOIMDNT', 'Boston Acoustics Duo-I AM/FM Clock Radio With iPod Dock - HDUOIMDNT/ Integrated iPod Dock/ Precision AM/FM Stereo Tuner/ 3 1/2'' Dual High Performance Full-Range Speakers/ BassTrac Audio Processing/ 2 Auxiliary Inputs/ High Contrast Display/ 10 FM & 5 AM Station Presets/ 360� Snooze Bar/ Remote Control Included/ Grey Finish', 199.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (232, 1, 'Panasonic Black DVD Home Theater Sound System - SCPT660', 'Panasonic Black DVD Home Theater Sound System - SCPT660/ Kelton Subwoofer/ Bamboo Diaphragm Center Speakers/ 1080p Up-Conversion/ Integrated Universal Dock And On-Screen Display For iPod/ iPod Video Playback/ Whisper-Mode Surround/ Built-In Dolby Digital And DTS Decoder/ High Speed 5-DVD/CD Changer/ Black Finish', 289.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (233, 1, 'Weber Summit E-620 Copper Liquid Propane Gas Outdoor Grill - 1752001', 'Weber Summit E-620 Copper Liquid Propane Gas Outdoor Grill - 1752001/ 6 Stainless Steel Burners/ 60,000 BTU-Per-Hour Input/ Snap-Jet Individual Burner Ignition System/ 838 Sq. In. Total Cooking Area/ Porcelain-Enameled Shroud/ Center-Mounted Thermometer/ Copper Finish/ Liquid Propane Model (LP Tank Not Included)/ Assembly Required', 1899.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (234, 1, 'Logitech Harmony One Advanced Universal Remote Control - HARMONY1', 'Logitech Harmony One Advanced Universal Remote Control - HARMONY1/ One-Touch Access To Your Entertainment/ Replaces Up To 15 Remotes/ Full-Color Touch Screen/ Sculpted, Backlighted Buttons In Logical Zones/ Ergonomic Design/ Rechargeable/ Guided Online Setup/ World?s Largest AV Control Database/915-000035', 249.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (235, 1, 'Z-Line Portland Black TV Stand - ZL2344MU', 'Z-Line Portland Black TV Stand - ZL2344MU/ Accommodates Most Flat Panel LCD/Plasma TVs Up To 50''/ Durable Black Glossy Powder Coat Metal Frame/ Tempered Black Safety Glass Shelves/ Chrome Cylinder Glass Supports/ Swivel Mount/ Wire Management/ Holds 65 lbs Per Shelf/ Distance Between Shelves- 8.25'' (Bottom to Middle) and 7'' (Middle to the bar below the top shelf)/ Black Finish', 399.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (236, 1, 'Sony Black USB Stereo Turntable System - PSLX300USB', 'Sony Black USB Stereo Turntable System - PSLX300USB/ Transfer Classic Vinyl To PC, Walkman, Or MP3 Player/ USB And RCA Audio Output/ 45 Rpm Record Playback/ Belt Drive System/ Dust Cover/ Black Finish', 149.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (237, 1, 'Sony Digital SLR Camera With Lens Kit - DSLRA200W', 'Sony Alpha Digital SLR Camera With Lens Kit - DSLRA200W/ 10.2 Megapixels/ 2.7'' Clear Photo LCD Screen/ Super SteadyShot In-Camera Image Stabilization/ Continuous Burst Mode/ Bionz Image Processor/ ISO Sensitivity/ 9-Point Center Cross AF Sensor/ Scene Selection Modes/ DT 18-70mm f3.5 Zoom Lens And 75-300mm f4.5-5.6 Compact Super Telephoto Zoom Lens Included/ Black Finish', 849.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (238, 1, 'Nyko Charge Base 2 Charger For PlayStation 3 Controller - 743840830535', 'Nyko Charge Base 2 Charger For PlayStation 3 Controller - 743840830535/ Compact Design/ Rapidly Charges Two PS3 Controllers Simultaneously/ Includes Two USB Charge Adaptors', 34.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (239, 1, 'Sony Remote Control Tripod - VCT60AV', 'Sony Remote Control Tripod - VCT60AV/ A/V Remote Connector/ 4 Stage Leg Extension/ Extends From 18.9'' To 57.6'' In Height/ Guide Frame Feature/ Available Vertical Position/ Supplied Carrying Case/ Black Finish', 99.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (240, 1, 'Klipsch Groove PM20 Computer Speakers - GROOVEPM20BK', 'Klipsch Groove PM20 Computer Speakers - GROOVEPM20BK/ 6 Ohms Nominal Impedance/ 3Full-Range 2.5? Fiber Composite Driver/ Overload Protection/ System-Specific Loudness Contour/ Black Finish', 99.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (241, 1, 'Weber Gas Barbecue Rotisserie - 7519', 'Weber Gas Barbecue Rotisserie - 7519/ Fits Genesis E-300, S-300 Gas Grills/ Heavy-Duty Electric Motor/ Counterbalance For Smooth Turning', 80.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (242, 1, 'Weber Cast Iron Griddle - 7531', 'Weber Cast Iron Griddle - 7531/ Heavy-Duty Cast Iron Griddle/ Fits Weber Genesis Silver A & Spirit 500 Gas Grills', 44.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (243, 1, 'Weber Cast Iron Griddle - 7542', 'Weber Cast Iron Griddle - 7542/ Heavy-Duty Cast Iron Griddle/ Two-Sided For Cooking A Variety Of Foods/ Fits Several Weber Grills', 44.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (244, 1, 'Sony 5.1 Channel Black A/V Receiver - STRDG520', 'Sony 5.1 Channel Black A/V Receiver - STRDG520/ 100 Watts X 5 Power/ 1080p HDMI Pass Through/ Accepts 1080/60p And 24p Video Signal Via HDMI/ Dolby Digital, Dolby Pro Logic, Dolby Pro Logic II, Digital Cinema Sound And Dts Decoding/ Black Finish', 199.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (245, 1, 'Sony Alpha DSLR Black Camera Body With 18-70mm Zoom Lens - DSLRA300K', 'Sony Alpha DSLR Black Camera Body With 18-70mm Zoom Lens - DSLRA300K/ 10.2 MP Super HAD CCD/ Tiltable 2.7 Clear Photo LCD Plus Screen/ Smart Teleconverter 2X Zoom/ Expanded ISO Sensitivity/ Super SteadyShot In-Camera Image Stabilization/ Anti-Dust Technology/ 9-Point Center Cross AF Sensor/ Index and Slide Show Display/ Black Finish', 599.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (246, 1, 'Polk Audio CSI A4 Black Center Channel Loudspeaker - CSIA4BK', 'Polk Audio CSI A4 Black Center Channel Loudspeaker - CSIA4BK/ 1'' Silk/Polymer Dome Tweeter/ Dual 5-1/4'' Mid/Woofers/ Magnetic Shielding/ All-MDF Construction/ Acoustically Inert Stamped Driver Baskets/ Floating Anti-Diffraction Grilles/ Dual Bi-Ampable Gold-Plated 5-Way Binding Post Inputs/ Black Finish/ Sold As A Single', 279.95); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (247, 1, 'Polk Audio CSI A4 Cherry Center Channel Loudspeaker - CSIA4CH', 'Polk Audio CSI A4 Cherry Center Channel Loudspeaker - CSIA4CH/ 1'' Silk/Polymer Dome Tweeter/ Dual 5-1/4'' Mid/Woofers/ Magnetic Shielding/ All-MDF Construction/ Acoustically Inert Stamped Driver Baskets/ Floating Anti-Diffraction Grilles/ Dual Bi-Ampable Gold-Plated 5-Way Binding Post Inputs/ Cherry Finish/ Sold As A Single', 279.95); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (248, 1, 'Polk Audio CSI A6 Black Center Channel Loudspeaker - CSIA6BK', 'Polk Audio CSI A6 Black Center Channel Loudspeaker - CSIA6BK/ Dual 6-1/2'' Mid/Woofers/ 1'' Silk/Polymer Dome Tweeter/ Dual Rear PowerPort Bass Venting/ Magnetic Shielding/ Mylar Bypass Capacitors/ Acoustic Resonance Control (ARC Port) Technology/ Dual Bi-Ampable Gold-Plated 5-Way Binding Post Inputs/ Butyl Rubber Surrounds/ Floating Anti-Diffraction Grilles/ All-MDF Construction/ Black Finish/ Sold As A Single', 449.95); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (249, 1, 'Polk Audio 5.1 Channel Black Home Theater Speaker System - RM705BK', 'Polk Audio 5.1 Channel Black Home Theater Speaker System - RM705BK/ Heavy-Duty Non-Resonant Composite Enclosures/ Downward Firing Powered 8'' Subwoofer/ Built-In Subwoofer Power Amp With Active Crossover/ Three-Sided Cabinet Design/ Magnetically Shielded/ Black Finish', 499.95); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (250, 1, 'Sony 3.1 Channel Home Theater Surround System In Black - HTCT100', 'Sony 3.1 Channel Home Theater Surround System In Black - HTCT100/ HDMI Active Intelligence/ LPCM Playback/ 3.1 Channel/ S-Force Surround/ BRAVIA� Sync/ Digital Media Port/ Black Finish/ ETA MID JANUARY 2009', 299.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (251, 1, 'Polk Audio Black 10'' Powered Subwoofer - PSW110BK', 'Polk Audio PSW110 Black 10'' Powered Subwoofer - PSW110BK/ 100 Watts Continuous Average Output/ 200 Watts Dynamic Power Output/ 10'' Dynamic Balance Composite Woofer Driver/ Klippel Optimized Woofer/ High Current Class A/B Amplifiers/ Downward Firing Port/ Line And Speaker Level Inputs/ Non-Resonant MDF Construction/ Black Finish', 299.95); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (252, 1, 'Twenty20 VholdR Mount Adhesive - 2200MA', 'Twenty20 VholdR Mount Adhesive - 2200MA/ Removable/ Resists Water, Heat And Cold', 6.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (253, 1, 'Weber Premium Black Grill Cover - 7550', 'Weber Premium Black Grill Cover - 7550/ Heavy-Duty Vinyl/ Compatible With Spirit E-200 Series, Spirit 500 And Genesis Silver A Gas Grills/ Black Finish', 40.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (254, 1, 'Sony Black Earbud Style Headphones - MDREX55BK', 'Sony MDREX55BLK Black Earbud Style Headphones - MDREX55BK/ 9mm EX Driver Provides Comfort Fit And Deep Bass Sound/ Soft Fitting Silicon Housing/ 3 Sizes Earbuds/ Carrying Pouch/ Black Finish', 39.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (255, 1, 'Hoover EmPower Bagless Upright Vacuum - U5269', 'Hoover EmPower Bagless Upright Vacuum - U5269/ Hush Mode/ Power Boost/ No Assembly Required/ Folding Handle For Easy Storage/ Allergen Filter/ 12 Amp Motor/ Tools Included/ Green Finish', 99.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (256, 1, 'Panasonic DECT 6.0 Expandable Digital Cordless Phone With All-Digital Answering System - KXTG9344T', 'Panasonic DECT 6.0 Expandable Digital Cordless Phone With All-Digital Answering System - KXTG9344T/ 4 Handsets System/ Up To 6 Multi-Handset Capability/ Digital Answering Machine System/ Ringer ID/ Call Waiting Caller ID/ Voicemail/ Hold/ Voice Menu/ Marker Message/ Mute/ Clock/ Alarm/ LED Lighting/ Night Mode/ Call Block/ Speakerphone/ 11 Days Standby/ 5 Hours Talk Time/ Black Metallic Finish', 139.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (257, 1, 'LaCie 500GB d2 Quadra External Hard Drive - 301825U', 'LaCie 500GB d2 Quadra External Hard Drive - 301825U/ Quadruple Interface For Full PC And Mac Compatibility/ Interface Bandwidth Up To 3Gbits/s (eSATA)/ Advanced Aluminum Heat Sink Design Cooling System For Quiet Operation/ 7200 Rotational Speed (rpm)/ 16MB Cache/ Compatible With Time Machine', 159.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (258, 1, 'Panasonic DECT 6.0 Black Expandable Digital Cordless Phone - KXTG9361B', 'Panasonic DECT 6.0 Black Expandable Digital Cordless Phone - KXTG9361B/ Drop And Splash Resistant/ Multi-Handset Capability/ Ringer ID/ Call Waiting Caller ID/ Voicemail/ Hold/ Mute/ Clock/ Alarm/ LED Lighting/ Night Mode/ Call Block/ Speakerphone/ 11 Days Standby/ 5 Hours Talk Time/ Black Finish', 48.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (259, 1, 'Sony 1GB Memory Stick PRO Duo Mark 2 Media Card - MSMT1G', 'Sony 1GB Memory Stick PRO Duo Mark 2 Media Card - MSMT1G/ 160 Mbps Transfer Speed/ 940MB Actual Capacity', 19.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (260, 1, 'Sony 2GB Memory Stick PRO Duo Mark 2 Media Card - MSMT2G', 'Sony 2GB Memory Stick PRO Duo Mark 2 Media Card - MSMT2G/ 160 Mbps Transfer Speed/ 1.85GB Actual Capacity', 29.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (261, 1, 'Pioneer Black Premier Single CD Receiver - DEHP700BT', 'Pioneer Black Premier Single CD Receiver - DEHP700BT/ Built-In Bluetooth Solution/ USB Direct Control For iPod/ Advanced Sound Retriever/ 3 RCA Hi-Volt Preouts/ Two-Way Crossover/ Built-In MOSFET 50 W x 4 Amplifier/ Supertuner IIID/ Amplifier Off Mode/ Display Off Mode', 308.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (262, 1, 'TomTom ONE 130S Car GPS Navigation System - 1EE005202', 'TomTom ONE 130S Car GPS Navigation System - 1EE005202/ 3.5'' LCD Anti-Glare Touch Screen/ Pre-Installed Maps/ Internal Lithium-Ion Battery/ Car Speed Linked Volume/ Automatic Day/Night Mode/ QuickGPSfix/ Text-To-Speech Included', 246.95); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (263, 1, 'TomTom ONE XL 330 Car GPS Navigation System - 1EG005200', 'TomTom ONE XL 330 Car GPS Navigation System - 1EG005200/ 4.3'' LCD Anti-Glare Touch Screen/ Pre-Installed Maps/ Internal Lithium-Ion Battery/ Car Speed Linked Volume/ Automatic Day/Night Mode/ QuickGPSfix', 246.95); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (264, 1, 'TomTom ONE XL 330S Car GPS Navigation System - 1EG005201', 'TomTom ONE XL 330S Car GPS Navigation System - 1EG005201/ 4.3'' LCD Anti-Glare Touch Screen/ Pre-Installed Maps/ Internal Lithium-Ion Battery/ Car Speed Linked Volume/ Automatic Day/Night Mode/ QuickGPSfix/ Text-To-Speech Included', 296.95); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (265, 1, 'Sony Black Camcorder Tripod - VCT80AV', 'Sony Black Camcorder Tripod - VCT80AV/ 3 Stage Leg Extension/ Extends From 24.88'' To 65.88'' In Height/ Guide Frame Feature/ Available Vertical Position/ For A/V Remote Connector/ Supplied Carrying Case/ Black Finish', 180.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (266, 1, 'Sony 7.1 Channel Black A/V Receiver - STRDG820', 'Sony 7.1 Channel Black A/V Receiver - STRDG820/ 770 Watts Total Power (110W x 7)/ Accepting Resolutions Up To 1080p Via HDMI/ Digital Cinema Auto Calibration/ BRAVIA Sync/ Digital Cinema Sound/ Dolby Digital, Dolby Digital EX, Dolby Pro Logic II, Dolby Pro Logic IIx, Dts, Dts-ES, Dts 96/24, Dts NEO:6 Decoding/ Black Finish', 399.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (267, 1, 'Sony Splash Resistant Shower Radio - ICFS79W', 'Sony Multi Band Digital Tuner Shower Radio - ICFS79W/ Splash Resistant/ AM/FM/Weather Band Reception/ Easy One Button Weather Band Select/ Built-In Digital Clock/ Selectable Automatic-Off Timer/ Quartz Synthesized Tuner/ Built-In Antennas', 49.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (268, 1, 'Samsung Black Combo DVD/VHS Player - DVDV9800', 'Samsung Black Combo DVD/VHS Player - DVDV9800/ Progressive Scan/ 1080p Up-Conversion Via HDMI/ 10Bit / 54MHz Digital-To-Analog Converter/ 4-Head Hi-Fi VCR/ Black Finish/ No Tuner', 98.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (269, 1, 'Omnimount Stellar Series Audio Tower - G303DARK', 'Omnimount Stellar Series Audio Tower - G303DARK/ Designed For Large Audio Components/ Supports Tabletop Flat Panels/ Three ?Floating? Shelf Design/ Integrated Cable Management/ Black Finish', 299.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (270, 1, 'Weber Q 320 Liquid Propane Table And Outdoor Grill - 586002', 'Weber Q 320 Liquid Propane Table And Outdoor Grill - 586002/ 462 Sq. In. Total Cooking Area/ 21,700 BTU Stainless Steel Burners/ Porcelain-Enameled Cast-Iron Cooking Grate/ Cast-Aluminum Lid And Body/ Electronic Ignition/ Grill Out Handle Light/ Folding Work Tables With Tool Holders/ Removable Catch Pan/ Built-In Thermometer/ Stationary Cart Included/ Black And Aluminum Finish/ Assembly Required', 379.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (271, 1, 'Sony Black Component Home Theater System - HT7200DH', 'Sony Black Component Home Theater System - HT7200DH/ 900 Watts/ 5.1 Channels/ HDMI 1080p Output DVD Player/ HDMI Active Intellegence AV Receiver/ 5 Satellite Speakers/ XM Ready/ Black Finish', 499.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (272, 1, 'TomTom Black Carry Case - 9UEA01700', 'TomTom Black Carry Case - 9UEA01700/ Specifically Designed For TomTom ONE 130 GPS/ Durable And Compact Protective Hardcover Material/ Wrist Strap/ Black Finish', 19.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (273, 1, 'Mitsubishi 835 Diamond Series 73'' 1080p DLP Rear Projection HDTV - WD73835', 'Mitsubishi 835 Diamond Series 73'' 1080p DLP Rear Projection HDTV - WD73835/ 1920 x 1080 Full HD Resolution/ 6-Color Processor/ Smooth 120Hz/ x.v.Color/ Plush1080p 12-Bit Digital Video Processing/ Color 4D Video Noise Reduction/ 3D Ready/ NetCommand/ DeepField Imager/ Black Finish', 3499.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (274, 1, 'Sony Black DVD Recorder And VHS Combo Player - RDRVX560', 'Sony Black DVD Recorder And VHS Combo Player - RDRVX560/ Multiformat DVD Compatible/ HDMI Output With 1080p,1080i,720p Upscaling/ USB One Touch Dubbing/ 4 Video Head Stereo VHS With 19 Micron Heads/ Virtual Surround Sound For DVD With Stereo TV Speakers/ Black Finish', 219.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (275, 1, 'Uniden DECT 6.0 Digital Accessory Handset - DCX300', 'Uniden DECT 6.0 Digital Accessory Handset - DCX300/ DECT 6.0 Interference Free Cordless Frequency/ Large Color Display/ Blue Backlit Keypad/ Handset Speakerphone/ Intercom or Call Transfer Between Handsets/ Polyphonic Ring Tones/ Advanced Phonebook Features/ Last 5 Number Redial/ Piano Black Finish', 34.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (276, 1, 'Sony DVD Recorder In Black - RDRGX360', 'Sony DVD Recorder In Black - RDRGX360/ 1080p/1080i/720p Upscaling For DVD/ USB One Touch Dubbing/ Line Input Recording/ BRAVIA Sync/ DVD+R Double Layer Recording/ Dolby Digital Decoding Playback Compatible/ Black Finish', 179.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (277, 1, 'Sennheisser Hi-Fi Wireless Headphone - RS130', 'Sennheisser Hi-Fi Wireless Headphone - RS130/ Switchable SRS Surround Sound Mode/ Intelligent Auto-Tuning/ Memory Function/ Self-Learning Automatic Level Control/ Black Finish', 159.95); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (278, 1, 'BlueAnt Black Bluetooth Headset - Z9I', 'BlueAnt Black Bluetooth Headset - Z9I/ Pairs With 5 Devices/ Bluetooth Version 2.0 Technology/ Dual Microphones For Pure Speech/ Revolutionary Voice Isolation Technology/ Automatic Connection And Reconnection With Notification/ Firmware Upgrade Via USB On Your PC/ Up To 5.5 Hours Talk Time/ 200 Hours Standby Time/ Gloss Black Finish', 99.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (279, 1, 'Escort Passport 9500CI Radar Detector - 9500CI', 'Escort Passport 9500CI Radar Detector - 9500CI/ 360 Degree Protection/ Completely Undetectable To All Detector Scanners/ Variable-Speed Radar Performance/ GPS-Powered Truelock Filter/ Adaptive Signal Processing/ Speed Alert/ Crystal-Clear Voice Alerts/ 280 LED Matrix Blue Display/ 5 Levels Of Brightness Control/ Black Finish/ Price Includes Installation', 1995.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (280, 1, 'Sony Black 5.1 Channel Home Theater System - HTDDWG700', 'Sony Black 5.1 Channel Home Theater System - HTDDWG700/ 5.1 Channel/ 900 Watts Power/ Portable Audio Enhancer With Front Audio Input/ iPod Cradle/ Digital Cinema Auto Calibration/ BRAVIA Sync/ Digital Media Port/ Black Finish', 199.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (281, 1, 'Denon Multi-Channel Digital Surround Sound Speaker System - DHTFS5', 'Denon Multi-Channel Digital Surround Sound Speaker System - DHTFS5/ Multiple Amplifier Channels/ Dolby Pro Logic II, Dolby Digital And DTS Surround/ Balanced Loudspeaker Drivers/ X-Space Surround Technology/ Night Mode/ Remote Control Included/ Black Finish', 499.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (282, 1, 'Danby White Countertop Dishwasher - DDW497WH', 'Danby White Countertop Dishwasher - DDW497WH/ 4 Place Settings/ Quick Connect To Any Kitchen Tap/ Automatic Detergent And Rinse Agent Dispenser/ Quiet Operation/ 5 Wash Cycles/ Durable Stainless Steel Spray Arm And Interior/ White Finish', 222.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (283, 1, 'Canon KP-36IP Color Ink & Paper Set - 7737A001', 'Canon KP-36IP Color Ink & Paper Set - 7737A001/ 36 Sheets Of 4'' x 6'' Photo Paper/ Ink Cartridge For Compatible Canon Dye Sublimation Printer', 12.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (284, 1, 'Linksys Ultra RangePlus Wireless-N Broadband Router - WRT160N', 'Linksys Ultra RangePlus Wireless-N Broadband Router - WRT160N/ Internet-Sharing Router/ 4-Port Switch/ Enhanced Wireless Access Point/ MIMO Technology/ Faster Than Wireless-G/ Protected By Wireless Encryption/ Powerful SPI Firewall/ 2 Antennas/ Glossy Black Finish', 79.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (285, 1, 'Pioneer USB iPod Interface Cable - CDIU230V', 'Pioneer USB iPod Interface Cable - CDIU230V/ Compatible With AVIC-F700BT And AVIC-F900BT Navigation Receivers', 48.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (286, 1, 'Canon White Selphy CP760 Compact Photo Printer - 2565B001', 'Canon White Selphy CP760 Compact Photo Printer - 2565B001/ 2.5'' TFT Display/ Portrait Image Optimize/ Print Water-Resistant Photos/ Print Directly From Your Memory Cards Or Bluetooth-Enabled Devices/ Big Buttons/ Automatic Red-Eye Correction/ White Finish', 95.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (287, 1, 'Sony 2GB Memory Stick Micro (M2) - MSA2GU2', 'Sony MSA2GD 2GB Memory Stick Micro (M2) - MSA2GU2/ Ultra-Small Size/ 2GB Storage Capacity With 1.85GB Available/ Designed For Use In Compatible Small Devices Such As Mobile Phone/ Dual Operating Voltage/ M2 Duo Adaptor Included/ Black Finish', 29.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (288, 1, 'Panasonic DECT 6.0 Silver Digital Cordless Handset - KXTGA630S', 'Panasonic DECT 6.0 Silver Digital Cordless Handset - KXTGA630S/ For Use With Panasonic 6300 And 9300 Series Phone Systems/ DECT 6.0 Technology/ 60 Channels/ Call Waiting Caller ID/ 1.4'' Amber Backlit LCD Display/ Wall Mountable/ 11 Days Standby Time/ 5 Hours Talk Time/ Silver Finish', 29.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (289, 1, 'Polk Audio White Round Two-Way In-Wall Loudspeaker - TC60I', 'Polk Audio White Round Two-Way In-Wall Loudspeaker - TC60I/ Dynamic Balance Polymer Composite Driver/ Aimable 1'' Silk Dome Tweeter With Neodymium Magnet/ 15-Degree Offset Drive Unit/ Wide Dispersion Design/ Durable, Moisture Resistant Materials/ Infinite Baffle Tuning/ Paintable, Powder-Coated Aluminum Grilles/ Conveniently Accessible Front Panel Controls/ Each Speaker Sold Seperately/ White Finish', 299.95); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (290, 1, 'Toshiba Black DVD/VCR Combinaton Player - SDV296', 'Toshiba Black DVD/VCR Combinaton Player - SDV296/ Progressive Scan DVD Player/ One Touch Recording For The VCR/ ColorStream Pro Progressive Scan Component Video Outputs/ Simultaneous DVD Playback And VHS Record/ JPEG Viewer/ Black Finish', 89.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (291, 1, 'Samsung 19'' Black Flat Panel Series 6 LCD HDTV - LN19A650', 'Samsung 19'' Black Flat Panel Series 6 LCD HDTV - LN19A650/ 1440 x 900 True 720p Resolution/ 3,000:1 Dynamic Contrast Ratio/ SRS TruSurround XT/ Built-In Digital Tuner (ATSC/Clear QAM)/ Wide Color Enhancer/ 8ms Response Time/ Touch Of Color Design/ Black With Red Finish', 499.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (292, 1, 'Samsung 22'' Black Flat Panel Series 6 LCD HDTV - LN22A650', 'Samsung 22'' Black Flat Panel Series 6 LCD HDTV - LN22A650/ 1680 x 1050 True 720p Resolution/ 5,000:1 Dynamic Contrast Ratio/ SRS TruSurround XT/ Built-In Digital Tuner (ATSC/Clear QAM)/ Wide Color Enhancer/ 8ms Response Time/ Touch Of Color Design/ Black With Red Finish', 599.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (293, 1, 'Canon Deluxe Burgundy Leather Case - 2350B001', 'Canon Deluxe Burgundy Leather Case - 2350B001/ Genuine Leather Case/ Designed For The PowerShot SD770 IS, SD1100 And SD1000/ Burgundy Finish', 18.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (294, 1, 'Canon Deluxe Black Digital Camera Case - 2595B002', 'Canon Deluxe Black Digital Camera Case - 2595B002/ Soft Nylon Case/ Flip-Down Cover/ Belt Loop Attachment For Hands-Free Convenience/ Compatible With Canon PowerShot A Series/ Black Finish', 13.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (295, 1, 'Griffin iPod RoadTrip With SmartScan - 4040RDTRPB', 'Griffin iPod RoadTrip With SmartScan - 4040RDTRPB/ Play Music From Your iPod On Your Car?s Stereo System As It Charges/ Switch Quickly Between Pre-Sets/ SmartSound Plus Technology Delivers Clear Sound Under Real-World Conditions/ Flexible Steel Neck/ Black Finish', 89.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (296, 1, 'Denon Black Home Theater Surround Sound Receiver - AVR1709', 'Denon Black AVR-1709 Home Theater Surround Sound Receiver - AVR1709/ 80 Watts Per Channel/ 7 Channels/ HDMI V1.3A Video Switching/ Dolby Digital Surround EX, Dolby Pro Logic IIx, DTS ES 6.1, DTS Neo:6 Decoding/ Audyssey MultEQ, Dynamic Volume And Dynamic EQ/ Video Up-Conversion/ Black Finish', 449.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (297, 1, 'Denon Black AVR-1609 Home Theater Surround Sound Receiver - AVR1609', 'Denon Black AVR-1609 Home Theater Surround Sound Receiver - AVR1609/ 75 Watts Per Channel/ 7 Channels/ HDMI V1.3A Video Switching/ Dolby Digital Surround EX, Dolby Pro Logic IIx, DTS ES 6.1, DTS Neo:6 Decoding/ Audyssey MultEQ, Dynamic Volume And Dynamic EQ/ Sirius Satellite Radio Ready/ Network And Digital Media Connectivity/ Black Finish', 349.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (298, 1, 'Sony Bud Style Headphones In Silver - MDRED12LPSLV', 'Sony Bud Style Headphones In Silver - MDRED12LPSLV/ 16mm Drivers/ Crisp Sound/ Neodymium Magnets Offer Powerful Sound Reproduction/ Convenient Cord Slider Reduces Tangles/ 3.9 Ft. Cord Length/ Frequency Response Of 8-22,000Hz/ Silver Finish', 14.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (299, 1, 'Sony Bud Style Headphones In Red - MDRED12LPRED', 'Sony Bud Style Headphones In Red - MDRED12LPRED/ 16mm Drivers/ Crisp Sound/ Neodymium Magnets Offer Powerful Sound Reproduction/ Convenient Cord Slider Reduces Tangles/ 3.9 Ft. Cord Length/ Frequency Response Of 8-22,000Hz/ Red Finish', 14.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (300, 1, 'Sony EX Ear Bud Headphones In Black - MDREX32LPBLK', 'Sony EX Ear Bud Headphones In Black - MDREX32LPBLK/ 9mm Drivers/ Deep Bass Sound/ Neodymium (400kJ/m3) Magnets Offer Powerful Bass Sound Reproduction/ 3.9 Ft. Cord Length/ Frequency Response Of 6-23,000Hz/ Black Finish', 24.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (301, 1, 'Sony EX Ear Bud Headphones In White - MDREX32LPWHI', 'Sony EX Ear Bud Headphones In White - MDREX32LPWHI/ 9mm Drivers/ Deep Bass Sound/ Neodymium (400kJ/m3) Magnets Offer Powerful Bass Sound Reproduction/ 3.9 Ft. Cord Length/ Frequency Response Of 6-23,000Hz/ White Finish', 24.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (302, 1, 'Griffin iPhone SmartTalk - 3016SMRTLKB', 'Griffin iPhone SmartTalk - 3016SMRTLKB/ Adds A Microphone And An iPhone Control Button To Your Favorite Earphones/ Play, Pause And Skip Through Your Tunes/ High-Sensitivity Microphone For Crystal-Clear Phone Conversations/ 30'' Cable Sheathed In Nylon Braiding', 19.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (303, 1, 'Logitech Driving Force Pro Steering Wheel With Pedals Set For Sony Playstation 2 - 9632930403', 'Logitech Driving Force Pro Steering Wheel With Pedals Set For Sony Playstation 2 - 9632930403/ Comfortable Soft Full Rubber Wheel/ Realistically Turn Through 2.5 Times Wheel Rotation/ 900 Degrees Of wheel Steering/ State-Of-The-Art Force Feedback Technology/ Stick Shifter/ Responsive Gas And Brake Pedals/ Black Finish', 129.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (304, 1, 'Monster iCarPlay Wireless 250 FM Transmitter With AutoScan for iPod And iPhone - AIPFMCH250', 'Monster iCarPlay Wireless 250 FM Transmitter With AutoScan For iPod And iPhone - AIPFMCH250/ Plays iPod Or iPhone Music Over Any Car Stereo/ Vibrant Sound/ Works With Any FM Car Radio/ 3 Programmable Presets/ FM Stations Range From 88.1 To 107.9/ Easy To Use/ Convenient Charging While You Drive/ Black Finish', 100.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (305, 1, 'D-Link Broadband Cable Modem - DCM202', 'D-Link Broadband Cable Modem - DCM202/ DOCSIS 2.0 CableLabs Certified/ High-Speed Internet Connectivity/ Always On And Always Connected/ Ethernet Or USB Connectivity/ Front Panel LED Indicator Lights/ Grey Finish', 79.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (306, 1, 'LaCie USB 2.0 Floppy Disk Drive - 706018', 'LaCie USB 2.0 Floppy Disk Drive - 706018/ Ultra-Thin Portable Design/ Compatible With Windows And Mac OS/ Plug And Play/ USB Powered/ 250 - 500 kbps Transfer Rate/ Silver Finish', 49.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (307, 1, 'Toshiba XDE Black 1080p Upconversion Extended Detail DVD Player - XDE500', 'Toshiba XDE Black 1080p Upconversion Extended Detail DVD Player - XDE500/ Full 1080p Upconversion With 24 Frames Per Second/ Detail Enhancement/ Intelligent Color/ Contrast Enhancement/ DivX Certified/ Black Finish', 99.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (308, 1, 'Griffin Black iPhone 3G Wave Case - 8227IP2WVB', 'Griffin Black iPhone 3G Wave Case - 8227IP2WVB/ Elegtant Wave-Shaped Closures/ Durable Polycarbonate Protection/ Rigid Touchscreen Protector/ Full Access To All Ports And Controls/ Black Finish', 24.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (309, 1, 'iHome iPod & iPhone Clock Radio & Audio System - IP99BR', 'iHome iP99 iPod & iPhone Clock Radio & Audio System - IP99BR/ Universal Dock For iPhone/ Auto-Set Clock/ Programmable Snooze/ Charges iPod Or iPhone While Docked/ Reason8 Speaker Chambers/ Line In Jack/ Full Function Remote Control Included/ Dual Alarm Clock/ Extra-Large LCD Display/ Black Finish (iPhone Not Included)', 149.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (310, 1, 'Transcend 8GB SDHC Card And Compact Card Reader - TS8GSDHC6S5W', 'Transcend 8GB SDHC Card And Compact Card Reader - TS8GSDHC6S5W/ SDHC Card Is Class 6 Compliant And Compatible With All SDHC-Labeled Host Devices/ Card Reader Is Fully Compatible With Hi Speed USB 2.0, Up To 480Mb/s And Supports SDHC Memory Cards', 26.30); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (311, 1, 'Denon 7.1 Channel AV Receiver With Network Client Compatible D-Dock Port In Black - AVR2809CI', 'Denon 7.1 Channel AV Home Theater Surround Receiver With Network Client Compatible D-Dock Port In Black - AVR2809CI/ 110 Watts x 7 Channels/ 1080p Upscaling/ PC Setup And Control Capability Via RS-232C/ Network Capable/ XM Satellite Radio Ready/ Dolby TrueHD And DTS-HD Master Audio/ HDMI 1.3a Repeater Inputs-Outputs/ Dual Remotes/ Black Finish', 1199.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (312, 1, 'LaCie Little Disk 320GB Black Portable Hard Drive - 301829', 'LaCie Little Disk 320GB Black Portable Hard Drive - 301829/ Compact, Thin And Lightweight Design/ Back Up, Synchronize And Secure Files And Settings/ Extractable Integrated USB Cable And Protective Cap/ Hi-Speed USB 2.0/ PC And Mac Compatible/ Black Finish', 119.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (313, 1, 'LaCie Little Disk 250GB Black Portable Hard Drive - 301278', 'LaCie Little Disk 250GB Black Portable Hard Drive - 301278/ Compact, Thin And Lightweight Design/ Back Up, Synchronize And Secure Files And Settings/ Extractable Integrated USB Cable And Protective Cap/ Hi-Speed USB 2.0/ PC And Mac Compatible/ Black Finish', 99.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (314, 1, 'AppleCare Protection Plan For iPod Touch Or iPod Classic - MB591LLA', 'AppleCare Protection Plan For iPod Touch Or iPod Classic - MB591LLA/ Extends Your Service Coverage To Up To Two Years/ Includes Both Phone And In Store Techinical Support', 59.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (315, 1, 'Nikon CoolPix S610 10 Megapixel Black Digital Camera - COOLPIXS610BK', 'Nikon CoolPix S610 10 Megapixel Black Digital Camera - COOLPIXS610BK/ 10.0 Megapixels/ 4x Zoom-NIKKOR Lens/ 3.0'' High-Resolution Wide-Viewing Angle LCD Monitor/ Scene Auto Selector/ Active Child Mode/ Smile And Food Mode/ Face-Priority AF/ In-Camera Red-Eye Fix/ D-Lighting/ Midnight Black Finish', 249.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (316, 1, 'Sony VAIO Black USB Docking Station - VGPUPR1', 'Sony VAIO Black USB Docking Station - VGPUPR1/ Perfect For The Constant Traveler Or Mobile Professional/ Easily Connect All Of Necessary Peripherals/ VGA Port/ 4 USB Ports/ Ethernet Port/ Headphone And Microphone Ports/ Compatible With VAIO CR Series, FZ Series, FW Series, NR Series And AR Series Notebooks/ Black Finish', 199.99); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (317, 1, 'Nikon SB-900 AF Speedlight In Black - SB900', 'Nikon AF Speedlight In Black - SB900/ Wireless Commander Mode/ Control Up To Three Remote/ 3 Light Distribution Patterns/ Flash Tube Overheat Protection/ Drip-Proof Mounting Foot Cover (Water Guard)/ Color Gel Filter Identification/ Black Finish', 499.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (318, 1, 'Denon D-M37 Black CD/AM/FM Micro System - DM37SBK', 'Denon D-M37 Black CD/AM/FM Micro System - DM37SBK/ 30 Watts x 2 Amplifier/ Precision Burr-Brown Audiophile Quality DACs/ MP3 And WMA Tracks Playback Capability/ European Engineered Loudspeakers/ 120mm Long-Throw D.D.L Double-Layered Cone Woofer/ 25mm Soft Dome Tweeter With Extended Response/ Triadic Noise Reduction Concept/ Portable Player Connectivity/ Black Finish', 399.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (319, 1, 'Griffin iPhone 3G Black Elan Form Hard-Shell Leather Case - 8223IP2EFRMB', 'Griffin iPhone 3G Black Elan Form Hard-Shell Leather Case - 8223IP2EFRMB/ Top-Grain Outer Shell Crafted From Hand-Matched Leather/ Protective Polycarbonate Inner Shell/ Easy Access To Controls/ Includes Stiff Polycarbonate Screen Protector & Premium Cleaning Cloth/ Black Finish (iPhone Not Included)', 24.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (320, 1, 'Speck Black ToughSkin Case For iPhone 3G - IPH3GBLKTS', 'Speck Black ToughSkin Case For iPhone 3G - IPH3GBLKTS/ Tough, Textured And Ruggedized Protection/ Bottom Hinges Open To Allow Docking/ Thicker Corners For Extra Protection/ Removable Rotating Belt Clip/ Lightweight Design/ Easy Access To All Ports & Controls/ Black Finish (iPhone Not Included)', 34.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (321, 1, 'Canon PIXMA iP2600 Photo Printer - IP2600', 'Canon PIXMA Photo Printer - IP2600/ 4800 x 1200 Color dpi/ Spectacular Resolution/ Fast Photo Printing/ FINE Technology/ 1,472 Precision Nozzles/ Auto Image Fix/ Easy-PhotoPrint EX Software/ 4 In 1 Or 2 In 1 Printing/ Energy Star Qualified/ Borderless 4'' x 6'' Print Approx. 55 Seconds/ Windows And Mac Compatible', 49.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (322, 1, 'Klipsch 5.25'' THX Ultra2 In-Ceiling White Loudspeaker - KS7502THX', 'Klipsch 5.25'' THX Ultra2 In-Ceiling White Loudspeaker - KS7502THX/ 100W Continuous/400W Peak Power Handling/ Dual 1'' Titanium Diaphragm Compression Drivers Mated To WDST Tractrix Horn Array/ Dual 5.25'' High-Output Cerametallic Cone Woofers/ MDF And Aluminum Motorboard/ABS Shell Enclosure/ White Finish/ Price Per Speaker', 1000.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (323, 1, 'Canon PIXMA Photo All-In-One Printer - MP620', 'Canon PIXMA Photo All-In-One Printer - MP620/ High Performance Printer And Copier, Scanner/ Easy Scroll Wheel/ Dual Paper Trays/ 2.5'' High Definition LCD Display/ Maximum 9600 x 2400 Color Dpi/ Automatic Image Optimization/ Quick Start/ Wi-Fi Ready/ Built-In Media Card Slot/ ENERGY STAR Qualified', 149.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (324, 1, 'TiVo HD XL Black Digital Video Recorder - TCD658000', 'TiVo HD XL Black Digital Video Recorder - TCD658000/ Search, Record And Watch Shows In HD/ Save Up To 150 Hours Of HD Programming At A Time/ Control Cable TV With Pause, Rewind, Fast-Forward, And Slow-Motion/ Record Two Shows At Once In HD/ Digital Transition Ready/ Backlit Remote Control/ Netflix Instant Streaming/ TiVo Service Required And Sold Separately', 599.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (325, 1, 'Apple 8GB Black 2nd Generation iPod Touch - MB528LLA', 'Apple 8GB Black 2nd Generation iPod Touch - MB528LLA/ Holds Up To 1,750 Songs In 128-Kbps AAC Format, 10,000 iPod-Viewable Photos And 10 Hours Of Video/ Wi-Fi (802.11b/g)/ Nike + iPod Support Built-In/ Maps Location-Based Service/ 3.5'' (Diagonal) Widescreen Multi-Touch Display/ 480x320-Pixel Resolution/ 480p And 576p Component TV Out/ Mac And Windows Compatible/ Black Finish', 229.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (326, 1, 'Apple 16GB Black 2nd Generation iPod Touch - MB531LLA', 'Apple 16GB Black 2nd Generation iPod Touch - MB531LLA/ Holds Up To 3,500 Songs In 128-Kbps AAC Format, 20,000 iPod-Viewable Photos And 20 Hours Of Video/ Wi-Fi (802.11b/g)/ Nike + iPod Support Built-In/ Maps Location-Based Service/ 3.5'' (Diagonal) Widescreen Multi-Touch Display/ 480x320-Pixel Resolution/ 480p And 576p Component TV Out/ Mac And Windows Compatible/ Black Finish', 299.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (327, 1, 'Apple 32GB Black 2nd Generation iPod Touch - MB533LLA', 'Apple 32GB Black 2nd Generation iPod Touch - MB533LLA/ Holds Up To 7,000 Songs In 128-Kbps AAC Format, 25,000 iPod-Viewable Photos And 40 Hours Of Video/ Wi-Fi (802.11b/g)/ Nike + iPod Support Built-In/ Maps Location-Based Service/ 3.5'' (Diagonal) Widescreen Multi-Touch Display/ 480x320-Pixel Resolution/ 480p And 576p Component TV Out/ Mac And Windows Compatible/ Black Finish', 399.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (328, 1, 'Apple 8GB Silver 4th Generation iPod Nano - MB598LLA', 'Apple 8GB Silver 4th Generation iPod Nano - MB598LLA/ Holds Up To 2,000 Songs In 128-Kbps AAC Format, 7,000 iPod-Viewable Photos And 8 Hours Of Video/ 2'' (Diagonal) Liquid Crystal Display With Blue-White LED Backlight/ 320-By-240-Pixel Resolution/ Give It A Shake To Shuffle Your Music/ Turn It Sideways To View Cover Flow/ Mac And Windows Compatible/ Silver Finish', 144.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (329, 1, 'Apple 8GB Blue 4th Generation iPod Nano - MB732LLA', 'Apple 8GB Blue 4th Generation iPod Nano - MB732LLA/ Holds Up To 2,000 Songs In 128-Kbps AAC Format, 7,000 iPod-Viewable Photos And 8 Hours Of Video/ 2'' (Diagonal) Liquid Crystal Display With Blue-White LED Backlight/ 320-By-240-Pixel Resolution/ Give It A Shake To Shuffle Your Music/ Turn It Sideways To View Cover Flow/ Mac And Windows Compatible/ Blue Finish', 149.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (330, 1, 'Apple 8GB Pink 4th Generation iPod Nano - MB735LLA', 'Apple 8GB Pink 4th Generation iPod Nano - MB735LLA/ Holds Up To 2,000 Songs In 128-Kbps AAC Format, 7,000 iPod-Viewable Photos And 8 Hours Of Video/ 2'' (Diagonal) Liquid Crystal Display With Blue-White LED Backlight/ 320-By-240-Pixel Resolution/ Give It A Shake To Shuffle Your Music/ Turn It Sideways To View Cover Flow/ Mac And Windows Compatible/ Pink Finish', 144.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (331, 1, 'Apple 8GB Purple 4th Generation iPod Nano - MB739LLA', 'Apple 8GB Purple 4th Generation iPod Nano - MB739LLA/ Holds Up To 2,000 Songs In 128-Kbps AAC Format, 7,000 iPod-Viewable Photos And 8 Hours Of Video/ 2'' (Diagonal) Liquid Crystal Display With Blue-White LED Backlight/ 320-By-240-Pixel Resolution/ Give It A Shake To Shuffle Your Music/ Turn It Sideways To View Cover Flow/ Mac And Windows Compatible/ Purple Finish', 149.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (332, 1, 'Apple 8GB Green 4th Generation iPod Nano - MB745LLA', 'Apple 8GB Green 4th Generation iPod Nano - MB745LLA/ Holds Up To 2,000 Songs In 128-Kbps AAC Format, 7,000 iPod-Viewable Photos And 8 Hours Of Video/ 2'' (Diagonal) Liquid Crystal Display With Blue-White LED Backlight/ 320-By-240-Pixel Resolution/ Give It A Shake To Shuffle Your Music/ Turn It Sideways To View Cover Flow/ Mac And Windows Compatible/ Green Finish', 149.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (333, 1, 'Apple 8GB Black 4th Generation iPod Nano - MB754LLA', 'Apple 8GB Black 4th Generation iPod Nano - MB754LLA/ Holds Up To 2,000 Songs In 128-Kbps AAC Format, 7,000 iPod-Viewable Photos And 8 Hours Of Video/ 2'' (Diagonal) Liquid Crystal Display With Blue-White LED Backlight/ 320-By-240-Pixel Resolution/ Give It A Shake To Shuffle Your Music/ Turn It Sideways To View Cover Flow/ Mac And Windows Compatible/ Black Finish', 144.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (334, 1, 'Apple 1GB Pink 2nd Generation iPod Shuffle - MB811LLA', 'Apple 1GB Pink 2nd Generation iPod Shuffle - MB811LLA/ Holds Up To 240 Songs In 128-Kbps AAC Format/ 12 Hours Of Continuous Playback/ Skip-Free Playback/ Battery Indicator/ Shuffle Switch/ Built-In Clip/ Mac And Windows Compatible/ Pink Finish', 49.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (335, 1, 'Sony BRAVIA Black SXRD 1080p Home Theater Front Projector - VPLHW10', 'Sony BRAVIA Black SXRD 1080p Home Theater Front Projector - VPLHW10/ SXRD 1920 x 1080p Full HD Panels/ 30,000:1 Dynamic Contrast Ratio/ Fully Digital Signal Processing/ 200Watts Ultra-High-Pressure Lamp/ Whisper-Quiet Fan Noise And Noise Reduction Function/ Two HDMI Inputs/ BRAVIA Theatre Sync/ Remote Commander/ Black Finish', 3499.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (336, 1, 'Canon PIXMA Black Photo Printer - IP4600', 'Canon PIXMA Black Photo Printer - IP4600/ Premium Printer With Individual Ink Tanks And Built-In Auto Duplex/ Print 4'' x 6'' Photo In 20 Seconds/ Dual Paper Trays/ Maximum 9600 x 2400 Color Dpi/ Automatic Image Optimization/ ENERGY STAR Qualified/ Black Finish', 99.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (337, 1, 'Canon PIXMA Photo All-In-One Printer - MP980', 'Canon PIXMA Photo All-In-One Printer - MP980/ High Performance Wireless Printer, Copier And Scanner/ Easy Scroll Wheel/ 3.5'' High Definition LCD Display/ Maximum 9600 x 2400 Color Dpi/ Six Individual Inks Tanks/ Auto Duplex Print/ Smart Copying/ Automatic Image Optimization/ No Warm-Up/ ENERGY STAR Qualified', 299.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (338, 1, 'Nintendo DS Lite Cobalt/Black Portable Gaming System - NDSUSGBMKB', 'Nintendo DS Lite Cobalt/Black Portable Gaming System - NDSUSGBMKB/ Dual 3'' TFT Color LCD Touchscreens/ Slimmer Design/ Dual Slot Compatibility (DS Lite/Game Boy Advance Game Paks)/ Twin Ultra Bright LCD Screens/ Up To 19 Hours Continuous Gameplay/ Nintendo Wi-Fi Connection/ Impressive 3D Graphics/ Dual Stereo Speakers/ Cobalt and Black Finish', 139.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (339, 1, 'Nintendo DS Lite Onyx Black Portable Gaming System - NDSUSGSKB', 'Nintendo DS Lite Onyx Black Portable Gaming System - NDSUSGSKB/ Dual 3'' TFT Color LCD Touchscreens/ Slimmer Design/ Dual Slot Compatibility (DS Lite/Game Boy Advance Game Paks)/ Twin Ultra Bright LCD Screens/ Up To 19 Hours Continuous Gameplay/ Nintendo Wi-Fi Connection/ Impressive 3D Graphics/ Dual Stereo Speakers/ Onyx Black Finish', 139.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (340, 1, 'Nintendo DS Lite Metallic Silver Portable Gaming System - NDSUSGSVB', 'Nintendo DS Lite Metallic Silver Portable Gaming System - NDSUSGSVB/ Dual 3'' TFT Color LCD Touchscreens/ Slimmer Design/ Dual Slot Compatibility (DS Lite/Game Boy Advance Game Paks)/ Twin Ultra Bright LCD Screens/ Up To 19 Hours Continuous Gameplay/ Nintendo Wi-Fi Connection/ Impressive 3D Graphics/ Dual Stereo Speakers/ Metallic Silver Finish', 139.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (341, 1, 'Nintendo DS Lite Metallic Rose Portable Gaming System - NDSUSGSZPB', 'Nintendo DS Lite Metallic Rose Portable Gaming System - NDSUSGSZPB/ Dual 3'' TFT Color LCD Touchscreens/ Slimmer Design/ Dual Slot Compatibility (DS Lite/Game Boy Advance Game Paks)/ Twin Ultra Bright LCD Screens/ Up To 19 Hours Continuous Gameplay/ Nintendo Wi-Fi Connection/ Impressive 3D Graphics/ Dual Stereo Speakers/ Metallic Rose Finish', 139.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (342, 1, 'Case Logic Vertical Universal Leather BlackBerry Case - CLP104BB', 'Case Logic Vertical Universal Leather BlackBerry Case - CLP104BB/ 360 Degree Swivel Belt Clip/ Magnetic Closure/ Soft Internal Lining/ Expandable Elastic Sides/ Compatible With Most BlackBerrys/ Leather Fabric/ Black Finish', 15.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (343, 1, 'Nintendo DS Lite Crimson/Black Portable Gaming System - NDSUSGSRMKB', 'Nintendo DS Lite Crimson/Black Portable Gaming System - NDSUSGSRMKB/ Dual 3'' TFT Color LCD Touchscreens/ Slimmer Design/ Dual Slot Compatibility (DS Lite/Game Boy Advance Game Paks)/ Twin Ultra Bright LCD Screens/ Up To 19 Hours Continuous Gameplay/ Nintendo Wi-Fi Connection/ Impressive 3D Graphics/ Dual Stereo Speakers/ Crimson/Black Finish', 139.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (344, 1, 'BlueAnt Bluetooth Voice Control Headset - V1', 'BlueAnt Bluetooth Voice Control Headset - V1/ Voice Control User Interface/ Voice Isolation Technology/ Dual Microphones/ Pairs With Up To 8 Bluetooth Devices/ Up To 5 Hours Talk-Time/ 3 Charging Options', 119.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (345, 1, 'Netgear Prosafe 5 Port Gigabit Ethernet Desktop Switch - GS105NA', 'Netgear Prosafe 5 Port Gigabit Ethernet Desktop Switch - GS105NA/ Auto-Switching Ethernet Connection/ Supports Windows And Macintosh Platforms/ Dual Color LEDs/ AutoUplink Technology/ Compact Metal Case/ Fanless Design/ Plug-And-Play Installation', 55.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (346, 1, 'Jabra Bluetooth Headset - BT2070', 'Jabra Bluetooth Headset - BT2070/ Up To 5.5 Hours Talk Time/ Up To 200 Hours Standby Time/ Earhook Included/ Bluetooth 2.0+ EDR & eSCO Technology/ Auto-Pairing/ Discreet Light/ Answer/End, Redial And Voice Dial Features/ USB Micro-B, 5-Pin Charging Plug', 49.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (347, 1, 'Canon Printer Ink Cartridge 4 Colors Pack - 2946B004', 'Canon Printer Ink Cartridge 4 Colors Pack - 2946B004/ FINE Technology For Exceptional Sharpness And Detail/ Compatible With PIXMA iP3600, PIXMA iP4600, PIXMA MP620 And PIXMA MP980/ Includes 4 Ink Tanks (Black, Cyan, Magenta, Yellow)', 47.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (348, 1, 'Canon PIXMA Photo All-In-One Printer - MP480', 'Canon PIXMA Photo All-In-One Printer - MP480/ High Performance Printer, Copier And Scanner/ 1.8'' TFT Display/ Maximum 2400 x 4800 Color Dpi/ Smart Scanning/ Quick Start/ Built-In Media Card Slot/ ENERGY STAR Qualified', 99.00); +INSERT INTO Product(id, modificationCounter, title, description, price) VALUES (349, 1, 'Sanus 30'' - 58'' VisionMount Flat Panel TV Black Tilting Wall Mount - LT25B1', 'Sanus 30'' - 58'' VisionMount Flat Panel TV Black Tilting Wall Mount - LT25B1/ Lateral Shift Adjustment/ Virtual Axis/ Height and Level Adjustments/ ClickStand/ ClickFit System/ Open Wall Plate/ Black Finish', 199.00); diff --git a/src/test/java/com/devonfw/demoquarkus/service/v1/ProductRestServiceTest.java b/src/test/java/com/devonfw/demoquarkus/service/v1/ProductRestServiceTest.java index a67186c9..56c63b05 100644 --- a/src/test/java/com/devonfw/demoquarkus/service/v1/ProductRestServiceTest.java +++ b/src/test/java/com/devonfw/demoquarkus/service/v1/ProductRestServiceTest.java @@ -1,100 +1,96 @@ -package com.devonfw.demoquarkus.service.v1; - -import static io.restassured.RestAssured.given; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.notNullValue; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import java.math.BigDecimal; - -import javax.ws.rs.core.MediaType; - -import org.junit.jupiter.api.Test; -import org.tkit.quarkus.rs.models.PageResultDTO; -import org.tkit.quarkus.test.WithDBData; -import org.tkit.quarkus.test.docker.DockerComposeTestResource; - -import com.devonfw.quarkus.productmanagement.service.v1.model.ProductDto; - -import io.quarkus.test.common.QuarkusTestResource; -import io.quarkus.test.junit.QuarkusTest; -import io.restassured.common.mapper.TypeRef; -import io.restassured.response.Response; - -//Before you run this test, tkit-test extension starts docker containers from resources/docker-compose.yaml -//we get a real postgresdb for our tests which will be stopped after tests. No manual test setup is needed. -@QuarkusTest -@QuarkusTestResource(DockerComposeTestResource.class) -class ProductRestServiceTest {// extends AbstractTest { - - @Test - // we also started a micro container, that can populated DB with data from excel - // annotating class or method with @WithDBData allows us to scope data for each test even if we use the same DB - @WithDBData(value = "data/product.xls", deleteBeforeInsert = true) - void getAll() { - - Response response = given().when().contentType(MediaType.APPLICATION_JSON).get("/products").then().statusCode(200) - .extract().response(); - - PageResultDTO productsReturned = response.as(new TypeRef>() { - }); - - // we import data from /import.sql - ergo expect 1 result - assertEquals(2, productsReturned.getTotalElements()); - } - - @Test - void getNonExistingTest() { - - Response response = given().when().contentType(MediaType.APPLICATION_JSON).get("/products/doesnoexist").then().log() - .all().statusCode(404).extract().response(); - } - - @Test - @WithDBData(value = "data/empty.xls", deleteBeforeInsert = true) - void createNewProduct() { - - ProductDto product = new ProductDto(); - product.setTitle("HP Notebook"); - product.setDescription("ZBook"); - product.setPrice(BigDecimal.valueOf(1)); - - Response response = given().when().body(product).contentType(MediaType.APPLICATION_JSON).post("/products").then() - .log().all().statusCode(201).header("Location", notNullValue()).extract().response(); - - assertEquals(201, response.statusCode()); - - response = given().when().contentType(MediaType.APPLICATION_JSON).get("/products").then().log().all() - .statusCode(200).extract().response(); - - PageResultDTO productsReturned = response.as(new TypeRef<>() { - }); - assertEquals(1, productsReturned.getTotalElements()); - ProductDto created = productsReturned.getStream().get(0); - assertNotNull(created); - assertEquals(product.getTitle(), created.getTitle()); - } - - @Test - @WithDBData(value = "data/product.xls", deleteBeforeInsert = true) - public void testGetById() { - - given().when().log().all().contentType(MediaType.APPLICATION_JSON).get("/products/1").then().statusCode(200) - .body("description", equalTo("Apple Notebook")); - } - - @Test - @WithDBData(value = "data/product.xls", deleteBeforeInsert = true) - public void deleteById() { - - // delete - given().when().log().all().contentType(MediaType.APPLICATION_JSON).delete("/products/1").then().statusCode(200) - .body("title", equalTo("MacBook Pro")); - - // after deletion it should be deleted - given().when().log().all().contentType(MediaType.APPLICATION_JSON).get("/products/1").then().statusCode(404); - - } - +package com.devonfw.demoquarkus.service.v1; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.math.BigDecimal; +import java.util.LinkedHashMap; +import java.util.List; + +import javax.ws.rs.core.MediaType; + +import org.junit.jupiter.api.Test; +import org.tkit.quarkus.test.WithDBData; +import org.tkit.quarkus.test.docker.DockerComposeTestResource; + +import com.devonfw.quarkus.productmanagement.service.v1.model.ProductDto; + +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusTest; +import io.restassured.response.Response; + +//Before you run this test, tkit-test extension starts docker containers from resources/docker-compose.yaml +//we get a real postgresdb for our tests which will be stopped after tests. No manual test setup is needed. +@QuarkusTest +@QuarkusTestResource(DockerComposeTestResource.class) +class ProductRestServiceTest {// extends AbstractTest { + + @Test + // we also started a micro container, that can populated DB with data from excel + // annotating class or method with @WithDBData allows us to scope data for each test even if we use the same DB + @WithDBData(value = "data/product.xls", deleteBeforeInsert = true) + void getAll() { + + Response response = given().when().contentType(MediaType.APPLICATION_JSON).get("/products").then().statusCode(200) + .extract().response(); + + int products = Integer.valueOf(response.jsonPath().getString("totalElements")); + assertEquals(2, products); + } + + @Test + void getNonExistingTest() { + + Response response = given().when().contentType(MediaType.APPLICATION_JSON).get("/products/doesnoexist").then().log() + .all().statusCode(500).extract().response(); + } + + @Test + @WithDBData(value = "data/empty.xls", deleteBeforeInsert = true) + void createNewProduct() { + + ProductDto product = new ProductDto(); + product.setTitle("HP Notebook"); + product.setDescription("ZBook"); + product.setPrice(BigDecimal.valueOf(1)); + + Response response = given().when().body(product).contentType(MediaType.APPLICATION_JSON).post("/products").then() + .log().all().statusCode(200).header("Location", nullValue()).extract().response(); + + assertEquals(200, response.statusCode()); + + response = given().when().contentType(MediaType.APPLICATION_JSON).get("/products").then().log().all() + .statusCode(200).extract().response(); + + int products = Integer.valueOf(response.jsonPath().getString("totalElements")); + assertEquals(1, products); + List> created = response.jsonPath().getList("content"); + assertNotNull(created); + assertEquals(product.getTitle(), created.get(0).get("title")); + } + + @Test + @WithDBData(value = "data/product.xls", deleteBeforeInsert = true) + public void testGetById() { + + given().when().log().all().contentType(MediaType.APPLICATION_JSON).get("/products/1").then().statusCode(200) + .body("description", equalTo("Apple Notebook")); + } + + @Test + @WithDBData(value = "data/product.xls", deleteBeforeInsert = true) + public void deleteById() { + + // delete + given().when().log().all().contentType(MediaType.APPLICATION_JSON).delete("/products/1").then().statusCode(200) + .body("title", equalTo("MacBook Pro")); + + // after deletion it should be deleted + given().when().log().all().contentType(MediaType.APPLICATION_JSON).get("/products/1").then().statusCode(500); + + } + } \ No newline at end of file diff --git a/src/test/resources/data/empty.xls b/src/test/resources/data/empty.xls index 1ee268f0..739015dc 100644 Binary files a/src/test/resources/data/empty.xls and b/src/test/resources/data/empty.xls differ diff --git a/src/test/resources/data/product.xls b/src/test/resources/data/product.xls index cbc64915..8738a93d 100644 Binary files a/src/test/resources/data/product.xls and b/src/test/resources/data/product.xls differ diff --git a/src/test/resources/docker-compose.yml b/src/test/resources/docker-compose.yml index cdabc2d5..289e9153 100644 --- a/src/test/resources/docker-compose.yml +++ b/src/test/resources/docker-compose.yml @@ -1,30 +1,30 @@ -version: '3.9' -services: - demo-db: - container_name: demo-db - image: postgres:11.5 - environment: - POSTGRES_DB: "demo" - POSTGRES_USER: "demo" - POSTGRES_PASSWORD: "demo" - labels: - - "test.priority=90" - - "test.Wait.forLogMessage.regex=.*database system is ready to accept connections.*\\s" - - "test.Wait.forLogMessage.times=2" - - "test.log=true" - # we can modify Quarkus test profile apps using labels in form `test.property.` - - "test.property.quarkus.datasource.jdbc.url=jdbc:postgresql://$${host:demo-db}:$${port:demo-db:5432}/demo?sslmode=disable" - # simple DB import app, that allows import of data from Excel files - dbimport: - container_name: dbimport - image: quay.io/tkit/dbimport:master - environment: - DB_URL: "jdbc:postgresql://demo-db:5432/demo?sslmode=disable" - DB_USERNAME: "demo" - DB_PASSWORD: "demo" - labels: - - "test.Wait.forLogMessage.regex=.*Installed features:.*" - - "test.Wait.forLogMessage.times=1" - - "test.log=true" - - "test.property.tkit.test.dbimport.url=$${url:dbimport:8080}" - +version: '3.9' +services: + demo-db: + container_name: demo-db + image: postgres:11.5 + environment: + POSTGRES_DB: "demo" + POSTGRES_USER: "demo" + POSTGRES_PASSWORD: "demo" + labels: + - "test.priority=90" + - "test.Wait.forLogMessage.regex=.*database system is ready to accept connections.*\\s" + - "test.Wait.forLogMessage.times=2" + - "test.log=true" + # we can modify Quarkus test profile apps using labels in form `test.property.` + - "test.property.quarkus.datasource.jdbc.url=jdbc:postgresql://$${host:demo-db}:$${port:demo-db:5432}/demo?sslmode=disable" + # simple DB import app, that allows import of data from Excel files + dbimport: + container_name: dbimport + image: quay.io/tkit/dbimport:master + environment: + DB_URL: "jdbc:postgresql://demo-db:5432/demo?sslmode=disable" + DB_USERNAME: "demo" + DB_PASSWORD: "demo" + labels: + - "test.Wait.forLogMessage.regex=.*Installed features:.*" + - "test.Wait.forLogMessage.times=1" + - "test.log=true" + - "test.property.tkit.test.dbimport.url=$${url:dbimport:8080}" + diff --git a/vMetrics.yaml b/vMetrics.yaml index 85205f6f..ff948c02 100644 --- a/vMetrics.yaml +++ b/vMetrics.yaml @@ -1,9 +1,9 @@ -scrape_configs: - #- job_name: 'otel-collector' - - job_name: "demo_quarkus" - scrape_interval: 10s - metrics_path: "/q/metrics" - static_configs: - - targets: ["host.docker.internal:8080"] - #- targets: ['otel-collector:8889'] +scrape_configs: + #- job_name: 'otel-collector' + - job_name: "demo_quarkus" + scrape_interval: 10s + metrics_path: "/q/metrics" + static_configs: + - targets: ["host.docker.internal:8080"] + #- targets: ['otel-collector:8889'] #- targets: ['otel-collector:8888'] \ No newline at end of file