diff --git a/cloud-claim-check-pattern/.gitignore b/cloud-claim-check-pattern/.gitignore deleted file mode 100644 index f508cf94f..000000000 --- a/cloud-claim-check-pattern/.gitignore +++ /dev/null @@ -1,38 +0,0 @@ -# Build output -target/ -*.class - -# Log file -*.log - -# BlueJ files -*.ctxt - -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - -# Package Files # -*.jar -*.war -*.ear -*.zip -*.tar.gz -*.rar - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* - -# IDE -.idea/ -*.iml -.settings/ -.project -.classpath - -# macOS -.DS_Store - -# Azure Functions -local.settings.json -bin/ -obj/ diff --git a/cloud-claim-check-pattern/README.md b/cloud-claim-check-pattern/README.md deleted file mode 100644 index b17866177..000000000 --- a/cloud-claim-check-pattern/README.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -title: Claim Check Pattern -category: Cloud -language: en -tag: - - Cloud distributed - - Microservices ---- - -## Name - -[Claim Check Pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/claim-check) - -## Also known as - -[Reference-Based Messaging](https://www.enterpriseintegrationpatterns.com/patterns/messaging/StoreInLibrary.html) - -## Intent - -- Reduce the load of data transfer through the Internet. Instead of sending actual data directly, just send the message reference. -- Improve data security. As only message reference is shared, no data is exposed to the Internet. - -## Explanation - -Real-World Example - -> Suppose if you want to build a photo processing system. A photo processing system takes an image as input, processes it, and outputs a different set of images. Consider system has one persistent storage, one input component, ten processing components, messaging platform. Once a photo is given to the input component, it stores that image on persistent storage. It then creates ten different messages/events with the same image location and publishes them to the messaging platform. The messaging platform triggers ten different processing components. The ten processing components extract information about image location from the received event and then read an image from persistent storage. They generate ten different images from the original image and drop these images again to persistent storage. - -In Plain words - -> Split a large message into a claim check and a payload. Send the claim check to the messaging platform and store the payload to an external service. This pattern allows large messages to be processed while protecting the message bus and the client from being overwhelmed or slowed down. This pattern also helps to reduce costs, as storage is usually cheaper than resource units used by the messaging platform.([ref](https://docs.microsoft.com/en-us/azure/architecture/patterns/claim-check)) - -## Architecture Diagram - -![alt text](./etc/Claim-Check-Pattern.png "Claim Check Pattern") - -## Applicability - -Use the Claim Check Pattern when - -- Huge processing data causes a lot of bandwidth consumption to transfer data through the Internet. -- To secure your data transfer by storing in common persistent storage. -- Using a cloud platform - Azure Functions or AWS Lambda, Azure EventGrid or AWS Event Bridge, Azure Blob Storage or AWS S3 Bucket. -- Each service must be independent and idempotent. Output data is dropped to persistent storage by the service. -- Publish-subscribe messaging pattern needs to be used. - -## Consequences - -- This pattern is stateless. Any compute API will not store any data. -- You must have persistent storage and a reliable messaging platform. - -## Tutorials - -### Workflow - -Suppose a telecom company wants to build call cost calculator system which generate the call cost daily. At the end of each day, details of the calls made by the consumers are stored somewhere. The call calculator system will read this data and generate call cost data for each user. Consumers will be billed using this generated data in case of postpaid service. - -Producer class( `UsageDetailPublisherFunction` Azure Function) will generate call usage details (here we are generating call data in producer class itself. In real world scenario, it will read from storage). `UsageDetailPublisherFunction` creates a message. Message consists of message header and message body. Message header is basically an event grid event or claim or message reference. Message body contains actual data. `UsageDetailPublisherFunction` sends a message header to Event Grid topic `usage-detail` and drops an entire message to the blob storage. Event Grid then sent this message header to the `UsageCostProcessorFunction` Azure function. It will read the entire message from blob storage with the help of the header, will calculate call cost and drop the result to the blob storage. - -### Class Diagrams - -![alt text](./etc/class-diagram.png "Claim-Check-Class-Diagram") - -### Setup - -- Any operating system can be used macOS, Windows, Linux as everything is deployed on Azure. -- Install Java JDK 11 and set up Java environmental variables. -- Install Git. -- Install Visual Studio Code. -- Install [ Azure Functions extension](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azurefunctions) to be able to deploy using Visual studio. - -### Storage Data - -The data is stored in the Azure blob storage in the container `callusageapp`. For every trigger, one GUID is created. Under the `GUID folder`, 2 files will be created `input.json` and `output.json`. -`Input.json` is dropped `producer` azure function which contains call usage details.` Output.json` contains call cost details which are dropped by the `consumer` azure function. - -## Credits - -- [Messaging Pattern - Claim Check](https://www.enterpriseintegrationpatterns.com/patterns/messaging/StoreInLibrary.html) -- [Azure Architecture Pattern - Claim Check Pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/claim-check) diff --git a/cloud-claim-check-pattern/call-usage-app/.gitignore b/cloud-claim-check-pattern/call-usage-app/.gitignore deleted file mode 100644 index f508cf94f..000000000 --- a/cloud-claim-check-pattern/call-usage-app/.gitignore +++ /dev/null @@ -1,38 +0,0 @@ -# Build output -target/ -*.class - -# Log file -*.log - -# BlueJ files -*.ctxt - -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - -# Package Files # -*.jar -*.war -*.ear -*.zip -*.tar.gz -*.rar - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* - -# IDE -.idea/ -*.iml -.settings/ -.project -.classpath - -# macOS -.DS_Store - -# Azure Functions -local.settings.json -bin/ -obj/ diff --git a/cloud-claim-check-pattern/call-usage-app/etc/call-usage-app.urm.puml b/cloud-claim-check-pattern/call-usage-app/etc/call-usage-app.urm.puml deleted file mode 100644 index 0ffec48b1..000000000 --- a/cloud-claim-check-pattern/call-usage-app/etc/call-usage-app.urm.puml +++ /dev/null @@ -1,117 +0,0 @@ -@startuml -package com.iluwatar.claimcheckpattern.producer.calldetails.functions { - class UsageDetailPublisherFunction { - - eventHandlerUtility : EventHandlerUtility - - messageHandlerUtility : MessageHandlerUtility - + UsageDetailPublisherFunction() - + UsageDetailPublisherFunction(messageHandlerUtility : MessageHandlerUtility, eventHandlerUtility : EventHandlerUtility) - + run(request : HttpRequestMessage>, context : ExecutionContext) : HttpResponseMessage - } -} -package com.iluwatar.claimcheckpattern.domain { - class Message { - - messageBody : MessageBody - - messageHeader : MessageHeader - + Message() - + getMessageBody() : MessageBody - + getMessageHeader() : MessageHeader - + setMessageBody(messageBody : MessageBody) - + setMessageHeader(messageHeader : MessageHeader) - } - class MessageBody { - - data : List - + MessageBody() - + getData() : List - + setData(data : List) - } - class MessageHeader { - - data : Object - - dataVersion : String - - eventTime : String - - eventType : String - - id : String - - subject : String - - topic : String - + MessageHeader() - + getData() : Object - + getDataVersion() : String - + getEventTime() : String - + getEventType() : String - + getId() : String - + getSubject() : String - + getTopic() : String - + setData(data : Object) - + setDataVersion(dataVersion : String) - + setEventTime(eventTime : String) - + setEventType(eventType : String) - + setId(id : String) - + setSubject(subject : String) - + setTopic(topic : String) - } - class MessageReference { - - dataFileName : String - - dataLocation : String - + MessageReference() - + MessageReference(dataLocation : String, dataFileName : String) - + getDataFileName() : String - + getDataLocation() : String - + setDataFileName(dataFileName : String) - + setDataLocation(dataLocation : String) - } - class UsageCostDetail { - - callCost : double - - dataCost : double - - userId : String - + UsageCostDetail() - + getCallCost() : double - + getDataCost() : double - + getUserId() : String - + setCallCost(callCost : double) - + setDataCost(dataCost : double) - + setUserId(userId : String) - } - class UsageDetail { - - data : int - - duration : int - - userId : String - + UsageDetail() - + getData() : int - + getDuration() : int - + getUserId() : String - + setData(data : int) - + setDuration(duration : int) - + setUserId(userId : String) - } -} -package com.iluwatar.claimcheckpattern.utility { - class EventHandlerUtility { - - customEventClient : EventGridPublisherClient - + EventHandlerUtility() - + EventHandlerUtility(customEventClient : EventGridPublisherClient) - + publishEvent(customEvent : T, logger : Logger) - } - class MessageHandlerUtility { - - blobServiceClient : BlobServiceClient - + MessageHandlerUtility() - + MessageHandlerUtility(blobServiceClient : BlobServiceClient) - + dropToPersistantStorage(message : Message, logger : Logger) - + readFromPersistantStorage(messageReference : MessageReference, logger : Logger) : Message - } -} -package com.iluwatar.claimcheckpattern.consumer.callcostprocessor.functions { - class UsageCostProcessorFunction { - - messageHandlerUtilityForUsageCostDetail : MessageHandlerUtility - - messageHandlerUtilityForUsageDetail : MessageHandlerUtility - + UsageCostProcessorFunction() - + UsageCostProcessorFunction(messageHandlerUtilityForUsageDetail : MessageHandlerUtility, messageHandlerUtilityForUsageCostDetail : MessageHandlerUtility) - - calculateUsageCostDetails(usageDetailsList : List) : List - + run(request : HttpRequestMessage>, context : ExecutionContext) : HttpResponseMessage - } -} -UsageCostProcessorFunction --> "-messageHandlerUtilityForUsageDetail" MessageHandlerUtility -Message --> "-messageBody" MessageBody -UsageDetailPublisherFunction --> "-eventHandlerUtility" EventHandlerUtility -Builder ..+ HttpResponseMessage -UsageDetailPublisherFunction --> "-messageHandlerUtility" MessageHandlerUtility -Message --> "-messageHeader" MessageHeader -@enduml \ No newline at end of file diff --git a/cloud-claim-check-pattern/call-usage-app/host.json b/cloud-claim-check-pattern/call-usage-app/host.json deleted file mode 100644 index 4ac89572d..000000000 --- a/cloud-claim-check-pattern/call-usage-app/host.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "version": "2.0", - "extensionBundle": { - "id": "Microsoft.Azure.Functions.ExtensionBundle", - "version": "[1.*, 2.0.0)" - } -} \ No newline at end of file diff --git a/cloud-claim-check-pattern/call-usage-app/pom.xml b/cloud-claim-check-pattern/call-usage-app/pom.xml deleted file mode 100644 index b40572c7f..000000000 --- a/cloud-claim-check-pattern/call-usage-app/pom.xml +++ /dev/null @@ -1,152 +0,0 @@ - - - - 4.0.0 - - - - com.iluwatar - claim-check-pattern - 1.25.0-SNAPSHOT - - - call-usage-app - call-usage-app - jar - - - UTF-8 - 1.14.0 - 1.4.2 - CallUsageApp - - - - - - com.azure - azure-sdk-bom - 1.0.4 - pom - import - - - - - - - com.microsoft.azure.functions - azure-functions-java-library - ${azure.functions.java.library.version} - - - - com.azure - azure-messaging-eventgrid - - - - com.azure - azure-storage-blob - 12.13.0 - - - - org.slf4j - slf4j-simple - test - - - - - org.mockito - mockito-core - test - - - - - - - - - com.microsoft.azure - azure-functions-maven-plugin - ${azure.functions.maven.plugin.version} - - - ${functionAppName} - - java-functions-group - - java-functions-app-service-plan - - - westus - - - - - - - - - windows - 11 - - - - FUNCTIONS_EXTENSION_VERSION - ~3 - - - - - - package-functions - - package - - - - - - - maven-clean-plugin - 3.1.0 - - - - obj - - - - - - - diff --git a/cloud-claim-check-pattern/call-usage-app/src/main/java/com/iluwatar/claimcheckpattern/consumer/callcostprocessor/functions/UsageCostProcessorFunction.java b/cloud-claim-check-pattern/call-usage-app/src/main/java/com/iluwatar/claimcheckpattern/consumer/callcostprocessor/functions/UsageCostProcessorFunction.java deleted file mode 100644 index 5d5022e0a..000000000 --- a/cloud-claim-check-pattern/call-usage-app/src/main/java/com/iluwatar/claimcheckpattern/consumer/callcostprocessor/functions/UsageCostProcessorFunction.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.claimcheckpattern.consumer.callcostprocessor.functions; - -import com.azure.core.util.BinaryData; -import com.azure.core.util.serializer.TypeReference; -import com.azure.messaging.eventgrid.EventGridEvent; -import com.azure.messaging.eventgrid.systemevents.SubscriptionValidationEventData; -import com.azure.messaging.eventgrid.systemevents.SubscriptionValidationResponse; -import com.iluwatar.claimcheckpattern.domain.Message; -import com.iluwatar.claimcheckpattern.domain.MessageBody; -import com.iluwatar.claimcheckpattern.domain.MessageHeader; -import com.iluwatar.claimcheckpattern.domain.MessageReference; -import com.iluwatar.claimcheckpattern.domain.UsageCostDetail; -import com.iluwatar.claimcheckpattern.domain.UsageDetail; -import com.iluwatar.claimcheckpattern.utility.MessageHandlerUtility; -import com.microsoft.azure.functions.ExecutionContext; -import com.microsoft.azure.functions.HttpMethod; -import com.microsoft.azure.functions.HttpRequestMessage; -import com.microsoft.azure.functions.HttpResponseMessage; -import com.microsoft.azure.functions.HttpStatus; -import com.microsoft.azure.functions.annotation.AuthorizationLevel; -import com.microsoft.azure.functions.annotation.FunctionName; -import com.microsoft.azure.functions.annotation.HttpTrigger; -import java.time.OffsetDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -/** - * Azure Functions with HTTP Trigger. - * This is Consumer class. - */ -public class UsageCostProcessorFunction { - - private MessageHandlerUtility messageHandlerUtilityForUsageDetail; - private MessageHandlerUtility messageHandlerUtilityForUsageCostDetail; - - public UsageCostProcessorFunction() { - this.messageHandlerUtilityForUsageDetail = new MessageHandlerUtility<>(); - this.messageHandlerUtilityForUsageCostDetail = new MessageHandlerUtility<>(); - } - - public UsageCostProcessorFunction( - MessageHandlerUtility messageHandlerUtilityForUsageDetail, - MessageHandlerUtility messageHandlerUtilityForUsageCostDetail) { - this.messageHandlerUtilityForUsageDetail = messageHandlerUtilityForUsageDetail; - this.messageHandlerUtilityForUsageCostDetail = messageHandlerUtilityForUsageCostDetail; - } - - /** - * Azure function which gets triggered when event grid event send event to it. - * After receiving event, it read input file from blob storage, calculate call cost details. - * It creates new message with cost details and drop message to blob storage. - * @param request represents HttpRequestMessage - * @param context represents ExecutionContext - * @return HttpResponseMessage - */ - @FunctionName("UsageCostProcessorFunction") - public HttpResponseMessage run(@HttpTrigger(name = "req", methods = { HttpMethod.GET, - HttpMethod.POST }, authLevel = AuthorizationLevel.ANONYMOUS) - HttpRequestMessage> request, - final ExecutionContext context) { - try { - var eventGridEvents = EventGridEvent.fromString(request.getBody().get()); - for (var eventGridEvent : eventGridEvents) { - // Handle system events - if (eventGridEvent.getEventType() - .equals("Microsoft.EventGrid.SubscriptionValidationEvent")) { - SubscriptionValidationEventData subscriptionValidationEventData = eventGridEvent.getData() - .toObject(SubscriptionValidationEventData.class); - // Handle the subscription validation event - var responseData = new SubscriptionValidationResponse(); - responseData.setValidationResponse(subscriptionValidationEventData.getValidationCode()); - return request.createResponseBuilder(HttpStatus.OK).body(responseData).build(); - - } else if (eventGridEvent.getEventType().equals("UsageDetail")) { - // Get message header and reference - var messageReference = eventGridEvent.getData() - .toObject(MessageReference.class); - - // Read message from persistent storage - var message = this.messageHandlerUtilityForUsageDetail - .readFromPersistantStorage(messageReference, context.getLogger()); - - // Get Data and generate cost details - List usageDetailsList = BinaryData.fromObject( - message.getMessageBody().getData()) - .toObject(new TypeReference<>() { - }); - var usageCostDetailsList = calculateUsageCostDetails(usageDetailsList); - - // Create message body - var newMessageBody = new MessageBody(); - newMessageBody.setData(usageCostDetailsList); - - // Create message header - var newMessageReference = new MessageReference("callusageapp", - eventGridEvent.getId() + "/output.json"); - var newMessageHeader = new MessageHeader(); - newMessageHeader.setId(eventGridEvent.getId()); - newMessageHeader.setSubject("UsageCostProcessor"); - newMessageHeader.setTopic(""); - newMessageHeader.setEventType("UsageCostDetail"); - newMessageHeader.setEventTime(OffsetDateTime.now().toString()); - newMessageHeader.setData(newMessageReference); - newMessageHeader.setDataVersion("v1.0"); - - // Create entire message - var newMessage = new Message(); - newMessage.setMessageHeader(newMessageHeader); - newMessage.setMessageBody(newMessageBody); - - // Drop data to persistent storage - this.messageHandlerUtilityForUsageCostDetail.dropToPersistantStorage(newMessage, - context.getLogger()); - - context.getLogger().info("Message is dropped successfully"); - return request.createResponseBuilder(HttpStatus.OK) - .body("Message is dropped successfully").build(); - } - } - } catch (Exception e) { - context.getLogger().warning(e.getMessage()); - } - - return request.createResponseBuilder(HttpStatus.INTERNAL_SERVER_ERROR).body(null).build(); - } - - private List calculateUsageCostDetails(List usageDetailsList) { - if (usageDetailsList == null) { - return null; - } - var usageCostDetailsList = new ArrayList(); - - usageDetailsList.forEach(usageDetail -> { - var usageCostDetail = new UsageCostDetail(); - usageCostDetail.setUserId(usageDetail.getUserId()); - usageCostDetail.setCallCost(usageDetail.getDuration() * 0.30); // 0.30₹ per minute - usageCostDetail.setDataCost(usageDetail.getData() * 0.20); // 0.20₹ per MB - - usageCostDetailsList.add(usageCostDetail); - }); - - return usageCostDetailsList; - } -} diff --git a/cloud-claim-check-pattern/call-usage-app/src/main/java/com/iluwatar/claimcheckpattern/domain/Message.java b/cloud-claim-check-pattern/call-usage-app/src/main/java/com/iluwatar/claimcheckpattern/domain/Message.java deleted file mode 100644 index b24b32a18..000000000 --- a/cloud-claim-check-pattern/call-usage-app/src/main/java/com/iluwatar/claimcheckpattern/domain/Message.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.claimcheckpattern.domain; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * It is the message which gets dropped or read by Producer or Consumer Azure functions. - * It is stored in the json format. - * @param represents UsageDetail or UsageCostDetail - */ -@Data -@NoArgsConstructor -@AllArgsConstructor -public class Message { - private MessageHeader messageHeader; - - private MessageBody messageBody; - -} \ No newline at end of file diff --git a/cloud-claim-check-pattern/call-usage-app/src/main/java/com/iluwatar/claimcheckpattern/domain/MessageBody.java b/cloud-claim-check-pattern/call-usage-app/src/main/java/com/iluwatar/claimcheckpattern/domain/MessageBody.java deleted file mode 100644 index 4bf2c055c..000000000 --- a/cloud-claim-check-pattern/call-usage-app/src/main/java/com/iluwatar/claimcheckpattern/domain/MessageBody.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.claimcheckpattern.domain; - -import java.util.List; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * It is message body of the message. - * It stores actual data in our case UsageCostDetail or UsageDetail. - * @param represents UsageDetail or UsageCostDetail - */ -@Data -@NoArgsConstructor -@AllArgsConstructor -public class MessageBody { - - private List data; - -} diff --git a/cloud-claim-check-pattern/call-usage-app/src/main/java/com/iluwatar/claimcheckpattern/domain/MessageHeader.java b/cloud-claim-check-pattern/call-usage-app/src/main/java/com/iluwatar/claimcheckpattern/domain/MessageHeader.java deleted file mode 100644 index 717339bd3..000000000 --- a/cloud-claim-check-pattern/call-usage-app/src/main/java/com/iluwatar/claimcheckpattern/domain/MessageHeader.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.claimcheckpattern.domain; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * This is message header or event which is sent to Event Grid. - * Its structure is same as Azure Event Grid Event Class. - */ -@Data -@NoArgsConstructor -@AllArgsConstructor -public class MessageHeader { - - private String id; - private String subject; - private String topic; - private String eventType; - private String eventTime; - private Object data; - private String dataVersion; - -} \ No newline at end of file diff --git a/cloud-claim-check-pattern/call-usage-app/src/main/java/com/iluwatar/claimcheckpattern/domain/MessageReference.java b/cloud-claim-check-pattern/call-usage-app/src/main/java/com/iluwatar/claimcheckpattern/domain/MessageReference.java deleted file mode 100644 index 226276321..000000000 --- a/cloud-claim-check-pattern/call-usage-app/src/main/java/com/iluwatar/claimcheckpattern/domain/MessageReference.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.claimcheckpattern.domain; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * This is claim/message reference class. - * It contains the information about data where it is stored in persistent storage - * and file name. - * dataLocation is blob storage container name. - * dataFileName is file name in above container. - */ -@Data -@NoArgsConstructor -@AllArgsConstructor -public class MessageReference { - - private String dataLocation; - private String dataFileName; - -} diff --git a/cloud-claim-check-pattern/call-usage-app/src/main/java/com/iluwatar/claimcheckpattern/domain/UsageCostDetail.java b/cloud-claim-check-pattern/call-usage-app/src/main/java/com/iluwatar/claimcheckpattern/domain/UsageCostDetail.java deleted file mode 100644 index 3b0b50b99..000000000 --- a/cloud-claim-check-pattern/call-usage-app/src/main/java/com/iluwatar/claimcheckpattern/domain/UsageCostDetail.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.claimcheckpattern.domain; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * This is call cost details class. - * It stores userId of the caller, call duration cost and data cost. - */ -@Data -@NoArgsConstructor -@AllArgsConstructor -public class UsageCostDetail { - - private String userId; - private double callCost; - private double dataCost; - -} diff --git a/cloud-claim-check-pattern/call-usage-app/src/main/java/com/iluwatar/claimcheckpattern/domain/UsageDetail.java b/cloud-claim-check-pattern/call-usage-app/src/main/java/com/iluwatar/claimcheckpattern/domain/UsageDetail.java deleted file mode 100644 index 1327bc692..000000000 --- a/cloud-claim-check-pattern/call-usage-app/src/main/java/com/iluwatar/claimcheckpattern/domain/UsageDetail.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.claimcheckpattern.domain; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * This is call usage detail calls. - * It stores userId of the caller, call duration and data used. - */ -@Data -@NoArgsConstructor -@AllArgsConstructor -public class UsageDetail { - - private String userId; - - private int duration; - - private int data; -} diff --git a/cloud-claim-check-pattern/call-usage-app/src/main/java/com/iluwatar/claimcheckpattern/producer/calldetails/functions/UsageDetailPublisherFunction.java b/cloud-claim-check-pattern/call-usage-app/src/main/java/com/iluwatar/claimcheckpattern/producer/calldetails/functions/UsageDetailPublisherFunction.java deleted file mode 100644 index b53744842..000000000 --- a/cloud-claim-check-pattern/call-usage-app/src/main/java/com/iluwatar/claimcheckpattern/producer/calldetails/functions/UsageDetailPublisherFunction.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.claimcheckpattern.producer.calldetails.functions; - -import com.azure.messaging.eventgrid.EventGridEvent; -import com.azure.messaging.eventgrid.systemevents.SubscriptionValidationEventData; -import com.azure.messaging.eventgrid.systemevents.SubscriptionValidationResponse; -import com.iluwatar.claimcheckpattern.domain.Message; -import com.iluwatar.claimcheckpattern.domain.MessageBody; -import com.iluwatar.claimcheckpattern.domain.MessageHeader; -import com.iluwatar.claimcheckpattern.domain.MessageReference; -import com.iluwatar.claimcheckpattern.domain.UsageDetail; -import com.iluwatar.claimcheckpattern.utility.EventHandlerUtility; -import com.iluwatar.claimcheckpattern.utility.MessageHandlerUtility; -import com.microsoft.azure.functions.ExecutionContext; -import com.microsoft.azure.functions.HttpMethod; -import com.microsoft.azure.functions.HttpRequestMessage; -import com.microsoft.azure.functions.HttpResponseMessage; -import com.microsoft.azure.functions.HttpStatus; -import com.microsoft.azure.functions.annotation.AuthorizationLevel; -import com.microsoft.azure.functions.annotation.FunctionName; -import com.microsoft.azure.functions.annotation.HttpTrigger; -import java.time.OffsetDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.Random; -import java.util.UUID; - -/** - * Azure Functions with HTTP Trigger. - * This is Producer class. - */ -public class UsageDetailPublisherFunction { - - private MessageHandlerUtility messageHandlerUtility; - private EventHandlerUtility eventHandlerUtility; - - public UsageDetailPublisherFunction() { - this.messageHandlerUtility = new MessageHandlerUtility<>(); - this.eventHandlerUtility = new EventHandlerUtility<>(); - } - - public UsageDetailPublisherFunction(MessageHandlerUtility messageHandlerUtility, - EventHandlerUtility eventHandlerUtility) { - this.messageHandlerUtility = messageHandlerUtility; - this.eventHandlerUtility = eventHandlerUtility; - } - - /** - * Azure function which create message, drop it in persistent storage - * and publish the event to Event Grid topic. - * @param request represents HttpRequestMessage - * @param context represents ExecutionContext - * @return HttpResponseMessage - */ - @FunctionName("UsageDetailPublisherFunction") - public HttpResponseMessage run(@HttpTrigger(name = "req", methods = { - HttpMethod.POST }, authLevel = AuthorizationLevel.ANONYMOUS) - HttpRequestMessage> request, - final ExecutionContext context) { - try { - - var eventGridEvents = EventGridEvent.fromString(request.getBody().get()); - - for (EventGridEvent eventGridEvent : eventGridEvents) { - // Handle system events - if (eventGridEvent.getEventType() - .equals("Microsoft.EventGrid.SubscriptionValidationEvent")) { - SubscriptionValidationEventData subscriptionValidationEventData = eventGridEvent.getData() - .toObject(SubscriptionValidationEventData.class); - // Handle the subscription validation event - var responseData = new SubscriptionValidationResponse(); - responseData.setValidationResponse(subscriptionValidationEventData.getValidationCode()); - return request.createResponseBuilder(HttpStatus.OK).body(responseData).build(); - - } else if (eventGridEvent.getEventType().equals("UsageDetail")) { - // Create message body - var messageBody = new MessageBody(); - var usageDetailsList = new ArrayList(); - var random = new Random(); - for (int i = 0; i < 51; i++) { - var usageDetail = new UsageDetail(); - usageDetail.setUserId("userId" + i); - usageDetail.setData(random.nextInt(500)); - usageDetail.setDuration(random.nextInt(500)); - - usageDetailsList.add(usageDetail); - } - messageBody.setData(usageDetailsList); - - // Create message header - var messageHeader = new MessageHeader(); - messageHeader.setId(UUID.randomUUID().toString()); - messageHeader.setSubject("UsageDetailPublisher"); - messageHeader.setTopic("usagecostprocessorfunction-topic"); - messageHeader.setEventType("UsageDetail"); - messageHeader.setEventTime(OffsetDateTime.now().toString()); - var messageReference = new MessageReference("callusageapp", - messageHeader.getId() + "/input.json"); - messageHeader.setData(messageReference); - messageHeader.setDataVersion("v1.0"); - - // Create entire message - var message = new Message(); - message.setMessageHeader(messageHeader); - message.setMessageBody(messageBody); - - // Drop data to persistent storage - this.messageHandlerUtility.dropToPersistantStorage(message, context.getLogger()); - - // Publish event to event grid topic - eventHandlerUtility.publishEvent(messageHeader, context.getLogger()); - - context.getLogger().info("Message is dropped and event is published successfully"); - return request.createResponseBuilder(HttpStatus.OK).body(message).build(); - } - } - } catch (Exception e) { - context.getLogger().warning(e.getMessage()); - } - - return request.createResponseBuilder(HttpStatus.OK).body(null).build(); - } -} diff --git a/cloud-claim-check-pattern/call-usage-app/src/main/java/com/iluwatar/claimcheckpattern/utility/EventHandlerUtility.java b/cloud-claim-check-pattern/call-usage-app/src/main/java/com/iluwatar/claimcheckpattern/utility/EventHandlerUtility.java deleted file mode 100644 index ef69ae4f0..000000000 --- a/cloud-claim-check-pattern/call-usage-app/src/main/java/com/iluwatar/claimcheckpattern/utility/EventHandlerUtility.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.claimcheckpattern.utility; - -import com.azure.core.credential.AzureKeyCredential; -import com.azure.core.util.BinaryData; -import com.azure.messaging.eventgrid.EventGridPublisherClient; -import com.azure.messaging.eventgrid.EventGridPublisherClientBuilder; -import java.util.logging.Logger; - -/** - * This class is event publisher utility which published message header to Event Grid topic. - * @param represents UsageDetail or UsageCostDetail - */ -public class EventHandlerUtility { - - private EventGridPublisherClient customEventClient; - - /** Default constructor. - */ - public EventHandlerUtility() { - this.customEventClient = new EventGridPublisherClientBuilder() - .endpoint(System.getenv("EventGridURL")) - .credential(new AzureKeyCredential(System.getenv("EventGridKey"))) - .buildCustomEventPublisherClient(); - } - - /** - Parameterized constructor. - */ - public EventHandlerUtility(EventGridPublisherClient customEventClient) { - this.customEventClient = customEventClient; - } - - /** - Method for publishing event to Event Grid Topic. - */ - public void publishEvent(T customEvent, Logger logger) { - try { - customEventClient.sendEvent(BinaryData.fromObject(customEvent)); - } catch (Exception e) { - logger.info(e.getMessage()); - } - } -} diff --git a/cloud-claim-check-pattern/call-usage-app/src/main/java/com/iluwatar/claimcheckpattern/utility/MessageHandlerUtility.java b/cloud-claim-check-pattern/call-usage-app/src/main/java/com/iluwatar/claimcheckpattern/utility/MessageHandlerUtility.java deleted file mode 100644 index 032cb11ae..000000000 --- a/cloud-claim-check-pattern/call-usage-app/src/main/java/com/iluwatar/claimcheckpattern/utility/MessageHandlerUtility.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.claimcheckpattern.utility; - -import com.azure.core.util.BinaryData; -import com.azure.core.util.serializer.TypeReference; -import com.azure.storage.blob.BlobClient; -import com.azure.storage.blob.BlobContainerClient; -import com.azure.storage.blob.BlobServiceClient; -import com.azure.storage.blob.BlobServiceClientBuilder; -import com.iluwatar.claimcheckpattern.domain.Message; -import com.iluwatar.claimcheckpattern.domain.MessageReference; -import java.util.logging.Logger; - -/** - * This class read and drop message from Azure blob storage. - * @param represents UsageDetail or UsageCostDetail - */ -public class MessageHandlerUtility { - - private BlobServiceClient blobServiceClient; - - /** - * Parameterized constructor. - * @param blobServiceClient represents BlobServiceClient - */ - public MessageHandlerUtility(BlobServiceClient blobServiceClient) { - this.blobServiceClient = blobServiceClient; - } - - /** - * Default constructor. - */ - public MessageHandlerUtility() { - // Create a BlobServiceClient object which will be used to create a container - // client - this.blobServiceClient = new BlobServiceClientBuilder() - .connectionString(System.getenv("BlobStorageConnectionString")).buildClient(); - - } - - /** - * Read message from blob storage. - * @param messageReference represents MessageReference - * @param logger represents Logger - * @return Message - */ - public Message readFromPersistantStorage(MessageReference messageReference, Logger logger) { - Message message = null; - try { - - // Get container name from message reference - String containerName = messageReference.getDataLocation(); - - // Get blob name from message reference - String blobName = messageReference.getDataFileName(); - - // Get container client - BlobContainerClient containerClient = blobServiceClient.getBlobContainerClient(containerName); - - // Get a reference to a blob - BlobClient blobClient = containerClient.getBlobClient(blobName); - - // download the blob - message = blobClient.downloadContent().toObject(new TypeReference>() { - }); - } catch (Exception e) { - logger.info(e.getMessage()); - } - return message; - - } - - /** - * Drop message to blob storage. - * @param message represents Message - * @param logger represents Logger - */ - public void dropToPersistantStorage(Message message, Logger logger) { - try { - - // Get message reference - MessageReference messageReference = (MessageReference) message.getMessageHeader().getData(); - - // Create a unique name for the container - String containerName = messageReference.getDataLocation(); - - // Create the container and return a container client object - BlobContainerClient containerClient = this.blobServiceClient - .getBlobContainerClient(containerName); - if (!containerClient.exists()) { - containerClient.create(); - } - - // Get a reference to a blob - BlobClient blobClient = containerClient.getBlobClient(messageReference.getDataFileName()); - - // Upload the blob - blobClient.upload(BinaryData.fromObject(message)); - } catch (Exception e) { - logger.info(e.getMessage()); - } - - } - -} diff --git a/cloud-claim-check-pattern/call-usage-app/src/test/java/com/iluwatar/claimcheckpattern/HttpResponseMessageMock.java b/cloud-claim-check-pattern/call-usage-app/src/test/java/com/iluwatar/claimcheckpattern/HttpResponseMessageMock.java deleted file mode 100644 index 0a1c32a4b..000000000 --- a/cloud-claim-check-pattern/call-usage-app/src/test/java/com/iluwatar/claimcheckpattern/HttpResponseMessageMock.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.claimcheckpattern; - -import com.microsoft.azure.functions.HttpResponseMessage; -import com.microsoft.azure.functions.HttpStatus; -import com.microsoft.azure.functions.HttpStatusType; -import java.util.HashMap; -import java.util.Map; - -/** - * The mock for HttpResponseMessage, can be used in unit tests to verify if the - * returned response by HTTP trigger function is correct or not. - */ -public class HttpResponseMessageMock implements HttpResponseMessage { - private int httpStatusCode; - private HttpStatusType httpStatus; - private Object body; - private Map headers; - - public HttpResponseMessageMock(HttpStatusType status, Map headers, Object body) { - this.httpStatus = status; - this.httpStatusCode = status.value(); - this.headers = headers; - this.body = body; - } - - @Override - public HttpStatusType getStatus() { - return this.httpStatus; - } - - @Override - public int getStatusCode() { - return httpStatusCode; - } - - @Override - public String getHeader(String key) { - return this.headers.get(key); - } - - @Override - public Object getBody() { - return this.body; - } - - public static class HttpResponseMessageBuilderMock implements HttpResponseMessage.Builder { - private Object body; - private int httpStatusCode; - private Map headers = new HashMap<>(); - private HttpStatusType httpStatus; - - public Builder status(HttpStatus status) { - this.httpStatusCode = status.value(); - this.httpStatus = status; - return this; - } - - @Override - public Builder status(HttpStatusType httpStatusType) { - this.httpStatusCode = httpStatusType.value(); - this.httpStatus = httpStatusType; - return this; - } - - @Override - public HttpResponseMessage.Builder header(String key, String value) { - this.headers.put(key, value); - return this; - } - - @Override - public HttpResponseMessage.Builder body(Object body) { - this.body = body; - return this; - } - - @Override - public HttpResponseMessage build() { - return new HttpResponseMessageMock(this.httpStatus, this.headers, this.body); - } - } -} diff --git a/cloud-claim-check-pattern/call-usage-app/src/test/java/com/iluwatar/claimcheckpattern/consumer/callcostprocessor/functions/UsageCostProcessorFunctionTest.java b/cloud-claim-check-pattern/call-usage-app/src/test/java/com/iluwatar/claimcheckpattern/consumer/callcostprocessor/functions/UsageCostProcessorFunctionTest.java deleted file mode 100644 index fc1683768..000000000 --- a/cloud-claim-check-pattern/call-usage-app/src/test/java/com/iluwatar/claimcheckpattern/consumer/callcostprocessor/functions/UsageCostProcessorFunctionTest.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.claimcheckpattern.consumer.callcostprocessor.functions; - -import com.iluwatar.claimcheckpattern.HttpResponseMessageMock; -import com.iluwatar.claimcheckpattern.domain.Message; -import com.iluwatar.claimcheckpattern.domain.MessageBody; -import com.iluwatar.claimcheckpattern.domain.MessageHeader; -import com.iluwatar.claimcheckpattern.domain.MessageReference; -import com.iluwatar.claimcheckpattern.domain.UsageCostDetail; -import com.iluwatar.claimcheckpattern.domain.UsageDetail; -import com.iluwatar.claimcheckpattern.utility.MessageHandlerUtility; -import com.microsoft.azure.functions.ExecutionContext; -import com.microsoft.azure.functions.HttpRequestMessage; -import com.microsoft.azure.functions.HttpResponseMessage; -import com.microsoft.azure.functions.HttpStatus; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.mockito.stubbing.Answer; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.time.OffsetDateTime; -import java.util.*; -import java.util.logging.Logger; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; - -/** - * Unit test for Function class. - */ -@ExtendWith(MockitoExtension.class) -class UsageCostProcessorFunctionTest { - - @Mock - MessageHandlerUtility mockMessageHandlerUtilityForUsageADetail; - @Mock - MessageHandlerUtility mockMessageHandlerUtilityForUsageCostDetail; - @Mock - ExecutionContext context; - - Message messageToDrop; - Message messageToRead; - MessageReference messageReference; - @InjectMocks - UsageCostProcessorFunction usageCostProcessorFunction; - - @BeforeEach - void setUp() { - var messageBodyUsageDetail = new MessageBody(); - var usageDetailsList = new ArrayList(); - - var messageBodyUsageCostDetail = new MessageBody(); - var usageCostDetailsList = new ArrayList(); - for (int i = 0; i < 2; i++) { - var usageDetail = new UsageDetail(); - usageDetail.setUserId("userId" + i); - usageDetail.setData(i + 1); - usageDetail.setDuration(i + 1); - usageDetailsList.add(usageDetail); - - var usageCostDetail = new UsageCostDetail(); - usageCostDetail.setUserId(usageDetail.getUserId()); - usageCostDetail.setDataCost(usageDetail.getData() * 0.20); - usageCostDetail.setCallCost(usageDetail.getDuration() * 0.30); - usageCostDetailsList.add(usageCostDetail); - } - messageBodyUsageDetail.setData(usageDetailsList); - messageBodyUsageCostDetail.setData(usageCostDetailsList); - - // Create message header - var messageHeader = new MessageHeader(); - messageHeader.setId(UUID.randomUUID().toString()); - messageHeader.setSubject("UsageDetailPublisher"); - messageHeader.setTopic("usagecostprocessorfunction-topic"); - messageHeader.setEventType("UsageDetail"); - messageHeader.setEventTime(OffsetDateTime.now().toString()); - this.messageReference = new MessageReference("callusageapp", "d8284456-dfff-4bd4-9cef-ea99f70f4835/input.json"); - messageHeader.setData(messageReference); - messageHeader.setDataVersion("v1.0"); - - // Create entire message - messageToRead = new Message<>(); - messageToRead.setMessageHeader(messageHeader); - messageToRead.setMessageBody(messageBodyUsageDetail); - - messageToDrop = new Message<>(); - messageToDrop.setMessageHeader(messageHeader); - messageToDrop.setMessageBody(messageBodyUsageCostDetail); - - } - - /** - * Unit test for HttpTriggerJava method. - */ - @Test - void shouldTriggerHttpAzureFunctionJavaWithSubscriptionValidationEventType() throws Exception { - - // Setup - @SuppressWarnings("unchecked") - final HttpRequestMessage> req = mock(HttpRequestMessage.class); - String fileAbsolutePath = getClass().getResource("/subscriptionValidationEvent.json").getPath() - .replaceAll("%20", " "), jsonBody = Files.readString(Paths.get(fileAbsolutePath)).replaceAll("\n", " "); - doReturn(Optional.of(jsonBody)).when(req).getBody(); - doAnswer(new Answer() { - @Override - public HttpResponseMessage.Builder answer(InvocationOnMock invocation) { - HttpStatus status = (HttpStatus) invocation.getArguments()[0]; - return new HttpResponseMessageMock.HttpResponseMessageBuilderMock().status(status); - } - }).when(req).createResponseBuilder(any(HttpStatus.class)); - - final ExecutionContext context = mock(ExecutionContext.class); - - // Invoke - final HttpResponseMessage ret = this.usageCostProcessorFunction.run(req, context); - - // Verify - assertEquals(ret.getStatus(), HttpStatus.OK); - } - - @Test - void shouldTriggerHttpAzureFunctionJavaWithUsageDetailEventType() throws Exception { - // Setup - @SuppressWarnings("unchecked") - final HttpRequestMessage> req = mock(HttpRequestMessage.class); - String fileAbsolutePath = getClass().getResource("/usageDetailEvent.json").getPath().replaceAll("%20", " "), - jsonBody = Files.readString(Paths.get(fileAbsolutePath)).replaceAll("\n", " "); - doReturn(Optional.of(jsonBody)).when(req).getBody(); - doReturn(Logger.getGlobal()).when(context).getLogger(); - - when(this.mockMessageHandlerUtilityForUsageADetail.readFromPersistantStorage(any(MessageReference.class), - eq(Logger.getGlobal()))).thenReturn(messageToRead); - doAnswer(new Answer() { - @Override - public HttpResponseMessage.Builder answer(InvocationOnMock invocation) { - HttpStatus status = (HttpStatus) invocation.getArguments()[0]; - return new HttpResponseMessageMock.HttpResponseMessageBuilderMock().status(status); - } - }).when(req).createResponseBuilder(any(HttpStatus.class)); - - assertNotNull(this.mockMessageHandlerUtilityForUsageADetail); - assertEquals(this.messageToRead, this.mockMessageHandlerUtilityForUsageADetail - .readFromPersistantStorage(this.messageReference, Logger.getGlobal())); - - // Invoke - final HttpResponseMessage ret = this.usageCostProcessorFunction.run(req, context); - - // Verify - assertEquals(HttpStatus.OK, ret.getStatus()); - assertEquals("Message is dropped successfully", ret.getBody()); - } - -} diff --git a/cloud-claim-check-pattern/call-usage-app/src/test/java/com/iluwatar/claimcheckpattern/producer/calldetails/functions/UsageDetailPublisherFunctionTest.java b/cloud-claim-check-pattern/call-usage-app/src/test/java/com/iluwatar/claimcheckpattern/producer/calldetails/functions/UsageDetailPublisherFunctionTest.java deleted file mode 100644 index c44e23b35..000000000 --- a/cloud-claim-check-pattern/call-usage-app/src/test/java/com/iluwatar/claimcheckpattern/producer/calldetails/functions/UsageDetailPublisherFunctionTest.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.claimcheckpattern.producer.calldetails.functions; - -import com.iluwatar.claimcheckpattern.HttpResponseMessageMock; -import com.iluwatar.claimcheckpattern.domain.MessageHeader; -import com.iluwatar.claimcheckpattern.domain.UsageDetail; -import com.iluwatar.claimcheckpattern.utility.EventHandlerUtility; -import com.iluwatar.claimcheckpattern.utility.MessageHandlerUtility; -import com.microsoft.azure.functions.ExecutionContext; -import com.microsoft.azure.functions.HttpRequestMessage; -import com.microsoft.azure.functions.HttpResponseMessage; -import com.microsoft.azure.functions.HttpStatus; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.mockito.stubbing.Answer; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.*; -import java.util.logging.Logger; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; - -/** - * Unit test for Function class. - */ -@ExtendWith(MockitoExtension.class) -class UsageDetailPublisherFunctionTest { - @Mock - MessageHandlerUtility mockMessageHandlerUtility; - @Mock - EventHandlerUtility mockEventHandlerUtility; - - @InjectMocks - UsageDetailPublisherFunction usageDetailPublisherFunction; - - /** - * Unit test for HttpTriggerJava method. - */ - @Test - void shouldTriggerHttpAzureFunctionJavaWithSubscriptionValidationEventType() throws Exception { - - // Setup - @SuppressWarnings("unchecked") - final HttpRequestMessage> req = mock(HttpRequestMessage.class); - String fileAbsolutePath = getClass().getResource("/subscriptionValidationEvent.json").getPath() - .replaceAll("%20", " "), jsonBody = Files.readString(Paths.get(fileAbsolutePath)).replaceAll("\n", " "); - doReturn(Optional.of(jsonBody)).when(req).getBody(); - doAnswer(new Answer() { - @Override - public HttpResponseMessage.Builder answer(InvocationOnMock invocation) { - HttpStatus status = (HttpStatus) invocation.getArguments()[0]; - return new HttpResponseMessageMock.HttpResponseMessageBuilderMock().status(status); - } - }).when(req).createResponseBuilder(any(HttpStatus.class)); - - final ExecutionContext context = mock(ExecutionContext.class); - - // Invoke - final HttpResponseMessage ret = this.usageDetailPublisherFunction.run(req, context); - - // Verify - assertEquals(ret.getStatus(), HttpStatus.OK); - } - - @Test - void shouldTriggerHttpAzureFunctionJavaWithUsageDetailEventType() throws Exception { - - // Setup - @SuppressWarnings("unchecked") - final HttpRequestMessage> req = mock(HttpRequestMessage.class); - String fileAbsolutePath = getClass().getResource("/usageDetailEvent.json").getPath().replaceAll("%20", " "), - jsonBody = Files.readString(Paths.get(fileAbsolutePath)).replaceAll("\n", " "); - doReturn(Optional.of(jsonBody)).when(req).getBody(); - doAnswer(new Answer() { - @Override - public HttpResponseMessage.Builder answer(InvocationOnMock invocation) { - HttpStatus status = (HttpStatus) invocation.getArguments()[0]; - return new HttpResponseMessageMock.HttpResponseMessageBuilderMock().status(status); - } - }).when(req).createResponseBuilder(any(HttpStatus.class)); - - final ExecutionContext context = mock(ExecutionContext.class); - doReturn(Logger.getGlobal()).when(context).getLogger(); - - // Invoke - final HttpResponseMessage ret = this.usageDetailPublisherFunction.run(req, context); - - // Verify - assertEquals(ret.getStatus(), HttpStatus.OK); - } - -} diff --git a/cloud-claim-check-pattern/call-usage-app/src/test/java/com/iluwatar/claimcheckpattern/utility/EventHandlerUtilityTest.java b/cloud-claim-check-pattern/call-usage-app/src/test/java/com/iluwatar/claimcheckpattern/utility/EventHandlerUtilityTest.java deleted file mode 100644 index 69e63241f..000000000 --- a/cloud-claim-check-pattern/call-usage-app/src/test/java/com/iluwatar/claimcheckpattern/utility/EventHandlerUtilityTest.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.claimcheckpattern.utility; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; - -import com.azure.core.util.BinaryData; -import com.azure.messaging.eventgrid.EventGridPublisherClient; -import com.iluwatar.claimcheckpattern.domain.Message; -import com.iluwatar.claimcheckpattern.domain.UsageDetail; -import java.util.logging.Logger; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class EventHandlerUtilityTest { - - @Mock - EventGridPublisherClient mockCustomEventClient; - - @InjectMocks - EventHandlerUtility> eventHandlerUtility; - - @BeforeEach - void setUp() { - - System.setProperty("EventGridURL", "https://www.dummyEndpoint.com/api/events"); - System.setProperty("EventGridKey", "EventGridURL"); - } - - @Test - void shouldPublishEvent() { - doNothing().when(mockCustomEventClient).sendEvent(any(BinaryData.class)); - eventHandlerUtility.publishEvent(null, Logger.getLogger("logger")); - verify(mockCustomEventClient, times(1)).sendEvent(any(BinaryData.class)); - - } - - @Test - void shouldPublishEventWithNullLogger() { - eventHandlerUtility.publishEvent(null, null); - verify(mockCustomEventClient, times(1)).sendEvent(any(BinaryData.class)); - } -} diff --git a/cloud-claim-check-pattern/call-usage-app/src/test/java/com/iluwatar/claimcheckpattern/utility/MessageHandlerUtilityTest.java b/cloud-claim-check-pattern/call-usage-app/src/test/java/com/iluwatar/claimcheckpattern/utility/MessageHandlerUtilityTest.java deleted file mode 100644 index 7bfc08b89..000000000 --- a/cloud-claim-check-pattern/call-usage-app/src/test/java/com/iluwatar/claimcheckpattern/utility/MessageHandlerUtilityTest.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.claimcheckpattern.utility; - -import com.azure.storage.blob.BlobClient; -import com.azure.storage.blob.BlobContainerClient; -import com.azure.storage.blob.BlobServiceClient; -import com.iluwatar.claimcheckpattern.domain.*; -import com.iluwatar.claimcheckpattern.utility.MessageHandlerUtility; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import java.time.OffsetDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; -import java.util.UUID; -import java.util.logging.Logger; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.*; - -@ExtendWith(MockitoExtension.class) -class MessageHandlerUtilityTest { - @Mock - private BlobClient mockBlobClient; - - @Mock - private BlobContainerClient mockContainerClient; - - @Mock - private BlobServiceClient mockBlobServiceClient; - - @InjectMocks - private MessageHandlerUtility messageHandlerUtility; - - private Message messageToPublish; - private MessageReference messageReference; - - @BeforeEach - void setUp() { - System.setProperty("BlobStorageConnectionString", "https://www.dummyEndpoint.com/api/blobs"); - - var messageBody = new MessageBody(); - var usageDetailsList = new ArrayList(); - var random = new Random(); - for (int i = 0; i < 51; i++) { - var usageDetail = new UsageDetail(); - usageDetail.setUserId("userId" + i); - usageDetail.setData(random.nextInt(500)); - usageDetail.setDuration(random.nextInt(500)); - - usageDetailsList.add(usageDetail); - } - messageBody.setData(usageDetailsList); - - // Create message header - var messageHeader = new MessageHeader(); - messageHeader.setId(UUID.randomUUID().toString()); - messageHeader.setSubject("UsageDetailPublisher"); - messageHeader.setTopic("usagecostprocessorfunction-topic"); - messageHeader.setEventType("UsageDetail"); - messageHeader.setEventTime(OffsetDateTime.now().toString()); - this.messageReference = new MessageReference("callusageapp", messageHeader.getId() + "/input.json"); - messageHeader.setData(messageReference); - messageHeader.setDataVersion("v1.0"); - - // Create entire message - this.messageToPublish = new Message<>(); - this.messageToPublish.setMessageHeader(messageHeader); - this.messageToPublish.setMessageBody(messageBody); - - when(mockContainerClient.getBlobClient(anyString())).thenReturn(mockBlobClient); - when(mockBlobServiceClient.getBlobContainerClient(anyString())).thenReturn(mockContainerClient); - } - - @Test - void shouldDropMessageToPersistantStorage() { - messageHandlerUtility.dropToPersistantStorage(messageToPublish, Logger.getLogger("logger")); - verify(mockBlobServiceClient, times(1)).getBlobContainerClient(anyString()); - // verify(mockContainerClient, times(0)).exists(); - } - - @Test - void shouldReadMessageFromPersistantStorage() { - - messageHandlerUtility.readFromPersistantStorage(messageReference, Logger.getLogger("logger")); - verify(mockBlobServiceClient, times(1)).getBlobContainerClient(anyString()); - } -} diff --git a/cloud-claim-check-pattern/call-usage-app/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/cloud-claim-check-pattern/call-usage-app/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker deleted file mode 100644 index ca6ee9cea..000000000 --- a/cloud-claim-check-pattern/call-usage-app/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker +++ /dev/null @@ -1 +0,0 @@ -mock-maker-inline \ No newline at end of file diff --git a/cloud-claim-check-pattern/call-usage-app/src/test/resources/subscriptionValidationEvent.json b/cloud-claim-check-pattern/call-usage-app/src/test/resources/subscriptionValidationEvent.json deleted file mode 100644 index 52bd6ee6a..000000000 --- a/cloud-claim-check-pattern/call-usage-app/src/test/resources/subscriptionValidationEvent.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - { - "data": { - "validationCode": "C12F266E-79D9-4C0A-9922-5EF6201A34C2", - "validationUrl": "https://rp-centralindia.eventgrid.azure.net:553/eventsubscriptions/usagedetailpublisherfunction-subscription/validate?idu003dC12F266E-79D9-4C0A-9922-5EF6201A34C2u0026tu003d2021-10-26T08:10:52.4999377Zu0026apiVersionu003d2020-10-15-previewu0026tokenu003d30kEVoL8rAOWzQv0buurhrKnbP%2bGMtHObbA%2bax6wb4Y%3d" - }, - "dataVersion": "2", - "eventTime": "2021-10-26T08:10:52.4999377Z", - "eventType": "Microsoft.EventGrid.SubscriptionValidationEvent", - "id": "e2a8466b-3dc0-46b7-bb7d-b999e51a2848", - "metadataVersion": "1", - "subject": "", - "topic": "/subscriptions/0fef643d-a6b1-48f9-a256-53fbd0d22f48/resourceGroups/resource-group-ccp/providers/Microsoft.EventGrid/domains/event-grid-domains-ccp/topics/usagedetailpublisherfunction-topic" - } -] diff --git a/cloud-claim-check-pattern/call-usage-app/src/test/resources/usageDetailEvent.json b/cloud-claim-check-pattern/call-usage-app/src/test/resources/usageDetailEvent.json deleted file mode 100644 index 137649e29..000000000 --- a/cloud-claim-check-pattern/call-usage-app/src/test/resources/usageDetailEvent.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - { - "data": { - "dataFileName": "d8284456-dfff-4bd4-9cef-ea99f70f4835/input.json", - "dataLocation": "callusageapp" - }, - "dataVersion": "v1.0", - "eventTime": "2021-10-25T19:17:15.7468501Z", - "eventType": "UsageDetail", - "id": "d8284456-dfff-4bd4-9cef-ea99f70f4835", - "metadataVersion": "1", - "subject": "UsageDetailPublisher", - "topic": "/subscriptions/0fef643d-a6b1-48f9-a256-ea99f70f4835/resourceGroups/resource-group-ccp/providers/Microsoft.EventGrid/domains/event-grid-domains-ccp/topics/usagecostprocessorfunction-topic" - } -] diff --git a/cloud-claim-check-pattern/etc/Claim-Check-Pattern.png b/cloud-claim-check-pattern/etc/Claim-Check-Pattern.png deleted file mode 100644 index a2d8040af..000000000 Binary files a/cloud-claim-check-pattern/etc/Claim-Check-Pattern.png and /dev/null differ diff --git a/cloud-claim-check-pattern/etc/claim-check-pattern.urm.puml b/cloud-claim-check-pattern/etc/claim-check-pattern.urm.puml deleted file mode 100644 index 14df8b68b..000000000 --- a/cloud-claim-check-pattern/etc/claim-check-pattern.urm.puml +++ /dev/null @@ -1,117 +0,0 @@ -@startuml -class UsageDetailPublisherFunction [[java:com.iluwatar.producer.calldetails.functions]] { - -messageHandlerUtility: MessageHandlerUtility - -eventHandlerUtility: EventHandlerUtility - +run(): HttpResponseMessage -} - -class UsageCostProcessorFunction [[java:com.iluwatar.consumer.callcostprocessor.functions]] { - -messageHandlerUtilityForUsageDetail: MessageHandlerUtility - -messageHandlerUtilityForUsageCostDetail: MessageHandlerUtility - +run(): HttpResponseMessage -} - -class "MessageHandlerUtility" as MessageHandlerUtility_T [[java:com.iluwatar.claimcheckpattern.utility]] { - +readFromPersistantStorage(messageReference: MessageReference, logger: Logger): Message - +dropToPersistantStorage(message: Message, logger: Logger): void -} - -class "EventHandlerUtility" as EventHandlerUtility_T [[java:com.callusage.utility.PersistentLocalStorageUtility]] { - +publishEvent(customEvent: T, logger: Logger): void -} - -class "Message" as Message_T [[java:com.iluwatar.claimcheckpattern.domain]] { - -messageHeader: MessageHeader - -messageData: MessageData - +Message(messageHeader: MessageHeader, messageData: MessageData) - +getMessageData(): MessageData - +getMessageHeader(): MessageHeader -} - - -class MessageHeader [[java:com.iluwatar.claimcheckpattern.domain]] { - -id: String - -subject: String - -topic: String - -eventType: String - -eventTime: String - -data: Object - -dataVersion: String - +getId(): String - +setId(id: String): void - +getSubject(): String - +setSubject(subject: String): void - +getTopic(): String - +setTopic(topic: String): void - +getEventType(): String - +setEventType(eventType: String): void - +getEventTime(): String - +setEventTime(eventTime: String): void - +getData(): Object - +setData(data: Object): void - +getDataVersion(): String - +setDataVersion(dataVersion:String): void - -} - - -class "MessageBody" as MessageBody_T [[java:com.iluwatar.claimcheckpattern.domain]] { - -data: List[] T - +getData(): List[] T - +setData(data:List[] T): void -} - -class MessageReference [[java:com.iluwatar.claimcheckpattern.domain]] { - -dataLocation: String - -dataFileName: String - +getDataLocation(): String - +setDataLocation(dataLocation:String): void - +getDataFileName(): String - +setDataFileName(dataFileName:String): void -} - -class UsageDetail [[java:com.iluwatar.claimcheckpattern.domain]] { - -userId: String - -duration: int - -data: int - +getUserId(): String - +setUserId(userId: String): void - +getDuration(): long - +setDuration(duration: long): void - +getData(): long - +setData(data: long): void -} - -class UsageCostDetail [[java:com.iluwatar.claimcheckpattern.domain]] { - -userId: String - -callCost: double - -dataCost: double - +getUserId(): String - +setUserId(userId: String): void - +getCallCost(): double - +setCallCost(callCost:double): void - +getDataCost(): double - +setDataCost(dataCost:double) : void -} - - - - - - - -Message_T "1" *-- "1" MessageHeader : has -Message_T "1" *-- "1" MessageBody_T : has -MessageHeader "1" *-- "1" MessageReference : has as data object -MessageBody_T "1" *-- "1" UsageDetail: has -MessageBody_T "1" *-- "1" UsageCostDetail: has - -EventHandlerUtility_T "1" *-- "1" MessageHeader: has -MessageHandlerUtility_T "1" *-- "1" Message_T: has - -UsageDetailPublisherFunction "1" *-- "1" MessageHandlerUtility_T : has -UsageDetailPublisherFunction "1" *-- "1" EventHandlerUtility_T : has - -UsageCostProcessorFunction "1" *-- "1" MessageHandlerUtility_T : has -UsageCostProcessorFunction "1" *-- "1" MessageHandlerUtility_T : has -@enduml \ No newline at end of file diff --git a/cloud-claim-check-pattern/etc/class-diagram.png b/cloud-claim-check-pattern/etc/class-diagram.png deleted file mode 100644 index d627b1b70..000000000 Binary files a/cloud-claim-check-pattern/etc/class-diagram.png and /dev/null differ diff --git a/cloud-claim-check-pattern/pom.xml b/cloud-claim-check-pattern/pom.xml deleted file mode 100644 index 1015bb0fd..000000000 --- a/cloud-claim-check-pattern/pom.xml +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - com.iluwatar - java-design-patterns - 1.25.0-SNAPSHOT - - - 4.0.0 - claim-check-pattern - pom - - - call-usage-app - - - - com.google.code.gson - gson - 2.8.9 - - - org.junit.jupiter - junit-jupiter - 5.8.1 - test - - - org.mockito - mockito-junit-jupiter - 4.0.0 - test - - - - org.mockito - mockito-inline - 4.0.0 - test - - - - \ No newline at end of file diff --git a/cloud-static-content-hosting/README.md b/cloud-static-content-hosting/README.md deleted file mode 100644 index 918931e34..000000000 --- a/cloud-static-content-hosting/README.md +++ /dev/null @@ -1,145 +0,0 @@ ---- -title: Static Content Hosting -category: Cloud -language: en -tag: -- Cloud distributed ---- - -## Intent - -Deploy static content to a cloud-based storage service that can deliver them directly to the client. -This can reduce the need for potentially expensive compute instances. - -## Explanation - -Real world example - -> A global marketing web site with static content needs to be quickly deployed to start attracting -> potential customers. To keep the hosting expenses and maintenance minimum, a cloud hosted storage -> service along with content delivery network is used. - -In plain words - -> Static Content Hosting pattern utilizes cloud native storage service to store the content and -> global content delivery network to cache it in multiple data centers around the world. -> -> On a static website, individual webpages include static content. They might also contain -> client-side scripts such as Javascript. By contrast, a dynamic website relies on server-side -> processing, including server-side scripts such as PHP, JSP, or ASP.NET. - -Wikipedia says - -> A static web page (sometimes called a flat page or a stationary page) is a web page that is -> delivered to the user's web browser exactly as stored, in contrast to dynamic web pages which are -> generated by a web application. -> -> Static web pages are suitable for content that never or rarely needs to be updated, though modern -> web template systems are changing this. Maintaining large numbers of static pages as files can be -> impractical without automated tools, such as static site generators. - -**Example** - -![alt text](./etc/static-content-hosting.png "Static Content Hosting") - -In this example we create a static web site using AWS S3 and utilize AWS Cloudfront to distribute -the content globally. - -1. First you will need an AWS account. You can create a free one here: [AWS Free Tier](https://aws.amazon.com/free/free-tier/) - -2. Login to the [AWS Console](https://console.aws.amazon.com/console/home?nc2=h_ct&src=header-signin) - -3. Go to Identity and Access Management (IAM) service. - -4. Create IAM user that has only the necessary rights for this application. - - * Click `Users` - * Click `Add user`. Choose `User name` as you wish and `Access type` should be `Programmatic access`. Click `Next: Permissions`. - * Choose `Attach existing policies directly`. Select `AmazonS3FullAccess` and `CloudFrontFullAccess`. Click `Next: Tags`. - * No tags are necessarily needed, so just click `Next: Review`. - * Review the presented information and if all seems good click `Create user`. - * You are presented with `Access key ID` and `Secret access key` which you will need to complete this example, so store them safely. - * Click `Close`. - -5. [Install AWS Command Line Interface (AWS CLI)](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv1.html) to gain programmic access to AWS cloud. - -6. Configure AWS CLI with command `aws configure` as desribed in the [instructions](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-config) - -7. Create AWS S3 bucket for the web site content. Note that the S3 bucket names must be globally unique. - - * The syntax is `aws s3 mb ` as described in the [instructions](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-buckets-creating) - * For example `aws s3 mb s3://my-static-website-jh34jsjmg` - * Verify that the bucket was successfully created with command `aws s3 ls` which list the existing buckets - -8. Configure the bucket as a web site with command `aws s3 website` as described in the [instructions](https://docs.aws.amazon.com/cli/latest/reference/s3/website.html). - - * E.g. `aws s3 website s3://my-static-website-jh34jsjmg --index-document index.html --error-document error.html` - -9. Upload content to the bucket. - - * First create the content, at least `index.html` and `error.html` documents. - * Upload the content to your bucket as described [here](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-copy) - * E.g. `aws s3 cp index.html s3://my-static-website-jh34jsjmg` and `aws s3 cp error.html s3://my-static-website-jh34jsjmg` - -10. Next we need to set the bucket policy to allow read access. - - * Create `policy.json` with the following contents (note that you need to replace the bucket name with your own). - - ```json - { - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "PublicReadGetObject", - "Effect": "Allow", - "Principal": "*", - "Action": "s3:GetObject", - "Resource": "arn:aws:s3:::my-static-website-jh34jsjmg/*" - } - ] - } - ``` - - * Set the bucket policy according to these [instructions](https://docs.aws.amazon.com/cli/latest/reference/s3api/put-bucket-policy.html) - * E.g. `aws s3api put-bucket-policy --bucket my-static-website-jh34jsjmg --policy file://policy.json` - -11. Test the web site in your browser. - - * The web site URL format is `http://.s3-website-.amazonaws.com` - * E.g. this web site was created in `eu-west-1` region with name `my-static-website-jh34jsjmg` so it can be accessed via url `http://my-static-website-jh34jsjmg.s3-website-eu-west-1.amazonaws.com` - -12. Create CloudFormation distribution for the web site. - - * The syntax is described in [this reference](https://docs.aws.amazon.com/cli/latest/reference/cloudfront/create-distribution.html) - * E.g. the easiest way is to call `aws cloudfront create-distribution --origin-domain-name my-static-website-jh34jsjmg.s3.amazonaws.com --default-root-object index.html` - * There's also JSON syntax e.g. `--distribution-config file://dist-config.json` to pass distribution configuration arguments in file - * The output of the call will show you the exact distribution settings including the generated CloudFront domain name you can use for testing e.g. `d2k3xwnaqa8nqx.cloudfront.net` - * CloudFormation distribution deployment takes some time, but once it's completed your web site is served from data centers all around the globe! - -13. That's it! You have implemented a static web site with content distribution network serving it lightning fast all around the world. - - * To update the web site you need to update the objects in S3 bucket and invalidate the objects in the CloudFront distribution - * To do it from AWS CLI see [this reference](https://docs.aws.amazon.com/cli/latest/reference/cloudfront/create-invalidation.html) - * Some further development you might want to do is serve the content over https and add a domain name for your site - -## Applicability - -Use the Static Content Hosting pattern when you want to: - -* Minimize the hosting cost for websites and applications that contain some static resources. -* Build a globally available web site with static content -* Monitor the web site traffic, bandwidth usage, costs etc. - -## Typical Use Case - -* Web sites with global reach -* Content produced by static web site generators -* Web sites with no dynamic content requirements - -## Real world examples - -* [Java Design Patterns web site](https://java-design-patterns.com) - -## Credits - -* [Static Content Hosting pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/static-content-hosting) diff --git a/cloud-static-content-hosting/etc/static-content-hosting.drawio b/cloud-static-content-hosting/etc/static-content-hosting.drawio deleted file mode 100644 index 50281e5e6..000000000 --- a/cloud-static-content-hosting/etc/static-content-hosting.drawio +++ /dev/null @@ -1 +0,0 @@ -7Vpbc9o6EP41PMZjW77AY0Kh56HttMOcIX3qCCxsNbLlyjKX/PqzMvING9rMQGE4mWQS72olrfbbXe8KBmgcbz8KnEafeUDYwDaD7QB9GNi2hRwL/inObs8ZIc0IBQ20UM2Y0Veimabm5jQgWUtQcs4kTdvMJU8SspQtHhaCb9piK87au6Y4JB3GbIlZlzungYz23KFr1vx/CA2jcmfL1CMxLoU1I4twwDcNFpoM0FhwLvdP8XZMmDJeaZf9vOmR0UoxQRL5JxOePj8vvN38XzEXc/KNzvDj65cH29PKyV15YhKAATTJhYx4yBPMJjX3aZmLNVGrWkDUIp84TzXzJ5Fyp8HEueTAimTM9CgoLHbPQJiGW5Lfm2MflPuYFbUrqS2Vz6UcPH+vlwCqnqSIcs7+eOpMR82mWRnPxZKcspWr/Q+LkMgTgsMKXQgLwmMCh4B5gjAs6bqtCNb+GVZyNYTwoFF8C6L+NRDVyJg3jox/VWS0lmvMcr1VFyrGILMpSDYRlWSW4uLgG0iubYvrpYiQZHvaft3j6gn2SCukU7M30plqUyc6G2le1Exy/uhCJhreloWc0iLaQrZvGe61beTflo089/ZMNLqhl5r5m5faGdNgWR/ddBYsC7vrgGO9Q3NCSes9bm62rrN60vzfBGfYRsewQKHflOuK+koEBQMQ8X+FrfO2DsiaMJ6CRQ7x5LlkNCHjqpVVBlvxRI4546KQQfAzVds/hQIHlNRjCU8U4ivKWJ94JgV/IQfCAc6iwj3URqoKoND4fsILwr7yjErKExhbcCl53BB4ZDRUA1I50RPW1BJ0USg33Ufprn2r8JaC1udVW+Is3R90RbdKj6eUU7XKZA2LZXoR6JtTNSHehuqKwcCbzDHyrNjrDPUL8ts1ntctgv1ht3gpeefvEjoO8zifAWOG4M8iX76Ar/+R41wa3B5ckLFX8MeGyugHX/wEbbKuU05M13bQcR8+A6qW20YVoS6sXk9N6lXV69mBRUeAHTOeB1MBoXHDuC6VkqtCyQ6cU3foIu+icLqeZ7T7DGQ5PX2GX4k1QR2hSyX3LqaWoS4jBcGSHI9XMIQ8MHpfem7aWbM6wB3iG9MgYMc6P8HzJKh85xxhZrfDzOrJnpbVE2flvPND4nQgsRUkOAhgvTwN9sCUuelukaku0Mu+3OxBpq8rvxwy3esv1AqWgIKt6SIvUtjdAuOWSaMMGf/qwHRvlJwqZEyaAJ9C2AAqdxwvnnMQL9bVYRl1YClfJ+aGLOBVr4KGJEFRNA9sjykkFtBWeOEeEwmWelRKqF8Px8pwe6FinYcEx6QaKOYYGXrQaz+0pwgSggP0TcExfoWmcpMZS6g47tZBDvKp0/OmQ30V5cX8o1y44R+NKg3SKY8xhURqasxOuUdgv6DtJsG/8DD5tW1Ue0ai/G16v7A69s3h2r0yUN1uN/e+Xxe86bogO9d9gdVyGN8x+xqRv3llYL3pY7PSQEWQHwmzM3+M1g4xt6cU9Z2eEKua+DdYDMj6KxXFWOOLKWjyHw== \ No newline at end of file diff --git a/cloud-static-content-hosting/etc/static-content-hosting.png b/cloud-static-content-hosting/etc/static-content-hosting.png deleted file mode 100644 index 6e0baa95e..000000000 Binary files a/cloud-static-content-hosting/etc/static-content-hosting.png and /dev/null differ diff --git a/eip-aggregator/README.md b/eip-aggregator/README.md deleted file mode 100644 index b4a69cf78..000000000 --- a/eip-aggregator/README.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: EIP Aggregator -category: Integration -language: en -tag: - - Enterprise Integration Pattern ---- - -## Intent -Sometimes in enterprise systems there is a need to group incoming data in order to process it as a whole. For example -you may need to gather offers and after defined number of offers has been received you would like to choose the one with -the best parameters. - -Aggregator allows you to merge messages based on defined criteria and parameters. It gathers original messages, -applies aggregation strategy and upon fulfilling given criteria, releasing merged messages. - -## Diagram -![alt text](./etc/aggregator.gif "Splitter") - -## Applicability -Use the Aggregator pattern when - -* You need to combine multiple incoming messages -* You want to process grouped data - -## Credits - -* [Gregor Hohpe, Bobby Woolf - Enterprise Integration Patterns](http://www.enterpriseintegrationpatterns.com/patterns/messaging/Aggregator.html) -* [Apache Camel - Documentation](http://camel.apache.org/aggregator2.html) -* [Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions](https://www.amazon.com/gp/product/0321200683/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321200683&linkCode=as2&tag=javadesignpat-20&linkId=122e0cff74eedd004cc81a3ecfa623cf) diff --git a/eip-aggregator/etc/aggregator.gif b/eip-aggregator/etc/aggregator.gif deleted file mode 100644 index b06cdfb0c..000000000 Binary files a/eip-aggregator/etc/aggregator.gif and /dev/null differ diff --git a/eip-aggregator/etc/eip-aggregator.urm.puml b/eip-aggregator/etc/eip-aggregator.urm.puml deleted file mode 100644 index 4d8661e21..000000000 --- a/eip-aggregator/etc/eip-aggregator.urm.puml +++ /dev/null @@ -1,14 +0,0 @@ -@startuml -package com.iluwatar.eip.aggregator { - class App { - + App() - + main(args : String[]) {static} - } -} -package com.iluwatar.eip.aggregator.routes { - class MessageAggregationStrategy { - + MessageAggregationStrategy() - + aggregate(oldExchange : Exchange, newExchange : Exchange) : Exchange - } -} -@enduml \ No newline at end of file diff --git a/eip-aggregator/pom.xml b/eip-aggregator/pom.xml deleted file mode 100644 index f24a205dd..000000000 --- a/eip-aggregator/pom.xml +++ /dev/null @@ -1,93 +0,0 @@ - - - - 4.0.0 - eip-aggregator - - com.iluwatar - java-design-patterns - 1.26.0-SNAPSHOT - - - - org.springframework.boot - spring-boot-starter-web - - - org.apache.camel - camel-core - - - org.apache.camel.springboot - camel-spring-boot - ${camel.version} - - - org.glassfish.jaxb - jaxb-runtime - - - javax.xml.bind - jaxb-api - - - - org.junit.jupiter - junit-jupiter-engine - test - - - org.springframework.boot - spring-boot-starter-test - - - org.apache.camel - camel-test-spring - ${camel.version} - - - - - - org.apache.maven.plugins - maven-assembly-plugin - - - - - - com.iluwatar.epi.aggregator.App - - - - - - - - - diff --git a/eip-aggregator/src/main/java/com/iluwatar/eip/aggregator/App.java b/eip-aggregator/src/main/java/com/iluwatar/eip/aggregator/App.java deleted file mode 100644 index d985199a1..000000000 --- a/eip-aggregator/src/main/java/com/iluwatar/eip/aggregator/App.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.eip.aggregator; - -import org.apache.camel.CamelContext; -import org.apache.camel.builder.RouteBuilder; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -/** - * Sometimes in enterprise systems there is a need to group incoming data in order to process it as - * a whole. For example you may need to gather offers and after defined number of offers has been - * received you would like to choose the one with the best parameters. - * - *

Aggregator allows you to merge messages based on defined criteria and parameters. It gathers - * original messages, applies aggregation strategy and upon fulfilling given criteria, releasing - * merged messages. - */ -@SpringBootApplication -public class App { - - /** - * Program entry point. It starts Spring Boot application and using Apache Camel it - * auto-configures routes. - * - * @param args command line args - */ - public static void main(String[] args) throws Exception { - // Run Spring Boot application and obtain ApplicationContext - var context = SpringApplication.run(App.class, args); - - // Get CamelContext from ApplicationContext - var camelContext = (CamelContext) context.getBean("camelContext"); - - // Add a new routes that will handle endpoints form SplitterRoute class. - camelContext.addRoutes(new RouteBuilder() { - @Override - public void configure() { - from("{{endpoint}}").log("ENDPOINT: ${body}"); - } - }); - - // Add producer that will send test message to an entry point in WireTapRoute - String[] stringArray = {"Test item #1", "Test item #2", "Test item #3"}; - camelContext.createProducerTemplate().sendBody("{{entry}}", stringArray); - - SpringApplication.exit(context); - } -} diff --git a/eip-aggregator/src/main/java/com/iluwatar/eip/aggregator/routes/AggregatorRoute.java b/eip-aggregator/src/main/java/com/iluwatar/eip/aggregator/routes/AggregatorRoute.java deleted file mode 100644 index ab1fdddec..000000000 --- a/eip-aggregator/src/main/java/com/iluwatar/eip/aggregator/routes/AggregatorRoute.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.eip.aggregator.routes; - -import org.apache.camel.builder.RouteBuilder; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -/** - * Sample aggregator route definition. - * - *

It consumes messages out of the direct:entry entry point and forwards them to - * direct:endpoint. Route accepts messages containing String as a body, it aggregates the - * messages based on the settings and forwards them as CSV to the output chanel. - * - *

Settings for the aggregation are: aggregate until 3 messages are bundled or wait 2000ms - * before sending bundled messages further. - * - *

In this example input/output endpoints names are stored in application.properties - * file. - */ -@Component -public class AggregatorRoute extends RouteBuilder { - - @Autowired - private MessageAggregationStrategy aggregator; - - /** - * Configures the route. - */ - @Override - public void configure() { - // Main route - from("{{entry}}").aggregate(constant(true), aggregator) - .completionSize(3).completionInterval(2000) - .to("{{endpoint}}"); - } -} diff --git a/eip-aggregator/src/main/java/com/iluwatar/eip/aggregator/routes/MessageAggregationStrategy.java b/eip-aggregator/src/main/java/com/iluwatar/eip/aggregator/routes/MessageAggregationStrategy.java deleted file mode 100644 index 07d3f2eeb..000000000 --- a/eip-aggregator/src/main/java/com/iluwatar/eip/aggregator/routes/MessageAggregationStrategy.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.eip.aggregator.routes; - -import org.apache.camel.AggregationStrategy; -import org.apache.camel.Exchange; -import org.springframework.stereotype.Component; - -/** - * Aggregation strategy joining bodies of messages. If message is first one oldMessage is - * null. All changes are made on IN messages. - */ -@Component -public class MessageAggregationStrategy implements AggregationStrategy { - - @Override - public Exchange aggregate(Exchange oldExchange, Exchange newExchange) { - if (oldExchange == null) { - return newExchange; - } - - var in1 = (String) oldExchange.getIn().getBody(); - var in2 = (String) newExchange.getIn().getBody(); - - oldExchange.getIn().setBody(in1 + ";" + in2); - - return oldExchange; - } -} diff --git a/eip-aggregator/src/main/resources/application.properties b/eip-aggregator/src/main/resources/application.properties deleted file mode 100644 index ca07b459e..000000000 --- a/eip-aggregator/src/main/resources/application.properties +++ /dev/null @@ -1,25 +0,0 @@ -# -# The MIT License -# Copyright © 2014-2021 Ilkka Seppälä -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -# - -entry=direct:entry -endpoint=direct:endpoint diff --git a/eip-aggregator/src/test/java/com/iluwatar/eip/aggregator/AppTest.java b/eip-aggregator/src/test/java/com/iluwatar/eip/aggregator/AppTest.java deleted file mode 100644 index 0b3d69861..000000000 --- a/eip-aggregator/src/test/java/com/iluwatar/eip/aggregator/AppTest.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.eip.aggregator; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; - -/** - * Test for App class - */ -class AppTest { - - /** - * Issue: Add at least one assertion to this test case. - * - * Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])} - * throws an exception. - */ - - @Test - void shouldExecuteApplicationWithoutException() { - assertDoesNotThrow(() -> App.main(new String[]{})); - } -} diff --git a/eip-aggregator/src/test/java/com/iluwatar/eip/aggregator/routes/AggregatorRouteTest.java b/eip-aggregator/src/test/java/com/iluwatar/eip/aggregator/routes/AggregatorRouteTest.java deleted file mode 100644 index 0dd3cf60e..000000000 --- a/eip-aggregator/src/test/java/com/iluwatar/eip/aggregator/routes/AggregatorRouteTest.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.eip.aggregator.routes; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import org.apache.camel.EndpointInject; -import org.apache.camel.ProducerTemplate; -import org.apache.camel.component.mock.MockEndpoint; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -/** - * Test class for AggregatorRoute. - *

- * In order for it to work we have to mock endpoints we want to read/write to. To mock those we need - * to substitute original endpoint names to mocks. - *

- */ -@ExtendWith(SpringExtension.class) -@SpringBootTest(classes = AggregatorRouteTest.class) -@ActiveProfiles("test") -@EnableAutoConfiguration -@ComponentScan -class AggregatorRouteTest { - - @EndpointInject(uri = "{{entry}}") - private ProducerTemplate entry; - - @EndpointInject(uri = "{{endpoint}}") - private MockEndpoint endpoint; - - /** - * Test if endpoint receives three separate messages. - * - * @throws Exception in case of en exception during the test - */ - @Test - @DirtiesContext - void testSplitter() throws Exception { - - // Three items in one entry message - entry.sendBody("TEST1"); - entry.sendBody("TEST2"); - entry.sendBody("TEST3"); - entry.sendBody("TEST4"); - entry.sendBody("TEST5"); - - // Endpoint should have three different messages in the end order of the messages is not important - endpoint.expectedMessageCount(2); - endpoint.assertIsSatisfied(); - - var body = (String) endpoint.getReceivedExchanges().get(0).getIn().getBody(); - assertEquals(3, body.split(";").length); - - var body2 = (String) endpoint.getReceivedExchanges().get(1).getIn().getBody(); - assertEquals(2, body2.split(";").length); - } -} diff --git a/eip-aggregator/src/test/java/com/iluwatar/eip/aggregator/routes/MessageAggregationStrategyTest.java b/eip-aggregator/src/test/java/com/iluwatar/eip/aggregator/routes/MessageAggregationStrategyTest.java deleted file mode 100644 index ed5d46e7b..000000000 --- a/eip-aggregator/src/test/java/com/iluwatar/eip/aggregator/routes/MessageAggregationStrategyTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.eip.aggregator.routes; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import org.apache.camel.CamelContext; -import org.apache.camel.impl.engine.SimpleCamelContext; -import org.apache.camel.support.DefaultExchange; -import org.junit.jupiter.api.Test; - -/** - * Tests MessageAggregationStrategy - */ -class MessageAggregationStrategyTest { - - private final CamelContext context = new SimpleCamelContext(); - - @Test - void testAggregate() { - var mas = new MessageAggregationStrategy(); - var oldExchange = new DefaultExchange(context); - oldExchange.getIn().setBody("TEST1"); - - var newExchange = new DefaultExchange(context); - newExchange.getIn().setBody("TEST2"); - - var output = mas.aggregate(oldExchange, newExchange); - var outputBody = (String) output.getIn().getBody(); - assertEquals("TEST1;TEST2", outputBody); - } - - @Test - void testAggregateOldNull() { - var mas = new MessageAggregationStrategy(); - - var newExchange = new DefaultExchange(context); - newExchange.getIn().setBody("TEST2"); - - var output = mas.aggregate(null, newExchange); - var outputBody = (String) output.getIn().getBody(); - - assertEquals(newExchange, output); - assertEquals("TEST2", outputBody); - } -} diff --git a/eip-aggregator/src/test/resources/application-test.properties b/eip-aggregator/src/test/resources/application-test.properties deleted file mode 100644 index 843005704..000000000 --- a/eip-aggregator/src/test/resources/application-test.properties +++ /dev/null @@ -1,25 +0,0 @@ -# -# The MIT License -# Copyright © 2014-2021 Ilkka Seppälä -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -# - -entry=direct:entry -endpoint=mock:endpoint diff --git a/eip-message-channel/.gitignore b/eip-message-channel/.gitignore deleted file mode 100644 index b83d22266..000000000 --- a/eip-message-channel/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target/ diff --git a/eip-message-channel/README.md b/eip-message-channel/README.md deleted file mode 100644 index 1d06174e2..000000000 --- a/eip-message-channel/README.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: EIP Message Channel -category: Integration -language: en -tag: - - Enterprise Integration Pattern ---- - -## Intent -When two applications communicate using a messaging system they do it by using logical addresses -of the system, so called Message Channels. - -## Class diagram -![alt text](./etc/message-channel.png "Message Channel") - -## Applicability -Use the Message Channel pattern when - -* two or more applications need to communicate using a messaging system - -## Real world examples - -* [akka-camel](http://doc.akka.io/docs/akka/snapshot/scala/camel.html) -* [Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions](https://www.amazon.com/gp/product/0321200683/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321200683&linkCode=as2&tag=javadesignpat-20&linkId=122e0cff74eedd004cc81a3ecfa623cf) diff --git a/eip-message-channel/etc/eip-message-channel.urm.puml b/eip-message-channel/etc/eip-message-channel.urm.puml deleted file mode 100644 index 38e2369ce..000000000 --- a/eip-message-channel/etc/eip-message-channel.urm.puml +++ /dev/null @@ -1,9 +0,0 @@ -@startuml -package com.iluwatar.eip.message.channel { - class App { - - LOGGER : Logger {static} - + App() - + main(args : String[]) {static} - } -} -@enduml \ No newline at end of file diff --git a/eip-message-channel/etc/message-channel.png b/eip-message-channel/etc/message-channel.png deleted file mode 100644 index 7db473281..000000000 Binary files a/eip-message-channel/etc/message-channel.png and /dev/null differ diff --git a/eip-message-channel/etc/message-channel.ucls b/eip-message-channel/etc/message-channel.ucls deleted file mode 100644 index 3ef0ed4bc..000000000 --- a/eip-message-channel/etc/message-channel.ucls +++ /dev/null @@ -1,320 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/eip-message-channel/pom.xml b/eip-message-channel/pom.xml deleted file mode 100644 index 898c47fcb..000000000 --- a/eip-message-channel/pom.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - - 4.0.0 - - com.iluwatar - java-design-patterns - 1.26.0-SNAPSHOT - - eip-message-channel - - - org.apache.camel - camel-core - - - org.apache.camel - camel-stream - - - org.junit.jupiter - junit-jupiter-engine - test - - - - - - org.apache.maven.plugins - maven-assembly-plugin - - - - - - com.iluwatar.eip.message.channel.App - - - - - - - - - diff --git a/eip-message-channel/src/main/java/com/iluwatar/eip/message/channel/App.java b/eip-message-channel/src/main/java/com/iluwatar/eip/message/channel/App.java deleted file mode 100644 index 90912d5fe..000000000 --- a/eip-message-channel/src/main/java/com/iluwatar/eip/message/channel/App.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.eip.message.channel; - -import lombok.extern.slf4j.Slf4j; -import org.apache.camel.builder.RouteBuilder; -import org.apache.camel.impl.DefaultCamelContext; - -/** - * When two applications communicate with each other using a messaging system they first need to - * establish a communication channel that will carry the data. Message Channel decouples Message - * producers and consumers. - * - *

The sending application doesn't necessarily know what particular application will end up - * retrieving it, but it can be assured that the application that retrieves the information is - * interested in that information. This is because the messaging system has different Message - * Channels for different types of information the applications want to communicate. When an - * application sends information, it doesn't randomly add the information to any channel available; - * it adds it to a channel whose specific purpose is to communicate that sort of information. - * Likewise, an application that wants to receive particular information doesn't pull info off some - * random channel; it selects what channel to get information from based on what type of information - * it wants. - * - *

In this example we use Apache Camel to establish two different Message Channels. The first - * one reads from standard input and delivers messages to Direct endpoint. The second Message - * Channel is established from the Direct component to console output. No actual messages are sent, - * only the established routes are printed to standard output. - */ -@Slf4j -public class App { - - /** - * Program entry point. - */ - public static void main(String[] args) throws Exception { - var context = new DefaultCamelContext(); - - context.addRoutes(new RouteBuilder() { - - @Override - public void configure() throws Exception { - from("stream:in").to("direct:greetings"); - from("direct:greetings").to("stream:out"); - } - }); - - context.start(); - context.getRoutes().forEach(r -> LOGGER.info(r.toString())); - context.stop(); - } -} diff --git a/eip-message-channel/src/test/java/com/iluwatar/eip/message/channel/AppTest.java b/eip-message-channel/src/test/java/com/iluwatar/eip/message/channel/AppTest.java deleted file mode 100644 index 427bceb73..000000000 --- a/eip-message-channel/src/test/java/com/iluwatar/eip/message/channel/AppTest.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.eip.message.channel; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; - -/** - * Application test - */ -class AppTest { - - /** - * Issue: Add at least one assertion to this test case. - * - * Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])} - * throws an exception. - */ - - @Test - void shouldExecuteApplicationWithoutException() { - assertDoesNotThrow(() -> App.main(new String[]{})); - } -} diff --git a/eip-publish-subscribe/.gitignore b/eip-publish-subscribe/.gitignore deleted file mode 100644 index b83d22266..000000000 --- a/eip-publish-subscribe/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target/ diff --git a/eip-publish-subscribe/README.md b/eip-publish-subscribe/README.md deleted file mode 100644 index fbdd35e7e..000000000 --- a/eip-publish-subscribe/README.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: EIP Publish Subscribe -category: Integration -language: en -tag: - - Enterprise Integration Pattern ---- - -## Intent -Broadcast messages from sender to all the interested receivers. - -## Class diagram -![alt text](./etc/publish-subscribe.png "Publish Subscribe Channel") - -## Applicability -Use the Publish Subscribe Channel pattern when - -* two or more applications need to communicate using a messaging system for broadcasts. - -## Credits - -* [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=48d37c67fb3d845b802fa9b619ad8f31) -* [Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions](https://www.amazon.com/gp/product/0321200683/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321200683&linkCode=as2&tag=javadesignpat-20&linkId=122e0cff74eedd004cc81a3ecfa623cf) diff --git a/eip-publish-subscribe/etc/eip-publish-subscribe.urm.puml b/eip-publish-subscribe/etc/eip-publish-subscribe.urm.puml deleted file mode 100644 index a201f59bb..000000000 --- a/eip-publish-subscribe/etc/eip-publish-subscribe.urm.puml +++ /dev/null @@ -1,9 +0,0 @@ -@startuml -package com.iluwatar.eip.publish.subscribe { - class App { - - LOGGER : Logger {static} - + App() - + main(args : String[]) {static} - } -} -@enduml \ No newline at end of file diff --git a/eip-publish-subscribe/etc/publish-subscribe.png b/eip-publish-subscribe/etc/publish-subscribe.png deleted file mode 100644 index 99867da66..000000000 Binary files a/eip-publish-subscribe/etc/publish-subscribe.png and /dev/null differ diff --git a/eip-publish-subscribe/etc/publish-subscribe.ucls b/eip-publish-subscribe/etc/publish-subscribe.ucls deleted file mode 100644 index 1b121506e..000000000 --- a/eip-publish-subscribe/etc/publish-subscribe.ucls +++ /dev/null @@ -1,218 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/eip-publish-subscribe/pom.xml b/eip-publish-subscribe/pom.xml deleted file mode 100644 index ecd3dc2ce..000000000 --- a/eip-publish-subscribe/pom.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - - 4.0.0 - - com.iluwatar - java-design-patterns - 1.26.0-SNAPSHOT - - eip-publish-subscribe - - - org.apache.camel - camel-core - - - org.apache.camel - camel-stream - - - org.junit.jupiter - junit-jupiter-engine - test - - - - - - org.apache.maven.plugins - maven-assembly-plugin - - - - - - com.iluwatar.eip.publish.subscribe.App - - - - - - - - - diff --git a/eip-publish-subscribe/src/main/java/com/iluwatar/eip/publish/subscribe/App.java b/eip-publish-subscribe/src/main/java/com/iluwatar/eip/publish/subscribe/App.java deleted file mode 100644 index 94ab862df..000000000 --- a/eip-publish-subscribe/src/main/java/com/iluwatar/eip/publish/subscribe/App.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.eip.publish.subscribe; - -import lombok.extern.slf4j.Slf4j; -import org.apache.camel.builder.RouteBuilder; -import org.apache.camel.impl.DefaultCamelContext; - -/** - * There are well-established patterns for implementing broadcasting. The Observer pattern describes - * the need to decouple observers from their subject (that is, the originator of the event) so that - * the subject can easily provide event notification to all interested observers no matter how many - * observers there are (even none). The Publish-Subscribe pattern expands upon Observer by adding - * the notion of an event channel for communicating event notifications. - * - *

A Publish-Subscribe Channel works like this: It has one input channel that splits into - * multiple output channels, one for each subscriber. When an event is published into the channel, - * the Publish-Subscribe Channel delivers a copy of the message to each of the output channels. Each - * output end of the channel has only one subscriber, which is allowed to consume a message only - * once. In this way, each subscriber gets the message only once, and consumed copies disappear from - * their channels. - * - *

In this example we use Apache Camel to establish a Publish-Subscribe Channel from - * "direct-origin" to "mock:foo", "mock:bar" and "stream:out". - */ -@Slf4j -public class App { - - /** - * Program entry point. - */ - public static void main(String[] args) throws Exception { - var context = new DefaultCamelContext(); - context.addRoutes(new RouteBuilder() { - @Override - public void configure() throws Exception { - from("direct:origin").multicast().to("mock:foo", "mock:bar", "stream:out"); - } - }); - var template = context.createProducerTemplate(); - context.start(); - context.getRoutes().forEach(r -> LOGGER.info(r.toString())); - template.sendBody("direct:origin", "Hello from origin"); - context.stop(); - } -} diff --git a/eip-publish-subscribe/src/main/resources/logback.xml b/eip-publish-subscribe/src/main/resources/logback.xml deleted file mode 100644 index 1f177fc24..000000000 --- a/eip-publish-subscribe/src/main/resources/logback.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - publish-subscribe.log - - publish-subscribe-%d.log - 5 - - - %-5p [%d{ISO8601,UTC}] %c: %m%n - - - - - %-5p [%d{ISO8601,UTC}] %c: %m%n - - - - - - - - - - diff --git a/eip-publish-subscribe/src/test/java/com/iluwatar/eip/publish/subscribe/AppTest.java b/eip-publish-subscribe/src/test/java/com/iluwatar/eip/publish/subscribe/AppTest.java deleted file mode 100644 index f8cc0083c..000000000 --- a/eip-publish-subscribe/src/test/java/com/iluwatar/eip/publish/subscribe/AppTest.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.eip.publish.subscribe; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; - -/** - * Application test - */ -class AppTest { - - /** - * Issue: Add at least one assertion to this test case. - * - * Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])} - * throws an exception. - */ - - @Test - void shouldExecuteApplicationWithoutException() { - assertDoesNotThrow(() -> App.main(new String[]{})); - } -} diff --git a/eip-splitter/README.md b/eip-splitter/README.md deleted file mode 100644 index 468685e00..000000000 --- a/eip-splitter/README.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: EIP Splitter -category: Integration -language: en -tag: - - Enterprise Integration Pattern ---- - -## Intent -It is very common in integration systems that incoming messages consists of many items bundled together. For example -an invoice document contains multiple invoice lines describing transaction (quantity, name of provided -service/sold goods, price etc.). Such bundled messages may not be accepted by other systems. This is where splitter -pattern comes in handy. It will take the whole document, split it based on given criteria and send individual -items to the endpoint. - -## Diagram -![alt text](./etc/sequencer.gif "Splitter") - -## Applicability -Use the Splitter pattern when - -* You need to split received data into smaller pieces to process them individually -* You need to control the size of data batches you are able to process - -## Credits - -* [Gregor Hohpe, Bobby Woolf - Enterprise Integration Patterns](http://www.enterpriseintegrationpatterns.com/patterns/messaging/Sequencer.html) -* [Apache Camel - Documentation](http://camel.apache.org/splitter.html) -* [Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions](https://www.amazon.com/gp/product/0321200683/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321200683&linkCode=as2&tag=javadesignpat-20&linkId=122e0cff74eedd004cc81a3ecfa623cf) diff --git a/eip-splitter/etc/eip-splitter.urm.puml b/eip-splitter/etc/eip-splitter.urm.puml deleted file mode 100644 index ad063b709..000000000 --- a/eip-splitter/etc/eip-splitter.urm.puml +++ /dev/null @@ -1,8 +0,0 @@ -@startuml -package com.iluwatar.eip.splitter { - class App { - + App() - + main(args : String[]) {static} - } -} -@enduml \ No newline at end of file diff --git a/eip-splitter/etc/sequencer.gif b/eip-splitter/etc/sequencer.gif deleted file mode 100644 index a925fa209..000000000 Binary files a/eip-splitter/etc/sequencer.gif and /dev/null differ diff --git a/eip-splitter/pom.xml b/eip-splitter/pom.xml deleted file mode 100644 index 49d2cf9e0..000000000 --- a/eip-splitter/pom.xml +++ /dev/null @@ -1,93 +0,0 @@ - - - - 4.0.0 - eip-splitter - - com.iluwatar - java-design-patterns - 1.26.0-SNAPSHOT - - - - org.springframework.boot - spring-boot-starter-web - - - org.apache.camel - camel-core - - - org.apache.camel.springboot - camel-spring-boot - ${camel.version} - - - org.glassfish.jaxb - jaxb-runtime - - - javax.xml.bind - jaxb-api - - - - org.junit.jupiter - junit-jupiter-engine - test - - - org.springframework.boot - spring-boot-starter-test - - - org.apache.camel - camel-test-spring - ${camel.version} - - - - - - org.apache.maven.plugins - maven-assembly-plugin - - - - - - com.iluwatar.eip.splitter.App - - - - - - - - - diff --git a/eip-splitter/src/main/java/com/iluwatar/eip/splitter/App.java b/eip-splitter/src/main/java/com/iluwatar/eip/splitter/App.java deleted file mode 100644 index c941e6883..000000000 --- a/eip-splitter/src/main/java/com/iluwatar/eip/splitter/App.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.eip.splitter; - -import org.apache.camel.CamelContext; -import org.apache.camel.builder.RouteBuilder; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -/** - * It is very common in integration systems that incoming messages consists of many items bundled - * together. For example an invoice document contains multiple invoice lines describing transaction - * (quantity, name of provided service/sold goods, price etc.). Such bundled messages may not be - * accepted by other systems. This is where splitter pattern comes in handy. It will take the whole - * document, split it based on given criteria and send individual items to the endpoint. - * - *

- * Splitter allows you to split messages based on defined criteria. It takes original message, - * process it and send multiple parts to the output channel. It is not defined if it should keep the - * order of items though. - *

- */ -@SpringBootApplication -public class App { - - /** - * Program entry point. It starts Spring Boot application and using Apache Camel it - * auto-configures routes. - * - * @param args command line args - */ - public static void main(String[] args) throws Exception { - // Run Spring Boot application and obtain ApplicationContext - var context = SpringApplication.run(App.class, args); - - // Get CamelContext from ApplicationContext - var camelContext = (CamelContext) context.getBean("camelContext"); - - // Add a new routes that will handle endpoints form SplitterRoute class. - camelContext.addRoutes(new RouteBuilder() { - - @Override - public void configure() throws Exception { - from("{{endpoint}}").log("ENDPOINT: ${body}"); - } - - }); - - // Add producer that will send test message to an entry point in WireTapRoute - String[] stringArray = {"Test item #1", "Test item #2", "Test item #3"}; - camelContext.createProducerTemplate().sendBody("{{entry}}", stringArray); - - SpringApplication.exit(context); - } -} diff --git a/eip-splitter/src/main/java/com/iluwatar/eip/splitter/routes/SplitterRoute.java b/eip-splitter/src/main/java/com/iluwatar/eip/splitter/routes/SplitterRoute.java deleted file mode 100644 index 1def66117..000000000 --- a/eip-splitter/src/main/java/com/iluwatar/eip/splitter/routes/SplitterRoute.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.eip.splitter.routes; - -import org.apache.camel.builder.RouteBuilder; -import org.springframework.stereotype.Component; - -/** - * Sample splitter route definition. - * - *

It consumes messages out of the direct:entry entry point and forwards them to - * direct:endpoint. Route accepts messages having body of array or collection of objects. - * Splitter component split message body and forwards single objects to the endpoint. - * - *

In this example input/output endpoints names are stored in application.properties - * file. - */ -@Component -public class SplitterRoute extends RouteBuilder { - - /** - * Configures the route. - * - * @throws Exception in case of exception during configuration - */ - @Override - public void configure() throws Exception { - // Main route - from("{{entry}}").split().body().to("{{endpoint}}"); - } -} diff --git a/eip-splitter/src/main/resources/application.properties b/eip-splitter/src/main/resources/application.properties deleted file mode 100644 index ca07b459e..000000000 --- a/eip-splitter/src/main/resources/application.properties +++ /dev/null @@ -1,25 +0,0 @@ -# -# The MIT License -# Copyright © 2014-2021 Ilkka Seppälä -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -# - -entry=direct:entry -endpoint=direct:endpoint diff --git a/eip-splitter/src/test/java/com/iluwatar/eip/splitter/AppTest.java b/eip-splitter/src/test/java/com/iluwatar/eip/splitter/AppTest.java deleted file mode 100644 index 0c1d30768..000000000 --- a/eip-splitter/src/test/java/com/iluwatar/eip/splitter/AppTest.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.eip.splitter; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; - -/** - * Test for App class - */ -class AppTest { - - /** - * Issue: Add at least one assertion to this test case. - * - * Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])} - * throws an exception. - */ - - @Test - void shouldExecuteApplicationWithoutException() { - assertDoesNotThrow(() -> App.main(new String[]{})); - } -} diff --git a/eip-splitter/src/test/java/com/iluwatar/eip/splitter/routes/SplitterRouteTest.java b/eip-splitter/src/test/java/com/iluwatar/eip/splitter/routes/SplitterRouteTest.java deleted file mode 100644 index 871ad1af6..000000000 --- a/eip-splitter/src/test/java/com/iluwatar/eip/splitter/routes/SplitterRouteTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.eip.splitter.routes; - -import org.apache.camel.EndpointInject; -import org.apache.camel.ProducerTemplate; -import org.apache.camel.component.mock.MockEndpoint; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -/** - * Test class for SplitterRoute. - *

- * In order for it to work we have to mock endpoints we want to read/write to. To mock those we need - * to substitute original endpoint names to mocks. - *

- */ -@ExtendWith(SpringExtension.class) -@SpringBootTest(classes = SplitterRouteTest.class) -@ActiveProfiles("test") -@EnableAutoConfiguration -@ComponentScan -class SplitterRouteTest { - - @EndpointInject(uri = "{{entry}}") - private ProducerTemplate entry; - - @EndpointInject(uri = "{{endpoint}}") - private MockEndpoint endpoint; - - /** - * Test if endpoint receives three separate messages. - * - * @throws Exception in case of en exception during the test - */ - @Test - @DirtiesContext - void testSplitter() throws Exception { - - // Three items in one entry message - entry.sendBody(new String[]{"TEST1", "TEST2", "TEST3"}); - - // Endpoint should have three different messages in the end order of the messages is not important - endpoint.expectedMessageCount(3); - endpoint.assertIsSatisfied(); - } -} diff --git a/eip-splitter/src/test/resources/application-test.properties b/eip-splitter/src/test/resources/application-test.properties deleted file mode 100644 index 843005704..000000000 --- a/eip-splitter/src/test/resources/application-test.properties +++ /dev/null @@ -1,25 +0,0 @@ -# -# The MIT License -# Copyright © 2014-2021 Ilkka Seppälä -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -# - -entry=direct:entry -endpoint=mock:endpoint diff --git a/eip-wire-tap/README.md b/eip-wire-tap/README.md deleted file mode 100644 index b0ab84e30..000000000 --- a/eip-wire-tap/README.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: EIP Wire Tap -category: Integration -language: en -tag: - - Enterprise Integration Pattern ---- - -## Intent -In most integration cases there is a need to monitor the messages flowing through the system. It is usually achieved -by intercepting the message and redirecting it to a different location like console, filesystem or the database. -It is important that such functionality should not modify the original message and influence the processing path. - -## Diagram -![alt text](./etc/wiretap.gif "Wire Tap") - -## Applicability -Use the Wire Tap pattern when - -* You need to monitor messages flowing through the system -* You need to redirect the same, unchanged message to two different endpoints/paths - -## Credits - -* [Gregor Hohpe, Bobby Woolf - Enterprise Integration Patterns](http://www.enterpriseintegrationpatterns.com/patterns/messaging/WireTap.html) -* [Apache Camel - Documentation](http://camel.apache.org/wire-tap.html) -* [Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions](https://www.amazon.com/gp/product/0321200683/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321200683&linkCode=as2&tag=javadesignpat-20&linkId=122e0cff74eedd004cc81a3ecfa623cf) diff --git a/eip-wire-tap/etc/eip-wire-tap.urm.puml b/eip-wire-tap/etc/eip-wire-tap.urm.puml deleted file mode 100644 index 51ee99723..000000000 --- a/eip-wire-tap/etc/eip-wire-tap.urm.puml +++ /dev/null @@ -1,8 +0,0 @@ -@startuml -package com.iluwatar.eip.wiretap { - class App { - + App() - + main(args : String[]) {static} - } -} -@enduml \ No newline at end of file diff --git a/eip-wire-tap/etc/wiretap.gif b/eip-wire-tap/etc/wiretap.gif deleted file mode 100644 index 414173716..000000000 Binary files a/eip-wire-tap/etc/wiretap.gif and /dev/null differ diff --git a/eip-wire-tap/pom.xml b/eip-wire-tap/pom.xml deleted file mode 100644 index cd9ad116f..000000000 --- a/eip-wire-tap/pom.xml +++ /dev/null @@ -1,93 +0,0 @@ - - - - 4.0.0 - eip-wire-tap - - com.iluwatar - java-design-patterns - 1.26.0-SNAPSHOT - - - - org.springframework.boot - spring-boot-starter-web - - - org.apache.camel - camel-core - - - org.apache.camel.springboot - camel-spring-boot - ${camel.version} - - - org.glassfish.jaxb - jaxb-runtime - - - javax.xml.bind - jaxb-api - - - - org.junit.jupiter - junit-jupiter-engine - test - - - org.springframework.boot - spring-boot-starter-test - - - org.apache.camel - camel-test-spring - ${camel.version} - - - - - - org.apache.maven.plugins - maven-assembly-plugin - - - - - - com.iluwatar.eip.wiretap.App - - - - - - - - - diff --git a/eip-wire-tap/src/main/java/com/iluwatar/eip/wiretap/App.java b/eip-wire-tap/src/main/java/com/iluwatar/eip/wiretap/App.java deleted file mode 100644 index 0c6da7cc1..000000000 --- a/eip-wire-tap/src/main/java/com/iluwatar/eip/wiretap/App.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.eip.wiretap; - -import org.apache.camel.CamelContext; -import org.apache.camel.builder.RouteBuilder; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -/** - * In most integration cases there is a need to monitor the messages flowing through the system. It - * is usually achieved by intercepting the message and redirecting it to a different location like - * console, filesystem or the database. It is important that such functionality should not modify - * the original message and influence the processing path. - * - *

- * Wire Tap allows you to route messages to a separate location while they are being forwarded to - * the ultimate destination. It basically consumes messages of the input channel and publishes the - * unmodified message to both output channels. - *

- */ -@SpringBootApplication -public class App { - - /** - * Program entry point. It starts Spring Boot application and using Apache Camel it - * auto-configures routes. - * - * @param args command line args - */ - public static void main(String[] args) throws Exception { - // Run Spring Boot application and obtain ApplicationContext - var context = SpringApplication.run(App.class, args); - - // Get CamelContext from ApplicationContext - var camelContext = (CamelContext) context.getBean("camelContext"); - - // Add a new routes that will handle endpoints form WireTapRoute class. - camelContext.addRoutes(new RouteBuilder() { - - @Override - public void configure() throws Exception { - from("{{endpoint}}").log("ENDPOINT: ${body}"); - from("{{wireTapEndpoint}}").log("WIRETAPPED ENDPOINT: ${body}"); - } - - }); - - // Add producer that will send test message to an entry point in WireTapRoute - camelContext.createProducerTemplate().sendBody("{{entry}}", "Test message"); - - SpringApplication.exit(context); - } -} diff --git a/eip-wire-tap/src/main/java/com/iluwatar/eip/wiretap/routes/WireTapRoute.java b/eip-wire-tap/src/main/java/com/iluwatar/eip/wiretap/routes/WireTapRoute.java deleted file mode 100644 index 79b948f66..000000000 --- a/eip-wire-tap/src/main/java/com/iluwatar/eip/wiretap/routes/WireTapRoute.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.eip.wiretap.routes; - -import org.apache.camel.builder.RouteBuilder; -import org.springframework.stereotype.Component; - -/** - * Sample wire tap route definition. - * - *

It consumes messages out of the direct:entry entry point and forwards them to - * direct:endpoint. Wire Tap intercepts the message and sends it to direct:wireTap, - * which in turn forwards it to - * direct:wireTapEndpoint. - * - *

In this example input/output endpoints names are stored in application.properties - * file. - */ -@Component -public class WireTapRoute extends RouteBuilder { - - /** - * Configures the route. - * - * @throws Exception in case of exception during configuration - */ - @Override - public void configure() throws Exception { - // Main route - from("{{entry}}").wireTap("direct:wireTap").to("{{endpoint}}"); - - // Wire tap route - from("direct:wireTap").log("Message: ${body}").to("{{wireTapEndpoint}}"); - } -} diff --git a/eip-wire-tap/src/main/resources/application.properties b/eip-wire-tap/src/main/resources/application.properties deleted file mode 100644 index cb77786ed..000000000 --- a/eip-wire-tap/src/main/resources/application.properties +++ /dev/null @@ -1,26 +0,0 @@ -# -# The MIT License -# Copyright © 2014-2021 Ilkka Seppälä -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -# - -entry=direct:entry -endpoint=direct:endpoint -wireTapEndpoint=direct:wireTapEndpoint \ No newline at end of file diff --git a/eip-wire-tap/src/test/java/com/iluwatar/eip/wiretap/AppTest.java b/eip-wire-tap/src/test/java/com/iluwatar/eip/wiretap/AppTest.java deleted file mode 100644 index 9440a6095..000000000 --- a/eip-wire-tap/src/test/java/com/iluwatar/eip/wiretap/AppTest.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.eip.wiretap; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; - -/** - * Test for App class - */ -class AppTest { - - /** - * Issue: Add at least one assertion to this test case. - * - * Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])} - * throws an exception. - */ - - @Test - void shouldExecuteApplicationWithoutException() { - assertDoesNotThrow(() -> App.main(new String[]{})); - } -} diff --git a/eip-wire-tap/src/test/java/com/iluwatar/eip/wiretap/routes/WireTapRouteTest.java b/eip-wire-tap/src/test/java/com/iluwatar/eip/wiretap/routes/WireTapRouteTest.java deleted file mode 100644 index b9c2c1460..000000000 --- a/eip-wire-tap/src/test/java/com/iluwatar/eip/wiretap/routes/WireTapRouteTest.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.eip.wiretap.routes; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import org.apache.camel.EndpointInject; -import org.apache.camel.ProducerTemplate; -import org.apache.camel.component.mock.MockEndpoint; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -/** - * Test class for WireTapRoute. - *

- * In order for it to work we have to mock endpoints we want to read/write to. To mock those we need - * to substitute original endpoint names to mocks. - *

- */ -@ExtendWith(SpringExtension.class) -@SpringBootTest(classes = WireTapRouteTest.class) -@ActiveProfiles("test") -@EnableAutoConfiguration -@ComponentScan -class WireTapRouteTest { - - @EndpointInject(uri = "{{entry}}") - private ProducerTemplate entry; - - @EndpointInject(uri = "{{endpoint}}") - private MockEndpoint endpoint; - - @EndpointInject(uri = "{{wireTapEndpoint}}") - private MockEndpoint wireTapEndpoint; - - /** - * Test if both endpoints receive exactly one message containing the same, unchanged body. - * - * @throws Exception in case of en exception during the test - */ - @Test - @DirtiesContext - void testWireTap() throws Exception { - entry.sendBody("TEST"); - - endpoint.expectedMessageCount(1); - wireTapEndpoint.expectedMessageCount(1); - - endpoint.assertIsSatisfied(); - wireTapEndpoint.assertIsSatisfied(); - - var endpointIn = endpoint.getExchanges().get(0).getIn(); - var wireTapEndpointIn = wireTapEndpoint.getExchanges().get(0).getIn(); - - assertEquals("TEST", endpointIn.getBody()); - assertEquals("TEST", wireTapEndpointIn.getBody()); - } -} diff --git a/eip-wire-tap/src/test/resources/application-test.properties b/eip-wire-tap/src/test/resources/application-test.properties deleted file mode 100644 index 801b7c928..000000000 --- a/eip-wire-tap/src/test/resources/application-test.properties +++ /dev/null @@ -1,26 +0,0 @@ -# -# The MIT License -# Copyright © 2014-2021 Ilkka Seppälä -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -# - -entry=direct:entry -endpoint=mock:endpoint -wireTapEndpoint=mock:wireTapEndpoint \ No newline at end of file diff --git a/pom.xml b/pom.xml index 95247640c..981b912e1 100644 --- a/pom.xml +++ b/pom.xml @@ -40,14 +40,10 @@ 2.7.5 0.8.8 1.4 - 3.18.3 19.0 2.66.0 4.0 3.12.8 - 1.1.0 - 1.12.13 - 2.0.1 1.1.0 2.0.0 3.0.0-M5 @@ -127,11 +123,9 @@ business-delegate half-sync-half-async layers - eip-message-channel fluentinterface reactor caching - eip-publish-subscribe delegation event-driven-architecture api-gateway @@ -162,13 +156,9 @@ throttling unit-of-work partial-response - eip-wire-tap - eip-splitter - eip-aggregator retry dirty-flag trampoline - serverless ambassador acyclic-visitor collection-pipeline @@ -234,16 +224,6 @@ commons-dbcp ${commons-dbcp.version} - - org.apache.camel - camel-core - ${camel.version} - - - org.apache.camel - camel-stream - ${camel.version} - com.google.guava guava diff --git a/serverless/README.md b/serverless/README.md deleted file mode 100644 index 6119508f5..000000000 --- a/serverless/README.md +++ /dev/null @@ -1,201 +0,0 @@ ---- -title: Serverless -category: Architectural -language: en -tag: - - Cloud distributed ---- - -## Serverless - -Serverless eliminates the need to plan for infrastructure and let's you focus on your -application. - -Following are optimization katas you should be aware of while building a serverless -applications - -* The Lean function - * Concise logic - Use functions to transform, not transport (utilize some of the - integration available from the provider to transport), and make sure you read only - what you need - * Efficient/single purpose code - avoid conditional/routing logic and break down - into individual functions, avoid "fat"/monolithic functions and control the - dependencies in the function deployment package to reduce the load time for your - function - * ephemeral environment - Utilize container start for expensive initializations -* Eventful Invocations - * Succinct payloads - Scrutinize the event as much as possible, and watch for - payload constraints (async - 128K) - * resilient routing - Understand retry policies and leverage dead letter queues - (SQS or SNS for replays) and remember retries count as invocations - * concurrent execution - lambda thinks of it's scale in terms of concurrency and - its not request based/duration based. Lambda will spin up the number of instances - based on the request. -* Coordinated calls - * Decoupled via APIs - best practice to setup your application is to have API's as - contracts that ensures separation of concerns - * scale-matched downstream - make sure when Lambda is calling downstream - components, you are matching scale configuration to it (by specifying max - concurrency based on downstream services) - * secured - Always ask a question, do I need a VPC? -* Serviceful operations - * Automated - use automated tools to manage and maintain the stack - * monitored applications - use monitoring services to get holistic view of your - serverless applications - -## Intent - -Whether to reduce your infrastructure costs, shrink the time you spend on ops tasks, -simplify your deployment processes, reach infinite scalability, serverless cuts time -to market in half. - -## Explanation - -Serverless computing is a cloud computing execution model in which the cloud provider -dynamically manages the allocation of machine resources. Pricing is based on the -actual amount of resources consumed by an application, rather than on pre-purchased -units of capacity. - -## Class diagram -![alt text](./etc/serverless.urm.png "Serverless pattern class diagram") - -## Serverless framework - -[Serverless](https://serverless.com/) is a toolkit for deploying and operating serverless architectures. - -## (Function as a Service or "FaaS") - -The term ‘Serverless’ is confusing since with such applications there are both server -hardware and server processes running somewhere, but the difference to normal -approaches is that the organization building and supporting a ‘Serverless’ application - is not looking after the hardware or the processes - they are outsourcing this to a vendor. - -Some of the Serverless Cloud Providers are - -![https://serverless.com/framework/docs/providers/aws/](./etc/aws-black.png "aws") -![https://serverless.com/framework/docs/providers/azure/](./etc/azure-black.png "azure") -![https://serverless.com/framework/docs/providers/openwhisk/](./etc/openwhisk-black.png "openwhisk") -![https://serverless.com/framework/docs/providers/google/](./etc/gcf-black.png "google") -![https://serverless.com/framework/docs/providers/kubeless/](./etc/kubeless-logos-black.png "kubeless") -![https://serverless.com/framework/docs/providers/spotinst/](./etc/spotinst-logos-black-small.png "spotinst") -![https://serverless.com/framework/docs/providers/webtasks/](./etc/webtask-small-grayscale.png "webtask") -... - -Anything that triggers an Lambda Function to execute is regarded by the Framework as -an Event. Most of the Serverless Cloud Providers support following Events -- Http -- PubSub Events -- scheduled - -AWS supports processing event generated from AWS Services (S3/Cloudwatch/etc) and -using aws as a compute engine is our first choice. - -## (Backend as a Service or "BaaS") -This example creates a backend for ‘persons’ collection which uses DynamoDB NoSQL -database service also provided by Amazon. - -## AWS lambda function implementation - -[AWS Lambda SDK](https://aws.amazon.com/sdk-for-java/) provides pre-defined interface -`com.amazonaws.services.lambda.runtime -.RequestHandler` to implement our lambda function. - -```java -public class LambdaInfoApiHandler implements RequestHandler, ApiGatewayResponse> { - - private static final Logger LOG = Logger.getLogger(LambdaInfoApiHandler.class); - private static final Integer SUCCESS_STATUS_CODE = 200; - - - @Override - public ApiGatewayResponse handleRequest(Map input, Context context) { - - } -} -``` -handleRequest method is where the function code is implemented. Context provides -useful information about Lambda execution environment. AWS Lambda function needs a -deployment package. This package is either a .zip or .jar file that contains all the -dependencies of the function. - -`serverless.yml` contains configuration to manage deployments for your functions. - -## Run example in local - -# Pre-requisites - -* Node.js v6.5.0 or later. -* Serverless CLI v1.9.0 or later. You can run npm install -g serverless to install it. -* An AWS account. If you don't already have one, you can sign up for a free trial that includes 1 million free Lambda requests per month. -* [Set-up](https://serverless.com/framework/docs/providers/aws/guide/credentials/) your Provider Credentials. Watch the video on setting up credentials - -# build and deploy - -* `cd serverless` -* `mvn clean package` -* `serverless deploy --stage=dev --verbose` - -Based on the configuration in `serverless.yml` serverless framework creates following -resources - -* CloudFormation stack for S3 (ServerlessDeploymentBucket) -* IAM Role (IamRoleLambdaExecution) -* CloudWatch (log groups) -* API Gateway (ApiGatewayRestApi) -* Lambda function -* DynamoDB collection - -The command will print out Stack Outputs which looks something like this - -```yaml -endpoints: - GET - https://xxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev/info - POST - https://xxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev/api/person - GET - https://xxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev/api/person/{id} - -``` - -```yaml -CurrentTimeLambdaFunctionQualifiedArn: arn:aws:lambda:us-east-1:xxxxxxxxxxx:function:lambda-info-http-endpoint-dev-currentTime:4 -ServiceEndpoint: https://xxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev -ServerlessDeploymentBucketName: lambda-info-http-endpoin-serverlessdeploymentbuck-2u8uz2i7cap2 -``` -access the endpoint to invoke the function. - -Use the following cURL commands to test the endpoints - -```cURL -curl -X GET \ - https://xxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev/info \ - -H 'cache-control: no-cache' -``` - -```cURL -curl -X POST \ - https://xxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev/api/person \ - -H 'cache-control: no-cache' \ - -H 'content-type: application/json' \ - -d '{ - "firstName": "Thor", - "lastName": "Odinson", - "address": { - "addressLineOne": "1 Odin ln", - "addressLineTwo": "100", - "city": "Asgard", - "state": "country of the Gods", - "zipCode": "00001" - } -}' -``` - -```cURL -curl -X GET \ - https://xxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev/api/person/{id} \ - -H 'cache-control: no-cache' -``` - -## Credits - -* [serverless docs](https://serverless.com/framework/docs/) -* [Serverless Architectures](https://martinfowler.com/articles/serverless.html) -* [Serverless Black Belt](https://youtu.be/oQFORsso2go) diff --git a/serverless/etc/aws-black.png b/serverless/etc/aws-black.png deleted file mode 100644 index 7b5ba3178..000000000 Binary files a/serverless/etc/aws-black.png and /dev/null differ diff --git a/serverless/etc/azure-black.png b/serverless/etc/azure-black.png deleted file mode 100644 index 95ceb7e82..000000000 Binary files a/serverless/etc/azure-black.png and /dev/null differ diff --git a/serverless/etc/gcf-black.png b/serverless/etc/gcf-black.png deleted file mode 100644 index b4e22982c..000000000 Binary files a/serverless/etc/gcf-black.png and /dev/null differ diff --git a/serverless/etc/kubeless-logos-black.png b/serverless/etc/kubeless-logos-black.png deleted file mode 100644 index dd6523c51..000000000 Binary files a/serverless/etc/kubeless-logos-black.png and /dev/null differ diff --git a/serverless/etc/openwhisk-black.png b/serverless/etc/openwhisk-black.png deleted file mode 100644 index e70139088..000000000 Binary files a/serverless/etc/openwhisk-black.png and /dev/null differ diff --git a/serverless/etc/serverless.urm.png b/serverless/etc/serverless.urm.png deleted file mode 100644 index 18149d562..000000000 Binary files a/serverless/etc/serverless.urm.png and /dev/null differ diff --git a/serverless/etc/serverless.urm.puml b/serverless/etc/serverless.urm.puml deleted file mode 100644 index 27ff043fd..000000000 --- a/serverless/etc/serverless.urm.puml +++ /dev/null @@ -1,138 +0,0 @@ -@startuml -package com.iluwatar.serverless.faas.api { - class LambdaInfoApiHandler { - - LOG : Logger {static} - - SUCCESS_STATUS_CODE : Integer {static} - + LambdaInfoApiHandler() - + handleRequest(input : Map, context : Context) : ApiGatewayResponse - - headers() : Map - - lambdaInfo(context : Context) : LambdaInfo - } -} -package com.iluwatar.serverless.baas.model { - class Address { - - addressLineOne : String - - addressLineTwo : String - - city : String - - serialVersionUID : long {static} - - state : String - - zipCode : String - + Address() - + equals(o : Object) : boolean - + getAddressLineOne() : String - + getAddressLineTwo() : String - + getCity() : String - + getState() : String - + getZipCode() : String - + hashCode() : int - + setAddressLineOne(addressLineOne : String) - + setAddressLineTwo(addressLineTwo : String) - + setCity(city : String) - + setState(state : String) - + setZipCode(zipCode : String) - + toString() : String - } - class Person { - - address : Address - - firstName : String - - id : String - - lastName : String - - serialVersionUID : long {static} - + Person() - + equals(o : Object) : boolean - + getAddress() : Address - + getFirstName() : String - + getId() : String - + getLastName() : String - + hashCode() : int - + setAddress(address : Address) - + setFirstName(firstName : String) - + setId(id : String) - + setLastName(lastName : String) - + toString() : String - } -} -package com.iluwatar.serverless.faas { - class ApiGatewayResponse { - - body : String - - headers : Map - - isBase64Encoded : Boolean - - serialVersionUID : long {static} - - statusCode : Integer - + ApiGatewayResponse(statusCode : Integer, body : String, headers : Map, isBase64Encoded : Boolean) - + getBody() : String - + getHeaders() : Map - + getStatusCode() : Integer - + isBase64Encoded() : Boolean - } - class ApiGatewayResponseBuilder { - - OBJECT_MAPPER : ObjectMapper {static} - - body : T extends Serializable - - headers : Map - - isBase64Encoded : Boolean - - statusCode : Integer - + ApiGatewayResponseBuilder() - + base64Encoded(isBase64Encoded : Boolean) : ApiGatewayResponseBuilder - + body(body : T extends Serializable) : ApiGatewayResponseBuilder - + build() : ApiGatewayResponse - + headers(headers : Map) : ApiGatewayResponseBuilder - + statusCode(statusCode : Integer) : ApiGatewayResponseBuilder - } - class LambdaInfo { - - awsRequestId : String - - functionName : String - - functionVersion : String - - logGroupName : String - - logStreamName : String - - memoryLimitInMb : Integer - - serialVersionUID : long {static} - + LambdaInfo() - + equals(o : Object) : boolean - + getAwsRequestId() : String - + getFunctionName() : String - + getFunctionVersion() : String - + getLogGroupName() : String - + getLogStreamName() : String - + getMemoryLimitInMb() : Integer - + hashCode() : int - + setAwsRequestId(awsRequestId : String) - + setFunctionName(functionName : String) - + setFunctionVersion(functionVersion : String) - + setLogGroupName(logGroupName : String) - + setLogStreamName(logStreamName : String) - + setMemoryLimitInMb(memoryLimitInMb : Integer) - + toString() : String - } -} -package com.iluwatar.serverless.baas.api { - abstract class AbstractDynamoDbHandler { - - dynamoDbMapper : DynamoDBMapper - - objectMapper : ObjectMapper - + AbstractDynamoDbHandler() - # apiGatewayProxyResponseEvent(statusCode : Integer, body : T extends Serializable) : APIGatewayProxyResponseEvent - # getDynamoDbMapper() : DynamoDBMapper - # getObjectMapper() : ObjectMapper - # headers() : Map - - initAmazonDynamoDb() - + setDynamoDbMapper(dynamoDbMapper : DynamoDBMapper) - } - class FindPersonApiHandler { - - LOG : Logger {static} - - SUCCESS_STATUS_CODE : Integer {static} - + FindPersonApiHandler() - + handleRequest(apiGatewayProxyRequestEvent : APIGatewayProxyRequestEvent, context : Context) : APIGatewayProxyResponseEvent - } - class SavePersonApiHandler { - - BAD_REQUEST_STATUS_CODE : Integer {static} - - CREATED_STATUS_CODE : Integer {static} - - LOG : Logger {static} - + SavePersonApiHandler() - + handleRequest(apiGatewayProxyRequestEvent : APIGatewayProxyRequestEvent, context : Context) : APIGatewayProxyResponseEvent - } -} -ApiGatewayResponseBuilder ..+ ApiGatewayResponse -Person --> "-address" Address -Access ..+ JsonProperty -FindPersonApiHandler --|> AbstractDynamoDbHandler -SavePersonApiHandler --|> AbstractDynamoDbHandler -@enduml \ No newline at end of file diff --git a/serverless/etc/spotinst-logos-black-small.png b/serverless/etc/spotinst-logos-black-small.png deleted file mode 100644 index b748f80c7..000000000 Binary files a/serverless/etc/spotinst-logos-black-small.png and /dev/null differ diff --git a/serverless/etc/webtask-small-grayscale.png b/serverless/etc/webtask-small-grayscale.png deleted file mode 100644 index 8e2180935..000000000 Binary files a/serverless/etc/webtask-small-grayscale.png and /dev/null differ diff --git a/serverless/pom.xml b/serverless/pom.xml deleted file mode 100644 index af44c29dd..000000000 --- a/serverless/pom.xml +++ /dev/null @@ -1,112 +0,0 @@ - - - - 4.0.0 - serverless - - com.iluwatar - java-design-patterns - 1.26.0-SNAPSHOT - - - - com.amazonaws - aws-lambda-java-core - ${aws-lambda-core.version} - - - com.amazonaws - aws-java-sdk-dynamodb - ${aws-java-sdk-dynamodb.version} - - - com.amazonaws - aws-lambda-java-events - ${aws-lambda-java-events.version} - - - com.fasterxml.jackson.core - jackson-core - - - com.fasterxml.jackson.core - jackson-databind - - - com.fasterxml.jackson.core - jackson-annotations - - - org.junit.jupiter - junit-jupiter-engine - test - - - org.mockito - mockito-core - test - - - org.hamcrest - hamcrest-core - test - - - - - - - org.apache.maven.plugins - maven-shade-plugin - 2.3 - - false - - - - package - - shade - - - ${project.artifactId} - - - - - - - diff --git a/serverless/serverless.yml b/serverless/serverless.yml deleted file mode 100644 index 6a5b867cf..000000000 --- a/serverless/serverless.yml +++ /dev/null @@ -1,104 +0,0 @@ -# -# This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). -# -# The MIT License -# Copyright © 2014-2022 Ilkka Seppälä -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -# - -service: serverless-services - -frameworkVersion: ">=1.2.0 <2.0.0" - -provider: - name: aws - runtime: java8 - usagePlan: - quota: - limit: 500 - offset: 2 - period: MONTH - throttle: - burstLimit: 20 - rateLimit: 10 - -package: - artifact: target/serverless.jar - -functions: - lambdaInfoApi: - handler: com.iluwatar.serverless.faas.api.LambdaInfoApiHandler - events: - - http: - path: info - method: get - - savePerson: - handler: com.iluwatar.serverless.baas.api.SavePersonApiHandler - events: - - http: - path: api/person - method: post - cors: true - integration: lambda-proxy - - getPerson: - handler: com.iluwatar.serverless.baas.api.FindPersonApiHandler - events: - - http: - path: api/person/{id} - method: get - cors: true - integration: lambda-proxy - -resources: - Resources: - DynamoDbTable: - Type: AWS::DynamoDB::Table - Properties: - TableName: persons - AttributeDefinitions: - - AttributeName: id - AttributeType: S - KeySchema: - - AttributeName: id - KeyType: HASH - ProvisionedThroughput: - ReadCapacityUnits: 1 - WriteCapacityUnits: 1 - DynamoDBIamPolicy: - Type: AWS::IAM::Policy - DependsOn: DynamoDbTable - Properties: - PolicyName: lambda-dynamodb - PolicyDocument: - Version: '2012-10-17' - Statement: - - Effect: Allow - Action: - - dynamodb:GetItem - - dynamodb:PutItem - - dynamodb:UpdateItem - - dynamodb:DeleteItem - - dynamodb:Query - - dynamodb:Scan - Resource: arn:aws:dynamodb:*:*:table/persons - Roles: - - Ref: IamRoleLambdaExecution \ No newline at end of file diff --git a/serverless/src/main/java/com/iluwatar/serverless/baas/api/AbstractDynamoDbHandler.java b/serverless/src/main/java/com/iluwatar/serverless/baas/api/AbstractDynamoDbHandler.java deleted file mode 100644 index b4f3c1590..000000000 --- a/serverless/src/main/java/com/iluwatar/serverless/baas/api/AbstractDynamoDbHandler.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.serverless.baas.api; - -import com.amazonaws.regions.Regions; -import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder; -import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper; -import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import java.io.Serializable; -import java.util.Map; - -/** - * abstract dynamodb handler. - * - * @param - serializable collection - */ -public abstract class AbstractDynamoDbHandler { - private DynamoDBMapper dynamoDbMapper; - - private final ObjectMapper objectMapper; - - public AbstractDynamoDbHandler() { - this.initAmazonDynamoDb(); - this.objectMapper = new ObjectMapper(); - } - - private void initAmazonDynamoDb() { - var amazonDynamoDb = AmazonDynamoDBClientBuilder - .standard() - .withRegion(Regions.US_EAST_1) - .build(); - - this.dynamoDbMapper = new DynamoDBMapper(amazonDynamoDb); - } - - protected DynamoDBMapper getDynamoDbMapper() { - return this.dynamoDbMapper; - } - - protected ObjectMapper getObjectMapper() { - return objectMapper; - } - - public void setDynamoDbMapper(DynamoDBMapper dynamoDbMapper) { - this.dynamoDbMapper = dynamoDbMapper; - } - - protected Map headers() { - return Map.of("Content-Type", "application/json"); - } - - /** - * API Gateway response. - * - * @param statusCode - status code - * @param body - Object body - * @return - api gateway proxy response - */ - protected APIGatewayProxyResponseEvent apiGatewayProxyResponseEvent(Integer statusCode, T body) { - var apiGatewayProxyResponseEvent = new APIGatewayProxyResponseEvent().withHeaders(headers()); - try { - apiGatewayProxyResponseEvent - .withStatusCode(statusCode) - .withBody(getObjectMapper().writeValueAsString(body)); - } catch (JsonProcessingException jsonProcessingException) { - throw new RuntimeException(jsonProcessingException); - } - - return apiGatewayProxyResponseEvent; - } -} diff --git a/serverless/src/main/java/com/iluwatar/serverless/baas/api/FindPersonApiHandler.java b/serverless/src/main/java/com/iluwatar/serverless/baas/api/FindPersonApiHandler.java deleted file mode 100644 index dc4dfa878..000000000 --- a/serverless/src/main/java/com/iluwatar/serverless/baas/api/FindPersonApiHandler.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.serverless.baas.api; - -import com.amazonaws.services.lambda.runtime.Context; -import com.amazonaws.services.lambda.runtime.RequestHandler; -import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent; -import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; -import com.iluwatar.serverless.baas.model.Person; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * find person from persons collection Created by dheeraj.mummar on 3/5/18. - */ -public class FindPersonApiHandler extends AbstractDynamoDbHandler - implements RequestHandler { - - private static final Logger LOG = LoggerFactory.getLogger(FindPersonApiHandler.class); - private static final Integer SUCCESS_STATUS_CODE = 200; - - @Override - public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent req, Context ctx) { - req.getPathParameters().forEach(FindPersonApiHandler::logKeyValue); - var id = req.getPathParameters().get("id"); - var person = this.getDynamoDbMapper().load(Person.class, id); - return apiGatewayProxyResponseEvent(SUCCESS_STATUS_CODE, person); - } - - private static void logKeyValue(String key, String value) { - LOG.info(key + "=" + value); - } - -} diff --git a/serverless/src/main/java/com/iluwatar/serverless/baas/api/SavePersonApiHandler.java b/serverless/src/main/java/com/iluwatar/serverless/baas/api/SavePersonApiHandler.java deleted file mode 100644 index e0a8d98b0..000000000 --- a/serverless/src/main/java/com/iluwatar/serverless/baas/api/SavePersonApiHandler.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.serverless.baas.api; - -import com.amazonaws.services.lambda.runtime.Context; -import com.amazonaws.services.lambda.runtime.RequestHandler; -import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent; -import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; -import com.iluwatar.serverless.baas.model.Person; -import java.io.IOException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * save person into persons collection Created by dheeraj.mummar on 3/4/18. - */ -public class SavePersonApiHandler extends AbstractDynamoDbHandler - implements RequestHandler { - - private static final Logger LOG = LoggerFactory.getLogger(SavePersonApiHandler.class); - private static final Integer CREATED_STATUS_CODE = 201; - private static final Integer BAD_REQUEST_STATUS_CODE = 400; - - @Override - public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent req, Context ctx) { - try { - var objectMapper = getObjectMapper(); - var person = objectMapper.readValue(req.getBody(), Person.class); - getDynamoDbMapper().save(person); - return apiGatewayProxyResponseEvent(CREATED_STATUS_CODE, person); - } catch (IOException ioException) { - LOG.error("unable to parse body", ioException); - return apiGatewayProxyResponseEvent(BAD_REQUEST_STATUS_CODE, null); - } - } -} diff --git a/serverless/src/main/java/com/iluwatar/serverless/baas/model/Address.java b/serverless/src/main/java/com/iluwatar/serverless/baas/model/Address.java deleted file mode 100644 index c0198f0a7..000000000 --- a/serverless/src/main/java/com/iluwatar/serverless/baas/model/Address.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.serverless.baas.model; - -import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute; -import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBDocument; -import java.io.Serializable; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; - -/** - * Address class Created by dheeraj.mummarareddy on 3/4/18. - */ -@Getter -@Setter -@EqualsAndHashCode -@ToString -@DynamoDBDocument -public class Address implements Serializable { - - private static final long serialVersionUID = 6760844284799736970L; - - @DynamoDBAttribute(attributeName = "addressLineOne") - private String addressLineOne; - - @DynamoDBAttribute(attributeName = "addressLineTwo") - private String addressLineTwo; - - @DynamoDBAttribute(attributeName = "city") - private String city; - - @DynamoDBAttribute(attributeName = "state") - private String state; - - @DynamoDBAttribute(attributeName = "zipCode") - private String zipCode; - -} diff --git a/serverless/src/main/java/com/iluwatar/serverless/baas/model/Person.java b/serverless/src/main/java/com/iluwatar/serverless/baas/model/Person.java deleted file mode 100644 index a7b3c83e6..000000000 --- a/serverless/src/main/java/com/iluwatar/serverless/baas/model/Person.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.serverless.baas.model; - -import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute; -import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAutoGeneratedKey; -import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey; -import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable; -import com.fasterxml.jackson.annotation.JsonProperty; -import java.io.Serializable; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; - -/** - * Person class Created by dheeraj.mummarareddy on 3/4/18. - */ -@Getter -@Setter -@ToString -@EqualsAndHashCode -@DynamoDBTable(tableName = "persons") -public class Person implements Serializable { - - private static final long serialVersionUID = -3413087924608627075L; - - @JsonProperty(access = JsonProperty.Access.READ_ONLY) - @DynamoDBHashKey(attributeName = "id") - @DynamoDBAutoGeneratedKey - private String id; - - @DynamoDBAttribute(attributeName = "firstName") - private String firstName; - - @DynamoDBAttribute(attributeName = "lastName") - private String lastName; - - @DynamoDBAttribute(attributeName = "address") - private Address address; - -} diff --git a/serverless/src/main/java/com/iluwatar/serverless/faas/ApiGatewayResponse.java b/serverless/src/main/java/com/iluwatar/serverless/faas/ApiGatewayResponse.java deleted file mode 100644 index 6d15ad8ec..000000000 --- a/serverless/src/main/java/com/iluwatar/serverless/faas/ApiGatewayResponse.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.serverless.faas; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import java.io.Serializable; -import java.util.Map; - -/** - * Api gateway response. - */ -public class ApiGatewayResponse implements Serializable { - - private static final long serialVersionUID = 1181159426782844892L; - - private final Integer statusCode; - private final String body; - private final Map headers; - private final Boolean isBase64Encoded; - - /** - * api gateway response. - * - * @param statusCode - http status code - * @param body - response body - * @param headers - response headers - * @param isBase64Encoded - base64Encoded flag - */ - public ApiGatewayResponse( - Integer statusCode, - String body, - Map headers, - Boolean isBase64Encoded - ) { - this.statusCode = statusCode; - this.body = body; - this.headers = headers; - this.isBase64Encoded = isBase64Encoded; - } - - /** - * http status code. - * - * @return statusCode - http status code - */ - public Integer getStatusCode() { - return statusCode; - } - - /** - * response body. - * - * @return string body - */ - public String getBody() { - return body; - } - - /** - * response headers. - * - * @return response headers - */ - public Map getHeaders() { - return headers; - } - - /** - * base64Encoded flag, API Gateway expects the property to be called "isBase64Encoded". - * - * @return base64Encoded flag - */ - public Boolean isBase64Encoded() { - return isBase64Encoded; - } - - /** - * ApiGatewayResponse Builder class. - * - * @param Serializable object - */ - public static class ApiGatewayResponseBuilder { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); - private Integer statusCode; - private T body; - private Map headers; - private Boolean isBase64Encoded; - - /** - * http status code. - * - * @param statusCode - http status code - * @return ApiGatewayResponseBuilder - */ - public ApiGatewayResponseBuilder statusCode(Integer statusCode) { - this.statusCode = statusCode; - return this; - } - - /** - * Serializable body. - * - * @param body - Serializable object - * @return ApiGatewayResponseBuilder - */ - public ApiGatewayResponseBuilder body(T body) { - this.body = body; - return this; - } - - /** - * response headers. - * - * @param headers - response headers - * @return ApiGatewayResponseBuilder - */ - public ApiGatewayResponseBuilder headers(Map headers) { - this.headers = headers; - return this; - } - - /** - * base64Encoded flag. - * - * @param isBase64Encoded - base64Encoded flag - * @return ApiGatewayResponseBuilder - */ - public ApiGatewayResponseBuilder base64Encoded(Boolean isBase64Encoded) { - this.isBase64Encoded = isBase64Encoded; - return this; - } - - /** - * build ApiGatewayResponse. - * - * @return ApiGatewayResponse - */ - public ApiGatewayResponse build() { - String strBody = null; - if (this.body != null) { - try { - strBody = OBJECT_MAPPER.writeValueAsString(body); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - } - - return new ApiGatewayResponse(this.statusCode, strBody, this.headers, this.isBase64Encoded); - } - } -} diff --git a/serverless/src/main/java/com/iluwatar/serverless/faas/LambdaInfo.java b/serverless/src/main/java/com/iluwatar/serverless/faas/LambdaInfo.java deleted file mode 100644 index 0ea1a5eee..000000000 --- a/serverless/src/main/java/com/iluwatar/serverless/faas/LambdaInfo.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.serverless.faas; - -import java.io.Serializable; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; - -/** - * Lambda context information. - */ -@ToString -@EqualsAndHashCode -@Setter -@Getter -public class LambdaInfo implements Serializable { - - private static final long serialVersionUID = 3936130599040848923L; - - private String awsRequestId; - private String logGroupName; - private String logStreamName; - private String functionName; - private String functionVersion; - private Integer memoryLimitInMb; - -} diff --git a/serverless/src/main/java/com/iluwatar/serverless/faas/api/LambdaInfoApiHandler.java b/serverless/src/main/java/com/iluwatar/serverless/faas/api/LambdaInfoApiHandler.java deleted file mode 100644 index 954215c0a..000000000 --- a/serverless/src/main/java/com/iluwatar/serverless/faas/api/LambdaInfoApiHandler.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.serverless.faas.api; - -import com.amazonaws.services.lambda.runtime.Context; -import com.amazonaws.services.lambda.runtime.RequestHandler; -import com.iluwatar.serverless.faas.ApiGatewayResponse; -import com.iluwatar.serverless.faas.LambdaInfo; -import java.util.Map; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * LambdaInfoApiHandler - simple api to get lambda context Created by dheeraj.mummar on 2/5/18. - */ -public class LambdaInfoApiHandler - implements RequestHandler, ApiGatewayResponse> { - - private static final Logger LOG = LoggerFactory.getLogger(LambdaInfoApiHandler.class); - private static final Integer SUCCESS_STATUS_CODE = 200; - - - @Override - public ApiGatewayResponse handleRequest(Map input, Context context) { - LOG.info("received: " + input); - - return new ApiGatewayResponse.ApiGatewayResponseBuilder() - .headers(headers()) - .statusCode(SUCCESS_STATUS_CODE) - .body(lambdaInfo(context)) - .build(); - } - - /** - * lambdaInfo. - * - * @param context - Lambda context - * @return LambdaInfo - */ - private LambdaInfo lambdaInfo(Context context) { - var lambdaInfo = new LambdaInfo(); - lambdaInfo.setAwsRequestId(context.getAwsRequestId()); - lambdaInfo.setFunctionName(context.getFunctionName()); - lambdaInfo.setFunctionVersion(context.getFunctionVersion()); - lambdaInfo.setLogGroupName(context.getLogGroupName()); - lambdaInfo.setLogStreamName(context.getLogStreamName()); - lambdaInfo.setMemoryLimitInMb(context.getMemoryLimitInMB()); - return lambdaInfo; - } - - private Map headers() { - return Map.of("Content-Type", "application/json"); - } -} diff --git a/serverless/src/test/java/com/iluwatar/serverless/baas/api/FindPersonApiHandlerTest.java b/serverless/src/test/java/com/iluwatar/serverless/baas/api/FindPersonApiHandlerTest.java deleted file mode 100644 index 97a0c7b4b..000000000 --- a/serverless/src/test/java/com/iluwatar/serverless/baas/api/FindPersonApiHandlerTest.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.serverless.baas.api; - -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper; -import com.amazonaws.services.lambda.runtime.Context; -import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent; -import com.iluwatar.serverless.baas.model.Person; -import java.util.Map; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -/** - * Unit tests for FindPersonApiHandler Created by dheeraj.mummar on 3/5/18. - */ -class FindPersonApiHandlerTest { - - private FindPersonApiHandler findPersonApiHandler; - - @Mock - private DynamoDBMapper dynamoDbMapper; - - @BeforeEach - void setUp() { - MockitoAnnotations.openMocks(this); - this.findPersonApiHandler = new FindPersonApiHandler(); - this.findPersonApiHandler.setDynamoDbMapper(dynamoDbMapper); - } - - @Test - void handleRequest() { - findPersonApiHandler.handleRequest(apiGatewayProxyRequestEvent(), mock(Context.class)); - verify(dynamoDbMapper, times(1)).load(Person.class, "37e7a1fe-3544-473d-b764-18128f02d72d"); - } - - private APIGatewayProxyRequestEvent apiGatewayProxyRequestEvent() { - var request = new APIGatewayProxyRequestEvent(); - return request.withPathParamters(Map.of("id", "37e7a1fe-3544-473d-b764-18128f02d72d")); - } -} diff --git a/serverless/src/test/java/com/iluwatar/serverless/baas/api/SavePersonApiHandlerTest.java b/serverless/src/test/java/com/iluwatar/serverless/baas/api/SavePersonApiHandlerTest.java deleted file mode 100644 index ccbeb92c1..000000000 --- a/serverless/src/test/java/com/iluwatar/serverless/baas/api/SavePersonApiHandlerTest.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.serverless.baas.api; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper; -import com.amazonaws.services.lambda.runtime.Context; -import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.iluwatar.serverless.baas.model.Address; -import com.iluwatar.serverless.baas.model.Person; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -/** - * Unit tests for SavePersonApiHandler Created by dheeraj.mummar on 3/4/18. - */ -class SavePersonApiHandlerTest { - - private SavePersonApiHandler savePersonApiHandler; - - @Mock - private DynamoDBMapper dynamoDbMapper; - - private final ObjectMapper objectMapper = new ObjectMapper(); - - @BeforeEach - void setUp() { - MockitoAnnotations.openMocks(this); - this.savePersonApiHandler = new SavePersonApiHandler(); - this.savePersonApiHandler.setDynamoDbMapper(dynamoDbMapper); - } - - @Test - void handleRequestSavePersonSuccessful() throws JsonProcessingException { - var person = newPerson(); - var body = objectMapper.writeValueAsString(person); - var request = apiGatewayProxyRequestEvent(body); - var ctx = mock(Context.class); - var apiGatewayProxyResponseEvent = this.savePersonApiHandler.handleRequest(request, ctx); - verify(dynamoDbMapper, times(1)).save(person); - assertNotNull(apiGatewayProxyResponseEvent); - assertEquals(Integer.valueOf(201), apiGatewayProxyResponseEvent.getStatusCode()); - } - - @Test - void handleRequestSavePersonException() { - var request = apiGatewayProxyRequestEvent("invalid sample request"); - var ctx = mock(Context.class); - var apiGatewayProxyResponseEvent = this.savePersonApiHandler.handleRequest(request, ctx); - assertNotNull(apiGatewayProxyResponseEvent); - assertEquals(Integer.valueOf(400), apiGatewayProxyResponseEvent.getStatusCode()); - } - - private APIGatewayProxyRequestEvent apiGatewayProxyRequestEvent(String body) { - var apiGatewayProxyRequestEvent = new APIGatewayProxyRequestEvent(); - return apiGatewayProxyRequestEvent.withBody(body); - } - - private Person newPerson() { - var person = new Person(); - person.setFirstName("Thor"); - person.setLastName("Odinson"); - var address = new Address(); - address.setAddressLineOne("1 Odin ln"); - address.setCity("Asgard"); - address.setState("country of the Gods"); - address.setZipCode("00001"); - person.setAddress(address); - return person; - } -} diff --git a/serverless/src/test/java/com/iluwatar/serverless/faas/api/LambdaInfoApiHandlerTest.java b/serverless/src/test/java/com/iluwatar/serverless/faas/api/LambdaInfoApiHandlerTest.java deleted file mode 100644 index 102a0dc3a..000000000 --- a/serverless/src/test/java/com/iluwatar/serverless/faas/api/LambdaInfoApiHandlerTest.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.serverless.faas.api; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.core.IsNull.notNullValue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import com.amazonaws.services.lambda.runtime.Context; -import org.junit.jupiter.api.Test; - -/** - * Unit tests for LambdaInfoApiHandler - */ -class LambdaInfoApiHandlerTest { - - @Test - void handleRequestWithMockContext() { - var lambdaInfoApiHandler = new LambdaInfoApiHandler(); - var context = mock(Context.class); - when(context.getAwsRequestId()).thenReturn("mock aws request id"); - - assertThat(lambdaInfoApiHandler.handleRequest(null, context), notNullValue()); - } -} \ No newline at end of file