release version 1.10.0
This commit is contained in:
@ -0,0 +1,84 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.platform.core.producer.audit;
|
||||
|
||||
import org.osgi.framework.Filter;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
import org.osgi.framework.InvalidSyntaxException;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ru.entaxy.audit.data.AuditEvent;
|
||||
import ru.entaxy.audit.data.Outcome;
|
||||
import ru.entaxy.audit.data.Severity;
|
||||
import ru.entaxy.audit.service.EventConverter;
|
||||
import ru.entaxy.audit.service.EventConverterInfo;
|
||||
import ru.entaxy.audit.service.InterpretedEvent;
|
||||
import ru.entaxy.audit.service.jmx.JMXInvokeEvent;
|
||||
|
||||
@Component(service = EventConverter.class, immediate = true)
|
||||
@EventConverterInfo(classes = {JMXInvokeEvent.class})
|
||||
public class ObjectProducerEventConverter implements EventConverter {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ObjectProducerEventConverter.class);
|
||||
|
||||
@Override
|
||||
public <T extends InterpretedEvent> AuditEvent convert(T event) {
|
||||
if (!JMXInvokeEvent.class.equals(event.getClass()))
|
||||
return null;
|
||||
JMXInvokeEvent invokeEvent = (JMXInvokeEvent) event;
|
||||
Filter filter;
|
||||
try {
|
||||
filter = FrameworkUtil
|
||||
.createFilter(
|
||||
"(&(jmx.domain=ru.entaxy.esb)(jmx.methodName=createObjectByInstructions)(jmx.property.factoryId=*))");
|
||||
} catch (InvalidSyntaxException e) {
|
||||
LOG.error("Error creating filter", e);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!filter.matches(event.getEventEssense())) {
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Event not matches: {}", event.toString());
|
||||
return null;
|
||||
}
|
||||
|
||||
String objectId = invokeEvent.getMethodParams()[0].toString();
|
||||
String factoryId = event.getEventEssense().getOrDefault("jmx.property.factoryId", "unknown").toString();
|
||||
|
||||
AuditEvent result = AuditEvent.AuditLoggingEventBuilder.getInstance()
|
||||
.target("ENTAXY OBJECTS")
|
||||
.outcome(Outcome.SUCCESS)
|
||||
.message(String.format("Object %s of factory %s was changed", objectId, factoryId))
|
||||
.severity(Severity.INFO)
|
||||
.category(String.format("%s:%s", objectId, factoryId))
|
||||
.build();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,174 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.platform.core.producer.executor.generationmodel;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import ru.entaxy.platform.base.objects.factory.EntaxyFactory;
|
||||
import ru.entaxy.platform.base.support.JSONUtils;
|
||||
import ru.entaxy.platform.core.producer.executor.objectmodel.FactoredObject;
|
||||
import ru.entaxy.platform.core.producer.executor.objectmodel.FactoredObjectRef;
|
||||
|
||||
public class GeneratedObjectsPublishDataStorage {
|
||||
|
||||
Map<String, JsonObject> publishData = new HashMap<>();
|
||||
|
||||
public JsonObject getPublishData(String objectUuid) {
|
||||
return publishData.getOrDefault(objectUuid, new JsonObject());
|
||||
}
|
||||
|
||||
public JsonObject generatePublishData(FactoredObject factoredObject, EntaxyFactory factory, String outputType) {
|
||||
|
||||
JsonObject result = new JsonObject();
|
||||
JsonObject originObject = factoredObject.origin;
|
||||
|
||||
result = getFilteredObject(originObject, originObject, factory, outputType);
|
||||
|
||||
publishData.put(factoredObject.getUuid(), result);
|
||||
|
||||
return getPublishData(factoredObject.getUuid());
|
||||
}
|
||||
|
||||
protected JsonObject getFilteredObject(JsonObject originObject, JsonObject rootObject, EntaxyFactory factory,
|
||||
String outputType) {
|
||||
|
||||
JsonObject result = new JsonObject();
|
||||
|
||||
Map<String, JsonObject> factoryFields = factory.getOutputByType(outputType).getFields().stream()
|
||||
.collect(Collectors.toMap(fi -> fi.getName(), fi -> fi.getJsonOrigin()));
|
||||
|
||||
for (Entry<String, JsonElement> entry : originObject.entrySet()) {
|
||||
String name = entry.getKey();
|
||||
|
||||
if (FactoredObject.EMBEDDED_FIELD.equals(name) || FactoredObject.IGNORE_SECTION.equals(name)
|
||||
|| (name.startsWith("##") && !name.startsWith("##config")))
|
||||
continue;
|
||||
|
||||
boolean skip = false;
|
||||
|
||||
// check @INTERNAL directive via factory data
|
||||
JsonObject joField = factoryFields.getOrDefault(name, new JsonObject());
|
||||
if (joField.has(EntaxyFactory.CONFIGURATION.DIRECTIVES.INTERNAL)) {
|
||||
try {
|
||||
skip = joField.get(EntaxyFactory.CONFIGURATION.DIRECTIVES.INTERNAL).getAsBoolean();
|
||||
} catch (Exception ignore) {
|
||||
// NOOP
|
||||
}
|
||||
}
|
||||
if (skip)
|
||||
continue;
|
||||
|
||||
// check @INTERNAL directive via object data
|
||||
JsonElement je = entry.getValue();
|
||||
if (je.isJsonObject()) {
|
||||
JsonObject jo = je.getAsJsonObject();
|
||||
|
||||
if (jo.has(EntaxyFactory.CONFIGURATION.DIRECTIVES.INTERNAL)) {
|
||||
try {
|
||||
skip = jo.get(EntaxyFactory.CONFIGURATION.DIRECTIVES.INTERNAL).getAsBoolean();
|
||||
} catch (Exception e) {
|
||||
// NOOP
|
||||
}
|
||||
if (skip)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// check for @PUBLISH_UNRESOLVED directive
|
||||
if (joField.has(GenerationModel.DIRECTIVE_PUBLISH_URESOLVED)) {
|
||||
|
||||
JsonElement publishUnresolved = joField.get(GenerationModel.DIRECTIVE_PUBLISH_URESOLVED);
|
||||
String publishUnresolvedValue = publishUnresolved.getAsString();
|
||||
|
||||
boolean publishRef = publishUnresolvedValue.equalsIgnoreCase(GenerationModel.PUBLISH_UNRESOLVED_REF);
|
||||
boolean publishObject =
|
||||
publishUnresolvedValue.equalsIgnoreCase(GenerationModel.PUBLISH_UNRESOLVED_OBJECT);
|
||||
|
||||
if (publishRef || publishObject) {
|
||||
|
||||
JsonObject unresolvedRef = null;
|
||||
|
||||
// first we must get unresolved ref
|
||||
if (je.isJsonObject()) {
|
||||
if (FactoredObjectRef.isRef(je.getAsJsonObject())) {
|
||||
// ref is found
|
||||
unresolvedRef = je.getAsJsonObject();
|
||||
}
|
||||
}
|
||||
if (unresolvedRef == null) {
|
||||
JsonElement unresolved = JSONUtils.findElementExt(rootObject,
|
||||
String.format("%s.properties.%s", GenerationModel.UNRESOLVED_CONTAINER_NAME, name));
|
||||
if (unresolved != null && unresolved.isJsonObject())
|
||||
unresolvedRef = unresolved.getAsJsonObject();
|
||||
}
|
||||
|
||||
if (unresolvedRef != null) {
|
||||
if (publishRef) {
|
||||
result.add(name, unresolvedRef);
|
||||
continue;
|
||||
} else {
|
||||
|
||||
// get target object
|
||||
JsonElement uuid = unresolvedRef.get(FactoredObjectRef.TARGET_UUID_FIELD);
|
||||
if (uuid.isJsonPrimitive()) {
|
||||
String objectUuid = uuid.getAsString();
|
||||
if (publishData.containsKey(objectUuid)) {
|
||||
JsonObject toPublish = publishData.get(objectUuid);
|
||||
// we nust remove 'isEmbedded'
|
||||
toPublish.remove(FactoredObject.IS_EMBEDDED_FIELD);
|
||||
result.add(name, toPublish);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (je.isJsonObject()) {
|
||||
JsonObject filtered = getFilteredObject(je.getAsJsonObject(), rootObject, factory, outputType);
|
||||
if (filtered != null)
|
||||
result.add(name, filtered);
|
||||
} else {
|
||||
result.add(name, je);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,186 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producer-core
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.platform.core.producer.impl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.osgi.service.component.ComponentContext;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.CollectionType;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
import org.osgi.service.component.annotations.ReferenceCardinality;
|
||||
import org.osgi.service.component.annotations.ReferencePolicy;
|
||||
import org.osgi.service.component.annotations.ReferencePolicyOption;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import ru.entaxy.esb.platform.runtime.base.extensions.api.EntaxyExtension;
|
||||
import ru.entaxy.esb.platform.runtime.base.extensions.api.EntaxyExtensionsAware;
|
||||
import ru.entaxy.platform.base.objects.factory.EntaxyFactory;
|
||||
import ru.entaxy.platform.base.support.JSONUtils;
|
||||
import ru.entaxy.platform.core.producer.api.EntaxyProducer;
|
||||
import ru.entaxy.platform.core.producer.wrapper.AbstractFactoryWrapper;
|
||||
import ru.entaxy.platform.core.producer.wrapper.DefaultFactoryWrapper;
|
||||
|
||||
@Component(service = {EntaxyProducer.class}, immediate = true, name = "UniformExtendableProducer")
|
||||
public class UniformExtendableProducer extends CommonObjectProducer implements EntaxyExtensionsAware {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(UniformExtendableProducer.class);
|
||||
|
||||
public static final String PRODUCER_EXTENSION_ATTR_SUPPORTED_TYPES = "supportedTypes";
|
||||
|
||||
public static final String PRODUCER_EXTENSION_PATH = "producer";
|
||||
public static final String PRODUCER_EXTENSION_NAME = "config.json";
|
||||
|
||||
public static final String PRODUCER_EXTENSION_KEY = PRODUCER_EXTENSION_PATH + "/" + PRODUCER_EXTENSION_NAME;
|
||||
|
||||
protected Map<EntaxyExtension, List<String>> extensionsToSupportedTypesMap = new HashMap<>();
|
||||
|
||||
protected Object extensionsLock = new Object();
|
||||
|
||||
protected ComponentContext componentContext;
|
||||
|
||||
protected List<EntaxyFactory> availableFactories = new ArrayList<>();
|
||||
|
||||
protected Object factoriesLock = new Object();
|
||||
|
||||
@Activate
|
||||
public void activate(ComponentContext componentContext) {
|
||||
this.componentContext = componentContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addExtension(EntaxyExtension entaxyExtension) {
|
||||
if (!entaxyExtension.getResources().containsKey(PRODUCER_EXTENSION_KEY))
|
||||
return;
|
||||
|
||||
synchronized (extensionsLock) {
|
||||
try {
|
||||
JsonObject config =
|
||||
JSONUtils.getJsonRootObject(entaxyExtension.getResources().get(PRODUCER_EXTENSION_KEY));
|
||||
if (!config.has(PRODUCER_EXTENSION_ATTR_SUPPORTED_TYPES))
|
||||
return;
|
||||
JsonArray ja = config.get(PRODUCER_EXTENSION_ATTR_SUPPORTED_TYPES).getAsJsonArray();
|
||||
if (ja.size() == 0)
|
||||
return;
|
||||
final List<String> list = new ArrayList<>();
|
||||
for (int i = 0; i < ja.size(); i++) {
|
||||
JsonElement je = ja.get(i);
|
||||
if (!je.isJsonPrimitive())
|
||||
continue;
|
||||
if (!je.getAsJsonPrimitive().isString())
|
||||
continue;
|
||||
list.add(je.getAsJsonPrimitive().getAsString());
|
||||
}
|
||||
if (!list.isEmpty())
|
||||
this.extensionsToSupportedTypesMap.put(entaxyExtension, list);
|
||||
calculateSupportedTypes();
|
||||
rescanAvailables();
|
||||
} catch (IOException e) {
|
||||
log.error(
|
||||
"Error reading resource: [" + entaxyExtension.getResources().get(PRODUCER_EXTENSION_KEY) + "]",
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeExtension(EntaxyExtension entaxyExtension) {
|
||||
if (extensionsToSupportedTypesMap.containsKey(entaxyExtension)) {
|
||||
synchronized (extensionsLock) {
|
||||
extensionsToSupportedTypesMap.remove(entaxyExtension);
|
||||
calculateSupportedTypes();
|
||||
rescanExisting();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void rescanAvailables() {
|
||||
synchronized (factoriesLock) {
|
||||
for (EntaxyFactory factory : availableFactories)
|
||||
if (!factories.containsKey(factory))
|
||||
addFactory(factory);
|
||||
}
|
||||
}
|
||||
|
||||
protected void rescanExisting() {
|
||||
synchronized (factoriesLock) {
|
||||
List<EntaxyFactory> existing = new ArrayList<>(factories.values());
|
||||
for (EntaxyFactory factory : existing)
|
||||
if (!isTypeSupported(factory.getType()))
|
||||
super.removeFactory(factory);
|
||||
}
|
||||
}
|
||||
|
||||
protected void calculateSupportedTypes() {
|
||||
final List<String> typesList = new ArrayList<>();
|
||||
supportedTypes.clear();
|
||||
supportedTypesPatterns.clear();
|
||||
extensionsToSupportedTypesMap.values().stream()
|
||||
.forEach(list -> typesList.addAll(list));
|
||||
setSupportedTypes(typesList);
|
||||
}
|
||||
|
||||
@Reference(bind = "addFactory", unbind = "removeFactory", cardinality = ReferenceCardinality.MULTIPLE,
|
||||
collectionType = CollectionType.SERVICE, policy = ReferencePolicy.DYNAMIC,
|
||||
policyOption = ReferencePolicyOption.GREEDY)
|
||||
public void addFactory(EntaxyFactory factory) {
|
||||
synchronized (factoriesLock) {
|
||||
if (!availableFactories.contains(factory))
|
||||
availableFactories.add(factory);
|
||||
}
|
||||
doAddFactory(factory);
|
||||
}
|
||||
|
||||
// WE MUST DECLARE IT for @Reference annotation processor
|
||||
@Override
|
||||
public void removeFactory(EntaxyFactory factory) {
|
||||
synchronized (factoriesLock) {
|
||||
availableFactories.remove(factory);
|
||||
}
|
||||
super.removeFactory(factory);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractFactoryWrapper doAddFactory(EntaxyFactory factory) {
|
||||
AbstractFactoryWrapper wrapper = super.doAddFactory(factory, DefaultFactoryWrapper.class);
|
||||
if (wrapper != null)
|
||||
wrapper.setGenerationProcessor(this);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,290 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producing-config-support
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.platform.core.producer.config;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.osgi.service.component.ComponentContext;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
import org.osgi.service.component.annotations.ReferenceCardinality;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
|
||||
import ru.entaxy.esb.platform.runtime.base.connecting.generator.Generated;
|
||||
import ru.entaxy.platform.base.objects.EntaxyObject;
|
||||
import ru.entaxy.platform.base.objects.EntaxyObject.FIELDS;
|
||||
import ru.entaxy.platform.base.objects.factory.EntaxyFactory;
|
||||
import ru.entaxy.platform.base.objects.factory.EntaxyFactory.OutputInfo;
|
||||
import ru.entaxy.platform.base.objects.factory.exceptions.FactoryNotFoundException;
|
||||
import ru.entaxy.platform.base.support.CommonUtils;
|
||||
import ru.entaxy.platform.base.support.JSONUtils;
|
||||
import ru.entaxy.platform.config.runtime.ObjectConfig;
|
||||
import ru.entaxy.platform.config.runtime.ObjectConfigHelper;
|
||||
import ru.entaxy.platform.config.runtime.ObjectConfig.FactoryOutputConfiguration;
|
||||
import ru.entaxy.platform.core.producer.api.EntaxyProducerService;
|
||||
import ru.entaxy.platform.core.producer.api.ExecutionPlan.ExecutionPlanUpdate;
|
||||
import ru.entaxy.platform.core.producer.api.ProducerResult;
|
||||
import ru.entaxy.platform.core.producer.api.ProducerResult.CommandResult;
|
||||
import ru.entaxy.platform.core.producer.api.ProducingCommandExecutor;
|
||||
import ru.entaxy.platform.core.producer.executor.AbstractCommandExecutor;
|
||||
import ru.entaxy.platform.core.producer.executor.objectmodel.FactoredObject;
|
||||
import ru.entaxy.platform.core.producer.executor.objectmodel.FactoredObjectProxy;
|
||||
import ru.entaxy.platform.core.producer.executor.objectmodel.FactoredObjectRef;
|
||||
import ru.entaxy.platform.core.producer.executor.objectmodel.ObjectModel;
|
||||
|
||||
// @Component(service = ProducingCommandExecutor.class, immediate = true)
|
||||
// @CommandExecutor(id = "add-config", predecessors = {"enrich"}, descendants = {"validate"})
|
||||
public class AddConfigCommand2 extends AbstractCommandExecutor implements ProducingCommandExecutor {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(AddConfigCommand2.class);
|
||||
|
||||
@Reference(cardinality = ReferenceCardinality.MANDATORY)
|
||||
EntaxyProducerService entaxyProducerServiceLocal;
|
||||
|
||||
public AddConfigCommand2() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
protected AddConfigCommand2(EntaxyProducerService entaxyProducerService) {
|
||||
super(entaxyProducerService);
|
||||
}
|
||||
|
||||
@Activate
|
||||
public void activate(ComponentContext componentContext) {
|
||||
this.entaxyProducerService = this.entaxyProducerServiceLocal;
|
||||
this.entaxyProducerService.registerCommand(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doExecute(ProducerResult currentResult, CommandResult commandResult,
|
||||
Map<String, Object> instructions) throws Exception {
|
||||
|
||||
printOutput("\n\n\t== ADD-CONFIG == \n\n");
|
||||
|
||||
ObjectModel objectModel = currentResult.findResultObject(ObjectModel.class);
|
||||
objectModel.startTracking();
|
||||
|
||||
JsonObject incomingJson = objectModel.getJsonCurrent().deepCopy();
|
||||
|
||||
for (FactoredObject fo : objectModel.objects) {
|
||||
|
||||
// skip proxies
|
||||
if (fo instanceof FactoredObjectProxy)
|
||||
continue;
|
||||
|
||||
log.debug("OBJECT :: {}/{}", fo.getObjectId(), fo.getObjectType());
|
||||
|
||||
String factoryId = fo.factoryId;
|
||||
|
||||
EntaxyFactory factory = entaxyProducerService.findFactoryById(factoryId);
|
||||
if (factory == null)
|
||||
throw new FactoryNotFoundException(factoryId);
|
||||
|
||||
String output = fo.getOutputType();
|
||||
log.debug("OUTPUT :: {}", output);
|
||||
|
||||
OutputInfo oi = CommonUtils.isValid(output) ? factory.getOutputByType(output) : factory.getDefaultOutput();
|
||||
Map<String, Object> config = oi.getConfig();
|
||||
if ((config == null) || (config.isEmpty()))
|
||||
continue;
|
||||
|
||||
String val = config.getOrDefault(ObjectConfig.CONFIGURABLE_ATTRIBUTE_NAME, "false").toString();
|
||||
Boolean configurable = Boolean.valueOf(val);
|
||||
if (!configurable)
|
||||
continue;
|
||||
|
||||
JsonObject objectOrigin = fo.origin;
|
||||
JsonObject objectProperties = objectOrigin.get(FIELDS.PROPERTIES).getAsJsonObject();
|
||||
|
||||
if (objectProperties.has(ObjectConfig.CONFIG_FIELD_NAME))
|
||||
continue;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
Generated g = this.entaxyProducerService.findFactoryById("common-config")
|
||||
.generate("config-field", "private", new HashMap<String, Object>() {
|
||||
{
|
||||
put(FIELDS.FACTORY_ID, "common-config");
|
||||
put(ObjectConfig.TARGET_FACTORY_FIELD_NAME, fo.factoryId);
|
||||
put(ObjectConfig.TARGET_TYPE_FIELD_NAME, fo.getObjectType());
|
||||
put(ObjectConfig.TARGET_ID_FIELD_NAME, fo.getObjectId());
|
||||
put(ObjectConfig.TARGET_OUTPUT_FIELD_NAME, fo.getOutputType());
|
||||
}
|
||||
});
|
||||
|
||||
objectProperties.add(ObjectConfig.CONFIG_FIELD_NAME, JSONUtils.getJsonRootObject(g.getObject().toString()));
|
||||
objectModel.setDirty();
|
||||
|
||||
}
|
||||
|
||||
for (FactoredObjectRef ref : objectModel.refs) {
|
||||
// process external refs and replace ref to object with ref to config if
|
||||
// - ref is not marked 'directValueOnly'
|
||||
// - the referenced object has config
|
||||
// - the referenced field is configurable
|
||||
|
||||
// if (!ref.isExternal())
|
||||
// continue;
|
||||
|
||||
log.debug("REF :: " + ref.relativePath);
|
||||
|
||||
if (ObjectConfigHelper.getInstance().isDirectValueOnly(ref))
|
||||
continue;
|
||||
|
||||
String objectId = ref.getTargetId();
|
||||
String objectType = ref.getTargetType();
|
||||
|
||||
log.debug("TO :: " + objectId + ":" + objectType);
|
||||
log.debug("DEFINED IN :: " + ref.definedIn.getObjectId());
|
||||
|
||||
String refField = ref.getOrDefault(FIELDS.REF_FIELD, FIELDS.OBJECT_ID).toString();
|
||||
if (FIELDS.OBJECT_ID.equals(refField))
|
||||
// objectId can't be configured
|
||||
continue;
|
||||
|
||||
// skip if it's already config
|
||||
if (ObjectConfig.CONFIG_OBJECT_TYPE.equals(objectType))
|
||||
continue;
|
||||
|
||||
String configurationPid = ObjectConfig.getConfigurationPid(objectId, objectType);
|
||||
|
||||
String factoryId = null;
|
||||
|
||||
JsonElement newTargetId = null;
|
||||
|
||||
if (ref.isExternal()) {
|
||||
|
||||
EntaxyObject theObject = ObjectConfigHelper.getInstance().findObject(objectId, objectType);
|
||||
if (theObject == null)
|
||||
// referenced object not found
|
||||
continue;
|
||||
|
||||
factoryId = theObject.getFactoryId();
|
||||
|
||||
EntaxyObject configObject = ObjectConfigHelper.getInstance()
|
||||
.findObject(configurationPid, ObjectConfig.CONFIG_OBJECT_TYPE);
|
||||
if (configObject == null)
|
||||
// config for referenced object not found
|
||||
continue;
|
||||
|
||||
newTargetId = new JsonPrimitive(configurationPid);
|
||||
|
||||
} else {
|
||||
|
||||
log.debug("EXTERNAL :: false");
|
||||
|
||||
Optional<FactoredObject> theObjectOpt = objectModel.objects.stream()
|
||||
.filter(obj -> objectId.equals(obj.getObjectId())).findFirst();
|
||||
if (!theObjectOpt.isPresent())
|
||||
continue;
|
||||
|
||||
FactoredObject theObject = theObjectOpt.get();
|
||||
|
||||
log.debug("TARGET OBJECT :: found");
|
||||
|
||||
factoryId = theObject.factoryId;
|
||||
|
||||
Optional<FactoredObjectRef> configRefOpt = objectModel.refs.stream()
|
||||
.filter(r -> r.definedIn.equals(theObject))
|
||||
.filter(r -> r.relativePath.endsWith(ObjectConfig.CONFIG_FIELD_NAME))
|
||||
.findFirst();
|
||||
|
||||
if (!configRefOpt.isPresent())
|
||||
continue;
|
||||
|
||||
log.debug("REF TO CONFIG :: found; TARGET :: " + configRefOpt.get().getTargetId());
|
||||
|
||||
Optional<FactoredObject> configObjectOpt = objectModel.objects.stream()
|
||||
.filter(obj -> obj.getObjectId().equals(configRefOpt.get().getTargetId()))
|
||||
.findFirst();
|
||||
if (!configObjectOpt.isPresent())
|
||||
continue;
|
||||
|
||||
log.debug("CONFIG OBJECT :: found");
|
||||
|
||||
newTargetId = new JsonPrimitive(configObjectOpt.get().getObjectId());
|
||||
}
|
||||
|
||||
|
||||
EntaxyFactory entaxyFactory = entaxyProducerService.findFactoryById(factoryId);
|
||||
if (entaxyFactory == null)
|
||||
// factory for referenced object not found
|
||||
continue;
|
||||
|
||||
FactoryOutputConfiguration conf = FactoryOutputConfiguration.read(entaxyFactory,
|
||||
EntaxyFactory.CONFIGURATION.OUTPUTS.OUTPUT_TYPE_INIT);
|
||||
if (!conf.isConfigurable)
|
||||
continue;
|
||||
|
||||
|
||||
if (!ObjectConfig.isConfigurable(entaxyFactory, EntaxyFactory.CONFIGURATION.OUTPUTS.OUTPUT_TYPE_INIT,
|
||||
refField, conf.defaultFieldsConfigurable, conf.configurations))
|
||||
// field is not configurable
|
||||
continue;
|
||||
|
||||
JSONUtils.replaceValue(ref.origin, FIELDS.OBJECT_TYPE, new JsonPrimitive(ObjectConfig.CONFIG_OBJECT_TYPE));
|
||||
JSONUtils.replaceValue(ref.origin, FactoredObjectRef.TARGET_TYPE_FIELD,
|
||||
new JsonPrimitive(ObjectConfig.CONFIG_OBJECT_TYPE));
|
||||
JSONUtils.replaceValue(ref.origin, FactoredObjectRef.TARGET_ID_FIELD, newTargetId);
|
||||
|
||||
// and we must generate ref to config to merge to main object
|
||||
JSONUtils.replaceValue(ref.origin, FIELDS.IS_REF_BY_VALUE_ONLY, new JsonPrimitive(false));
|
||||
|
||||
objectModel.setDirty();
|
||||
|
||||
}
|
||||
|
||||
if (objectModel.stopTracking()) {
|
||||
|
||||
// remove ##embedded
|
||||
for (FactoredObject fo : objectModel.objects)
|
||||
fo.origin.remove(FactoredObject.EMBEDDED_FIELD);
|
||||
|
||||
|
||||
commandResult.planUpdate = ExecutionPlanUpdate.create()
|
||||
// .updateInstructions().target("enrich").value("skip", true).complete()
|
||||
.reset().target("analyze").complete();
|
||||
}
|
||||
|
||||
JsonObject outgoingJson = objectModel.getJsonCurrent();
|
||||
|
||||
printOutput("\n== INCOMING JSON ==\n");
|
||||
printOutput(incomingJson.toString());
|
||||
printOutput("\n== OUTGOING JSON ==\n");
|
||||
printOutput(outgoingJson.toString());
|
||||
|
||||
commandResult.resultObject(outgoingJson);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,194 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producing-config-support
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.platform.core.producer.config;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.osgi.service.component.annotations.CollectionType;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
import org.osgi.service.component.annotations.ReferenceCardinality;
|
||||
import org.osgi.service.component.annotations.ReferencePolicy;
|
||||
import org.osgi.service.component.annotations.ReferencePolicyOption;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ru.entaxy.esb.platform.runtime.base.connecting.generator.Generated;
|
||||
import ru.entaxy.platform.base.objects.EntaxyObject;
|
||||
import ru.entaxy.platform.base.objects.factory.EntaxyFactory;
|
||||
import ru.entaxy.platform.base.objects.factory.EntaxyFactoryException;
|
||||
import ru.entaxy.platform.base.support.CommonUtils;
|
||||
import ru.entaxy.platform.config.runtime.ObjectConfig;
|
||||
import ru.entaxy.platform.core.producer.api.EntaxyProducer;
|
||||
import ru.entaxy.platform.core.producer.api.EntaxyProducerService;
|
||||
import ru.entaxy.platform.core.producer.api.EntaxyWrappedFactory;
|
||||
import ru.entaxy.platform.core.producer.executor.generationmodel.GeneratedHeaders;
|
||||
import ru.entaxy.platform.core.producer.impl.CommonObjectProducer;
|
||||
import ru.entaxy.platform.core.producer.wrapper.AbstractFactoryWrapper;
|
||||
|
||||
// @Component(service = EntaxyProducer.class, immediate = true)
|
||||
// @EntaxyProducerInfo (supportedTypes = {ObjectConfig.CONFIG_OBJECT_TYPE})
|
||||
public class ConfigProducer2 extends CommonObjectProducer implements EntaxyProducer {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ConfigProducer2.class);
|
||||
|
||||
@Reference(cardinality = ReferenceCardinality.MANDATORY)
|
||||
EntaxyProducerService entaxyProducerService;
|
||||
|
||||
@Reference(bind = "addFactory", unbind = "removeFactory", cardinality = ReferenceCardinality.MULTIPLE,
|
||||
collectionType = CollectionType.SERVICE, policy = ReferencePolicy.DYNAMIC,
|
||||
policyOption = ReferencePolicyOption.GREEDY)
|
||||
public void addFactory(EntaxyFactory factory) {
|
||||
AbstractFactoryWrapper wrapper = super.doAddFactory(factory);
|
||||
if (wrapper != null)
|
||||
wrapper.setGenerationProcessor(this);
|
||||
}
|
||||
|
||||
// WE MUST DECLARE IT for @Reference annotation processor
|
||||
@Override
|
||||
public void removeFactory(EntaxyFactory factory) {
|
||||
super.removeFactory(factory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preGenerate(EntaxyWrappedFactory wrappedFactory, String outputType, String scope, String objectType,
|
||||
Map<String, Object> parameters) throws EntaxyFactoryException {
|
||||
super.preGenerate(wrappedFactory, outputType, scope, objectType, parameters);
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> properties = (Map<String, Object>) parameters.get(EntaxyObject.FIELDS.PROPERTIES);
|
||||
|
||||
// System.out.println("\n\n\tCONFIG PRODUCER :: preGenerate");
|
||||
// System.out.println("\t" + parameters.toString());
|
||||
|
||||
// properties can be null for 'config-field' output
|
||||
if (properties != null) {
|
||||
|
||||
/* System.out.println("\n\n\tGENERATE CONFIG: "
|
||||
+ "\noutput: " + outputType
|
||||
+ "\nscope: " + scope
|
||||
+ "\nproperties: " + properties.toString()); */
|
||||
|
||||
ObjectConfig.backupProperties(parameters, ObjectConfig.CONFIG_PROPERTIES_FIELD_NAME);
|
||||
ObjectConfig.removeConfigData(parameters, ObjectConfig.CONFIG_PROPERTIES_FIELD_NAME);
|
||||
|
||||
Map<String, Object> configurables = new HashMap<>();
|
||||
Map<String, Object> immutables = new HashMap<>();
|
||||
|
||||
String targetFactoryId = properties.get(ObjectConfig.CONFIG_FACTORY_FIELD_NAME).toString();
|
||||
String targetOutput = properties.get(ObjectConfig.CONFIG_OUTPUT_FIELD_NAME).toString();
|
||||
|
||||
EntaxyFactory f = entaxyProducerService.findFactoryById(targetFactoryId);
|
||||
if (!CommonUtils.isValid(targetOutput))
|
||||
targetOutput = f.getDefaultOutput().getType();
|
||||
|
||||
fillConfigMaps(f, targetOutput, scope, objectType, parameters, configurables, immutables);
|
||||
|
||||
parameters.put(ObjectConfig.CONFIGURABLES_FIELD_NAME, configurables);
|
||||
parameters.put(ObjectConfig.IMMUTABLES_FIELD_NAME, immutables);
|
||||
|
||||
String configuredId = parameters.get(ObjectConfig.CONFIG_ID_FIELD_NAME).toString();
|
||||
String configuredType = parameters.get(ObjectConfig.CONFIG_TYPE_FIELD_NAME).toString();
|
||||
|
||||
String configurationPid = ObjectConfig.getConfigurationPid(configuredId, configuredType);
|
||||
String placeholderPrefix = ObjectConfig.getConfigurationPrefix(configuredId, configuredType);
|
||||
|
||||
// set objectId to configurationPid
|
||||
|
||||
parameters.put(EntaxyObject.FIELDS.OBJECT_ID, configurationPid);
|
||||
|
||||
parameters.put(ObjectConfig.CONFIG_PID_FIELD_NAME, configurationPid);
|
||||
parameters.put(ObjectConfig.CONFIG_PLACEHOLDER_PREFIX_FIELD_NAME, placeholderPrefix);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postGenerate(EntaxyWrappedFactory wrappedFactory, String outputType, String scope, String objectType,
|
||||
Map<String, Object> parameters, Generated generated) throws EntaxyFactoryException {
|
||||
super.postGenerate(wrappedFactory, outputType, scope, objectType, parameters, generated);
|
||||
ObjectConfig.restoreBackupProperties(parameters, ObjectConfig.CONFIG_PROPERTIES_FIELD_NAME);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> properties = (Map<String, Object>) parameters.get(EntaxyObject.FIELDS.PROPERTIES);
|
||||
|
||||
// properties can be null for 'config-field' output
|
||||
if (properties != null) {
|
||||
|
||||
// enrich paramaters with configured fields placeholders
|
||||
String placeholderPrefix = parameters.get(ObjectConfig.CONFIG_PLACEHOLDER_PREFIX_FIELD_NAME).toString();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> configuredFields =
|
||||
(Map<String, Object>) parameters.getOrDefault(ObjectConfig.CONFIGURABLES_FIELD_NAME,
|
||||
Collections.emptyMap());
|
||||
configuredFields.putAll(
|
||||
(Map<String, Object>) parameters.getOrDefault(ObjectConfig.IMMUTABLES_FIELD_NAME,
|
||||
Collections.emptyMap()));
|
||||
|
||||
log.debug("CONFIGURED: \n" + configuredFields);
|
||||
|
||||
Map<String, Object> placeholdersMap = configuredFields.entrySet().stream()
|
||||
// .map(entry -> entry.setValue(placeholderPrefix + entry.getKey() + "}"))
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, entry -> placeholderPrefix + entry.getKey() + "}"));
|
||||
|
||||
log.debug("\n\n\tPLACEHOLDERS: \n" + placeholdersMap);
|
||||
|
||||
parameters.putAll(placeholdersMap);
|
||||
|
||||
// add headers
|
||||
String configuredId = parameters.get(ObjectConfig.CONFIG_ID_FIELD_NAME).toString();
|
||||
String configuredType = parameters.get(ObjectConfig.CONFIG_TYPE_FIELD_NAME).toString();
|
||||
|
||||
String configurationPid = ObjectConfig.getConfigurationPid(configuredId, configuredType);
|
||||
|
||||
GeneratedHeaders headers = GeneratedHeaders.getHeaders(generated.getProperties());
|
||||
headers.set(ObjectConfig.HEADER_OBJECT_CONFIG_PID,
|
||||
configuredId + ":" + configuredType + ":" + configurationPid);
|
||||
}
|
||||
}
|
||||
|
||||
protected void fillConfigMaps(EntaxyFactory factory, String outputType, String scope, String objectType,
|
||||
Map<String, Object> parameters, Map<String, Object> configurables, Map<String, Object> immutables) {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> properties =
|
||||
(Map<String, Object>) parameters.get(ObjectConfig.CONFIG_PROPERTIES_FIELD_NAME);
|
||||
for (Entry<String, Object> entry : properties.entrySet()) {
|
||||
Map<String, Object> targetMap =
|
||||
ObjectConfig.getTargetConfigMap(factory, outputType, entry.getKey(), configurables, immutables);
|
||||
if (targetMap == null) {
|
||||
continue;
|
||||
}
|
||||
targetMap.put(entry.getKey(), entry.getValue());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producing-config-support
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.platform.core.producer.config.support;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.felix.utils.properties.TypedProperties;
|
||||
import org.apache.karaf.config.core.ConfigRepository;
|
||||
import org.osgi.framework.ServiceReference;
|
||||
import org.osgi.service.cm.ConfigurationAdmin;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
|
||||
import ru.entaxy.esb.platform.runtime.base.connecting.generator.Generated;
|
||||
import ru.entaxy.platform.config.runtime.ObjectConfigHelper;
|
||||
import ru.entaxy.platform.core.producer.executor.builder.BuiltObject;
|
||||
import ru.entaxy.platform.core.producer.executor.builder.DefaultBuiltObject;
|
||||
import ru.entaxy.platform.core.producer.executor.builder.ObjectBuilder;
|
||||
import ru.entaxy.platform.core.producer.executor.deployer.DefaultDeployedObject;
|
||||
import ru.entaxy.platform.core.producer.executor.deployer.DeployedObject;
|
||||
import ru.entaxy.platform.core.producer.executor.deployer.ObjectDeployer;
|
||||
import ru.entaxy.platform.core.producer.executor.installer.DefaultInstalledObject;
|
||||
import ru.entaxy.platform.core.producer.executor.installer.InstalledObject;
|
||||
import ru.entaxy.platform.core.producer.executor.installer.ObjectInstaller;
|
||||
|
||||
@Component(service = {ObjectBuilder.class, ObjectDeployer.class, ObjectInstaller.class})
|
||||
public class ConfigObjectSupport implements ObjectBuilder, ObjectDeployer, ObjectInstaller {
|
||||
|
||||
private static final String CONFIG_TYPE_PREFIX = "config:";
|
||||
|
||||
@Override
|
||||
public boolean isBuildable(Generated generated) {
|
||||
return generated.getType().startsWith(CONFIG_TYPE_PREFIX);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BuiltObject build(Generated generated, Map<String, Object> instructions) throws Exception {
|
||||
return new DefaultBuiltObject(new DeployableConfig(
|
||||
generated.getProperties().getOrDefault("configurationPid",
|
||||
generated.getProperties().getOrDefault("objectId", "unknown")).toString(),
|
||||
|
||||
generated.getObject().toString()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDeployable(BuiltObject object) {
|
||||
return object.getObject() instanceof DeployableConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeployedObject deploy(BuiltObject object, Map<String, Object> instructions) throws Exception {
|
||||
return new DefaultDeployedObject(object.getObject());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInstallable(DeployedObject object) {
|
||||
return object.getObject() instanceof DeployableConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstalledObject install(DeployedObject object, Map<String, Object> instructions) throws Exception {
|
||||
DeployableConfig deployableConfig = (DeployableConfig) object.getObject();
|
||||
Map<String, Object> map = deployableConfig.properties;
|
||||
|
||||
ServiceReference<ConfigRepository> ref = ObjectConfigHelper.getInstance().getReference(ConfigRepository.class);
|
||||
ServiceReference<ConfigurationAdmin> ref2 =
|
||||
ObjectConfigHelper.getInstance().getReference(ConfigurationAdmin.class);
|
||||
if (ref != null) {
|
||||
|
||||
ConfigurationAdmin configurationAdmin = ObjectConfigHelper.getInstance().getService(ref2);
|
||||
|
||||
// we need this to not bind config to felix bundle
|
||||
configurationAdmin.getConfiguration(deployableConfig.configurationPid, "?");
|
||||
|
||||
ConfigRepository configRepository = ObjectConfigHelper.getInstance().getService(ref);
|
||||
TypedProperties typedProperties = configRepository.getConfig(deployableConfig.configurationPid);
|
||||
|
||||
typedProperties.clear();
|
||||
|
||||
for (Map.Entry<String, Object> entry : map.entrySet())
|
||||
typedProperties.put(entry.getKey(), entry.getValue());
|
||||
|
||||
configRepository.update(deployableConfig.configurationPid, typedProperties);
|
||||
|
||||
ObjectConfigHelper.getInstance().ungetService(ref);
|
||||
ObjectConfigHelper.getInstance().ungetService(ref2);
|
||||
}
|
||||
|
||||
return new DefaultInstalledObject(map);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producing-config-support
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.platform.core.producer.config.support;
|
||||
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jline.utils.Log;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ru.entaxy.platform.base.support.CommonUtils;
|
||||
import ru.entaxy.platform.base.support.JSONUtils;
|
||||
import ru.entaxy.platform.config.runtime.ObjectConfig;
|
||||
import ru.entaxy.platform.config.runtime.ObjectConfig.ConfigHint;
|
||||
|
||||
public class DeployableConfig {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DeployableConfig.class);
|
||||
|
||||
public String jsonData;
|
||||
public Map<String, Object> properties;
|
||||
|
||||
public String configurationPid;
|
||||
|
||||
public DeployableConfig(String configurationPid, String jsonData) {
|
||||
|
||||
this.configurationPid = configurationPid;
|
||||
|
||||
this.jsonData = jsonData;
|
||||
|
||||
Map<String, Object> origin = JSONUtils.element2map(JSONUtils.getJsonRootObject(jsonData));
|
||||
properties = new HashMap<>();
|
||||
if (origin == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Map.Entry<String, Object> entry : origin.entrySet())
|
||||
if (!entry.getKey().startsWith("#"))
|
||||
properties.put(entry.getKey(), entry.getValue());
|
||||
|
||||
try {
|
||||
generateHint();
|
||||
} catch (Exception e) {
|
||||
Log.error("Error generating condig hint", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void generateHint() throws Exception {
|
||||
|
||||
properties.remove(ObjectConfig.CONFIG_HINT_FIELD_NAME);
|
||||
|
||||
String factoryId = properties.getOrDefault(ObjectConfig.CONFIG_FACTORY_FIELD_NAME, "").toString();
|
||||
String outputType = properties.getOrDefault(ObjectConfig.CONFIG_OUTPUT_FIELD_NAME, "").toString();
|
||||
|
||||
ConfigHint configHint = new ConfigHint();
|
||||
configHint.generate(properties, factoryId, outputType);
|
||||
|
||||
String jsonHint = configHint.getAsJsonString();
|
||||
if (CommonUtils.isValid(jsonHint)) {
|
||||
properties.put(ObjectConfig.CONFIG_HINT_FIELD_NAME,
|
||||
Base64.getEncoder().encodeToString(jsonHint.getBytes()));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
{
|
||||
"property-placeholder": {
|
||||
"targetNodeName": "##root",
|
||||
"position": "inside_first",
|
||||
"unique": ["persistent-id"],
|
||||
"conflict": "ignore" /*[ignore, replace]*/
|
||||
}
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
{
|
||||
"factory": {
|
||||
"id": "object-config",
|
||||
"type": "entaxy.runtime.config",
|
||||
"description": "Entaxy object configuration factory",
|
||||
"isAbstract": false
|
||||
},
|
||||
"entaxy.runtime.config": {},
|
||||
"fields": {
|
||||
"configurables": {
|
||||
"type": "Map",
|
||||
"group": "config",
|
||||
"required": true,
|
||||
"defaultValue": {}
|
||||
},
|
||||
"immutables": {
|
||||
"type": "Map",
|
||||
"group": "config",
|
||||
"required": true,
|
||||
"defaultValue": {}
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"init": {
|
||||
"isDefault": true,
|
||||
"scopes": ["private", "public"],
|
||||
"fields": {
|
||||
"__entaxy_configuredId": {
|
||||
"type": "String",
|
||||
"isHidden": true
|
||||
},
|
||||
"__entaxy_configuredType": {
|
||||
"type": "String",
|
||||
"isHidden": true
|
||||
},
|
||||
"__entaxy_configuredFactoryId": {
|
||||
"type": "String",
|
||||
"isHidden": true
|
||||
},
|
||||
"__entaxy_configuredOutput": {
|
||||
"type": "String",
|
||||
"isHidden": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"config-defaults": {
|
||||
"isDefault": false,
|
||||
"scopes": ["private", "public"],
|
||||
"fields": {
|
||||
"##publish": {
|
||||
"defaultValue": {
|
||||
"name": {
|
||||
"@CALCULATED": {
|
||||
"expression": "${properties.configurationPid}",
|
||||
"lazy": true
|
||||
}
|
||||
},
|
||||
"objectId": {
|
||||
"@CALCULATED": {
|
||||
"expression": "${properties.configurationPid}",
|
||||
"lazy": true
|
||||
}
|
||||
},
|
||||
"relation": [
|
||||
{
|
||||
"@CALCULATED": {
|
||||
"expression": "${properties.__entaxy_configuredId}:${properties.__entaxy_configuredType}:config:-composition:config",
|
||||
"lazy": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"target": {
|
||||
"@CALCULATED": {
|
||||
"expression": "${properties.__entaxy_configuredId}:${properties.__entaxy_configuredType}",
|
||||
"lazy": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"@PUBLISH_AS": {
|
||||
"*": "configurationPid"
|
||||
}
|
||||
}
|
||||
},
|
||||
"config-link-field": {
|
||||
"isDefault": false,
|
||||
"generator": "",
|
||||
"config": {},
|
||||
"scopes": ["private", "public"]
|
||||
},
|
||||
"config-defaults-field": {
|
||||
"isDefault": false,
|
||||
"generator": "",
|
||||
"config": {},
|
||||
"scopes": ["private"]
|
||||
},
|
||||
"ref":{
|
||||
"scopes": ["private", "public"]
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
[#ftl attributes={"generated.type":"json"}]
|
||||
{
|
||||
"factoryId": "object-config",
|
||||
"objectId": "[=objectId]",
|
||||
"scope": "private",
|
||||
"outputType": "config-defaults",
|
||||
"@FILL_CONFIGURABLES": "",
|
||||
"properties": {
|
||||
"configured": {
|
||||
"@CALCULATED": {
|
||||
"resultType": "String",
|
||||
"expression": "${#OWNER#.objectId}",
|
||||
"lazy": true
|
||||
}
|
||||
},
|
||||
"__entaxy_configuredId":"[=targetObjectId]",
|
||||
"__entaxy_configuredType":"[=targetObjectType]",
|
||||
"__entaxy_configuredFactoryId":"[=targetObjectFactoryId]",
|
||||
"__entaxy_configuredOutput":"[=targetObjectOutput]",
|
||||
"configurationPid": [=configurationPid],
|
||||
"configuredProperties": {
|
||||
"@CALCULATED": {
|
||||
"resultType": "Map",
|
||||
"expression": "${#OWNER#.properties}",
|
||||
"lazy": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
[#ftl attributes={"generated.type":"blueprint.fragment"}]
|
||||
<!--
|
||||
config for
|
||||
objectId: [=__entaxy_configuredId]
|
||||
type: [=__entaxy_configuredType]
|
||||
pid: [=configurationPid]
|
||||
prefix: [=placeholderPrefix]
|
||||
|
||||
configurables:
|
||||
[#if configurables??]
|
||||
[#list configurables as key, value]
|
||||
[=key] = [#if value?is_boolean][=value?c][#else][=value][/#if]
|
||||
[/#list]
|
||||
[/#if]
|
||||
|
||||
-->
|
||||
<cm:property-placeholder persistent-id="[=configurationPid]" update-strategy="reload" id="[=configurationPid].placeholder"
|
||||
placeholder-prefix="[=placeholderPrefix]" placeholder-suffix="}"
|
||||
xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0">
|
||||
<cm:default-properties>
|
||||
[#if configurables??]
|
||||
[#list configurables as key, value]
|
||||
<cm:property name="[=key]" value="[#if value?is_boolean][=value?c][#else][=value][/#if]" />
|
||||
[/#list]
|
||||
[/#if]
|
||||
</cm:default-properties>
|
||||
</cm:property-placeholder>
|
||||
|
||||
|
||||
<!-- BEGIN placeholders for Camel -->
|
||||
<!-- make property placeholder available in Camel context -->
|
||||
|
||||
<bean id="[=configurationPid].placeholder.wrapper" class="ru.entaxy.platform.core.support.runtime.camel.CmPropertiesAccessorFunction" activation="eager">
|
||||
<property name="bundleContext" ref="blueprintBundleContext"/>
|
||||
<property name="persistentId" value="[=configurationPid]" />
|
||||
<property name="prefix" value="[=placeholderPrefix[1..placeholderPrefix?length-2]]" />
|
||||
<property name="wrappedPlaceholder" ref="[=configurationPid].placeholder" />
|
||||
</bean>
|
||||
|
||||
<propertyPlaceholder id="propertiesForCamel">
|
||||
<propertiesFunction ref="[=configurationPid].placeholder.wrapper"/>
|
||||
</propertyPlaceholder>
|
||||
|
||||
<!-- END placeholders for Camel -->
|
@ -0,0 +1,23 @@
|
||||
[#ftl attributes={"generated.type":"json"}]
|
||||
{
|
||||
"factoryId": "object-config",
|
||||
"objectId": "[=objectId]",
|
||||
"scope": "public",
|
||||
"@FILL_CONFIGURABLES": "properties",
|
||||
"properties": {
|
||||
"__entaxy_configuredId":"[=targetObjectId]",
|
||||
"__entaxy_configuredType":"[=targetObjectType]",
|
||||
"__entaxy_configuredFactoryId":"[=targetObjectFactoryId]",
|
||||
"__entaxy_configuredOutput":"[=targetObjectOutput]"
|
||||
},
|
||||
"configuredProperties": {
|
||||
"@CALCULATED": {
|
||||
"resultType": "Map",
|
||||
"expression": "${#OWNER#.properties}",
|
||||
"lazy": true
|
||||
}
|
||||
},
|
||||
"refConfig": {
|
||||
"isRefByValueOnly": true
|
||||
}
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
[#ftl attributes={"generated.type":"config:json"}]
|
||||
[=configurables_json!]
|
@ -0,0 +1,22 @@
|
||||
[#ftl attributes={"generated.type":"blueprint.fragment"}]
|
||||
|
||||
<cm:property-placeholder persistent-id="[=configurationPid]" update-strategy="reload" id="[=configurationPid].placeholder"
|
||||
placeholder-prefix="[=placeholderPrefix]" placeholder-suffix="}"
|
||||
xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0">
|
||||
</cm:property-placeholder>
|
||||
|
||||
<!-- BEGIN placeholders for Camel -->
|
||||
<!-- make property placeholder available in Camel context -->
|
||||
|
||||
<bean id="[=configurationPid].placeholder.wrapper" class="ru.entaxy.platform.core.support.runtime.camel.CmPropertiesAccessorFunction" activation="eager">
|
||||
<property name="bundleContext" ref="blueprintBundleContext"/>
|
||||
<property name="persistentId" value="[=configurationPid]" />
|
||||
<property name="prefix" value="[=placeholderPrefix[1..placeholderPrefix?length-2]]" />
|
||||
<property name="wrappedPlaceholder" ref="[=configurationPid].placeholder" />
|
||||
</bean>
|
||||
|
||||
<propertyPlaceholder id="propertiesForCamel">
|
||||
<propertiesFunction ref="[=configurationPid].placeholder.wrapper"/>
|
||||
</propertyPlaceholder>
|
||||
|
||||
<!-- END placeholders for Camel -->
|
@ -0,0 +1,37 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producing-resources-support
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.platform.core.producer.resources;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface EntaxyResourceProducingProcessor {
|
||||
|
||||
String PROP_PROCESSOR = "processor";
|
||||
|
||||
String getName();
|
||||
Object process(Object value, Map<String, Object> properties) throws Exception;
|
||||
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producing-resources-support
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.platform.core.producer.resources;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface EntaxyResourceProducingProcessorService {
|
||||
|
||||
Object process(Object value, Map<String, Object> properties) throws Exception;
|
||||
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producing-resources-support
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.platform.core.producer.resources.impl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.CollectionType;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
import org.osgi.service.component.annotations.ReferenceCardinality;
|
||||
import org.osgi.service.component.annotations.ReferencePolicy;
|
||||
import org.osgi.service.component.annotations.ReferencePolicyOption;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ru.entaxy.platform.core.producer.resources.EntaxyResourceProducingProcessor;
|
||||
import ru.entaxy.platform.core.producer.resources.EntaxyResourceProducingProcessorService;
|
||||
|
||||
@Component (service = EntaxyResourceProducingProcessorService.class, immediate = true)
|
||||
public class EntaxyResourceProducingProcessorServiceImpl implements EntaxyResourceProducingProcessorService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(EntaxyResourceProducingProcessorServiceImpl.class);
|
||||
|
||||
protected static EntaxyResourceProducingProcessorService _INSTANCE;
|
||||
|
||||
public static EntaxyResourceProducingProcessorService getInstance() {
|
||||
return _INSTANCE;
|
||||
}
|
||||
|
||||
protected Map<String, EntaxyResourceProducingProcessor> processorsMap = new HashMap<>();
|
||||
|
||||
@Activate
|
||||
public void activate() {
|
||||
_INSTANCE = this;
|
||||
}
|
||||
|
||||
@Reference (cardinality = ReferenceCardinality.MULTIPLE, collectionType = CollectionType.SERVICE, policy = ReferencePolicy.DYNAMIC
|
||||
, policyOption = ReferencePolicyOption.GREEDY, unbind = "removeProcessor")
|
||||
public void addProcessor(EntaxyResourceProducingProcessor processor) {
|
||||
synchronized (processorsMap) {
|
||||
this.processorsMap.put(processor.getName(), processor);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeProcessor(EntaxyResourceProducingProcessor processor) {
|
||||
synchronized (processorsMap) {
|
||||
this.processorsMap.remove(processor.getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object process(Object value, Map<String, Object> properties) throws Exception{
|
||||
Object val = properties.get(EntaxyResourceProducingProcessor.PROP_PROCESSOR);
|
||||
if (val == null)
|
||||
return value;
|
||||
String processorName = val.toString();
|
||||
if (!processorsMap.containsKey(processorName)) {
|
||||
log.warn("Unknown processor [{}] in [{}]", processorName, properties);
|
||||
return value;
|
||||
}
|
||||
return processorsMap.get(processorName).process(value, properties);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producing-shell
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.platform.core.producer.shell;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.karaf.shell.api.action.Command;
|
||||
import org.apache.karaf.shell.api.action.Option;
|
||||
import org.apache.karaf.shell.api.action.lifecycle.Service;
|
||||
|
||||
import ru.entaxy.platform.base.support.karaf.shell.ShellTableExt;
|
||||
import ru.entaxy.platform.core.producer.api.EntaxyProducerUtils;
|
||||
|
||||
@Service
|
||||
@Command(scope = EntaxyProducerServiceSupport.SCOPE, name = "factory-essence")
|
||||
public class FactoryEssence extends FactoryAwareCommand {
|
||||
|
||||
@Option(name = "-p", aliases = {"--prefix"})
|
||||
String prefix = "";
|
||||
|
||||
@Override
|
||||
protected Object doExecute() throws Exception {
|
||||
|
||||
Map<String, Object> essence = EntaxyProducerUtils.getFactoryEssence(entaxyFactory, prefix);
|
||||
|
||||
ShellTableExt table = new ShellTableExt();
|
||||
table.column("Key");
|
||||
table.column("Value");
|
||||
|
||||
for (Map.Entry<String, Object> entry : essence.entrySet())
|
||||
table.addRow().addContent(entry.getKey(), entry.getValue() == null ? "" : entry.getValue().toString());
|
||||
|
||||
// print output
|
||||
table.print(System.out);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
/*-
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* object-producing-shell
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
* rights to the Software and any copies are the property of the Copyright Holder. Unless
|
||||
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
|
||||
* Software for commercial purposes to provide services to third parties.
|
||||
*
|
||||
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
|
||||
* Under no circumstances does the Copyright Holder guarantee or promise that the
|
||||
* Software provided by him will be suitable or not suitable for the specific purposes
|
||||
* of the User, that the Software will meet all commercial and personal subjective
|
||||
* expectations of the User, that the Software will work properly, without technical
|
||||
* errors, quickly and uninterruptedly.
|
||||
*
|
||||
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
|
||||
* to the User for any direct or indirect losses of the User, his expenses or actual
|
||||
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
|
||||
* or damage to data, property, etc.
|
||||
* ~~~~~~/licensing~~~~~~
|
||||
*/
|
||||
package ru.entaxy.platform.core.producer.shell;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.karaf.shell.api.action.Action;
|
||||
import org.apache.karaf.shell.api.action.Argument;
|
||||
import org.apache.karaf.shell.api.action.Command;
|
||||
import org.apache.karaf.shell.api.action.lifecycle.Service;
|
||||
import org.osgi.framework.Filter;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
import org.osgi.framework.InvalidSyntaxException;
|
||||
|
||||
import ru.entaxy.platform.base.objects.factory.EntaxyFactory;
|
||||
import ru.entaxy.platform.base.support.karaf.shell.ShellTableExt;
|
||||
|
||||
@Service
|
||||
@Command(scope = "producer", name = "factory-find")
|
||||
public class FindFactories extends EntaxyProducerServiceSupport implements Action {
|
||||
|
||||
@Argument(index = 0, required = true)
|
||||
String filter;
|
||||
|
||||
@Override
|
||||
public Object execute() throws Exception {
|
||||
|
||||
Filter osgiFilter = null;
|
||||
|
||||
try {
|
||||
osgiFilter = FrameworkUtil.createFilter(filter);
|
||||
} catch (InvalidSyntaxException e) {
|
||||
|
||||
// print error
|
||||
System.err.println("Invalid filter:");
|
||||
e.printStackTrace(System.err);
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
List<EntaxyFactory> factories =
|
||||
producerService.findFactories(osgiFilter).stream().sorted(new Comparator<EntaxyFactory>() {
|
||||
|
||||
@Override
|
||||
public int compare(EntaxyFactory o1, EntaxyFactory o2) {
|
||||
return o1.getId().compareToIgnoreCase(o2.getId());
|
||||
}
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
ShellTableExt table = new ShellTableExt();
|
||||
|
||||
table.column("Id");
|
||||
table.column("Type");
|
||||
|
||||
for (EntaxyFactory f : factories)
|
||||
table.addRow().addContent(f.getId(), f.getType());
|
||||
|
||||
// print output
|
||||
table.print(System.out);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user