/*******************************************************************************
* This file is protected by Copyright.
* Please refer to the COPYRIGHT file distributed with this source distribution.
*
* This file is part of REDHAWK IDE.
*
* All rights reserved. This program and the accompanying materials are made available under
* the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package gov.redhawk.bulkio.util;
import gov.redhawk.sca.util.Debug;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.Servant;
import BULKIO.PortStatistics;
import BULKIO.PortUsageType;
import BULKIO.PrecisionUTCTime;
import BULKIO.SDDSStreamDefinition;
import BULKIO.StreamSRI;
import BULKIO.dataSDDSOperations;
import BULKIO.dataSDDSPOATie;
import BULKIO.dataSDDSPackage.AttachError;
import BULKIO.dataSDDSPackage.DetachError;
import BULKIO.dataSDDSPackage.InputUsageState;
import BULKIO.dataSDDSPackage.StreamInputError;
import CF.DataType;
/**
* @since 2.0
*/
public abstract class AbstractBulkIOSDDSPort implements dataSDDSOperations {
private static final Debug TRACE_LOG = new Debug(BulkIOUtilActivator.getDefault(), AbstractBulkIOSDDSPort.class.getSimpleName());
private final PortStatistics stats = new PortStatistics();
/** key=attachUuid value=SddsStreamSession */
private Map<String, SddsStreamSession> sddsSessionMap = new ConcurrentHashMap<String, SddsStreamSession>();
/** key=streamID value=StreamSRI */
private final Map<String, StreamSRI> streamSRIMap = new ConcurrentHashMap<String, StreamSRI>();
// static initializer for PortStatisticsstats field
{
stats.callsPerSecond = -1;
stats.elementsPerSecond = -1;
stats.timeSinceLastCall = -1;
stats.bitsPerSecond = -1;
stats.keywords = new DataType[0];
stats.portName = "sddsPort_" + System.getProperty("user.name", "user").replace(' ', '_') + "_" + System.currentTimeMillis();
stats.streamIDs = new String[0];
}
protected AbstractBulkIOSDDSPort() {
}
/* (non-Javadoc)
* @see BULKIO.ProvidesPortStatisticsProviderOperations#state()
*/
@Override
public PortUsageType state() {
if (sddsSessionMap.isEmpty()) {
return PortUsageType.IDLE;
}
return PortUsageType.ACTIVE;
}
/* (non-Javadoc)
* @see BULKIO.ProvidesPortStatisticsProviderOperations#statistics()
*/
@Override
public PortStatistics statistics() {
// updateStatitics(); // TODO: what do we do here?
return stats;
}
/* (non-Javadoc)
* @see BULKIO.dataSDDSOperations#usageState()
*/
@Override
public InputUsageState usageState() {
if (sddsSessionMap.isEmpty()) {
return InputUsageState.IDLE;
} else {
return InputUsageState.ACTIVE;
}
}
/* (non-Javadoc)
* @see BULKIO.dataSDDSOperations#attachedStreams()
*/
@Override
public SDDSStreamDefinition[] attachedStreams() {
SddsStreamSession[] values = sddsSessionMap.values().toArray(new SddsStreamSession[0]);
SDDSStreamDefinition[] retVals = new SDDSStreamDefinition[values.length];
int ii = 0;
for (SddsStreamSession val : values) {
retVals[ii] = val.getSddsStreamDef();
ii++;
}
return retVals;
}
/* (non-Javadoc)
* @see BULKIO.dataSDDSOperations#attachmentIds()
*/
@Override
public String[] attachmentIds() {
SddsStreamSession[] values = sddsSessionMap.values().toArray(new SddsStreamSession[0]);
String[] retVals = new String[values.length];
int ii = 0;
for (SddsStreamSession val : values) {
retVals[ii] = val.getAttachId();
ii++;
}
return retVals;
}
/* (non-Javadoc)
* @see BULKIO.dataSDDSOperations#attach(BULKIO.SDDSStreamDefinition, java.lang.String)
*/
@Override
public String attach(SDDSStreamDefinition sddsStreamDef, String userid) throws AttachError, StreamInputError {
TRACE_LOG.enteringMethod(sddsStreamDef, userid);
if (sddsStreamDef == null) {
throw new AttachError("Invalid/null SDDSStreamDefinition");
} else if (userid == null) {
throw new AttachError("Invalid/null userid");
}
String attachUuid = UUID.randomUUID().toString();
SddsStreamSession sss = new SddsStreamSession(sddsStreamDef, userid, attachUuid);
handleAttach(sss);
sddsSessionMap.put(attachUuid, sss);
return attachUuid;
}
/* (non-Javadoc)
* @see BULKIO.dataSDDSOperations#detach(java.lang.String)
*/
@Override
public void detach(String attachId) throws DetachError, StreamInputError {
TRACE_LOG.enteringMethod(attachId);
SddsStreamSession sss = sddsSessionMap.get(attachId);
if (sss == null) {
return;
}
handleDetach(sss);
sddsSessionMap.remove(attachId);
streamSRIMap.remove(sss.getSddsStreamDef().id);
}
/* (non-Javadoc)
* @see BULKIO.dataSDDSOperations#getStreamDefinition(java.lang.String)
*/
@Override
public SDDSStreamDefinition getStreamDefinition(String attachId) throws StreamInputError {
SddsStreamSession sss = sddsSessionMap.get(attachId);
if (sss == null) {
throw new StreamInputError("No SDDSStreamDefinition found for attachId: " + attachId);
}
return sss.getSddsStreamDef();
}
/* (non-Javadoc)
* @see BULKIO.dataSDDSOperations#getUser(java.lang.String)
*/
@Override
public String getUser(String attachId) throws StreamInputError {
SddsStreamSession sss = sddsSessionMap.get(attachId);
if (sss == null) {
throw new StreamInputError("No user found for attachId: " + attachId);
}
return sss.getUserId();
}
/* (non-Javadoc)
* @see BULKIO.dataSDDSOperations#attachedSRIs()
*/
@Override
public StreamSRI[] attachedSRIs() {
return this.streamSRIMap.values().toArray(new StreamSRI[this.streamSRIMap.size()]);
}
/* (non-Javadoc)
* @see BULKIO.dataSDDSOperations#pushSRI(BULKIO.StreamSRI, BULKIO.PrecisionUTCTime)
* Push SRI to downstream components with time tag
*/
@Override
public void pushSRI(StreamSRI sri, PrecisionUTCTime time) {
if (TRACE_LOG.enabled) {
TRACE_LOG.enteringMethod(StreamSRIUtil.toString(sri), time);
}
// FYI: StreamSRI <=> SDDSStreamDefinition.id
if (sri != null) {
String streamId = sri.streamID;
if (streamId != null) {
StreamSRI oldSri = this.streamSRIMap.put(streamId, sri);
if (!StreamSRIUtil.equals(oldSri, sri)) {
handleStreamSRIChanged(streamId, oldSri, sri);
}
}
} else {
TRACE_LOG.message("Ignoring null StreamSRI");
}
}
@NonNull
public Servant toServant(POA poa) {
return new dataSDDSPOATie(this, poa);
}
/**
* @param streamID stream ID
* @return StreamSRI for specified stream ID (null if it does not exist or has been detached)
*/
@Nullable
public StreamSRI getSri(@NonNull String streamID) {
return this.streamSRIMap.get(streamID);
}
protected StreamSRI putSri(@NonNull String streamID, StreamSRI sri) {
return this.streamSRIMap.put(streamID, sri);
}
// =========================================================================
// Methods that sub-classes MUST implement
// =========================================================================
/** callback to notify when there is a new SDDSStreamDefinition attach request. */
protected abstract void handleAttach(@NonNull SddsStreamSession sss) throws AttachError, StreamInputError;
/** callback to notify when there is a SDDSStreamDefinition detach request. */
protected abstract void handleDetach(@NonNull SddsStreamSession sss) throws DetachError, StreamInputError;
/** callback to notify that SRI has changed for specified streamID. */
protected abstract void handleStreamSRIChanged(@NonNull String streamID, @Nullable StreamSRI oldSri, @NonNull StreamSRI newSri);
// =========================================================================
// Inner classes
// =========================================================================
@NonNullByDefault
public static class SddsStreamSession {
private final SDDSStreamDefinition sddsStreamDef;
private final String userId;
private final String attachId;
public SddsStreamSession(SDDSStreamDefinition sddsStreamDef, String userId, String attachId) {
super();
this.sddsStreamDef = sddsStreamDef;
this.userId = userId;
this.attachId = attachId;
}
/**
* @return the sddsStreamDef
*/
public SDDSStreamDefinition getSddsStreamDef() {
return sddsStreamDef;
}
/**
* @return the userId
*/
public String getUserId() {
return userId;
}
/**
* @return the attachId
*/
public String getAttachId() {
return attachId;
}
public String toString() {
return "( SDDSStreamDefinition ["
+ " id=" + sddsStreamDef.id
+ " multicastAddress=" + sddsStreamDef.multicastAddress
+ " port=" + sddsStreamDef.port
+ " vlan=" + sddsStreamDef.vlan
+ " dataFormat=" + sddsStreamDef.dataFormat.value()
+ " sampleRate=" + sddsStreamDef.sampleRate
+ " timeTagValid=" + sddsStreamDef.timeTagValid
+ " privateInfo=" + sddsStreamDef.privateInfo
+ " ]; userID = " + userId
+ " attachID = " + attachId
+ " ; " + super.toString()
+ " ) " + hashCode();
}
} // end class SddsStreamSession
}