/** * Copyright (C) 2015 Orange * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.francetelecom.clara.cloud.logicalmodel; import com.francetelecom.clara.cloud.commons.GuiClassMapping; import com.francetelecom.clara.cloud.commons.GuiMapping; import javax.persistence.Entity; import javax.persistence.Table; import javax.validation.constraints.Max; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import javax.xml.bind.annotation.XmlRootElement; /** * Intra-application async messaging service (MOM) * Allows asynchronous messaging to be exchanged within an application through a messaging oriented middleware (MOM) using the JMS API. * * JMS api version supported: 1.1 * * Limitations w.r.t. JMS: * <ol> * <li>JMS ReplyTo field is not supported</li> * <li>Only queues are supported (topic are planned for future)</li> * </ol> * * An ExecutionNode is connected to one or more LogicalMomService. Both message reception and message sending may be * performed on the same service. * * FIXME: rename into LogicalInternalMomService * @author APOG7416 */ @XmlRootElement @Entity @Table(name = "MOM_SERVICE") @GuiClassMapping(isExternal = false, serviceCatalogName = "Internal Point-to-point messaging", serviceCatalogNameKey = "internal.ptp.messaging", status = GuiClassMapping.StatusType.BETA) public class LogicalMomService extends LogicalService { /** * Jndi name at which the javax.jms.ConnectionFactory instance will be made available. * This ConnectionFactory supports XA transactions, and therefore may be involved into a * transaction with RDB service. The JTA transaction manager is available in the JNDI * in the default well-known location. * * Currently, a single default instance is available named "CF". */ @GuiMapping(status = GuiMapping.StatusType.READ_ONLY) @NotNull @Size(min = 1) private String jmsConnectionFactoryJndiName = "CF"; /** * Name of the JNDI property under which the javax.jms.Destination instance will be available. * Should be unique within all LogicalMomService connected in the architecture */ @GuiMapping @NotNull @Size(min = 1, max=255) String destinationName = ""; /** * Optional name of the JNDI property under which the deadLetter queue javax.jms.Queue instance will be available. * Should be unique within all LogicalMomService connected in the architecture. */ @Size(min = 0, max=255) @GuiMapping String deadLetterQueueName = ""; // // SLO // /** * Number of messages in the dead letter queue, after which an alert should be raised. */ //@Transient //private int deadLetterQueueAlarmingThreshold = 100; /** * Hint to the paas for the sizing of the deadletter queue. Max number of messages to be hold in the queue. * When this capacity is exceeded, unprocessed messages are lost (app-ops may check logs for such occurence) */ @GuiMapping @Min(value = 1) @Max(value = 100) private int deadLetterQueueCapacity = 100; /** * sla: maximum message size. Should be smaller than 10 MB. * This is measured as the number of bytes of serialized Java message object * * This information is leveraged to size the message persistence storage * */ @NotNull @GuiMapping(status = GuiMapping.StatusType.SUPPORTED, functional = false) @Min(value = 1) @Max(value = 10000) private int msgMaxSizeKB = 10; /** * Max number of message to be persisted in the queue when the receiver is not consumming * messages. This should include messages sent by all ExecNode using this MomService. * * Note that the queue may enforce this max number of messages. When this maximum capacity is reached, * the next message sending will be rejected. * * A large capacity can be rejected if insufficient persistent storage is available * to guarantee this SLO. */ @GuiMapping(functional = false) @Min(value = 1000) int destinationCapacity = 1000; /** * Optionally enables the deadLetter queue to which dead messages would be added. * Dead messages are messages that errored during processeing * (e.g. a transaction rollback while processing the message, or an exception thrown). * * When enabled, the application is responsible for processing messages in the dead letter queue * (usually with a lower priority, possibly as a scheduled batch in a distinct ExecNode) to avoid being filled up. * */ @GuiMapping(functional = false) boolean hasDeadLetterQueue = true; /** * On message reception error (e.g. a transaction rollback while processing the message, or an exception * thrown), the max number of times the message will be sent to the receiver. */ @GuiMapping(functional = false) @Min(value = 0) @Max(value = 10) int retriesBeforeMovingToDeadLetterQueue = 3; /** * hints to the paas to indicate that some persistent messages will be sent. This is used as an optimization * hint for the paas to not provision persistent capacity for applications that exchange only non persistent messages * Set this to false only for apps handling messages whose loss has no business impact. */ @GuiMapping(functional = false) boolean persistentMessagesUsed = true; /** * In the future, controls whether high availability is requested for this queue. */ @GuiMapping(functional = false, status = GuiMapping.StatusType.READ_ONLY) boolean highAvailability = false; /** * @deprecated TODO: remove this,this is builtin. */ boolean loadBalancing = false; // not yet implemented /** * private constructor for mapping */ public LogicalMomService() { } /** * Constructor * * @param label * @param logicalDeployment * @deprecated Should not be called anymore, use empty constructor instead * followed by {@link LogicalDeployment#addLogicalService(LogicalService)} */ public LogicalMomService(String label, LogicalDeployment logicalDeployment) { super(label, logicalDeployment); } /** * * @return */ public String getDestinationName() { return destinationName; } /** * * @param destinationName */ public void setDestinationName(String destinationName) { this.destinationName = destinationName; } /** * * @return */ public int getDestinationCapacity() { return destinationCapacity; } /** * * @param destinationCapacity */ public void setDestinationCapacity(int destinationCapacity) { this.destinationCapacity = destinationCapacity; } /** * * @return */ public boolean isHasDeadLetterQueue() { return hasDeadLetterQueue; } /** * * @param hasDeadLetterQueue */ public void setHasDeadLetterQueue(boolean hasDeadLetterQueue) { this.hasDeadLetterQueue = hasDeadLetterQueue; } /** * * @param persistent */ public void setPersistent(boolean persistent) { this.persistentMessagesUsed = persistent; } public Boolean getPersistent() { return this.persistentMessagesUsed; } /** * * @return */ public boolean isHighAvailability() { return highAvailability; } /** * * @param highAvailability */ public void setHighAvailability(boolean highAvailability) { this.highAvailability = highAvailability; } /** * * @return */ public boolean isLoadBalancing() { return loadBalancing; } /** * * @param loadBalancing */ public void setLoadBalancing(boolean loadBalancing) { this.loadBalancing = loadBalancing; } /** * @return the jmsConnectionFactoryJndiName */ public String getJmsConnectionFactoryJndiName() { return jmsConnectionFactoryJndiName; } /** * @param jmsConnectionFactoryJndiName the jmsConnectionFactoryJndiName to set */ public void setJmsConnectionFactoryJndiName(String jmsConnectionFactoryJndiName) { this.jmsConnectionFactoryJndiName = jmsConnectionFactoryJndiName; } /** * @return the deadLetterQueueName */ public String getDeadLetterQueueName() { return deadLetterQueueName; } /** * @param deadLetterQueueName the deadLetterQueueName to set */ public void setDeadLetterQueueName(String deadLetterQueueName) { this.deadLetterQueueName = deadLetterQueueName; } /** * @return the deadLetterQueueCapacity */ public int getDeadLetterQueueCapacity() { return deadLetterQueueCapacity; } /** * @param deadLetterQueueCapacity the deadLetterQueueCapacity to set */ public void setDeadLetterQueueCapacity(int deadLetterQueueCapacity) { this.deadLetterQueueCapacity = deadLetterQueueCapacity; } /** * @return the msgMaxSizeKB */ public int getMsgMaxSizeKB() { return msgMaxSizeKB; } /** * @param msgMaxSizeKB the msgMaxSizeKB to set */ public void setMsgMaxSizeKB(int msgMaxSizeKB) { this.msgMaxSizeKB = msgMaxSizeKB; } /** * @return the retriesBeforeMovingToDeadLetterQueue */ public int getRetriesBeforeMovingToDeadLetterQueue() { return retriesBeforeMovingToDeadLetterQueue; } /** * @param retriesBeforeMovingToDeadLetterQueue the retriesBeforeMovingToDeadLetterQueue to set */ public void setRetriesBeforeMovingToDeadLetterQueue(int retriesBeforeMovingToDeadLetterQueue) { this.retriesBeforeMovingToDeadLetterQueue = retriesBeforeMovingToDeadLetterQueue; } /** * @return the persistentMessagesUsed */ public boolean isPersistentMessagesUsed() { return persistentMessagesUsed; } /** * @param persistentMessagesUsed the persistentMessagesUsed to set */ public void setPersistentMessagesUsed(boolean persistentMessagesUsed) { this.persistentMessagesUsed = persistentMessagesUsed; } }