use of org.opensearch.ad.model.ModelProfile in project anomaly-detection by opensearch-project.
the class PriorityCache method getModelProfile.
/**
* Gets an entity's model state
*
* @param detectorId detector id
* @param entityModelId entity model id
* @return the model state
*/
@Override
public Optional<ModelProfile> getModelProfile(String detectorId, String entityModelId) {
CacheBuffer cacheBuffer = activeEnities.get(detectorId);
if (cacheBuffer != null && cacheBuffer.getModel(entityModelId).isPresent()) {
EntityModel model = cacheBuffer.getModel(entityModelId).get();
Entity entity = null;
if (model != null && model.getEntity().isPresent()) {
entity = model.getEntity().get();
}
return Optional.of(new ModelProfile(entityModelId, entity, cacheBuffer.getMemoryConsumptionPerEntity()));
}
return Optional.empty();
}
use of org.opensearch.ad.model.ModelProfile in project anomaly-detection by opensearch-project.
the class ProfileNodeResponse method toXContent.
/**
* Converts profile to xContent
*
* @param builder XContentBuilder
* @param params Params
* @return XContentBuilder
* @throws IOException thrown by builder for invalid field
*/
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(CommonName.MODEL_SIZE_IN_BYTES);
for (Map.Entry<String, Long> entry : modelSize.entrySet()) {
builder.field(entry.getKey(), entry.getValue());
}
builder.endObject();
builder.field(CommonName.SHINGLE_SIZE, shingleSize);
builder.field(CommonName.ACTIVE_ENTITIES, activeEntities);
builder.field(CommonName.TOTAL_UPDATES, totalUpdates);
builder.field(CommonName.MODEL_COUNT, modelCount);
builder.startArray(CommonName.MODELS);
for (ModelProfile modelProfile : modelProfiles) {
builder.startObject();
modelProfile.toXContent(builder, params);
builder.endObject();
}
builder.endArray();
return builder;
}
use of org.opensearch.ad.model.ModelProfile in project anomaly-detection by opensearch-project.
the class ProfileResponse method writeTo.
@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
out.writeVInt(modelProfile.length);
if (Bwc.supportMultiCategoryFields(out.getVersion())) {
for (ModelProfileOnNode profile : modelProfile) {
profile.writeTo(out);
}
} else {
for (ModelProfileOnNode profile : modelProfile) {
ModelProfile oldFormatModelProfile = profile.getModelProfile();
oldFormatModelProfile.writeTo(out);
}
}
out.writeInt(shingleSize);
out.writeString(coordinatingNode);
out.writeVLong(totalSizeInBytes);
out.writeVLong(activeEntities);
out.writeVLong(totalUpdates);
if (Bwc.supportMultiCategoryFields(out.getVersion())) {
out.writeVLong(modelCount);
}
}
use of org.opensearch.ad.model.ModelProfile in project anomaly-detection by opensearch-project.
the class EntityProfileTransportAction method doExecute.
@Override
protected void doExecute(Task task, EntityProfileRequest request, ActionListener<EntityProfileResponse> listener) {
String adID = request.getAdID();
Entity entityValue = request.getEntityValue();
Optional<String> modelIdOptional = entityValue.getModelId(adID);
if (false == modelIdOptional.isPresent()) {
listener.onFailure(new AnomalyDetectionException(adID, NO_MODEL_ID_FOUND_MSG));
return;
}
// we use entity's toString (e.g., app_0) to find its node
// This should be consistent with how we land a model node in AnomalyResultTransportAction
Optional<DiscoveryNode> node = hashRing.getOwningNodeWithSameLocalAdVersionForRealtimeAD(entityValue.toString());
if (false == node.isPresent()) {
listener.onFailure(new AnomalyDetectionException(adID, NO_NODE_FOUND_MSG));
return;
}
String nodeId = node.get().getId();
String modelId = modelIdOptional.get();
DiscoveryNode localNode = clusterService.localNode();
if (localNode.getId().equals(nodeId)) {
EntityCache cache = cacheProvider.get();
Set<EntityProfileName> profilesToCollect = request.getProfilesToCollect();
EntityProfileResponse.Builder builder = new EntityProfileResponse.Builder();
if (profilesToCollect.contains(EntityProfileName.ENTITY_INFO)) {
builder.setActive(cache.isActive(adID, modelId));
builder.setLastActiveMs(cache.getLastActiveMs(adID, modelId));
}
if (profilesToCollect.contains(EntityProfileName.INIT_PROGRESS) || profilesToCollect.contains(EntityProfileName.STATE)) {
builder.setTotalUpdates(cache.getTotalUpdates(adID, modelId));
}
if (profilesToCollect.contains(EntityProfileName.MODELS)) {
Optional<ModelProfile> modleProfile = cache.getModelProfile(adID, modelId);
if (modleProfile.isPresent()) {
builder.setModelProfile(new ModelProfileOnNode(nodeId, modleProfile.get()));
}
}
listener.onResponse(builder.build());
} else if (request.remoteAddress() == null) {
// redirect if request comes from local host.
// If a request comes from remote machine, it is already redirected.
// One redirection should be enough.
// We don't want a potential infinite loop due to any bug and thus give up.
LOG.info("Sending entity profile request to {} for detector {}, entity {}", nodeId, adID, entityValue);
try {
transportService.sendRequest(node.get(), EntityProfileAction.NAME, request, option, new TransportResponseHandler<EntityProfileResponse>() {
@Override
public EntityProfileResponse read(StreamInput in) throws IOException {
return new EntityProfileResponse(in);
}
@Override
public void handleResponse(EntityProfileResponse response) {
listener.onResponse(response);
}
@Override
public void handleException(TransportException exp) {
listener.onFailure(exp);
}
@Override
public String executor() {
return ThreadPool.Names.SAME;
}
});
} catch (Exception e) {
LOG.error(String.format(Locale.ROOT, "Fail to get entity profile for detector {}, entity {}", adID, entityValue), e);
listener.onFailure(new AnomalyDetectionException(adID, FAIL_TO_GET_ENTITY_PROFILE_MSG, e));
}
} else {
// Prior to Opensearch 1.1, we map a node using model id in the profile API.
// This is not consistent how we map node in AnomalyResultTransportAction, where
// we use entity values. We fixed that bug in Opensearch 1.1. But this can cause
// issue when a request involving an old node according to model id.
// The new node finds the entity value does not map to itself, so it redirects to another node.
// The redirection can cause an infinite loop. This branch breaks the loop and gives up.
LOG.error("Fail to get entity profile for detector {}, entity {}. Maybe because old and new node" + " are using different keys for the hash ring.", adID, entityValue);
listener.onFailure(new AnomalyDetectionException(adID, FAIL_TO_GET_ENTITY_PROFILE_MSG));
}
}
use of org.opensearch.ad.model.ModelProfile in project anomaly-detection by opensearch-project.
the class EntityProfileResponse method writeTo.
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeOptionalBoolean(isActive);
out.writeLong(lastActiveMs);
out.writeLong(totalUpdates);
if (modelProfile != null) {
out.writeBoolean(true);
if (Bwc.supportMultiCategoryFields(out.getVersion())) {
modelProfile.writeTo(out);
} else {
ModelProfile oldFormatModelProfile = modelProfile.getModelProfile();
oldFormatModelProfile.writeTo(out);
}
} else {
out.writeBoolean(false);
}
}
Aggregations