use of org.omg.CORBA.IntHolder in project ACS by ACS-Community.
the class ManagerImpl method internalRequestDynamicComponent.
/**
* Internal method for requesting dynamic components.
*
* Resolution:
* <code>component_name</code> and <code>component_type</code> can be considered as "determinator" fields,
* they play important role in search algorithm.
* <code>component_code</code> and <code>container_name</code> can be considered as "override" fields,
* they only help to find closest match.
* Rule: unspecified <code>component_name</code> case implies that a new component will be activated.
* Search points (8,4,2,1): <code>component_name</code>, <code>component_type</code>, <code>component_code</code>, <code>container_name</code>.
* <pre>
*
* name | type | search criteria
* -----------------------------
* * | * | throw IncompleteComponentSpecException
* X | * | (equals, wildcard)
* * | X | (equals, equals) w/ name generation
* X | X | (wildcard, equals) - overriding type is not allowed
*
* </pre>
* 'name' can be also something like "ANT1/*" (ends with) and is threated just like "*".
*
* @param requestor requestor of the component.
* @param componentSpec requested component <code>ComponentSpec</code>
* @return componentInfo <code>ComponentInfo</code> of requested dynamic component.
*/
private ComponentInfo internalRequestDynamicComponent(int requestor, ComponentSpec componentSpec) throws AcsJCannotGetComponentEx, AcsJSyncLockFailedEx, AcsJNoPermissionEx, AcsJIncompleteComponentSpecEx, AcsJInvalidComponentSpecEx, AcsJComponentSpecIncompatibleWithActiveComponentEx {
boolean unspecifiedName = componentSpec.getName().endsWith(ComponentSpec.COMPSPEC_ANY);
boolean unspecifiedType = componentSpec.getType().equals(ComponentSpec.COMPSPEC_ANY);
// * | * | throw IncompleteComponentSpecException
if (unspecifiedName && unspecifiedType) {
AcsJInvalidComponentSpecEx ex = new AcsJInvalidComponentSpecEx();
ex.setReason("'name' and 'type' cannot be both '" + ComponentSpec.COMPSPEC_ANY + "'.");
throw ex;
} else // all fields are fully specified, no search needed
if (!unspecifiedName && !unspecifiedType && !componentSpec.getCode().equals(ComponentSpec.COMPSPEC_ANY) && !componentSpec.getContainer().equals(ComponentSpec.COMPSPEC_ANY)) {
StatusHolder statusHolder = new StatusHolder();
// We let exceptions occurring here fly up
return internalRequestComponent(requestor, componentSpec.getName(), componentSpec.getType(), componentSpec.getCode(), componentSpec.getContainer(), RELEASE_TIME_UNDEFINED, statusHolder, true);
}
//
// prepare search conditions
//
final String[] fieldNames = new String[] { "Name", "Type", "Code", "Container" };
final String[] requiredValues = new String[] { componentSpec.getName(), componentSpec.getType(), componentSpec.getCode(), componentSpec.getContainer() };
final int[] equalityPoints = new int[] { 8, 4, /* never used */
2, 1 };
boolean[] equalityRequired = null;
boolean allowNameGeneration = false;
boolean prohibitSearch = false;
// X | X | (wildcard, equals)
if (!unspecifiedName && !unspecifiedType) {
equalityRequired = new boolean[] { false, true, false, false };
allowNameGeneration = true;
} else // X | * | (equals, wildcard)
if (!unspecifiedName && unspecifiedType) {
equalityRequired = new boolean[] { true, false, false, false };
} else // prefix* | X | (equals, equals) w/ name generation
if (unspecifiedName && !unspecifiedType) {
equalityRequired = new boolean[] { true, true, false, false };
// no search needed case...
if (!componentSpec.getCode().equals(ComponentSpec.COMPSPEC_ANY) && !componentSpec.getContainer().equals(ComponentSpec.COMPSPEC_ANY))
prohibitSearch = true;
allowNameGeneration = true;
}
// search
IntHolder keepAliveTimeHolder = new IntHolder(RELEASE_TIME_UNDEFINED);
String[] result = prohibitSearch ? null : searchDynamicComponent(fieldNames, requiredValues, equalityRequired, equalityPoints, keepAliveTimeHolder);
// none found
if (result == null) {
boolean failed = true;
// only name or container not speficied...
if ((allowNameGeneration || !unspecifiedName) && !unspecifiedType && !componentSpec.getCode().equals(ComponentSpec.COMPSPEC_ANY)) {
// container name already specified, i.e. name is *, which is OK
if (!componentSpec.getContainer().equals(ComponentSpec.COMPSPEC_ANY)) {
result = new String[] { componentSpec.getName(), componentSpec.getType(), componentSpec.getCode(), componentSpec.getContainer() };
failed = false;
} else // container name is *, use load balancing if available
if (loadBalancingStrategy != null) {
String containerName = loadBalancingStrategy.selectContainer(getClientInfo(requestor), getContainersInfo());
if (containerName != null) {
result = new String[] { componentSpec.getName(), componentSpec.getType(), componentSpec.getCode(), containerName };
failed = false;
}
}
}
if (failed) {
AcsJInvalidComponentSpecEx ex = new AcsJInvalidComponentSpecEx();
ex.setReason("Requested ComponentSpec does not match any entry in the CDB.");
throw ex;
}
}
// override...
for (int i = 0; i < result.length; i++) if (!requiredValues[i].equals(ComponentSpec.COMPSPEC_ANY))
result[i] = requiredValues[i];
// check completeness
int i = 0;
if (allowNameGeneration)
i++;
for (; i < result.length; i++) if (result[i].equals(ComponentSpec.COMPSPEC_ANY)) {
// if load balancing strategy is registered, use it to determine container name
if (fieldNames[i].equals("Container") && loadBalancingStrategy != null) {
String containerName = loadBalancingStrategy.selectContainer(getClientInfo(requestor), getContainersInfo());
if (containerName != null) {
result[i] = containerName;
continue;
}
}
AcsJIncompleteComponentSpecEx ex = new AcsJIncompleteComponentSpecEx();
ex.setReason("'" + fieldNames[i] + "' equals '" + ComponentSpec.COMPSPEC_ANY + "'.");
throw ex;
}
// generate name if necessary
if (allowNameGeneration && result[0].endsWith(ComponentSpec.COMPSPEC_ANY)) {
synchronized (this) {
/// @todo not perfect
if (result[0].equals(ComponentSpec.COMPSPEC_ANY))
result[0] = result[1] + "_" + System.currentTimeMillis();
else
// ends with case
result[0] = result[0].substring(0, result[0].length() - 1) + "_" + System.currentTimeMillis();
// flatten hierarchical name (remove IDL separators)
if (result[0].indexOf('/') >= 0)
result[0] = result[0].replaceAll("/", "_");
}
}
StatusHolder statusHolder = new StatusHolder();
// Same exceptions are let flying up
return internalRequestComponent(requestor, result[0], result[1], result[2], result[3], keepAliveTimeHolder.value, statusHolder, true);
}
use of org.omg.CORBA.IntHolder in project ACS by ACS-Community.
the class Helper method createNotificationChannel.
/**
* Tries to create a notification channel (using quality of service and administrative properties
* specified by configQofS() and configAdminProps() respectively).
* If this succeeds, then registers this channel with the naming service.
* <p>
* Should only be invoked when the channel that this supplier or consumer is attempting to connect to
* does not exist.
* However even with prior check for the existence of this channel, a race condition with other suppliers or consumers
* can lead to multiple attempts to create the same channel, which will result in <code>NameAlreadyUsed</code> exception.
* <p>
* Design note: Currently the TAO notification extensions are used to synch channel creation with other clients
* by supplying the channel name to the factory.
* If we want to use only standard NC factories then we'd have to implement our own locking mechanisms in all
* ACS consumer and supplier classes, see http://jira.alma.cl/browse/COMP-2808
*
* @return Reference to the newly created channel.
* @param channelKind
* Kind of the channel as registered with the CORBA naming service.
* @param notifyFactoryName
* Name of the notification service as registered with the CORBA naming service.
* @throws AcsJException
* Standard ACS Java exception.
* @throws NameAlreadyUsed thrown if the channel of this name already exists.
*/
protected EventChannel createNotificationChannel(String channelKind, String notifyFactoryName) throws AcsJException, NameAlreadyUsed {
LOG_NC_ChannelCreated_ATTEMPT.log(m_logger, channelName, notifyFactoryName);
// return value
EventChannel retValue = null;
// to be assigned by factory
channelId = -1;
StopWatch stopwatch = new StopWatch();
try {
initializeNotifyFactory(notifyFactoryName);
// create the channel
// here we use the channel properties taken directly from our channel properties helper object.
// presumably these values come from the ACS configuration database.
IntHolder channelIdHolder = new IntHolder();
retValue = createNotifyChannel_internal(m_channelProperties.configQofS(channelName), m_channelProperties.configAdminProps(channelName), channelIdHolder);
// sanity check
if (retValue == null) {
// a null reference implies we cannot go any further
Throwable cause = new Throwable("Null reference obtained for the '" + channelName + "' channel!");
// TODO: more specific ex type
throw new alma.ACSErrTypeJavaNative.wrappers.AcsJJavaLangEx(cause);
}
channelId = channelIdHolder.value;
// register our new channel with the naming service
try {
NameComponent[] t_NameChannel = { new NameComponent(combineChannelAndDomainName(channelName, domainName), channelKind) };
getNamingService().rebind(t_NameChannel, retValue);
// Create an entry into the Naming Service to store the timestamp of the channel in order to allow
// subscribers to reconnect to the channel (ICT-4730)
int maxNumAttempts = 10;
int nAttempts = maxNumAttempts;
boolean timestampCreated = setChannelTimestamp(retValue);
while (false == timestampCreated && nAttempts > 0) {
try {
Thread.sleep(2000);
} catch (InterruptedException ex1) {
// too bad
}
nAttempts--;
timestampCreated = setChannelTimestamp(retValue);
}
if (false == timestampCreated) {
Throwable cause = new Throwable("Failed to register the timestamp of the channel '" + channelName + "' into the Naming Service after " + String.valueOf(maxNumAttempts) + " attempts");
// TODO: more specific ex type
throw new alma.ACSErrTypeJavaNative.wrappers.AcsJJavaLangEx(cause);
}
} catch (org.omg.CosNaming.NamingContextPackage.NotFound ex) {
// Corba spec: "If already bound, the previous binding must be of type nobject;
// otherwise, a NotFound exception with a why reason of not_object is raised."
String reason = "Failed to register the new channel '" + channelName + "' with the Naming Service: " + ex.why.toString();
AcsJCORBAProblemEx ex2 = new AcsJCORBAProblemEx(ex);
ex2.setInfo(reason);
throw ex2;
}
} catch (org.omg.CosNaming.NamingContextPackage.CannotProceed e) {
// Think there is virtually no chance of this every happening but...
Throwable cause = new Throwable(e.getMessage());
throw new alma.ACSErrTypeCommon.wrappers.AcsJCORBAProblemEx(cause);
} catch (org.omg.CosNaming.NamingContextPackage.InvalidName e) {
// Think there is virtually no chance of this every happening but...
Throwable cause = new Throwable(e.getMessage());
throw new alma.ACSErrTypeCommon.wrappers.AcsJCORBAProblemEx(cause);
} catch (org.omg.CosNotification.UnsupportedQoS e) {
Throwable cause = new Throwable("The quality of service properties specified for the '" + channelName + "' channel are unsupported: " + e.getMessage());
throw new alma.ACSErrTypeCommon.wrappers.AcsJCORBAProblemEx(cause);
}
LOG_NC_ChannelCreated_OK.log(m_logger, channelName, channelId, notifyFactoryName, stopwatch.getLapTimeMillis());
return retValue;
}
use of org.omg.CORBA.IntHolder in project ACS by ACS-Community.
the class NCSubscriber method createProxySupplier.
/**
* Creates the proxy supplier (push-style, for structured events)
* that lives in the Notify server process, managed by the consumer admin object, and
* will later be connected to this client-side subscriber object.
*
* @throws AcsJCORBAProblemEx If creation of the proxy supplier failed.
*/
private StructuredProxyPushSupplier createProxySupplier() throws AcsJCORBAProblemEx {
StructuredProxyPushSupplier ret = null;
String errMsg = null;
// will get assigned "a numeric identifier [...] that is unique among all proxy suppliers [the admin object] has created"
IntHolder proxyIdHolder = new IntHolder();
String randomizedClientName = null;
try {
ProxySupplier proxy = null;
while (proxy == null) {
// See the comments on Consumer#createConsumer() for a nice explanation of why this randomness is happening here
randomizedClientName = Helper.createRandomizedClientName(clientName);
try {
proxy = sharedConsumerAdmin.obtain_named_notification_push_supplier(ClientType.STRUCTURED_EVENT, proxyIdHolder, randomizedClientName);
} catch (NameAlreadyUsed e) {
// Hopefully we won't run into this situation. Still, try to go on in the loop,
// with a different client name next time.
} catch (NameMapError e) {
// Default to the unnamed version
proxy = sharedConsumerAdmin.obtain_notification_push_supplier(ClientType.STRUCTURED_EVENT, proxyIdHolder);
}
}
ret = StructuredProxyPushSupplierHelper.narrow(proxy);
} catch (AdminLimitExceeded ex) {
// See NC spec 3.4.15.10
// If the number of consumers currently connected to the channel with which the target ConsumerAdmin object is associated
// exceeds the value of the MaxConsumers administrative property, the AdminLimitExceeded exception is raised.
String limit = ex.admin_property_err.value.extract_string();
errMsg = "NC '" + channelName + "' is configured for a maximum of " + limit + " subscribers, which does not allow this client to subscribe.";
}
if (ret != null) {
LOG_NC_SupplierProxyCreation_OK.log(logger, proxyIdHolder.value, clientName, randomizedClientName, channelName, getNotificationFactoryName());
} else {
LOG_NC_SupplierProxyCreation_FAIL.log(logger, clientName, channelName, getNotificationFactoryName(), errMsg);
AcsJCORBAProblemEx ex2 = new AcsJCORBAProblemEx();
ex2.setInfo("Failed to create proxy supplier on NC '" + channelName + "' for client '" + clientName + "': " + errMsg);
throw ex2;
}
return ret;
}
use of org.omg.CORBA.IntHolder in project alliance by codice.
the class SampleNsiliClient method getHitCount.
public int getHitCount() throws Exception {
if (catalogMgr != null) {
LOGGER.info("Getting Hit Count From Query...");
HitCountRequest hitCountRequest = catalogMgr.hit_count(QUERY, new NameValue[0]);
IntHolder intHolder = new IntHolder();
hitCountRequest.complete(intHolder);
LOGGER.info("Server responded with {} hit(s). ", intHolder.value);
return intHolder.value;
} else {
LOGGER.warn("CatalogMgr was not initialized, unable to find hit count");
return -1;
}
}
use of org.omg.CORBA.IntHolder in project alliance by codice.
the class NsiliSource method submitQuery.
/**
* Submits and completes a BQS Query to the STANAG 4559 server and returns the response.
*
* @param queryRequest - the query request generated from the search
* @param query - a BQS query
* @param resultAttributes - a list of desired result attributes
* @param sortAttributes - a list of attributes to sort by
* @param properties - a list of properties for the query
* @return - the server's response
*/
private SourceResponse submitQuery(QueryRequest queryRequest, org.codice.alliance.nsili.common.GIAS.Query query, String[] resultAttributes, SortAttribute[] sortAttributes, NameValue[] properties) {
DAGListHolder dagListHolder = new DAGListHolder();
SourceResponseImpl sourceResponse = null;
long numHits = 0;
try {
synchronized (queryLockObj) {
LOGGER.debug("{} : Submit query: {}", sourceId, query.bqs_query);
LOGGER.debug("{} : Requesting result attributes: {}", sourceId, resultAttributes);
LOGGER.debug("{} : Sort Attributes: {}", sourceId, sortAttributes);
LOGGER.debug("{} : Properties: {}", sourceId, properties);
HitCountRequest hitCountRequest = catalogMgr.hit_count(query, properties);
IntHolder hitHolder = new IntHolder();
hitCountRequest.complete(hitHolder);
numHits = hitHolder.value;
SubmitQueryRequest submitQueryRequest;
if (hitHolder.value > 1) {
submitQueryRequest = catalogMgr.submit_query(query, resultAttributes, sortAttributes, properties);
} else {
submitQueryRequest = catalogMgr.submit_query(query, resultAttributes, new SortAttribute[0], new NameValue[0]);
}
submitQueryRequest.set_user_info(ddfOrgName);
submitQueryRequest.set_number_of_hits(maxHitCount);
submitQueryRequest.complete_DAG_results(dagListHolder);
}
} catch (ProcessingFault | SystemFault | InvalidInputParameter e) {
LOGGER.debug("{} : Unable to query source. {}", sourceId, NsilCorbaExceptionUtil.getExceptionDetails(e), e);
}
if (dagListHolder.value != null) {
List<Result> results = new ArrayList<>();
String id = getId();
List<Future> futures = new ArrayList<>(dagListHolder.value.length);
for (DAG dag : dagListHolder.value) {
Callable<Result> convertRunner = () -> {
DAGConverter dagConverter = new DAGConverter(resourceReader);
dagConverter.setNsiliMetacardType(nsiliMetacardType);
Metacard card = dagConverter.convertDAG(dag, swapCoordinates, id);
if (card != null) {
if (LOGGER.isTraceEnabled()) {
DAGConverter.logMetacard(card, getId());
}
return new ResultImpl(card);
} else {
LOGGER.debug("{} : Unable to convert DAG to metacard, returned card is null", getId());
}
return null;
};
futures.add(completionService.submit(convertRunner));
}
Future<Result> completedFuture;
while (!futures.isEmpty()) {
try {
completedFuture = completionService.take();
futures.remove(completedFuture);
results.add(completedFuture.get());
} catch (ExecutionException e) {
LOGGER.debug("Unable to create result.", e);
} catch (InterruptedException ignore) {
// ignore
}
}
sourceResponse = new SourceResponseImpl(queryRequest, results, numHits);
} else {
LOGGER.debug("{} : Source returned empty DAG list", getId());
}
return sourceResponse;
}
Aggregations