Skip to content

Commit

Permalink
- Fix copyrights
Browse files Browse the repository at this point in the history
- Add docs for nameservice feature
- Updated docs and error message produced
  when invalid address string is provided to a session
  • Loading branch information
rlubke committed Feb 4, 2025
1 parent 4f45931 commit 62b1ba5
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 14 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2020, 2023, Oracle Corporation and/or its affiliates. All rights reserved.
# Copyright 2020, 2025, Oracle Corporation and/or its affiliates. All rights reserved.
# Licensed under the Universal Permissive License v 1.0 as shown at
# https://oss.oracle.com/licenses/upl.

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/discovery.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2020, 2023, Oracle Corporation and/or its affiliates. All rights reserved.
# Copyright 2025, Oracle Corporation and/or its affiliates. All rights reserved.
# Licensed under the Universal Permissive License v 1.0 as shown at
# https://oss.oracle.com/licenses/upl.

Expand Down
38 changes: 32 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ the network transport.
* Registration of listeners to be notified of map mutations

### Requirements
* Coherence CE `22.06` or later (or equivalent non-open source editions) with a configured [gRPC Proxy](https://docs.oracle.com/en/middleware/standalone/coherence/14.1.1.2206/develop-remote-clients/using-coherence-grpc-server.html)
* Coherence CE versions `22.06`, `14.1.2-0-0`, `24.09` or later (or equivalent non-open source editions) with a configured [gRPC Proxy](https://docs.oracle.com/en/middleware/standalone/coherence/14.1.1.2206/develop-remote-clients/using-coherence-grpc-server.html)
* Node `18.15.x` or later
* NPM `9.x` or later

Expand Down Expand Up @@ -40,7 +40,7 @@ For more details on the image, see the [documentation](https://github.com/oracle

### Declare Your Dependency

To use the Coherence gRPC JavaScript Client, simply declare it as a dependency in your
To use the JavaScript Client for Oracle Coherence, simply declare it as a dependency in your
project's `package.json`:
```
...
Expand All @@ -52,8 +52,8 @@ project's `package.json`:

### Compatibility with Java Types
The following table provides a listing of mappings between Java types and Javascript types when working with
Coherence `23.09` or later. If using Coherence `22.06.x`, these types will be returned as Number. It is recommended
using `23.09` if intentionally using `java.math.BigInteger` or `java.math.BigDecimal` as part of your application.
Coherence `24.09` or later. If using Coherence `22.06.x`, these types will be returned as Number. It is recommended
using `24.09` if intentionally using `java.math.BigInteger` or `java.math.BigDecimal` as part of your application.

| Java Type | JavascriptType |
|----------------------|------------------------|
Expand All @@ -68,15 +68,15 @@ using `23.09` if intentionally using `java.math.BigInteger` or `java.math.BigDec
#### Establishing a Session

The Coherence uses the concept of a `Session` to manage a set of related Coherence resources,
such as maps and/or caches. When using the Coherence JavaScript Client, a `Session` connects to a specific
such as maps and/or caches. When using the JavaScript Client for Oracle Coherence, a `Session` connects to a specific
gRPC endpoint and uses a specific serialization format to marshal requests and responses.
This means that different sessions using different serializers may connect to the same server endpoint. Typically,
for efficiency the client and server would be configured to use matching serialization formats to avoid
deserialization of data on the server, but this does not have to be the case. If the server is using a different
serializer for the server-side caches, it must be able to deserialize the client's requests, so there must be
a serializer configured on the server to match that used by the client.

> NOTE: Currently, the Coherence JavaScript client only supports JSON serialization
> NOTE: Currently, the JavaScript Client for Oracle Coherence only supports JSON serialization
A `Session` is constructed using an `Options` instance, or a generic object with the same keys and values.

Expand Down Expand Up @@ -126,6 +126,32 @@ const opts = new Options({address: 'example.com:4444'})
let session = new Session(opts)
```

As of v1.2.3 of the JavaScript Client for Oracle Coherence, it's now possible to use the Coherence
NameService to lookup gRPC Proxy endpoints. The format to enable this feature is
`coherence:<host>([:port]|[:cluster-name]|[:port:cluster-name])`

For example:
* `coherence:localhost` will connect to the name service bound to a local coherence cluster on port `7574` (the default Coherence cluster port).
* `coherence:localhost:8000` will connect to the name service bound to a local coherence cluster on port `8000`.
* `coherence:localhost:remote-cluster` will connect to the name service bound to a local coherence cluster on port `7574` (the default Coherence cluster port) and look up the name service for the given cluster name. Note: this typically means both clusters have a local member sharing a cluster port.
* `coherence:localhost:8000:remote-cluster` will connect to the name service bound to a local coherence cluster on port `8000` and look up the name service for the given cluster name. Note: this typically means both clusters have a local member sharing a cluster port.

While this is useful for local development, this may have limited uses in a production environment. For example,
Coherence running within a container with the cluster port (`7574`) exposed so external clients may connect. The
lookup will fail to work for the client as the Coherence name service return a private network address which
won't resolve. Lastly, if connecting to a cluster that has multiple proxies bound to different ports, gRPC, by default,
will use the first address returned by the resolver. It is possible to enable round-robin load balancing by including
a custom channel option when creating the session:

```typescript
const { Session } = require('@oracle/coherence')

const opts = new Options({address: 'example.com:4444',
channelOptions: {'grpc.service_config': JSON.stringify({ loadBalancingConfig: [{ round_robin: {} }], })}})

let session = new Session(opts)
```

It's also possible to control the default address the session will bind to by providing
an address via the `COHERENCE_SERVER_ADDRESS` environment variable. The format of the value would
be the same as if you configured it programmatically as the above example shows.
Expand Down
8 changes: 3 additions & 5 deletions src/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,15 +110,16 @@ export class Options {
* `coherence:[host]:[port]`.
*
* @param address the IPv4 host address and port in the format of `[host]:[port]`
* or the Coherence name service format of `coherence:[host]:[port]`
* or the Coherence name service format of
* `coherence:<host>([:port]|[:cluster-name]|[:port:cluster-name])`
*/
set address (address: string) {
if (this.locked) {
return
}
// ensure address is sane
if (!Options.ADDRESS_REGEXP.test(address)) {
throw new Error('Expected address format is \'<hostname>:<port>\' || \'coherence:<hostname>:<port>\'. Configured: ' + address)
throw new Error('Expected address format is \'<hostname>:<port>\' or \'coherence:<host>([:port]|[:cluster-name]|[:port:cluster-name])\'. Configured: ' + address)
}

this._address = address
Expand Down Expand Up @@ -918,7 +919,6 @@ export class CoherenceResolver implements experimental.Resolver {

private readonly target: experimental.GrpcUri
private readonly listener: experimental.ResolverListener
private lastResolve?: Endpoint[]

constructor (
target: experimental.GrpcUri,
Expand Down Expand Up @@ -1003,10 +1003,8 @@ export class CoherenceResolver implements experimental.Resolver {
let socket: net.Socket = this.createSocket(state)
socket.connect(port, host)
state.waitResolve.then(() => {
setTimeout(() => { this.lastResolve = undefined }, 5000)
let ep: Endpoint[] = this.parseLookupResult(state)
if (ep.length > 0) {
this.lastResolve = ep
this.listener.onSuccessfulResolution(ep, null, null, null, {})
} else {
this.listener.onError({
Expand Down
4 changes: 3 additions & 1 deletion test/session-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ describe('Session Tests Suite (unit/IT)', () => {
})

it('should have active sessions after getCache() is called', async () => {
const sess = new Session()
const sess = new Session({
address: 'example.com:4444',
channelOptions: {'grpc.service_config': JSON.stringify({ loadBalancingConfig: [{ round_robin: {} }], })}})

sess.getCache('sess-cache')
assert.equal(sess.activeCacheCount, 1)
Expand Down

0 comments on commit 62b1ba5

Please sign in to comment.