1212 */
1313package com .ibm .watson .developer_cloud .util ;
1414
15+ import java .util .Hashtable ;
1516import java .util .Map .Entry ;
1617import java .util .logging .Level ;
1718import java .util .logging .Logger ;
@@ -91,6 +92,9 @@ public String getUsername() {
9192 /** The services. */
9293 private static String services ;
9394
95+ /** The context. */
96+ private static Context context ;
97+
9498 /** The Constant USERNAME. */
9599 private static final String USERNAME = "username" ;
96100
@@ -109,26 +113,46 @@ public String getUsername() {
109113 /** The Constant API_KEY. */
110114 private static final String API_KEY = "api_key" ;
111115
116+ /** The Constant LOOKUP_NAME_EXTENSION_API_KEY. */
117+ private static final String LOOKUP_NAME_EXTENSION_API_KEY = "/credentials" ;
118+
119+ /** The Constant LOOKUP_NAME_EXTENSION_URL. */
120+ private static final String LOOKUP_NAME_EXTENSION_URL = "/url" ;
121+
112122 private CredentialUtils () {
113123 // This is a utility class - no instantiation allowed.
114124 }
115125
116126 /**
117- * Attempt to get the Base64-encoded API key through JNDI.
127+ * Builds the lookup name to be searched for in JDNI
128+ * and uses it to call the overloaded JDNI method.
129+ *
130+ * @param serviceName Name of the bluemix service
131+ * @param lookupNameExtension Extension to determine which value should be retrieved through JDNI
132+ * @return The encoded desired value
133+ */
134+ private static String getJDNIValue (String serviceName , String lookupNameExtension ) {
135+ return getJDNIValue ("watson-developer-cloud/" + serviceName + lookupNameExtension );
136+ }
137+
138+ /**
139+ * Attempt to get the Base64-encoded value through JNDI.
118140 *
119141 * This method should always return null on Android due to the javax functions being unsupported
120142 *
121- * @param serviceName Name of the bluemix service
122- * @return The encoded API Key
143+ * @param lookupName Key to lookup in JDNI
144+ * @return The encoded desired value
123145 */
124- private static String getKeyUsingJNDI (String serviceName ) {
146+ private static String getJDNIValue (String lookupName ) {
125147 if (!isClassAvailable ("javax.naming.Context" ) || !isClassAvailable ("javax.naming.InitialContext" )) {
126148 log .info ("JNDI string lookups is not available." );
127149 return null ;
128150 }
129- String lookupName = "watson-developer-cloud/" + serviceName + "/credentials" ;
151+
130152 try {
131- Context context = new InitialContext ();
153+ if (context == null ) {
154+ context = new InitialContext ();
155+ }
132156 return (String ) context .lookup (lookupName );
133157 } catch (Exception e ) {
134158 log .fine ("JNDI " + lookupName + " not found." );
@@ -192,7 +216,7 @@ public static String getAPIKey(String serviceName, String plan) {
192216
193217 final JsonObject services = getVCAPServices ();
194218 if (services == null ) {
195- return getKeyUsingJNDI (serviceName );
219+ return getJDNIValue (serviceName , LOOKUP_NAME_EXTENSION_API_KEY );
196220 }
197221 if (serviceName .equalsIgnoreCase (ALCHEMY_API )) {
198222 final JsonObject credentials = getCredentialsObject (services , serviceName , plan );
@@ -299,12 +323,12 @@ public static String getAPIUrl(String serviceName) {
299323 }
300324
301325 /**
302- * Returns the apiKey from the VCAP_SERVICES or null if doesn't exists. If plan is specified, then only credentials
303- * for the given plan will be returned.
326+ * Returns the API URL from the VCAP_SERVICES, JDNI, or null if doesn't exists. If plan is specified, then only
327+ * credentials for the given plan will be returned.
304328 *
305329 * @param serviceName the service name
306330 * @param plan the service plan: standard, free or experimental
307- * @return the API key
331+ * @return the API URL
308332 */
309333 public static String getAPIUrl (String serviceName , String plan ) {
310334 if ((serviceName == null ) || serviceName .isEmpty ()) {
@@ -313,7 +337,7 @@ public static String getAPIUrl(String serviceName, String plan) {
313337
314338 final JsonObject services = getVCAPServices ();
315339 if (services == null ) {
316- return null ;
340+ return getJDNIValue ( serviceName , LOOKUP_NAME_EXTENSION_URL ) ;
317341 }
318342
319343 final JsonObject credentials = getCredentialsObject (services , serviceName , plan );
@@ -332,4 +356,32 @@ public static String getAPIUrl(String serviceName, String plan) {
332356 public static void setServices (String services ) {
333357 CredentialUtils .services = services ;
334358 }
359+
360+ /**
361+ * Sets the context variable for JDNI. This is a utility method for testing.
362+ *
363+ * @param env Configuration options for the context
364+ */
365+ public static void setContext (Hashtable <String , String > env ) {
366+ try {
367+ CredentialUtils .context = new InitialContext (env );
368+ } catch (Exception e ) {
369+ log .fine ("Error setting up JDNI context: " + e .getMessage ());
370+ }
371+ }
372+
373+ /**
374+ * Method for testing the getAPIUrl method that bypasses the VCAP
375+ * services to ensure retrieval from JDNI.
376+ *
377+ * @param serviceName the service name
378+ * @return the API URL
379+ */
380+ public static String getAPIUrlTest (String serviceName ) {
381+ if ((serviceName == null ) || serviceName .isEmpty ()) {
382+ return null ;
383+ }
384+
385+ return getJDNIValue ("jdni/watson-developer-cloud/" + serviceName + LOOKUP_NAME_EXTENSION_URL );
386+ }
335387}
0 commit comments