/** * Is this a fault that should put the endpoint on SUSPEND? or is this a fault to ignore? * * @param synCtx the current fault message * @return true if this fault should suspend the endpoint */ protected boolean isSuspendFault(MessageContext synCtx) { Integer errorCode = (Integer) synCtx.getProperty(SynapseConstants.ERROR_CODE); if (errorCode != null) { if (definition.getSuspendErrorCodes().isEmpty()) { // if suspend codes are not defined, any error will be fatal for the endpoint if (log.isDebugEnabled()) { log.debug(this.toString() + " encountered a fatal error : " + errorCode); } return true; } else { if (definition.getSuspendErrorCodes().contains(errorCode)) { if (log.isDebugEnabled()) { log.debug( "Encountered a suspend error : " + errorCode + " defined suspend codes are : " + definition.getSuspendErrorCodes()); } return true; } } } if (log.isDebugEnabled()) { log.debug( "Encountered a non-fatal error sending to " + this.toString() + ", error code : " + errorCode + ". Error will be handled, but endpoint will not fail"); } return false; }
private Map<String, EndpointDescription> createStaticEndpointDescriptions( EndpointDefinitionsProvider provider) { Map<String, EndpointDescription> descs = new HashMap<>(); for (EndpointDefinition definition : provider.getStaticEndpointDefinitions()) { descs.put(definition.getName(), new EndpointDescription(definition, endpointType)); } return descs; }
/** * Is this [fault] message a timeout? * * @param synCtx the current fault message * @return true if this is defined as a timeout */ protected boolean isTimeout(MessageContext synCtx) { Object error = synCtx.getProperty(SynapseConstants.ERROR_CODE); Integer errorCode = 0; if (error != null) { try { errorCode = Integer.parseInt(error.toString()); } catch (NumberFormatException e) { errorCode = 0; } } if (errorCode != null) { if (definition.getTimeoutErrorCodes().isEmpty()) { // if timeout codes are not defined, assume only HTTP timeout and connection close boolean isTimeout = SynapseConstants.NHTTP_CONNECTION_TIMEOUT == errorCode; boolean isClosed = SynapseConstants.NHTTP_CONNECTION_CLOSED == errorCode; if (isTimeout || isClosed) { if (log.isDebugEnabled()) { log.debug( "Encountered a default HTTP connection " + (isClosed ? "close" : "timeout") + " error : " + errorCode); } return true; } } else { if (definition.getTimeoutErrorCodes().contains(errorCode)) { if (log.isDebugEnabled()) { log.debug( "Encountered a mark for suspension error : " + errorCode + " defined " + "error codes are : " + definition.getTimeoutErrorCodes()); } return true; } } } if (log.isDebugEnabled()) { log.debug( "Encountered a non-timeout error sending to " + this.toString() + ", error code : " + errorCode); } return false; }
/** Adds initial endpoints, if there are some declared. */ public void addInitialDynamicEndpointDescriptions() { for (EndpointDefinition definition : endpointDefinitionsProvider.getDynamicEndpointDefinitions()) { for (InitialDynamicEndpointDefinition initialDefinition : definition.getInitialDynamicEndpointDefinitions()) { addDynamicEndpointDescription( definition.getIdentifier(), initialDefinition.getName(), initialDefinition.getDataType(), new HashMap<String, String>()); } } }
/** Compute the suspension duration according to the geometric series parameters defined */ private void computeNextRetryTimeForSuspended() { boolean notYetSuspended = true; long lastSuspendDuration = definition.getInitialSuspendDuration(); if (isClustered) { Long lastDuration = (Long) cfgCtx.getPropertyNonReplicable(LAST_SUSPEND_DURATION_KEY); if (lastDuration != null) { lastSuspendDuration = lastDuration; notYetSuspended = false; } } else if (localLastSuspendDuration > 0) { lastSuspendDuration = localLastSuspendDuration; notYetSuspended = false; } long nextSuspendDuration = (notYetSuspended ? definition.getInitialSuspendDuration() : (long) (lastSuspendDuration * definition.getSuspendProgressionFactor())); if (nextSuspendDuration > definition.getSuspendMaximumDuration()) { nextSuspendDuration = definition.getSuspendMaximumDuration(); } else if (nextSuspendDuration < 0) { nextSuspendDuration = SynapseConstants.DEFAULT_ENDPOINT_SUSPEND_TIME; } long nextRetryTime = System.currentTimeMillis() + nextSuspendDuration; if (isClustered) { Replicator.setAndReplicateState(LAST_SUSPEND_DURATION_KEY, nextSuspendDuration, cfgCtx); Replicator.setAndReplicateState(NEXT_RETRY_TIME_KEY, nextRetryTime, cfgCtx); } else { localLastSuspendDuration = nextSuspendDuration; localNextRetryTime = nextRetryTime; } log.warn( "Suspending endpoint : " + endpointName + (notYetSuspended ? " -" : " - last suspend duration was : " + lastSuspendDuration + "ms and") + " current suspend duration is : " + nextSuspendDuration + "ms - " + "Next retry after : " + new Date(nextRetryTime)); }
public void init(SynapseEnvironment synapseEnvironment) { ConfigurationContext cc = ((Axis2SynapseEnvironment) synapseEnvironment).getAxis2ConfigurationContext(); if (!initialized) { // The check for clustering environment ClusteringAgent clusteringAgent = cc.getAxisConfiguration().getClusteringAgent(); if (clusteringAgent != null && clusteringAgent.getStateManager() != null) { isClusteringEnabled = Boolean.TRUE; } else { isClusteringEnabled = Boolean.FALSE; } context = new EndpointContext(getName(), getDefinition(), isClusteringEnabled, cc, metricsMBean); } initialized = true; if (children != null) { for (Endpoint e : children) { e.init(synapseEnvironment); } } contentAware = definition != null && ((definition.getFormat() != null && !definition.getFormat().equals(SynapseConstants.FORMAT_REST)) || definition.isSecurityOn() || definition.isReliableMessagingOn() || definition.isAddressingOn() || definition.isUseMTOM() || definition.isUseSwa()); }
/** * Process statistics for this message * * @param synCtx the current message */ protected void prepareForEndpointStatistics(MessageContext synCtx) { // Setting Required property to reportForComponent the End Point aspects if (definition != null && definition.isStatisticsEnable()) { String opName = null; if (synCtx.getProperty(SynapseConstants.ENDPOINT_OPERATION) != null) { opName = synCtx.getProperty(SynapseConstants.ENDPOINT_OPERATION).toString(); } else if (synCtx instanceof Axis2MessageContext) { AxisOperation operation = ((Axis2MessageContext) synCtx).getAxis2MessageContext().getAxisOperation(); if (operation != null) { opName = operation.getName().getLocalPart(); } if (opName == null || SynapseConstants.SYNAPSE_OPERATION_NAME.getLocalPart().equals(opName)) { String soapAction = synCtx.getSoapAction(); opName = null; if (soapAction != null) { int index = soapAction.indexOf("urn:"); if (index >= 0) { opName = soapAction.substring("urn:".length()); } else { opName = soapAction; } } } } AspectConfiguration oldConfiguration = definition.getAspectConfiguration(); if (opName != null) { AspectConfiguration newConfiguration = new AspectConfiguration( oldConfiguration.getId() + SynapseConstants.STATISTICS_KEY_SEPARATOR + opName); if (oldConfiguration.isStatisticsEnable()) { newConfiguration.enableStatistics(); } if (oldConfiguration.isTracingEnabled()) { newConfiguration.enableTracing(); } } } }
protected boolean isRetry(MessageContext synCtx) { Integer errorCode = (Integer) synCtx.getProperty(SynapseConstants.ERROR_CODE); if (errorCode != null && definition != null) { if (definition.getRetryDisabledErrorCodes().contains(errorCode)) { if (log.isDebugEnabled()) { log.debug( "Encountered a retry disabled error : " + errorCode + ", defined retry disabled error codes are : " + definition.getRetryDisabledErrorCodes()); } // for given disabled error codes system wont retry return false; } else if (definition.getRetryEnableErrorCodes().size() > 0) { if (definition.getRetryEnableErrorCodes().contains(errorCode)) { if (log.isDebugEnabled()) { log.debug( "Encountered a retry enabled error : " + errorCode + ", defined retry Enable error codes are : " + definition.getRetryEnableErrorCodes()); } // for given error codes in EnableErrorCodes only system retries return true; } else { return false; } } } if (log.isDebugEnabled()) { log.debug( "Encountered an error sending to endpoint : " + endpointName + ", with error code : " + errorCode + ", but not a retry disabled error"); } return true; }
/** * Create an EndpointContext to hold runtime state of an Endpoint * * @param endpointName the name of the endpoint (mainly for logging) * @param endpointDefinition the definition of the endpoint (e.g. retry time, suspend duration..) * @param clustered is the environment clustered? * @param cfgCtx the Axis2 configurationContext for clustering */ public EndpointContext( String endpointName, EndpointDefinition endpointDefinition, boolean clustered, ConfigurationContext cfgCtx, EndpointView metricsBean) { if (clustered) { if (endpointName == null) { if (endpointDefinition != null && !endpointDefinition.isReplicationDisabled()) { handleException( "For proper clustered mode operation, all endpoints should " + "be uniquely named"); } } this.isClustered = true; this.cfgCtx = cfgCtx; } this.definition = endpointDefinition; if (endpointName != null) { this.endpointName = endpointName; } else if (endpointDefinition != null) { this.endpointName = endpointDefinition.toString(); } this.metricsBean = metricsBean; STATE_KEY = KEY_PREFIX + endpointName + STATE; NEXT_RETRY_TIME_KEY = KEY_PREFIX + endpointName + NEXT_RETRY_TIME; REMAINING_RETRIES_KEY = KEY_PREFIX + endpointName + REMAINING_RETRIES; LAST_SUSPEND_DURATION_KEY = KEY_PREFIX + endpointName + LAST_SUSPEND_DURATION; if (isClustered && (endpointDefinition == null || !endpointDefinition.isReplicationDisabled())) { // In a clustered environment, we need to set the state of an Endpoint when it is created. cfgCtx.setNonReplicableProperty(STATE_KEY, ST_ACTIVE); } }
public void setComponentStatisticsId(ArtifactHolder holder) { if (this instanceof IndirectEndpoint) { String sequenceId = StatisticIdentityGenerator.getIdReferencingComponent( ((IndirectEndpoint) (this)).getKey(), ComponentType.ENDPOINT, holder); StatisticIdentityGenerator.reportingEndEvent(sequenceId, ComponentType.ENDPOINT, holder); } else { if (definition == null) { EndpointDefinition definition = new EndpointDefinition(); this.setDefinition(definition); } if (definition.getAspectConfiguration() == null) { definition.configure(new AspectConfiguration(getReportingName())); } String sequenceId = StatisticIdentityGenerator.getIdForComponent( getReportingName(), ComponentType.ENDPOINT, holder); definition.getAspectConfiguration().setUniqueId(sequenceId); StatisticIdentityGenerator.reportingEndEvent(sequenceId, ComponentType.ENDPOINT, holder); } }
/** * Update the internal state of the endpoint * * @param state the new state of the endpoint */ private void setState(int state) { recordStatistics(state); if (isClustered) { Replicator.setAndReplicateState(STATE_KEY, state, cfgCtx); if (definition == null) return; switch (state) { case ST_ACTIVE: { Replicator.setAndReplicateState( REMAINING_RETRIES_KEY, definition.getRetriesOnTimeoutBeforeSuspend(), cfgCtx); Replicator.setAndReplicateState(LAST_SUSPEND_DURATION_KEY, null, cfgCtx); break; } case ST_TIMEOUT: { Integer retries = (Integer) cfgCtx.getPropertyNonReplicable(REMAINING_RETRIES_KEY); if (retries == null) { retries = definition.getRetriesOnTimeoutBeforeSuspend(); } if (retries <= 0) { log.info( "Endpoint : " + endpointName + " has been marked for SUSPENSION," + " but no further retries remain. Thus it will be SUSPENDED."); setState(ST_SUSPENDED); } else { Replicator.setAndReplicateState(REMAINING_RETRIES_KEY, (retries - 1), cfgCtx); long nextRetry = System.currentTimeMillis() + definition.getRetryDurationOnTimeout(); Replicator.setAndReplicateState(NEXT_RETRY_TIME_KEY, nextRetry, cfgCtx); log.warn( "Endpoint : " + endpointName + " is marked as TIMEOUT and " + "will be retried : " + (retries - 1) + " more time/s after : " + new Date(nextRetry) + " until its marked SUSPENDED for failure"); } break; } case ST_SUSPENDED: { computeNextRetryTimeForSuspended(); break; } case ST_OFF: { // mark as in maintenence, and reset all other information Replicator.setAndReplicateState( REMAINING_RETRIES_KEY, definition == null ? -1 : definition.getRetriesOnTimeoutBeforeSuspend(), cfgCtx); Replicator.setAndReplicateState(LAST_SUSPEND_DURATION_KEY, null, cfgCtx); break; } } } else { localState = state; if (definition == null) return; switch (state) { case ST_ACTIVE: { localRemainingRetries = definition.getRetriesOnTimeoutBeforeSuspend(); localLastSuspendDuration = -1; break; } case ST_TIMEOUT: { int retries = localRemainingRetries; if (retries == -1) { retries = definition.getRetriesOnTimeoutBeforeSuspend(); } if (retries <= 0) { log.info( "Endpoint : " + endpointName + " has been marked for SUSPENSION, " + "but no further retries remain. Thus it will be SUSPENDED."); setState(ST_SUSPENDED); } else { localRemainingRetries = retries - 1; localNextRetryTime = System.currentTimeMillis() + definition.getRetryDurationOnTimeout(); log.warn( "Endpoint : " + endpointName + " is marked as TIMEOUT and " + "will be retried : " + localRemainingRetries + " more time/s " + "after : " + new Date(localNextRetryTime) + " until its marked SUSPENDED for failure"); } break; } case ST_SUSPENDED: { computeNextRetryTimeForSuspended(); break; } case ST_OFF: { // mark as in maintenence, and reset all other information localRemainingRetries = definition == null ? -1 : definition.getRetriesOnTimeoutBeforeSuspend(); localLastSuspendDuration = -1; break; } } } }
private boolean isStatisticCollected() { return (definition.getAspectConfiguration() != null && definition.getAspectConfiguration().isStatisticsEnable() && this.endpointName != null); }
/** * Should this mediator perform tracing? True if its explicitly asked to trace, or its parent has * been asked to trace and it does not reject it * * @param msgCtx the current message * @return true if tracing should be performed */ protected boolean isTraceOn(MessageContext msgCtx) { return (definition.getAspectConfiguration() != null && definition.getAspectConfiguration().isTracingEnabled()); }
public void send(MessageContext synCtx) { logSetter(); Integer statisticReportingIndex = null; boolean isStatisticsEnabled = RuntimeStatisticCollector.isStatisticsEnabled(); if (isStatisticsEnabled) { statisticReportingIndex = OpenEventCollector.reportEntryEvent( synCtx, getReportingName(), definition.getAspectConfiguration(), ComponentType.ENDPOINT); } boolean traceOn = isTraceOn(synCtx); boolean traceOrDebugOn = isTraceOrDebugOn(traceOn); if (!initialized) { // can't send to a non-initialized endpoint. This is a program fault throw new IllegalStateException( "not initialized, " + "endpoint must be in initialized state"); } prepareForEndpointStatistics(synCtx); if (traceOrDebugOn) { String address = definition.getAddress(); if (address == null && synCtx.getTo() != null && synCtx.getTo().getAddress() != null) { // compute address for the default endpoint only for logging purposes address = synCtx.getTo().getAddress(); } traceOrDebug( traceOn, "Sending message through endpoint : " + getName() + " resolving to address = " + address); traceOrDebug( traceOn, "SOAPAction: " + (synCtx.getSoapAction() != null ? synCtx.getSoapAction() : "null")); traceOrDebug( traceOn, "WSA-Action: " + (synCtx.getWSAAction() != null ? synCtx.getWSAAction() : "null")); if (traceOn && trace.isTraceEnabled()) { trace.trace("Envelope : \n" + synCtx.getEnvelope()); } } // push the errorHandler sequence into the current message as the fault handler if (errorHandler != null) { Mediator errorHandlerMediator = synCtx.getSequence(errorHandler); if (errorHandlerMediator != null) { if (traceOrDebugOn) { traceOrDebug( traceOn, "Setting the onError handler : " + errorHandler + " for the endpoint : " + endpointName); } synCtx.pushFaultHandler(new MediatorFaultHandler(errorHandlerMediator)); } else { log.warn( "onError handler sequence : " + errorHandler + " for : " + endpointName + " cannot be found"); } } // register this as the immediate fault handler for this message. synCtx.pushFaultHandler(this); // add this as the last endpoint to process this message - used by statistics counting code synCtx.setProperty(SynapseConstants.LAST_ENDPOINT, this); // set message level metrics collector org.apache.axis2.context.MessageContext axis2Ctx = ((Axis2MessageContext) synCtx).getAxis2MessageContext(); axis2Ctx.setProperty(BaseConstants.METRICS_COLLECTOR, metricsMBean); if (contentAware) { try { RelayUtils.buildMessage(((Axis2MessageContext) synCtx).getAxis2MessageContext(), false); axis2Ctx.setProperty(RelayConstants.FORCE_RESPONSE_EARLY_BUILD, Boolean.TRUE); if (forceBuildMC) { ((Axis2MessageContext) synCtx).getAxis2MessageContext().getEnvelope().build(); } } catch (Exception e) { handleException("Error while building message", e); } } evaluateProperties(synCtx); // if the envelope preserving set build the envelope MediatorProperty preserveEnv = getProperty(SynapseConstants.PRESERVE_ENVELOPE); if (preserveEnv != null && JavaUtils.isTrueExplicitly( preserveEnv.getValue() != null ? preserveEnv.getValue() : preserveEnv.getEvaluatedExpression(synCtx))) { if (traceOrDebugOn) { traceOrDebug( traceOn, "Preserving the envelope by building it before " + "sending, since it is explicitly set"); } synCtx.getEnvelope().build(); } // Send the message through this endpoint synCtx.getEnvironment().send(definition, synCtx); if (isStatisticsEnabled) { CloseEventCollector.closeEntryEvent( synCtx, getReportingName(), ComponentType.ENDPOINT, statisticReportingIndex, false); } }
public void setDefinition(EndpointDefinition definition) { this.definition = definition; definition.setLeafEndpoint(this); }