| /* |
| * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0, |
| * or the Eclipse Distribution License v. 1.0 which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
| */ |
| |
| // Contributors: |
| // Oracle - initial API and implementation from Oracle TopLink |
| package org.eclipse.persistence.internal.sessions.coordination; |
| |
| import org.eclipse.persistence.sessions.coordination.ServiceId; |
| |
| /** |
| * <p> |
| * <b>Purpose</b>: A structured message object to announce a new RCM service |
| * instance becoming available |
| * </p><p> |
| * <b>Description</b>: This object is sent over the multicast by a service wanting |
| * to join the EclipseLink cluster. It is received by all other services subscribing |
| * to the same channel. Receipt of this announcement triggers an exchange protocol |
| * between the sending and receiving services to establish communications with all |
| * of the other services on the channel. |
| * </p> |
| */ |
| public class ServiceAnnouncement { |
| |
| /** The id information of the sending service */ |
| ServiceId serviceId; |
| |
| /** |
| * INTERNAL: |
| * Constructor to initialize a new instance when receiving a message |
| */ |
| public ServiceAnnouncement(byte[] bytes) { |
| readFromBytes(bytes); |
| } |
| |
| /** |
| * INTERNAL: |
| * Constructor to initialize a new instance when creating a message |
| */ |
| public ServiceAnnouncement(ServiceId newServiceId) { |
| this.serviceId = newServiceId; |
| } |
| |
| /** |
| * INTERNAL: |
| * Initialize the instance fields from the serialized bytes. |
| * |
| * Assumptions: |
| * - Same character converters exist on the reading and storing sides |
| * - Strings are not greater than 255 bytes (bytes, not characters) |
| * |
| * Byte storage: |
| * - 1 byte to store length of String that is to follow |
| * - String of 'length' bytes follows |
| */ |
| public void readFromBytes(byte[] bytes) { |
| serviceId = new ServiceId(); |
| int curPos = 0; |
| |
| // Read the channel |
| int channelLength = bytes[curPos]; |
| curPos++; |
| serviceId.setChannel(new String(bytes, curPos, channelLength)); |
| curPos += channelLength; |
| |
| // Read the id |
| int idLength = bytes[curPos]; |
| curPos++; |
| serviceId.setId(new String(bytes, curPos, idLength)); |
| curPos += idLength; |
| |
| // Read the URL |
| int urlLength = bytes[curPos]; |
| curPos++; |
| if (urlLength > 0) { |
| serviceId.setURL(new String(bytes, curPos, urlLength)); |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * Convert the instance attributes to serialized bytes. |
| * |
| * Assumptions: |
| * - Same character converters exist on the reading and storing sides |
| * - channel, id and converted to bytes < 256 bytes each |
| * |
| * Byte storage: |
| * - 1 byte to store length of String that is to follow |
| * - String of 'length' bytes follows |
| */ |
| public byte[] toBytes() { |
| byte[] bytes; |
| int curPos = 0; |
| |
| // Convert the strings to bytes |
| byte[] channelBytes = serviceId.getChannel().getBytes(); |
| int channelLength = channelBytes.length; |
| |
| byte[] idBytes = serviceId.getId().getBytes(); |
| int idLength = idBytes.length; |
| |
| byte[] urlBytes = null; |
| int urlLength = 0; |
| if (serviceId.getURL() == null) { |
| urlBytes = new byte[]{}; |
| } else { |
| urlBytes = serviceId.getURL().getBytes(); |
| urlLength = urlBytes.length; |
| } |
| |
| // Create the byte array to hold the data |
| bytes = new byte[channelLength + idLength + urlLength + 3]; |
| |
| // Store the fields in the byte array |
| bytes[curPos] = (byte)channelLength; |
| curPos++; |
| System.arraycopy(channelBytes, 0, bytes, curPos, channelLength); |
| curPos += channelLength; |
| |
| bytes[curPos] = (byte)idLength; |
| curPos++; |
| System.arraycopy(idBytes, 0, bytes, curPos, idLength); |
| curPos += idLength; |
| |
| bytes[curPos] = (byte)urlLength; |
| curPos++; |
| System.arraycopy(urlBytes, 0, bytes, curPos, urlLength); |
| return bytes; |
| } |
| |
| /** |
| * INTERNAL: |
| * Return the id of the service sending this announcement |
| */ |
| public ServiceId getServiceId() { |
| return serviceId; |
| } |
| } |