001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019:
020: package org.apache.synapse.endpoints;
021:
022: import org.apache.axis2.clustering.ClusterManager;
023: import org.apache.axis2.context.ConfigurationContext;
024: import org.apache.commons.logging.Log;
025: import org.apache.commons.logging.LogFactory;
026: import org.apache.synapse.FaultHandler;
027: import org.apache.synapse.MessageContext;
028: import org.apache.synapse.SynapseConstants;
029: import org.apache.synapse.SynapseException;
030: import org.apache.synapse.core.axis2.Axis2MessageContext;
031: import org.apache.synapse.endpoints.utils.EndpointDefinition;
032:
033: /**
034: * This class represents the endpoints referred by keys. It does not store the actual referred
035: * endpoint as a private variable as it could expire. Therefore, it only stores the key and gets the
036: * actual endpoint from the synapse configuration.
037: * <p/>
038: * As this is also an instance of endpoint, this can be used any place, where a normal endpoint is used.
039: */
040: public class IndirectEndpoint implements Endpoint {
041:
042: private static final Log trace = LogFactory
043: .getLog(SynapseConstants.TRACE_LOGGER);
044: private static final Log log = LogFactory
045: .getLog(IndirectEndpoint.class);
046:
047: private String name = null;
048: private String key = null;
049: private boolean active = true;
050: private Endpoint parentEndpoint = null;
051:
052: /**
053: * This should have a reference to the current message context as it gets the referred endpoint
054: * from it.
055: */
056: private MessageContext currentMsgCtx = null;
057: private final EndpointContext endpointContext = new EndpointContext();
058:
059: public void send(MessageContext synMessageContext) {
060:
061: // get the actual endpoint and send
062: Endpoint endpoint = synMessageContext.getEndpoint(key);
063: if (endpoint == null) {
064: handleException("Reference to non-existent endpoint for key : "
065: + key);
066: }
067:
068: boolean isClusteringEnable = false;
069: // get Axis2 MessageContext and ConfigurationContext
070: org.apache.axis2.context.MessageContext axisMC = ((Axis2MessageContext) synMessageContext)
071: .getAxis2MessageContext();
072: ConfigurationContext cc = axisMC.getConfigurationContext();
073:
074: //The check for clustering environment
075:
076: ClusterManager clusterManager = cc.getAxisConfiguration()
077: .getClusterManager();
078: if (clusterManager != null
079: && clusterManager.getContextManager() != null) {
080: isClusteringEnable = true;
081: }
082:
083: String endPointName = this .getName();
084: if (endPointName == null) {
085:
086: if (log.isDebugEnabled() && isClusteringEnable) {
087: log
088: .warn("In a clustering environment , the endpoint name should be specified"
089: + "even for anonymous endpoints. Otherwise , the clustering would not be "
090: + "functioned correctly if there are more than one anonymous endpoints. ");
091: }
092: endPointName = SynapseConstants.ANONYMOUS_ENDPOINT;
093: }
094:
095: if (isClusteringEnable) {
096: // if this is a cluster environment , then set configuration context to endpoint context
097: if (endpointContext.getConfigurationContext() == null) {
098: endpointContext.setConfigurationContext(cc);
099: endpointContext.setContextID(endPointName);
100: }
101: }
102:
103: if (endpoint.isActive(synMessageContext)) {
104: endpoint.send(synMessageContext);
105:
106: } else {
107: // if this is a child of some other endpoint, inform parent about the failure.
108: // if not, inform to the next fault handler.
109: if (parentEndpoint != null) {
110: auditWarn("Endpoint : " + endpoint.getName()
111: + " is currently inactive"
112: + " - invoking parent endpoint",
113: synMessageContext);
114: parentEndpoint.onChildEndpointFail(this ,
115: synMessageContext);
116:
117: } else {
118: auditWarn(
119: "Endpoint : "
120: + endpoint.getName()
121: + " is currently inactive"
122: + " - invoking fault handler / assuming failure",
123: synMessageContext);
124:
125: Object o = synMessageContext.getFaultStack().pop();
126: if (o != null) {
127: ((FaultHandler) o).handleFault(synMessageContext);
128: }
129: }
130: }
131: }
132:
133: public String getName() {
134: return name;
135: }
136:
137: public void setName(String name) {
138: this .name = name.trim();
139: }
140:
141: public String getKey() {
142: return key;
143: }
144:
145: public void setKey(String key) {
146: this .key = key;
147: }
148:
149: /**
150: * IndirectEndpoints are active if its referref endpoint is active and vise versa. Therefore,
151: * this returns if its referred endpoint is active or not.
152: *
153: * @param synMessageContext MessageContext of the current message.
154: * @return true if the referred endpoint is active. false otherwise.
155: */
156: public boolean isActive(MessageContext synMessageContext) {
157: Endpoint endpoint = synMessageContext.getEndpoint(key);
158: if (endpoint == null) {
159: handleException("Reference to non-existent endpoint for key : "
160: + key);
161: }
162:
163: return endpoint.isActive(synMessageContext);
164: }
165:
166: /**
167: * Activating or deactivating an IndirectEndpoint is the activating or deactivating its
168: * referref endpoint. Therefore, this sets the active state of its referred endpoint.
169: *
170: * @param active true if active. false otherwise.
171: * @param synMessageContext MessageContext of the current message.
172: */
173: public void setActive(boolean active,
174: MessageContext synMessageContext) {
175: Endpoint endpoint = synMessageContext.getEndpoint(key);
176: if (endpoint == null) {
177: handleException("Reference to non-existent endpoint for key : "
178: + key);
179: }
180:
181: endpoint.setActive(active, synMessageContext);
182: }
183:
184: public void setParentEndpoint(Endpoint parentEndpoint) {
185: this .parentEndpoint = parentEndpoint;
186: }
187:
188: public void onChildEndpointFail(Endpoint endpoint,
189: MessageContext synMessageContext) {
190:
191: // if this is a child of some other endpoint, inform parent about the failure.
192: // if not, inform to the next fault handler.
193: if (parentEndpoint != null) {
194: parentEndpoint.onChildEndpointFail(this , synMessageContext);
195: } else {
196: Object o = synMessageContext.getFaultStack().pop();
197: if (o != null) {
198: ((FaultHandler) o).handleFault(synMessageContext);
199: }
200: }
201: }
202:
203: private void handleException(String msg) {
204: log.error(msg);
205: throw new SynapseException(msg);
206: }
207:
208: protected void auditWarn(String msg, MessageContext msgContext) {
209: log.warn(msg);
210: if (msgContext.getServiceLog() != null) {
211: msgContext.getServiceLog().warn(msg);
212: }
213: if (shouldTrace(msgContext)) {
214: trace.warn(msg);
215: }
216: }
217:
218: public boolean shouldTrace(MessageContext synCtx) {
219: Endpoint endpoint = synCtx.getEndpoint(key);
220: EndpointDefinition endptDefn = null;
221: if (endpoint instanceof AddressEndpoint) {
222: AddressEndpoint addEndpt = (AddressEndpoint) endpoint;
223: endptDefn = addEndpt.getEndpoint();
224: } else if (endpoint instanceof WSDLEndpoint) {
225: WSDLEndpoint wsdlEndpt = (WSDLEndpoint) endpoint;
226: endptDefn = wsdlEndpt.getEndpoint();
227: }
228:
229: if (endptDefn != null) {
230: return (endptDefn.getTraceState() == SynapseConstants.TRACING_ON)
231: || (endptDefn.getTraceState() == SynapseConstants.TRACING_UNSET && synCtx
232: .getTracingState() == SynapseConstants.TRACING_ON);
233: }
234: return false;
235: }
236:
237: }
|