KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > petals > jbi > routing > AddressResolver


1 /*
2  * PETALS: PETALS Services Platform
3  * Copyright (C) 2005 EBM WebSourcing
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18  * USA.
19  *
20  * Initial developer(s): EBM WebSourcing
21  * --------------------------------------------------------------------------
22  * $Id: AddressResolver.java,v 1.1 2005/07/22 10:24:27 alouis Exp $
23  * --------------------------------------------------------------------------
24  */

25
26 package org.objectweb.petals.jbi.routing;
27
28 import javax.jbi.component.Component;
29 import javax.jbi.messaging.MessageExchange;
30 import javax.jbi.servicedesc.ServiceEndpoint;
31 import javax.xml.namespace.QName JavaDoc;
32
33 import org.objectweb.petals.jbi.component.context.ComponentContextImpl;
34 import org.objectweb.petals.jbi.management.service.EndpointService;
35 import org.objectweb.petals.jbi.messaging.MessageExchangeImpl;
36 import org.objectweb.petals.jbi.registry.AbstractEndpoint;
37 import org.objectweb.petals.jbi.registry.InternalEndpoint;
38 import org.objectweb.petals.util.SystemUtil;
39
40 /**
41  * The <code>AddressResolver</code> resolves implicit addresses such as
42  * <code>interface</code> or <code>service</code> into an
43  * <code>endpoint</code>. Rules are used to help the
44  * <code>AddressResolver</code> in the choice of the <code>endpoint</code>,
45  * if more than one implement the implicit address.
46  *
47  * @author Adrien LOUIS - EBM WebSourcing
48  *
49  */

50 public class AddressResolver {
51
52     protected EndpointService endpointService;
53
54     public AddressResolver(EndpointService endpointService) {
55         this.endpointService = endpointService;
56     }
57
58     /**
59      * Resolve the address if necessary. Resolution consist in finding an
60      * endpoint satisfying <code>interface</code> or <code>service</code>.
61      * the source of the exchange and the exchange help the
62      * <code>AddressResolver</code> to find the endpoint. The
63      * <code>containerName</code> and <code>ComponentName</code> properties
64      * are set. If <code>containerName</code> and <code>ComponentName</code>
65      * already exist, do nothing. The check of acceptance from the two part is
66      * done here (the Component method isExchangeWithXXXOkay()).
67      *
68      * @param source
69      * @param exchange
70      * @throws RoutingException
71      * no destination can be found, or problem accessing the
72      * registry
73      */

74     public void resolveAddress(ComponentContextImpl source,
75         MessageExchangeImpl exchange) throws RoutingException {
76         ServiceEndpoint givenEndpoint = exchange.getEndpoint();
77         QName JavaDoc givenServiceName = exchange.getService();
78         QName JavaDoc givenInterfaceName = exchange.getInterfaceName();
79
80         // Construct an array of potential matching endpoints.
81
// If the endpoint has been set in the messageExchange,
82
// this array contains only one element, which is this endpoint.
83
ServiceEndpoint[] endpoints = null;
84         ServiceEndpoint targetedEndpoint = null;
85
86         if (givenEndpoint != null) {
87             // try to resolve address with a connection
88
// TODO minimize registry access, refactor
89
if (givenEndpoint instanceof AbstractEndpoint
90                 && ((AbstractEndpoint) givenEndpoint).getType() == AbstractEndpoint.EndpointType.INTERNAL) {
91                 // Assume it is a real endpoint
92
//FIXME don't check if it is still registered
93
targetedEndpoint = givenEndpoint;
94             } else {
95                 targetedEndpoint = resolveLinkedAddressForEndpoint(
96                     givenEndpoint.getServiceName(), givenEndpoint
97                         .getEndpointName());
98
99                 // if no connection, try to retrieve the real endpoint object
100
// from the registry
101
if (targetedEndpoint == null) {
102                     targetedEndpoint = endpointService.getEndpoint(
103                         givenEndpoint.getServiceName(), givenEndpoint
104                             .getEndpointName());
105                     // no endpoint found, we can not find a destination
106
if (targetedEndpoint == null) {
107                         throw new RoutingException("The specified endpoint ("
108                             + givenEndpoint
109                             + ") does not match a registered endpoint.");
110                     }
111                 }
112             }
113         } else if (givenServiceName != null) {
114             // find an Endpoint with the specified ServiceName
115
endpoints = endpointService
116                 .getInternalEndpointsForService(givenServiceName);
117
118             // if there is several endpoints that matching
119
// the given information, we have to choose one.
120
targetedEndpoint = electEndpoint(endpoints, source, exchange);
121
122             if (targetedEndpoint == null) {
123                 throw new RoutingException(
124                     "No endpoint found for the specified service : "
125                         + givenServiceName + ".");
126             }
127         } else if (givenInterfaceName != null) {
128             // try to resolve address with a connection
129
targetedEndpoint = resolveLinkedAddressForInterface(givenInterfaceName);
130
131             if (targetedEndpoint == null) {
132                 // find an Endpoint with the specified InterfaceName
133
endpoints = endpointService
134                     .getInternalEndpointsForInterface(givenInterfaceName);
135
136                 // if there is several endpoints that matching
137
// the given information, we have to choose one.
138
targetedEndpoint = electEndpoint(endpoints, source, exchange);
139
140                 if (targetedEndpoint == null) {
141                     throw new RoutingException(
142                         "No endpoint found for the specified interface : "
143                             + givenInterfaceName + ".");
144                 }
145             }
146         }
147
148         // Now, we can set the real endpoint that will
149
// serves the MessageExchange
150
exchange.setEndpoint(targetedEndpoint);
151     }
152
153     /**
154      * Retrieve a potential mapping between an interface name and an endpoint.
155      *
156      * @param interfaceName
157      * @return the linked endpoint, null if no connection retrieved
158      */

159     protected ServiceEndpoint resolveLinkedAddressForInterface(
160         QName JavaDoc interfaceName) {
161         ServiceEndpoint[] internalEndpoints = endpointService
162             .getInternalEndpointsForInterface(interfaceName);
163         if (internalEndpoints.length > 0) {
164             return internalEndpoints[0];
165         }
166         return null;
167     }
168
169     /**
170      * Retrieve a potential mapping between a fully qualified endpoint name
171      * (service name + endpoint name)and a real endpoint.
172      *
173      * @param serviceName
174      * @param endpointName
175      * @return the linked endpoint, null if no connection retrieved
176      */

177     protected ServiceEndpoint resolveLinkedAddressForEndpoint(
178         QName JavaDoc serviceName, String JavaDoc endpointName) throws RoutingException {
179         return endpointService.getEndpoint(serviceName, endpointName);
180     }
181
182     /**
183      * Elects the address in the list of endpoints as the message recipient,
184      * with the defined strategy. Ask the consumer and the provider if they are
185      * Okay for the exchange.
186      *
187      * <br>
188      * Strategy : <br>
189      * Each endpoint is tested, with the following rules.
190      * <li> if the endpoint is hosted by a shutdown-container, keep it, but try
191      * to find another 'active' endpoint.</li>
192      * <li> if isExchangeValidation server.properties is set to true, test the
193      * "isExchangeWithXXXOkay" (for an endpoint on an active container). If
194      * okay, return the endpoint.</li>
195      * <br>
196      * If no 'active' endpoint is found, but one 'inactive' is found, return it;
197      * so the message will be send, but will be delivered when the corresponding
198      * container will start again.
199      *
200      * @param addresses
201      * @return the elected recipient
202      */

203     protected ServiceEndpoint electEndpoint(ServiceEndpoint[] endpoints,
204         ComponentContextImpl ctxSource, MessageExchange exchange) {
205
206         ServiceEndpoint result = null;
207         ServiceEndpoint inactiveEndpoint = null;
208
209         if (endpoints != null && endpoints.length > 0) {
210             Component consumer = ctxSource.getComponent();
211
212             for (int i = 0; i < endpoints.length && result == null; i++) {
213                 InternalEndpoint providerEP = (InternalEndpoint) endpoints[i];
214
215                 // Check if the container of the endpoint is started
216
if (endpointService.isContainerStarted(providerEP)) {
217                     // test if isExchangeWithXXXOkay has to be used.
218
if (SystemUtil.isExchangeValidation()) {
219                         // apply isExchangeWithXXXOkay
220
if (consumer.isExchangeWithProviderOkay(providerEP,
221                             exchange)
222                             && providerEP.getEndpointService()
223                                 .isExchangeWithConsumerOkayForComponent(
224                                     providerEP, exchange)) {
225                             result = providerEP;
226                         }
227                     } else {
228                         result = providerEP;
229                     }
230                 }
231                 // the container of the endpoint is inactive,
232
// keep the endpoint to use it if no active is found
233
else {
234                     inactiveEndpoint = providerEP;
235                 }
236             }
237             // if no active endpoint was found,
238
// maybe an inactive endpoint was found.
239
if (result == null) {
240                 result = inactiveEndpoint;
241             }
242         }
243         return result;
244     }
245 }
246
Popular Tags