Giter Club home page Giter Club logo

gp-java-client's Introduction

Java Client SDK for Globalization Pipeline on IBM Bluemix

Maven Central

What is this?

This is a Java client SDK for Globalization Pipeline on IBM Bluemix. This SDK provides JDK ResourceBundle integration and Java APIs for accessing Globalization Pipeline's REST endpoints.

Custom ResourceBundle implementation

In a Java applications, localized UI strings are usually stored in Java resource bundle class files or in Java properties files. These localized strings are accessed through java.util.ResourceBundle class. The ResourceBundle class provides a way to support custom resource bundle formats by specifying a custom instance of ResourceBundle.Control. This SDK contains an implementation of ResourceBundle.Control which looks up and load resource strings from an instance of Globalization Pipeline service.

Java APIs for Globalization Pipeline REST endpoints

Globalization Pipeline provides REST APIs. for creating translation bundles, fetching translated strings, managing user accounts used for accessing the service and various other operations. This SDK provides Java APIs for these REST endpoints, so you can develop Java applciation managing end to end translation process.

Getting started

To get started, you should familiarize yourself with the service itself. A good place to begin is by reading the Quick Start Guide and the official Getting Started with IBM Globalization documentation.

The documentation explains how to find the service on Bluemix, create a new service instance, create a new bundle, and access the translated messages.

Usage

Minimum requirements

This library requires Java 7 or later version of Java Runtime Environment.

To build the library from the source files, JDK 8 is required.

Accessing translated resources from a Bluemix Java application

Once a new bundle is created, and the contents in the source language is uploaded, your Java application can use the translated results through Java's standard ResourceBundle class.

Your original code may look like below:

...
Locale locale;  // the target language
...

ResourceBundle rb = ResourceBundle.getBundle("com.ibm.app.MyMessages", locale);
String msg = rb.getString("msg1");

Using ResourceBundleControlProvider SPI (Java 8 or later)

This SDK implements ResourceBundelControlProvider introduced in Java 8. With the provider implementation, you can retrieve translated resource strings stored in a Globalization Pipeline project without any code changes.

To enable this feature, you can put the SDK jar file(s) into Java's extension directory. The SDK is distributed in two different formats - gp-java-client-X.X.X.jar and gp-java-client-X.X.X-jar-with-dependencies.jar. If you use the one wihout dependencies, you also need to put the dependencies (for now, Gson and Guava) in the same directory.

If the application is running on Bluemix, then what you need is to package the SDK jar file (and the dependencies) in your application to the JRE overlay directory corresponding to the JRE's extension directory 'resources/.java-overlay/.java/jre/lib/ext'. For more details, please refer Customizing the JRE

If the application is not running on Bluemix, then you need to supply credentials used for accessing the Globalization Pipeline service instance. The service supports Globalization Service Authentication and Identity and Access Management (IAM) authentication. IAM authentication uses a service API key to get an access token that is passed with the call.

Irrespective of which you choose the following common credentials can be specified by following environment variables:

The Globalization Service Authentication specific credentials can be specified by following environment variables:

  • GP_USER_ID: User ID (e.g. e92a1282a0e4f97bec93aa9f56fdb838)
  • GP_PASSWORD: User password (e.g. zg5SlD+ftXYRIZDblLgEA/ILkkCNqE1y)

For IAM authentication, you supply either an IAM service API key or a bearer token.

  • Use the API key to have the SDK manage the lifecycle of the access token. The SDK requests an access token, ensures that the access token is valid, and fetches a new one when necessary.
  • Use the bearer token if you want to manage the lifecycle yourself.

The IAM specific credentials can be specified by following environment variables::

  • GP_IAM_API_KEY: IAM API Key

  • GP_IAM_ENDPOINT: IAM endpoint (e.g. https://iam.cloud.ibm.com)

  • GP_IAM_BEARER_TOKEN: IAM Bearer token

Please also refer Java Tutorials article Installing a Custom Resource Bundle as an Extension about the service provider interface and configuration in general.

Using CloudResourceBundleControl

If your application is running on JRE 7 or you want to limit the use of Globalization Pipeline service to specific bundles, then you can use the custom ResourceBundle.Control implementation included in this SDK.

If the application is running on Bluemix, the source code should be changed to:

import com.ibm.g11n.pipeline.client.rb.CloudResourceBundleControl;
...
Locale locale;  // the target language
...
// ResourceBundle is created with the custom control
ResourceBundle rb = ResourceBundle.getBundle("com.ibm.app.MyMessages", locale,
                                             CloudResourceBundleControl.getInstance());
String msg = rb.getString("msg1");

With the code above, your application will retrieve a translated resource string from your translation bundle stored in the Globalization Pipeline service instance. If the specified language (Locale) is not available in the translation bundle, the custom control will automatically fallback to local resources (.class or .properties included in your application).

When the application is not running on Bluemix, you need to supply credentials manually to create the custom control, instead of calling the no-arg factory method CloudResourceBundleControl.getInstance(). For example,

import com.ibm.g11n.pipeline.client.ServiceAccount;
import com.ibm.g11n.pipeline.client.rb.CloudResourceBundleControl;
import com.ibm.g11n.pipeline.iam.TokenManager;
import com.ibm.g11n.pipeline.iam.TokenManagerFactory;

...
Locale locale;  // the target language
...

ServiceAccount account = ServiceAccount.getInstance(
    "https://gp-rest.ng.bluemix.net/translate/rest", // service URL
    "d3f537cd617f34c86ac6b270f3065e73",              // instance ID
    "e92a1282a0e4f97bec93aa9f56fdb838",              // user ID
    "zg5SlD+ftXYRIZDblLgEA/ILkkCNqE1y");             // user password
/* For IAM Authentication.
//For having SDK manage the lifecycle of the access token 
TokenManager tokenManager = TokenManagerFactory.getTokenLifeCycleManager(
    "https://iam.cloud.ibm.com",                     // IAM endpoint
    "aADSdd=ejkfs");                                 // IAM API Key

//For managing the lifecycle yourself
TokenManager tokenManager = TokenManagerFactory.getTokenManager(
    "djkfjjejfiehfjhfjhfhskjklshkufkhde");           // IAM Bearer Token
    
ServiceAccount account = ServiceAccount getInstance(
    "https://gp-rest.ng.bluemix.net/translate/rest", // service URL
    "d3f537cd617f34c86ac6b270f3065e73",              // instance ID
    tokenManager)
*/
// ResourceBundle is created with the custom control
ResourceBundle rb = ResourceBundle.getBundle("com.ibm.app.MyMessages", locale,
                                             CloudResourceBundleControl.getInstance(account));
String msg = rb.getString("msg1");

Community

Contributing

See CONTRIBUTING.md.

License

Apache 2.0. See LICENSE.txt.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

gp-java-client's People

Contributors

dependabot[bot] avatar jcemmons avatar jugu avatar pgaglani1 avatar sid41 avatar srl295 avatar yumaoka avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gp-java-client's Issues

Failed to access resource entry information when resource key contains a space character

You can create a resource entry with a key including space characters. However, ServiceClient#getResourceEntry() and ServiceClient#updateResourceEntry() do not work well with such resource key.

com.ibm.g11n.pipeline.client.ServiceException: Error while processing API request GET yoshito001/v2/bundles/my.bundle/fr/key 1
    at com.ibm.g11n.pipeline.client.impl.ServiceClientImpl.invokeApi(ServiceClientImpl.java:949)
    at com.ibm.g11n.pipeline.client.impl.ServiceClientImpl.invokeApi(ServiceClientImpl.java:856)
    at com.ibm.g11n.pipeline.client.impl.ServiceClientImpl.getResourceEntry(ServiceClientImpl.java:507)
    at com.ibm.g11n.sandbox.KeyWithSpace.main(KeyWithSpace.java:17)
Caused by: java.lang.NullPointerException
    at com.ibm.g11n.pipeline.client.impl.ServiceClientImpl.invokeApi(ServiceClientImpl.java:920)
    ... 3 more

RFE: Consider packging dependencies with Jar Jar Links

If someone wants to utilize Java 8 ResourceBundleControlProvider SPI, gp-java-client JAR file and its dependencies must be in JRE's extension classpath. At this moment, gp-java-client depends on Gson, but if user's application require a different version of Gson, it may cause a problem by the version conflict.

gp-java-client may offer a single fat jar utilizing Jar Jar Links and rename dependency packages, so user can avoid the component version conflict.

DatatypeConverter.printBase64Binary throws NPE

There are few places calling javax.xml.bind.DatatypeConverter#printBase64Binary to encode bytes into Base64 string. We found this static method call throws NullPointerException on WAS Liberty.

DatatypeConverter is a part of JDK, but Liberty's implementation requires initialization. See this page: https://developer.ibm.com/answers/questions/200553/jaxb-datatypeconverter-throws-nullpointerexception.html

We probably should replace the call sites with portable/self-contained base64 encoder implementation.

Java SE 8 added java.util.Base64. However, gp-java-client supports Java 7, so we cannot use Base64 class.

throw specific exceptions

Currently gp-rest-client only throws ServiceException . We may want to create specific exceptions for subclasses.

Fail to update TR metadata

When a TR is in MERGED status, updateTranslationRequest() fails to update metadata field even the change set does not try to change the status.

Exception in thread "main" com.ibm.g11n.pipeline.client.ServiceException: The status of translation request (1c07efb71fc2f079886e969609d2ed9b) cannot be updated from MERGED to DRAFT
at com.ibm.g11n.pipeline.client.impl.ServiceClientImpl.updateTranslationRequest(ServiceClientImpl.java:981)

Return empty set in BundleData#getTargetLanguages()

For now, BundleData#getTargetLanguages() may return empty set or null when there are no target languages, depending on how bundle is created (without target languages vs. empty target languages).

The distinction between null and empty set does not make sense for this case. The method should probably return empty set always if no target languages are available.

See also IBM-Cloud/gp-java-tools#43.

CloudResourceBundleContol should not depend on supported languages returned by $service/v2/info

GP REST endpoint $service/v2/info used to return all available languages handled by GP service in beta. However, in GA version, it only returns a set of languages supported by the basic MT. CloudResourceBundleControl checks if the given Locale is handled by GP by isLocaleSupportedByService, which calls the endpoint. But it no longer reflects that the set of languages held by the user's service instance. The lookup logic should be updated to check the target bundle's contents.

Post beta updates

There are some REST API updates after beta. New client API should be created for the updates.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.