001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.activemq.broker;
018
019 import java.net.InetAddress;
020 import java.net.URI;
021 import java.net.UnknownHostException;
022 import java.util.Locale;
023
024 import org.apache.activemq.util.InetAddressUtil;
025
026 /**
027 * Policy object that controls how a TransportConnector publishes the connector's
028 * address to the outside world. By default the connector will publish itself
029 * using the resolved host name of the bound server socket.
030 *
031 * @org.apache.xbean.XBean
032 */
033 public class PublishedAddressPolicy {
034
035 private String clusterClientUriQuery;
036 private PublishedHostStrategy publishedHostStrategy = PublishedHostStrategy.DEFAULT;
037
038 /**
039 * Defines the value of the published host value.
040 */
041 public enum PublishedHostStrategy {
042 DEFAULT,
043 IPADDRESS,
044 HOSTNAME,
045 FQDN;
046
047 public static PublishedHostStrategy getValue(String value) {
048 return valueOf(value.toUpperCase(Locale.ENGLISH));
049 }
050 }
051
052 /**
053 * Using the supplied TransportConnector this method returns the String that will
054 * be used to update clients with this connector's connect address.
055 *
056 * @param connector
057 * The TransportConnector whose address is to be published.
058 * @return a string URI address that a client can use to connect to this Transport.
059 * @throws Exception
060 */
061 public String getPublishableConnectString(TransportConnector connector) throws Exception {
062
063 URI connectorURI = connector.getConnectUri();
064
065 if (connectorURI == null) {
066 return null;
067 }
068
069 String scheme = connectorURI.getScheme();
070 String userInfo = getPublishedUserInfoValue(connectorURI.getUserInfo());
071 String host = getPublishedHostValue(connectorURI.getHost());
072 int port = connectorURI.getPort();
073 String path = getPublishedPathValue(connectorURI.getPath());
074 String fragment = getPublishedFragmentValue(connectorURI.getFragment());
075
076 URI publishedURI = new URI(scheme, userInfo, host, port, path, getClusterClientUriQuery(), fragment);
077
078 return publishedURI.toString();
079 }
080
081 /**
082 * Subclasses can override what host value is published by implementing alternate
083 * logic for this method.
084 *
085 * @param uriHostEntry
086 * @return
087 * @throws UnknownHostException
088 */
089 protected String getPublishedHostValue(String uriHostEntry) throws UnknownHostException {
090
091 // By default we just republish what was already present.
092 String result = uriHostEntry;
093
094 if (this.publishedHostStrategy.equals(PublishedHostStrategy.IPADDRESS)) {
095 InetAddress address = InetAddress.getByName(uriHostEntry);
096 result = address.getHostAddress();
097 } else if (this.publishedHostStrategy.equals(PublishedHostStrategy.HOSTNAME)) {
098 InetAddress address = InetAddress.getByName(uriHostEntry);
099 if (address.isAnyLocalAddress()) {
100 // make it more human readable and useful, an alternative to 0.0.0.0
101 result = InetAddressUtil.getLocalHostName();
102 } else {
103 result = address.getHostName();
104 }
105 } else if (this.publishedHostStrategy.equals(PublishedHostStrategy.FQDN)) {
106 InetAddress address = InetAddress.getByName(uriHostEntry);
107 if (address.isAnyLocalAddress()) {
108 // make it more human readable and useful, an alternative to 0.0.0.0
109 result = InetAddressUtil.getLocalHostName();
110 } else {
111 result = address.getCanonicalHostName();
112 }
113 }
114
115 return result;
116 }
117
118 /**
119 * Subclasses can override what path value is published by implementing alternate
120 * logic for this method. By default this method simply returns what was already
121 * set as the Path value in the original URI.
122 *
123 * @param uriPathEntry
124 * The original value of the URI path.
125 *
126 * @return the desired value for the published URI's path.
127 */
128 protected String getPublishedPathValue(String uriPathEntry) {
129 return uriPathEntry;
130 }
131
132 /**
133 * Subclasses can override what host value is published by implementing alternate
134 * logic for this method. By default this method simply returns what was already
135 * set as the Fragment value in the original URI.
136 *
137 * @param uriFragmentEntry
138 * The original value of the URI Fragment.
139 *
140 * @return the desired value for the published URI's Fragment.
141 */
142 protected String getPublishedFragmentValue(String uriFragmentEntry) {
143 return uriFragmentEntry;
144 }
145
146 /**
147 * Subclasses can override what user info value is published by implementing alternate
148 * logic for this method. By default this method simply returns what was already
149 * set as the UserInfo value in the original URI.
150 *
151 * @param uriUserInfoEntry
152 * The original value of the URI user info.
153 *
154 * @return the desired value for the published URI's user info.
155 */
156 protected String getPublishedUserInfoValue(String uriUserInfoEntry) {
157 return uriUserInfoEntry;
158 }
159
160 /**
161 * Gets the URI query that's configured on the published URI that's sent to client's
162 * when the cluster info is updated.
163 *
164 * @return the clusterClientUriQuery
165 */
166 public String getClusterClientUriQuery() {
167 return clusterClientUriQuery;
168 }
169
170 /**
171 * Sets the URI query that's configured on the published URI that's sent to client's
172 * when the cluster info is updated.
173 *
174 * @param clusterClientUriQuery the clusterClientUriQuery to set
175 */
176 public void setClusterClientUriQuery(String clusterClientUriQuery) {
177 this.clusterClientUriQuery = clusterClientUriQuery;
178 }
179
180 /**
181 * @return the publishedHostStrategy
182 */
183 public PublishedHostStrategy getPublishedHostStrategy() {
184 return publishedHostStrategy;
185 }
186
187 /**
188 * @param publishedHostStrategy the publishedHostStrategy to set
189 */
190 public void setPublishedHostStrategy(PublishedHostStrategy strategy) {
191 this.publishedHostStrategy = strategy;
192 }
193
194 /**
195 * @param publishedHostStrategy the publishedHostStrategy to set
196 */
197 public void setPublishedHostStrategy(String strategy) {
198 this.publishedHostStrategy = PublishedHostStrategy.getValue(strategy);
199 }
200 }