Skip to content

Commit 38a947b

Browse files
Merge pull request #821 from watson-developer-cloud/jdni-service-url
Retrieve service URL from JDNI
2 parents a675d71 + db31159 commit 38a947b

File tree

3 files changed

+85
-11
lines changed

3 files changed

+85
-11
lines changed

core/src/main/java/com/ibm/watson/developer_cloud/util/CredentialUtils.java

Lines changed: 63 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
*/
1313
package com.ibm.watson.developer_cloud.util;
1414

15+
import java.util.Hashtable;
1516
import java.util.Map.Entry;
1617
import java.util.logging.Level;
1718
import 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
}

core/src/test/java/com/ibm/watson/developer_cloud/util/CredentialUtilsTest.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
import static org.junit.Assert.assertEquals;
1616
import static org.junit.Assert.assertNull;
1717
import static org.junit.Assert.assertTrue;
18+
import static org.junit.Assume.assumeTrue;
1819

1920
import java.io.InputStream;
21+
import java.util.Hashtable;
2022

2123
import org.junit.Assert;
2224
import org.junit.Before;
@@ -50,6 +52,8 @@ public class CredentialUtilsTest extends WatsonServiceTest {
5052

5153
private static final String VISUAL_RECOGNITION = "watson_vision_combined";
5254

55+
private static final String PERSONALITY_INSIGHTS_URL = "https://gateway.watsonplatform.net/personality-insights/api";
56+
5357
/**
5458
* Setup.
5559
*/
@@ -58,6 +62,13 @@ public void setup() {
5862
final InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(VCAP_SERVICES);
5963
final String vcapServices = getStringFromInputStream(in);
6064
CredentialUtils.setServices(vcapServices);
65+
66+
final Hashtable<String, String> env = new Hashtable<>();
67+
env.put("java.naming.factory.initial", "org.osjava.sj.SimpleContextFactory");
68+
env.put("org.osjava.sj.delimiter", "/");
69+
env.put("org.osjava.sj.root", "src/test/resources");
70+
71+
CredentialUtils.setContext(env);
6172
}
6273

6374
/**
@@ -113,4 +124,14 @@ public void testGetUserCredentialsWithPlan() {
113124
assertEquals(credentials.getUsername(), NOT_A_USERNAME);
114125
assertEquals(credentials.getPassword(), NOT_A_PASSWORD);
115126
}
127+
128+
/**
129+
* Test getting the API URL using JDNI. We ignore this test in Travis because
130+
* it always fails there.
131+
*/
132+
@Test
133+
public void testGetAPIUrlFromJDNI() {
134+
assumeTrue(!System.getenv().containsKey("TRAVIS"));
135+
assertEquals(CredentialUtils.getAPIUrlTest(SERVICE_NAME), PERSONALITY_INSIGHTS_URL);
136+
}
116137
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
watson-developer-cloud/personality_insights/url=https://gateway.watsonplatform.net/personality-insights/api

0 commit comments

Comments
 (0)