ENTAXY-374 release 1.8.2

This commit is contained in:
2022-08-23 13:40:11 +03:00
parent b68642f81c
commit 1061b96c7e
616 changed files with 60896 additions and 3202 deletions

View File

@ -3,7 +3,7 @@
<parent>
<groupId>ru.entaxy.esb.platform.runtime</groupId>
<artifactId>core</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
<artifactId>artifact-management</artifactId>

View File

@ -22,6 +22,8 @@ package ru.entaxy.platform.core.artifact;
import java.io.File;
import java.util.Map;
import ru.entaxy.platform.core.artifact.capabilities.CapabilityDescriptor;
public interface Artifact {
public static final String ARTIFACT_CATEGORY_UNKNOWN = "unknown";
@ -35,9 +37,6 @@ public interface Artifact {
public static final String DEFAULT_RUNTIME_GROUP_ID = "entaxy.runtime";
public static final String MANIFEST_HEADER_ENTAXY_BUNLDE = "Entaxy-Bundle";
public static final String MANIFEST_HEADER_ENTAXY_RUNTIME = "Entaxy-Runtime";
public String getCategory();
public ArtifactCoordinates getCoordinates();
@ -55,7 +54,13 @@ public interface Artifact {
// capabilities support
@Deprecated(forRemoval = true, since = "1.8.2")
public CapabilityDescriptor provideCapability(String namespace);
@Deprecated(forRemoval = true, since = "1.8.2")
public CapabilityDescriptor requireCapability(String namespace);
public default boolean isManifested() {
return Manifested.class.isAssignableFrom(this.getClass());
}
}

View File

@ -19,7 +19,10 @@
*/
package ru.entaxy.platform.core.artifact;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashSet;
import java.util.Set;
import org.apache.camel.tooling.model.Strings;
@ -29,14 +32,47 @@ public class ArtifactCoordinates {
public static final ArtifactCoordinates EMPTY = new ArtifactCoordinates();
public static final String DEFAULT_VERSION = "1.0.0";
public static final String SNAPSHOT_QUALIFIER = "SNAPSHOT";
// x.y.z[-qualifier]
public static final String VERSION_POLICY_CLEAR = "";
// x.y.z-timestamp
public static final String VERSION_POLICY_TIMESTAMPED = "timestamped";
// x.y.z-yyMMddHHmmss
public static final String VERSION_POLICY_DATED = "dated";
// x.yyMMdd.HHmmss[-qualifier]
public static final String VERSION_POLICY_DATED_EMBEDDED = "dated-embedded";
protected String groupId;
protected String artifactId;
protected String version = "1.0";
protected String type;
protected String classifier;
protected String versionPolicy = VERSION_POLICY_CLEAR;
protected String versionQualifier = "";
protected String timestamp = "";
protected Calendar calendar = null;
protected boolean isSnapshot = false;
protected Set<String> allowedPolicies = new HashSet<>() {/**
*
*/
private static final long serialVersionUID = 1L;
{
add(VERSION_POLICY_CLEAR);
add(VERSION_POLICY_DATED);
add(VERSION_POLICY_DATED_EMBEDDED);
add(VERSION_POLICY_TIMESTAMPED);
}};
public ArtifactCoordinates groupId(String groupId) {
setGroupId(groupId);
return this;
@ -47,6 +83,12 @@ public class ArtifactCoordinates {
return this;
}
public ArtifactCoordinates versionPolicy(String versionPolicy) {
if (this.allowedPolicies.contains(versionPolicy))
this.versionPolicy = versionPolicy;
return this;
}
public ArtifactCoordinates version(String version) {
this.versionQualifier = "";
setVersion(version);
@ -54,20 +96,95 @@ public class ArtifactCoordinates {
}
public ArtifactCoordinates timestampedVersion(String version) {
version(version);
this.versionQualifier = "-" + Calendar.getInstance().getTimeInMillis();
this.version(version);
this.timestamped();
// versionQualifier = "-" + Calendar.getInstance().getTimeInMillis();
return this;
}
public ArtifactCoordinates timestamp(String timestamp) {
this.timestamp = timestamp;
return this;
}
public ArtifactCoordinates timestamped() {
return qualifier(Calendar.getInstance().getTimeInMillis()+"");
return timestamped(Calendar.getInstance().getTimeInMillis()+"");
}
public ArtifactCoordinates timestamped(String timestamp) {
if (CommonUtils.isValid(timestamp))
return qualifier(timestamp);
else
return timestamped();
if (CommonUtils.isValid(timestamp)) {
this.timestamp = timestamp;
this.versionPolicy(VERSION_POLICY_TIMESTAMPED);
} else {
this.timestamp = "";
this.versionPolicy(VERSION_POLICY_CLEAR);
}
return this;
}
public ArtifactCoordinates datedVersion(String version) {
this.version(version);
this.dated();
// versionQualifier = "-" + Calendar.getInstance().getTimeInMillis();
return this;
}
public ArtifactCoordinates dated() {
this.calendar = Calendar.getInstance();
versionPolicy(VERSION_POLICY_DATED);
return this;
}
public ArtifactCoordinates datedEmbeddedVersion(String version) {
this.version(version);
this.datedEmbedded();
return this;
}
public ArtifactCoordinates datedEmbedded() {
this.calendar = Calendar.getInstance();
versionPolicy(VERSION_POLICY_DATED_EMBEDDED);
return this;
}
protected String getResultQualifier() {
if (isSnapshot)
return "-" + SNAPSHOT_QUALIFIER;
if (CommonUtils.isValid(this.versionQualifier))
return "-" + this.versionQualifier;
return "";
}
protected String calculateFinalVersion() {
if (VERSION_POLICY_TIMESTAMPED.equals(this.versionPolicy)) {
if (!CommonUtils.isValid(this.timestamp))
this.timestamp = Calendar.getInstance().getTimeInMillis() + "";
return this.version + "-" + this.timestamp;
}
if (VERSION_POLICY_DATED.equals(this.versionPolicy)) {
prepareCalendar();
return this.version + "-" + ((new SimpleDateFormat("yyMMddHHmmss")).format(this.calendar.getTime()));
}
if (VERSION_POLICY_DATED_EMBEDDED.equals(this.versionPolicy)) {
prepareCalendar();
return this.version.split("\\.")[0]
+ "."
+ ((new SimpleDateFormat("yyMMdd.HHmmss")).format(this.calendar.getTime()))
+ getResultQualifier();
}
return this.version + this.getResultQualifier();
}
protected void prepareCalendar() {
if (this.calendar == null)
this.calendar = Calendar.getInstance();
if (CommonUtils.isValid(this.timestamp)) {
try {
this.calendar.setTimeInMillis(Long.parseLong(this.timestamp));
} catch (Exception e) {
// NOOP
}
}
}
public ArtifactCoordinates type(String type) {
@ -77,7 +194,7 @@ public class ArtifactCoordinates {
public ArtifactCoordinates qualifier(String qualifier) {
if (CommonUtils.isValid(qualifier))
this.versionQualifier = "-" + qualifier;
this.versionQualifier = qualifier;
else
this.versionQualifier = "";
return this;
@ -112,10 +229,13 @@ public class ArtifactCoordinates {
}
public boolean isSnapshot() {
return !Strings.isNullOrEmpty(this.version)
&& this.version.endsWith("-SNAPSHOT");
return this.isSnapshot || SNAPSHOT_QUALIFIER.equals(this.versionQualifier);
}
public void setSnapshot(boolean isSnapshot) {
this.isSnapshot = isSnapshot;
}
public String getGroupId() {
return groupId;
}
@ -129,18 +249,26 @@ public class ArtifactCoordinates {
this.artifactId = artifactId;
}
public String getVersion() {
return version + versionQualifier;
return this.calculateFinalVersion();
}
public void setVersion(String version) {
if (!CommonUtils.isValid(version))
this.version = "1.0.0";
this.version = DEFAULT_VERSION;
else {
String[] splitted = version.split("\\.");
if (splitted.length == 2)
this.version = version + ".0";
else if ((splitted.length==3) && (!CommonUtils.isValid(splitted[2])))
this.version = version + "0";
else this.version = version;
String[] splittedDefault = DEFAULT_VERSION.split("\\.");
String result = "";
for (int i=0; i<splittedDefault.length; i++) {
if (i != 0)
result += ".";
if ((splitted.length >= i+1) && CommonUtils.isValid(splitted[i]))
result += splitted[i];
else
result += splittedDefault[i];
}
this.version = result;
}
}
public String getType() {
@ -156,9 +284,17 @@ public class ArtifactCoordinates {
this.classifier = classifier;
}
public String getVersionPolicy() {
return versionPolicy;
}
public void setVersionPolicy(String versionPolicy) {
this.versionPolicy(versionPolicy);
}
@Override
public String toString() {
String result = String.format("%s/%s/%s%s", groupId, artifactId, version, versionQualifier);
String result = String.format("%s/%s/%s", getGroupId(), getArtifactId(), getVersion());
if (!Strings.isNullOrEmpty(type)) {
result += "/" + type;
if (!Strings.isNullOrEmpty(classifier))

View File

@ -1,8 +1,8 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management
* test-producers
* ==========
* Copyright (C) 2020 - 2021 EmDev LLC
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,12 +19,17 @@
*/
package ru.entaxy.platform.core.artifact;
import org.osgi.resource.Capability;
import java.util.Map;
public interface CapabilityDescriptor extends Capability {
public interface ArtifactManifest {
public CapabilityDescriptor namespace(String namespace);
public CapabilityDescriptor attribute(String name, String value);
public CapabilityDescriptor attribute(String name, String value, String type);
public static interface HEADERS {
String ENTAXY_BUNDLE = "Entaxy-Bundle";
String ENTAXY_RUNTIME = "Entaxy-Runtime";
}
public Map<String, String> getCustomAttributes();
}

View File

@ -57,17 +57,17 @@ public class Artifacts {
if (DefaultArtifact.class.isAssignableFrom(instance.getClass()))
return (DefaultArtifact)instance;
} catch (NoSuchMethodException e) {
log.error("Erorr creating artifact", e);
log.error("Error creating artifact", e);
} catch (SecurityException e) {
log.error("Erorr creating artifact", e);
log.error("Error creating artifact", e);
} catch (InstantiationException e) {
log.error("Erorr creating artifact", e);
log.error("Error creating artifact", e);
} catch (IllegalAccessException e) {
log.error("Erorr creating artifact", e);
log.error("Error creating artifact", e);
} catch (IllegalArgumentException e) {
log.error("Erorr creating artifact", e);
log.error("Error creating artifact", e);
} catch (InvocationTargetException e) {
log.error("Erorr creating artifact", e);
log.error("Error creating artifact", e);
}
}
return new DefaultArtifact();

View File

@ -19,23 +19,13 @@
*/
package ru.entaxy.platform.core.artifact;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Enumeration;
import java.util.Properties;
import java.util.jar.Manifest;
import org.osgi.framework.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import ru.entaxy.platform.base.support.CommonUtils;
import ru.entaxy.platform.base.support.xml.CommonXMLUtils;
import ru.entaxy.platform.core.artifact.annotation.ArtifactSupport;
@ -43,10 +33,14 @@ import ru.entaxy.platform.core.artifact.annotation.ArtifactSupport;
, supportedContentClasses = {String.class, Document.class, byte[].class}
, defaultArtifactClassifier = Artifact.ARTIFACT_CATEGORY_BLUEPRINT
, defaultArtifactType = "xml")
public class Blueprint extends DefaultArtifact {
public class Blueprint extends DefaultArtifact implements Manifested {
private final static Logger log = LoggerFactory.getLogger(Blueprint.class);
public static final String ARTIFACT_CATEGORY_BLUEPRINT = "blueprint";
protected BlueprintManifest manifest = null;
@Override
public void setContent(Object content) {
super.setContent(content);
@ -63,8 +57,17 @@ public class Blueprint extends DefaultArtifact {
e.printStackTrace();
}
}
}
}
@Override
public ArtifactManifest getManifest() {
if (this.manifest == null)
this.manifest = new BlueprintManifest(this);
if (this.content instanceof Document)
this.manifest.load((Document)this.content);
return this.manifest;
}
@Override
public void toFile(File destination) {
if (this.content instanceof String)
@ -72,18 +75,17 @@ public class Blueprint extends DefaultArtifact {
else if (this.content instanceof Document) {
Document doc = (Document)this.content;
try {
prepareManifest(doc);
asByteArray();
CommonXMLUtils.saveDocument(doc, destination);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
log.error("Error saving to file", e);
}
}
else if (this.content instanceof byte[]) {
// TODO to be implemented
}
}
}
@Override
public byte[] asByteArray() {
@ -94,91 +96,14 @@ public class Blueprint extends DefaultArtifact {
if (this.content instanceof Document)
try {
Document doc = (Document)this.content;
prepareManifest(doc);
if (!this.manifest.isLoaded())
this.manifest.load(doc);
this.manifest.save(doc);
return CommonXMLUtils.doc2string(doc).getBytes();
} catch (Exception e) {
e.printStackTrace();
log.error("Error getting as byte[]: " + this.getCoordinates().toString(), e);
}
return new byte[] {};
}
protected void prepareManifest(Document doc) {
Manifest m = new Manifest();
m.getMainAttributes().putValue("Manifest-Version", "2");
m.getMainAttributes().putValue(Constants.BUNDLE_MANIFESTVERSION, "2");
m.getMainAttributes().putValue(Constants.BUNDLE_SYMBOLICNAME
, this.coordinates.getGroupId() + "." + this.coordinates.getArtifactId());
m.getMainAttributes().putValue(Constants.BUNDLE_NAME
, this.coordinates.getGroupId() + "." + this.coordinates.getArtifactId());
m.getMainAttributes().putValue(Constants.BUNDLE_VERSION, this.coordinates.getVersion().replaceAll("-", "."));
m.getMainAttributes().putValue(Constants.DYNAMICIMPORT_PACKAGE, "*");
m.getMainAttributes().putValue(Artifact.MANIFEST_HEADER_ENTAXY_BUNLDE, "true");
m.getMainAttributes().putValue(Artifact.MANIFEST_HEADER_ENTAXY_RUNTIME, "true");
NodeList l = doc.getElementsByTagName("manifest");
if (l != null) {
for (int i = 0; i < l.getLength(); i++) {
Element e = (Element) l.item(i);
String text = e.getTextContent();
Properties props = new Properties();
try {
props.load(new ByteArrayInputStream(text.trim().getBytes()));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Enumeration en = props.propertyNames();
while (en.hasMoreElements()) {
String k = (String) en.nextElement();
String v = props.getProperty(k);
m.getMainAttributes().putValue(k, v);
}
e.getParentNode().removeChild(e);
}
}
// add capabilities info
String requiredCapabilities = getRequiredCapabilitiesValue();
String providedCapabilities = getProvidedCapabilitiesValue();
if (CommonUtils.isValid(requiredCapabilities)) {
Object v = m.getMainAttributes().get(Constants.REQUIRE_CAPABILITY);
String value = (v==null?"":v.toString());
if (CommonUtils.isValid(value))
value += "," + requiredCapabilities;
else
value = requiredCapabilities;
m.getMainAttributes().putValue(Constants.REQUIRE_CAPABILITY, value);
}
if (CommonUtils.isValid(providedCapabilities)) {
Object v = m.getMainAttributes().get(Constants.PROVIDE_CAPABILITY);
String value = (v==null?"":v.toString());
if (CommonUtils.isValid(value))
value += "," + providedCapabilities;
else
value = providedCapabilities;
m.getMainAttributes().putValue(Constants.PROVIDE_CAPABILITY, value);
}
ByteArrayOutputStream bos = new ByteArrayOutputStream();
String manifestContent = "";
try {
m.write(bos);
manifestContent = bos.toString(StandardCharsets.ISO_8859_1);
manifestContent = manifestContent.replaceAll("\r", "").replaceAll("\n ", "");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Element manifest = doc.createElementNS("http://karaf.apache.org/xmlns/deployer/blueprint/v1.0.0", "manifest");
manifest.setTextContent(manifestContent);
doc.getDocumentElement().insertBefore(manifest, doc.getDocumentElement().getFirstChild());
// copy manifest data to artifact properties
for (Object key: m.getMainAttributes().keySet()) {
this.properties.put(key.toString(), m.getMainAttributes().get(key));
}
}
}

View File

@ -0,0 +1,143 @@
/*-
* ~~~~~~licensing~~~~~~
* test-producers
* ==========
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.jar.Manifest;
import org.osgi.framework.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
public class BlueprintManifest implements ArtifactManifest {
private static final Logger log = LoggerFactory.getLogger(BlueprintManifest.class);
protected Artifact artifact;
protected Manifest manifest = new Manifest();
boolean isLoaded = false;
protected Map<String, String> customAttributes = new HashMap<>();
public BlueprintManifest(Artifact artifact) {
super();
this.artifact = artifact;
}
public void load(Document document) {
this.isLoaded = false;
manifest = new Manifest();
manifest.getMainAttributes().putValue("Manifest-Version", "1.0");
manifest.getMainAttributes().putValue(Constants.BUNDLE_MANIFESTVERSION, "2");
manifest.getMainAttributes().putValue(Constants.DYNAMICIMPORT_PACKAGE, "*");
manifest.getMainAttributes().putValue(HEADERS.ENTAXY_BUNDLE, "true");
manifest.getMainAttributes().putValue(HEADERS.ENTAXY_RUNTIME, "true");
NodeList l = document.getElementsByTagName("manifest");
if (l != null) {
for (int i = 0; i < l.getLength(); i++) {
Element e = (Element) l.item(i);
String text = e.getTextContent();
Properties props = new Properties();
try {
props.load(new ByteArrayInputStream(text.trim().getBytes()));
} catch (IOException e1) {
log.error("Error loading manifest", e1);
}
Enumeration en = props.propertyNames();
while (en.hasMoreElements()) {
String k = (String) en.nextElement();
String v = props.getProperty(k);
manifest.getMainAttributes().putValue(k, v);
}
e.getParentNode().removeChild(e);
}
}
this.isLoaded = true;
}
protected void appendCustoms(Document document) {
for (Entry<String, String> entry: this.customAttributes.entrySet())
this.manifest.getMainAttributes().putValue(entry.getKey(), entry.getValue());
}
protected void beforeSave(Document document) {
this.manifest.getMainAttributes().putValue(Constants.BUNDLE_SYMBOLICNAME
, this.artifact.getCoordinates().getGroupId() + "." + this.artifact.getCoordinates().getArtifactId());
this.manifest.getMainAttributes().putValue(Constants.BUNDLE_NAME
, this.artifact.getCoordinates().getGroupId() + "." + this.artifact.getCoordinates().getArtifactId());
this.manifest.getMainAttributes().putValue(Constants.BUNDLE_VERSION
, this.artifact.getCoordinates().getVersion().replaceAll("-", "."));
appendCustoms(document);
}
public void save(Document document) {
beforeSave(document);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
String manifestContent = "";
try {
this.manifest.write(bos);
manifestContent = bos.toString(StandardCharsets.ISO_8859_1);
manifestContent = manifestContent.replaceAll("\r", "").replaceAll("\n ", "");
} catch (IOException e) {
log.error("Error saving manifest to document", e);
}
// remove old manifests
NodeList l = document.getElementsByTagName("manifest");
if (l != null)
for (int i = 0; i < l.getLength(); i++) {
Element e = (Element) l.item(i);
e.getParentNode().removeChild(e);
}
Element manifest = document.createElementNS("http://karaf.apache.org/xmlns/deployer/blueprint/v1.0.0", "manifest");
manifest.setTextContent(manifestContent);
document.getDocumentElement().insertBefore(manifest
, document.getDocumentElement().getFirstChild());
}
@Override
public Map<String, String> getCustomAttributes() {
return this.customAttributes;
}
public boolean isLoaded() {
return isLoaded;
}
}

View File

@ -31,6 +31,7 @@ import java.util.Map;
import org.apache.camel.tooling.model.Strings;
import ru.entaxy.platform.core.artifact.annotation.ArtifactSupport;
import ru.entaxy.platform.core.artifact.capabilities.CapabilityDescriptor;
import ru.entaxy.platform.core.artifact.impl.CapabilityDescriptorImpl;
public class DefaultArtifact implements Artifact {
@ -92,7 +93,7 @@ public class DefaultArtifact implements Artifact {
}
protected void checkSetContent(Object content) {
// TODO throw exception if content suites none of the supported clssses
// TODO throw exception if content suites none of the supported classes
if (this.supportedContentClasses.contains(content.getClass()))
this.content = content;

View File

@ -0,0 +1,26 @@
/*-
* ~~~~~~licensing~~~~~~
* test-producers
* ==========
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact;
public interface Manifested {
public ArtifactManifest getManifest();
}

View File

@ -0,0 +1,60 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management
* ==========
* Copyright (C) 2020 - 2021 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.capabilities;
import org.osgi.resource.Capability;
import java.util.Map;
public interface CapabilityDescriptor extends Capability {
public static final String HEADER_PROVIDE_CAPABILITY = "Provide-Capability";
public static final String HEADER_REQUIRE_CAPABILITY = "Require-Capability";
public static interface ATTRIBUTE_TYPES {
public static final String STRING = "String";
public static final String VERSION = "Version";
public static final String LONG = "Long";
public static final String DOUBLE = "Double";
public static final String LIST = "List";
public static String TYPED_LIST(String itemType) {
return LIST + "<" + itemType + ">";
}
public static boolean isList(String itemType) {
return (itemType!=null) && (itemType.startsWith(LIST));
}
public static String itemType(String listType) {
if (!isList(listType))
return null;
return listType.substring(listType.indexOf("<"), listType.indexOf(">"));
}
}
public CapabilityDescriptor namespace(String namespace);
public CapabilityDescriptor attributes(Map<String, Object> attributes);
public CapabilityDescriptor attribute(String name, Object value);
public CapabilityDescriptor attribute(String name, Object value, String type);
}

View File

@ -0,0 +1,158 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management
* ==========
* Copyright (C) 2020 - 2021 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.capabilities;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import org.osgi.resource.Resource;
import ru.entaxy.platform.base.support.CommonUtils;
public class CapabilityDescriptorImpl implements CapabilityDescriptor {
protected String namespace;
protected Map<String, String> directives = new HashMap<>();
protected Map<String, AttributeDescriptor> attributes = new HashMap<>();
private static class AttributeDescriptor {
String type;
Object value;
public AttributeDescriptor(Object value) {
this(value, CapabilityTypeHelper.getTypeName(value));
}
public AttributeDescriptor(Object value, String type) {
this.type = type;
this.value = value==null?"":value.toString();
}
public String getValueAsString() {
if (value == null)
return null;
if (CapabilityDescriptor.ATTRIBUTE_TYPES.isList(type))
return CapabilityTypeHelper.getListAsString((List<?>)value);
return value.toString();
}
}
public CapabilityDescriptorImpl() {
// TODO Auto-generated constructor stub
}
public CapabilityDescriptorImpl(String namespace) {
this();
namespace(namespace);
}
public String getAttributesAsString() {
return this.attributes.entrySet().stream()
.map(entry->
entry.getKey()
+ (!ATTRIBUTE_TYPES.STRING.equals(entry.getValue().type)?(":" + entry.getValue().type):"")
+ "=" + entry.getValue().getValueAsString())
.collect(Collectors.joining(";"));
}
@Override
public String getNamespace() {
return this.namespace;
}
@Override
public Map<String, String> getDirectives() {
return this.directives;
}
@Override
public Map<String, Object> getAttributes() {
Map<String, Object> result = new HashMap<>();
for (Map.Entry<String, AttributeDescriptor> entry: this.attributes.entrySet())
result.put(entry.getKey(), entry.getValue().value);
return result;
}
@Override
public Resource getResource() {
// not implemented
return null;
}
@Override
public CapabilityDescriptor namespace(String namespace) {
this.namespace = namespace;
return this;
}
@Override
public CapabilityDescriptor attribute(String name, Object value) {
this.attributes.put(name, new AttributeDescriptor(value));
return this;
}
@Override
public CapabilityDescriptor attribute(String name, Object value, String type) {
this.attributes.put(name, new AttributeDescriptor(value, type));
return this;
}
public CapabilityDescriptor parseAttribute(String attributeData) {
String nameType = attributeData.substring(0, attributeData.indexOf("="));
if (!CommonUtils.isValid(nameType))
return this;
String[] nameTypeSplit = nameType.split(":");
String name = nameTypeSplit[0].trim();
String type = (nameTypeSplit.length > 1?nameTypeSplit[1]:CapabilityDescriptor.ATTRIBUTE_TYPES.STRING);
if (!CommonUtils.isValid(type))
type = CapabilityDescriptor.ATTRIBUTE_TYPES.STRING;
type = type.trim();
String value = attributeData.substring(attributeData.indexOf("=")+1);
if (!CommonUtils.isValid(value))
value = "";
value = value.trim();
Object typedValue = CapabilityTypeHelper.getTypedValue(type, value);
this.attribute(name, typedValue, type);
return this;
}
@Override
public CapabilityDescriptor attributes(Map<String, Object> attributes) {
if (attributes == null)
return this;
for (Entry<String, Object> entry: attributes.entrySet()) {
this.attribute(entry.getKey(), entry.getValue());
}
return this;
}
}

View File

@ -0,0 +1,109 @@
/*-
* ~~~~~~licensing~~~~~~
* test-producers
* ==========
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.capabilities;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import ru.entaxy.platform.base.support.CommonUtils;
import ru.entaxy.platform.core.artifact.capabilities.CapabilityDescriptor.ATTRIBUTE_TYPES;
public class CapabilityTypeHelper {
public static String getTypeName(Object object) {
if (object == null)
return ATTRIBUTE_TYPES.STRING;
if (object instanceof List<?>) {
return ATTRIBUTE_TYPES.TYPED_LIST(getListTypeName((List<?>)object));
}
return getScalarTypeName(object);
}
public static String getListTypeName(List<?> list) {
if (list.size() == 0)
return ATTRIBUTE_TYPES.STRING;
else
return getScalarTypeName(list.get(0));
}
public static String getScalarTypeName(Object object) {
if ((object instanceof Integer) || (object instanceof Long))
return ATTRIBUTE_TYPES.LONG;
if (object instanceof Number)
return ATTRIBUTE_TYPES.DOUBLE;
return ATTRIBUTE_TYPES.STRING;
}
public static String getListAsString(List<?> list) {
String result = "\"";
if (list != null)
result += list.stream().map(item->(item==null)?"":item.toString())
.collect(Collectors.joining(","));
return result + "\"";
}
public static Object getTypedValue(String type, String value) {
if (CapabilityDescriptor.ATTRIBUTE_TYPES.STRING.equals(type))
return value;
if (CapabilityDescriptor.ATTRIBUTE_TYPES.VERSION.equals(type))
return value;
if (CapabilityDescriptor.ATTRIBUTE_TYPES.LONG.equals(type))
try {
return Long.parseLong(value);
} catch (Exception e) {
return Long.valueOf(-1);
}
if (CapabilityDescriptor.ATTRIBUTE_TYPES.DOUBLE.equals(type))
try {
return Double.parseDouble(value);
} catch (Exception e) {
return Double.valueOf(-1);
}
if (CapabilityDescriptor.ATTRIBUTE_TYPES.isList(type)) {
String itemType = CapabilityDescriptor.ATTRIBUTE_TYPES.itemType(type);
if (!CommonUtils.isValid(itemType))
return value;
List<Object> result = new ArrayList<>();
String val = value;
if (val.startsWith("\""))
val = val.substring(1);
if (val.endsWith("\""))
val = val.substring(0, val.length()-1);
if (!CommonUtils.isValid(val))
return result;
String[] vals = val.split(",");
for (int i=0; i< vals.length; i++)
if (vals[i] == null)
continue;
else
result.add(getTypedValue(itemType, vals[i]));
return result;
}
return value;
}
}

View File

@ -0,0 +1,136 @@
/*-
* ~~~~~~licensing~~~~~~
* test-producers
* ==========
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.capabilities;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import ru.entaxy.platform.base.support.CommonUtils;
import ru.entaxy.platform.core.artifact.ArtifactManifest;
public class ManifestCapabilityHelper {
protected ArtifactManifest manifest;
protected Map<String, CapabilityDescriptorImpl> requiredCapabilities = new HashMap<>();
protected Map<String, CapabilityDescriptorImpl> providedCapabilities = new HashMap<>();
public ManifestCapabilityHelper(ArtifactManifest manifest) {
super();
this.manifest = manifest;
this.load();
}
protected void load() {
String existing = this.manifest.getCustomAttributes().get(CapabilityDescriptor.HEADER_PROVIDE_CAPABILITY);
if (CommonUtils.isValid(existing)) {
List<CapabilityDescriptorImpl> list = parse(existing);
for (CapabilityDescriptorImpl c: list)
addProvidedCapability(c);
}
existing = this.manifest.getCustomAttributes().get(CapabilityDescriptor.HEADER_REQUIRE_CAPABILITY);
if (CommonUtils.isValid(existing)) {
List<CapabilityDescriptorImpl> list = parse(existing);
for (CapabilityDescriptorImpl c: list)
addRequiredCapability(c);
}
}
protected void addProvidedCapability(CapabilityDescriptorImpl capabilityDescriptorImpl) {
if (capabilityDescriptorImpl == null)
return;
this.providedCapabilities.put(capabilityDescriptorImpl.getNamespace(), capabilityDescriptorImpl);
}
protected void addRequiredCapability(CapabilityDescriptorImpl capabilityDescriptorImpl) {
if (capabilityDescriptorImpl == null)
return;
this.requiredCapabilities.put(capabilityDescriptorImpl.getNamespace(), capabilityDescriptorImpl);
}
protected List<CapabilityDescriptorImpl> parse(String capabilities) {
List<CapabilityDescriptorImpl> result = new ArrayList<>();
String[] caps = capabilities.split(",");
for (int i=0; i< caps.length; i++)
if (CommonUtils.isValid(caps[i])) {
result.add(parseCapability(caps[i]));
}
return result;
}
protected CapabilityDescriptorImpl parseCapability(String capability) {
String[] parsed = capability.split(";");
CapabilityDescriptorImpl result = new CapabilityDescriptorImpl(parsed[0].trim());
for (int i=1; i<parsed.length; i++) {
result.parseAttribute(parsed[i]);
}
return result;
}
public List<CapabilityDescriptor> getProvidedCapabilities(){
return this.providedCapabilities.values().stream()
.map(c -> (CapabilityDescriptor)c)
.collect(Collectors.toList());
}
public List<CapabilityDescriptor> getRequiredCapabilities(){
return this.requiredCapabilities.values().stream()
.map(c -> (CapabilityDescriptor)c)
.collect(Collectors.toList());
}
public boolean isCapabilityProvided(String namespace) {
return this.providedCapabilities.containsKey(namespace);
}
public boolean isCapabilityRequired(String namespace) {
return this.requiredCapabilities.containsKey(namespace);
}
public CapabilityDescriptor provideCapability(String namespace) {
if (!this.providedCapabilities.containsKey(namespace))
this.providedCapabilities.put(namespace, new CapabilityDescriptorImpl(namespace));
return this.providedCapabilities.get(namespace);
}
public CapabilityDescriptor requireCapability(String namespace) {
if (!this.requiredCapabilities.containsKey(namespace))
this.requiredCapabilities.put(namespace, new CapabilityDescriptorImpl(namespace));
return this.requiredCapabilities.get(namespace);
}
public void save() {
this.manifest.getCustomAttributes().put(CapabilityDescriptor.HEADER_PROVIDE_CAPABILITY,
this.providedCapabilities.values().stream()
.map(
cap -> (
cap.getNamespace()
+ ";"
+ cap.getAttributesAsString()
)
)
.collect(Collectors.joining(","))
);
}
}

View File

@ -24,8 +24,9 @@ import java.util.Map;
import org.osgi.resource.Resource;
import ru.entaxy.platform.core.artifact.CapabilityDescriptor;
import ru.entaxy.platform.core.artifact.capabilities.CapabilityDescriptor;
@Deprecated(forRemoval = true, since = "1.8.2")
public class CapabilityDescriptorImpl implements CapabilityDescriptor {
protected String namespace;
@ -103,16 +104,24 @@ public class CapabilityDescriptorImpl implements CapabilityDescriptor {
return this;
}
@Override
public CapabilityDescriptor attribute(String name, String value) {
this.attributes.put(name, new AttributeDescriptor(value));
return this;
public CapabilityDescriptor attributes(Map<String, Object> attributes) {
// TODO Auto-generated method stub
return null;
}
@Override
public CapabilityDescriptor attribute(String name, String value, String type) {
this.attributes.put(name, new AttributeDescriptor(value, type));
return this;
public CapabilityDescriptor attribute(String name, Object value) {
// TODO Auto-generated method stub
return null;
}
@Override
public CapabilityDescriptor attribute(String name, Object value, String type) {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -47,7 +47,7 @@ public abstract class AbstractInstaller<T extends Installer<T>, H extends TypedI
protected String bundleName = null;
protected Map<String, Class<? extends TypedInstallerImpl>> typedInstallerClasses = new HashMap<>();
protected Map<Class<? extends TypedInstallerImpl>, Class<? extends H>> typedHelpeClasses = new HashMap<>();
protected Map<Class<? extends TypedInstallerImpl>, Class<? extends H>> typedHelperClasses = new HashMap<>();
// for BundleInstaller implementation
@ -57,7 +57,7 @@ public abstract class AbstractInstaller<T extends Installer<T>, H extends TypedI
protected AbstractInstaller() {
this.typedInstallerClasses = new HashMap<>();
this.typedHelpeClasses = new HashMap<>();
this.typedHelperClasses = new HashMap<>();
}
protected void doCreateTypedInstaller(Class<? extends TypedInstallerImpl> clazz) {
@ -114,7 +114,7 @@ public abstract class AbstractInstaller<T extends Installer<T>, H extends TypedI
}
protected H createHelper() {
Class<? extends H> clazz = typedHelpeClasses.get(typedInstaller.getClass());
Class<? extends H> clazz = typedHelperClasses.get(typedInstaller.getClass());
if (clazz == null)
return createDefaultHelper();
Constructor<?> constructor;

View File

@ -75,7 +75,7 @@ public class ClusterCommonBundleInstallerHelper extends ClusterTypedInstallerHel
.failed("Can't install/update: CellarBundleMBean not available");
}
// TODO decide if we really need several grouos
// TODO decide if we really need several groups
// now we use only the first one
String groupToInstall = groupsToInstall.get(0);
@ -198,7 +198,7 @@ public class ClusterCommonBundleInstallerHelper extends ClusterTypedInstallerHel
.failed("Can't install/update: CellarBundleMBean not available");
}
// TODO decide if we really need several grouos
// TODO decide if we really need several groups
// now we use only the first one
String groupToInstall = groupsToInstall.get(0);
String bundleId = this.config.getBundleId();

View File

@ -48,11 +48,11 @@ public class DefaultCellarInstaller extends AbstractInstaller<ClusterInstaller,
this.typedInstallerClasses.put(Artifact.ARTIFACT_CATEGORY_BUNDLE, ru.entaxy.platform.core.artifact.installer.builder.typed.impl.BundleInstallerImpl.class);
this.typedInstallerClasses.put(Artifact.ARTIFACT_CATEGORY_JAR, ru.entaxy.platform.core.artifact.installer.builder.typed.impl.JarInstallerImpl.class);
this.typedHelpeClasses.put(ru.entaxy.platform.core.artifact.installer.builder.typed.impl.BlueprintInstallerImpl.class
this.typedHelperClasses.put(ru.entaxy.platform.core.artifact.installer.builder.typed.impl.BlueprintInstallerImpl.class
, ClusterCommonBundleInstallerHelper.class);
this.typedHelpeClasses.put(ru.entaxy.platform.core.artifact.installer.builder.typed.impl.BundleInstallerImpl.class
this.typedHelperClasses.put(ru.entaxy.platform.core.artifact.installer.builder.typed.impl.BundleInstallerImpl.class
, ClusterCommonBundleInstallerHelper.class);
this.typedHelpeClasses.put(ru.entaxy.platform.core.artifact.installer.builder.typed.impl.JarInstallerImpl.class
this.typedHelperClasses.put(ru.entaxy.platform.core.artifact.installer.builder.typed.impl.JarInstallerImpl.class
, ClusterCommonBundleInstallerHelper.class);
initGroups();

View File

@ -38,9 +38,9 @@ public class DefaultLocalInstaller extends AbstractInstaller<LocalInstaller, Loc
this.typedInstallerClasses.put(Artifact.ARTIFACT_CATEGORY_JAR, JarInstallerImpl.class);
this.typedHelpeClasses.put(BlueprintInstallerImpl.class, LocalCommonBundleInstallerHelper.class);
this.typedHelpeClasses.put(BundleInstallerImpl.class, LocalCommonBundleInstallerHelper.class);
this.typedHelpeClasses.put(JarInstallerImpl.class, LocalCommonBundleInstallerHelper.class);
this.typedHelperClasses.put(BlueprintInstallerImpl.class, LocalCommonBundleInstallerHelper.class);
this.typedHelperClasses.put(BundleInstallerImpl.class, LocalCommonBundleInstallerHelper.class);
this.typedHelperClasses.put(JarInstallerImpl.class, LocalCommonBundleInstallerHelper.class);
}
@Override

View File

@ -3,7 +3,7 @@
<parent>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
<artifactId>cluster</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<groupId>ru.entaxy.esb.platform.runtime.core.cluster</groupId>
<artifactId>cluster-persistence-service</artifactId>

View File

@ -3,7 +3,7 @@
<parent>
<groupId>ru.entaxy.esb.platform.runtime</groupId>
<artifactId>core</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
<artifactId>cluster</artifactId>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>ru.entaxy.esb.platform.runtime</groupId>
<artifactId>core</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
<artifactId>infrastructure</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ru.entaxy.esb.platform.runtime.core.infrastructure</groupId>
<artifactId>schema</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -19,7 +19,10 @@
*/
package ru.entaxy.esb.platform.runtime.core.infrastructure.schema.api.entity;
import org.hibernate.annotations.Type;
import javax.persistence.*;
import java.sql.Blob;
import java.util.Arrays;
import java.util.Date;
@ -31,6 +34,7 @@ public class Resource {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private long id;
@Lob
@Column(name = "resource_value")
private byte[] resourceValue;
@Column(name = "created_date")

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ru.entaxy.esb.platform.runtime.core.infrastructure</groupId>
<artifactId>schema</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ru.entaxy.esb.platform.runtime.core.infrastructure</groupId>
<artifactId>schema</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -29,6 +29,7 @@
<property name="hibernate.hbm2ddl.auto">validate</property>
<property name="hibernate.enable_lazy_load_no_trans">true</property>
<property name="hibernate.jdbc.use_streams_for_binary">false</property>
<mapping class="ru.entaxy.esb.platform.runtime.core.infrastructure.schema.api.entity.ResourceInfo"/>
<mapping class="ru.entaxy.esb.platform.runtime.core.infrastructure.schema.api.entity.Resource"/>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ru.entaxy.esb.platform.runtime.core.infrastructure</groupId>
<artifactId>schema</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
<artifactId>initializer</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -30,7 +30,7 @@
<extensions>true</extensions>
<configuration>
<instructions>
<Entaxy-Initializer-Class>ru.entaxy.esb.platform.runtime.core.initializer.connection.ConnectionInitializer?id=connections&amp;repeat=true&amp;depends-on=core,datasources</Entaxy-Initializer-Class>
<Entaxy-Initializer-Class>ru.entaxy.esb.platform.runtime.core.initializer.connection.ConnectionInitializer?id=connections&amp;repeat=true&amp;retries=10&amp;interval=2000&amp;depends-on=core,datasources</Entaxy-Initializer-Class>
</instructions>
</configuration>
</plugin>
@ -51,6 +51,11 @@
<type>json</type>
<classifier>init-config</classifier>
</artifact>
<artifact>
<file>src/main/non-packaged-resources/etc/init/file-connections.json</file>
<type>json</type>
<classifier>init-config-files</classifier>
</artifact>
</artifacts>
</configuration>
</execution>
@ -84,5 +89,19 @@
<artifactId>base-support</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>
ru.entaxy.esb.platform.runtime.core.object-producing
</groupId>
<artifactId>object-producer-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>
ru.entaxy.esb.platform.runtime.core.object-producing
</groupId>
<artifactId>object-producer-core</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -23,16 +23,28 @@ import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.JsonObject;
import ru.entaxy.esb.platform.runtime.core.initializer.api.AbstractInitializer;
import ru.entaxy.esb.platform.runtime.core.initializer.api.InitializerException;
import ru.entaxy.esb.platform.runtime.core.management.connection.util.ConnectionManagerUtil;
import ru.entaxy.platform.base.support.FileUtils;
import ru.entaxy.platform.base.support.JSONUtils;
import ru.entaxy.platform.base.support.osgi.OSGIUtils;
import ru.entaxy.platform.core.artifact.ArtifactCoordinates;
import ru.entaxy.platform.core.artifact.service.ArtifactService;
import ru.entaxy.platform.core.producer.api.EntaxyProducerService;
import ru.entaxy.platform.core.producer.api.EntaxyProducerUtils;
import ru.entaxy.platform.core.producer.executor.objectmodel.ObjectModel;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.List;
import java.util.stream.Collectors;
public class ConnectionInitializer extends AbstractInitializer {
@ -41,22 +53,49 @@ public class ConnectionInitializer extends AbstractInitializer {
private static final String JSON_FILE_NAME = "entaxy-platform-connections.json";
private static final String jsonBundlePath = "/connection/" + JSON_FILE_NAME;
private static final String JSON_FILE_PATH = System.getProperty("karaf.etc")
private static final String INIT_FILES_PATH = System.getProperty("karaf.etc")
+ File.separator
+ "init"
+ "init";
private static final String JSON_FILE_PATH = INIT_FILES_PATH
+ File.separator
+ JSON_FILE_NAME;
private EntaxyProducerService entaxyProducerService;
@Override
public void init() throws InitializerException {
log.info("ConnectionInitializer started");
log.info("-->> " + JSON_FILE_PATH);
try {
entaxyProducerService = OSGIUtils.services().bundleContext(bundleContext)
.ofClass(EntaxyProducerService.class)
.waitService(50000)
.get();
if (entaxyProducerService == null)
throw new InitializerException(this, "Service EntaxyProducerService not found", "", null);
} catch (Exception e) {
log.error("Error getting EntaxyProducerService", e);
throw new InitializerException(this, "Error getting EntaxyProducerService", "", e);
}
// first scan factory-base files
try {
scanAndInitFromFactoryFiles();
} catch (Exception e) {
log.error("Error initializing connections from factory files", e);
throw new InitializerException(this, "Can't create platform connections", "", e);
}
// then use the old one
try {
initPlatformConnections(bundleContext);
} catch (Exception e) {
e.printStackTrace();
log.error("Error initializing connections from " + JSON_FILE_PATH, e);
throw new InitializerException(this, "Can't create platform connections", "", e);
}
}
@ -64,16 +103,147 @@ public class ConnectionInitializer extends AbstractInitializer {
@Override
public void reinit() throws InitializerException {
// TODO Auto-generated method stub
}
private void scanAndInitFromFactoryFiles() throws Exception {
File initDir = new File(INIT_FILES_PATH);
if (!initDir.exists() || !initDir.isDirectory())
return;
File[] files = initDir.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".json") && !JSON_FILE_NAME.equals(name);
}
});
if ((files == null) || (files.length==0))
return;
for (int i=0; i<files.length; i++) {
log.debug("FOUND FILE :: " + files[i].getName());
//
// check if the file contains objects
//
FileUtils.FileHelper helper = new FileUtils.FileHelper(files[i].getAbsolutePath());
if (!helper.isReadable()) {
// TODO throw exception
log.warn("Platform connections file {} is not readable", JSON_FILE_PATH);
continue;
}
JsonObject jsonData;
try {
URL url = files[i].toURI().toURL();
jsonData = JSONUtils.getJsonRootObject(url);
} catch (Exception e) {
log.warn("Configuration loading failed:" + e.getMessage());
continue;
}
ObjectModel objectModel = new ObjectModel();
try {
objectModel.load(jsonData);
objectModel.checkRefs();
} catch (Exception e) {
log.warn("Error loading model from " + files[i].getAbsolutePath(), e);
continue;
}
if (objectModel.objects.size() == 0)
continue;
log.debug("CONTAINS OBJECTS :: " + files[i].getName());
//
// check availability of factories
//
List<String> factoryIds = objectModel.objects.stream()
.map(obj -> obj.factoryId)
.collect(Collectors.toList());
for (String factoryId: factoryIds) {
String message = "CHECK FACTORY :: " + factoryId + "..";
if (entaxyProducerService.findFactoryById(factoryId) == null) {
message += " NOT FOUND";
log.debug(message);
throw new InitializerException(this, "Factory not found: " + factoryId, "", null);
}
message += " FOUND";
log.debug(message);
}
log.debug("FACTORIES AVAILABLE :: " + files[i].getName());
//
// produce objects
//
EntaxyProducerUtils.InstructionsBuilder builder = EntaxyProducerUtils.instructions()
.any()
.command("add-config")
.command("pre-generate")
.set(EntaxyProducerService.INSTRUCTIONS.PRINT_OUTPUT, true)
.command("build")
.set(EntaxyProducerService.INSTRUCTIONS.ARTIFACT.VERSION_POLICY
, ArtifactCoordinates.VERSION_POLICY_DATED_EMBEDDED)
.command("deploy")
.set("deployLocal", true);
if (helper.isChanged()) {
log.info("File is new or changed, install/update connections: " + files[i].getAbsolutePath());
// we need to create/update connections with new timestamp
String oldTimestamp = helper.getTimestamp();
String newTimestamp = helper.updateTimestamp();
builder
.command("build")
.set(EntaxyProducerService.INSTRUCTIONS.ARTIFACT.TIMESTAMP, newTimestamp)
.command("install")
.set("update", "");
String instructions = builder
.getInstructionsString();
entaxyProducerService.produce(jsonData, instructions);
helper.updateMd5();
} else {
log.info("File is not changed, install/check connection: " + files[i].getAbsolutePath());
String oldTimestamp = helper.getTimestamp();
builder
.command("build")
.set(EntaxyProducerService.INSTRUCTIONS.ARTIFACT.TIMESTAMP, oldTimestamp)
.command("install")
.set("installOnlyIfMissing", true);
String instructions = builder
.getInstructionsString();
entaxyProducerService.produce(jsonData, instructions);
}
}
}
private void initPlatformConnections(BundleContext bundleContext) throws Exception {
chackAndPrepareFile(bundleContext);
checkAndPrepareFile(bundleContext);
String json = getJsonAsString(bundleContext);
FileUtils.FileHelper helper = new FileUtils.FileHelper(JSON_FILE_PATH);
if (!helper.isReadable()) {
// TODO throw exception
log.error("Platform connectons file {} is not readable", JSON_FILE_PATH);
log.error("Platform connections file {} is not readable", JSON_FILE_PATH);
return;
}
@ -89,7 +259,7 @@ public class ConnectionInitializer extends AbstractInitializer {
helper.updateMd5();
} else {
log.info("File is not changed, install/check connections");
// we need to create if absent connectoins with old timestamp
// we need to create if absent connections with old timestamp
// ConnectionManagerUtil.getService().createAndInstallConnections(json);
ConnectionManagerUtil.getService().checkInstallConnections(json, helper.getTimestamp());
}
@ -97,7 +267,7 @@ public class ConnectionInitializer extends AbstractInitializer {
}
private void chackAndPrepareFile(BundleContext context) throws IOException {
private void checkAndPrepareFile(BundleContext context) throws IOException {
File f = new File(JSON_FILE_PATH);
if (!f.exists()) {
FileUtils.string2file(getJsonAsString(context), JSON_FILE_PATH);

View File

@ -1,19 +1,5 @@
{
"connections": [
{
"nodeType": "connection",
"uuid": "connection-uuid-1",
"name": "entaxy-file",
"adapterName": "fileAdapter",
"platform": true,
"pathParameter": "data/shared",
"properties": {},
"options": {
"noop": true,
"fileName": "default.txt",
"allowNullBody": "true"
}
},
{
"nodeType": "connection",
"uuid": "connection-uuid-2",
@ -34,7 +20,8 @@
"nodeType": "connection",
"uuid": "connection-uuid-3",
"name": "entaxy-db-storage",
"adapterName": "postgresqlAdapter",
"adapterName.pg": "postgresqlAdapter",
"adapterName": "h2Adapter",
"platform": true,
"pathParameter": "entaxy.esb.storage",
"properties": {},
@ -44,7 +31,8 @@
"nodeType": "connection",
"uuid": "connection-uuid-4",
"name": "entaxy-db-cache",
"adapterName": "postgresqlAdapter",
"adapterName.pg": "postgresqlAdapter",
"adapterName": "h2Adapter",
"platform": true,
"pathParameter": "entaxy.esb.cache",
"properties": {},

View File

@ -0,0 +1,29 @@
{
"connections": [
{
"factoryId": "file-adapter",
"objectId": "entaxy-file",
"properties": {
"rootDirectory": "data/shared"
}
},
{
"factoryId": "file-adapter",
"objectId": "entaxy-file-internal",
"properties": {
"__parentConnection": {
"isRef": true,
"type": "entaxy.runtime.connection",
"required": true,
"isRefByValueOnly": true,
"refField": "rootDirectory",
"targetId": "entaxy-file"
},
"rootDirectory": {
"isCalculated": true,
"expression": "${__parentConnection}/.entaxy"
}
}
}
]
}

View File

@ -1,54 +0,0 @@
{
"connections": [
{
"nodeType": "connection",
"uuid": "connection-uuid-1",
"name": "entaxy-file",
"adapterName": "fileAdapter",
"platform": true,
"pathParameter": "data/shared",
"properties": {},
"options": {
"noop": true,
"fileName": "default.txt",
"allowNullBody": "true"
}
},
{
"nodeType": "connection",
"uuid": "connection-uuid-2",
"name": "entaxy-broker",
"adapterName": "artemisAmqpAdapter",
"platform": true,
"pathParameter": "queue:entaxy.default",
"properties": {
"url": "amqp://localhost:5672",
"username": "entaxy",
"password": "entaxy"
},
"options": {}
},
{
"nodeType": "connection",
"uuid": "connection-uuid-3",
"name": "entaxy-db-storage",
"adapterName.pg": "postgresqlAdapter",
"adapterName": "h2Adapter",
"platform": true,
"pathParameter": "entaxy.esb.storage",
"properties": {},
"options": {}
},
{
"nodeType": "connection",
"uuid": "connection-uuid-4",
"name": "entaxy-db-cache",
"adapterName.pg": "postgresqlAdapter",
"adapterName": "h2Adapter",
"platform": true,
"pathParameter": "entaxy.esb.cache",
"properties": {},
"options": {}
}
]
}

View File

@ -3,7 +3,7 @@
<parent>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
<artifactId>initializer</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<groupId>ru.entaxy.esb.platform.runtime.core.initializer</groupId>
<artifactId>core-initializer</artifactId>

View File

@ -3,7 +3,7 @@
<parent>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
<artifactId>initializer</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<groupId>ru.entaxy.esb.platform.runtime.core.initializer</groupId>
<artifactId>datasources-initializer</artifactId>

View File

@ -64,7 +64,7 @@ public class DataSourcesInitializer extends AbstractInitializer {
}
@Override
public void setCalllback(Callback callback) {
public void setCallback(Callback callback) {
DataSourcesInitializer.callback = callback;
}
}

View File

@ -3,7 +3,7 @@
<parent>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
<artifactId>initializer</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<groupId>ru.entaxy.esb.platform.runtime.core.initializer</groupId>
<artifactId>init-manager</artifactId>

View File

@ -133,7 +133,7 @@ public class InitManager {
try {
this.retries = Integer.parseInt(retriesValue);
} catch (NumberFormatException e) {
log.error("Retries paramater [{}] is not an integer", retriesValue);
log.error("Retries parameter [{}] is not an integer", retriesValue);
}
String intervalValue = params.get(Initializer.INITIALIZER_QUERY_STRING_PARAM_INTERVAL);
@ -141,7 +141,7 @@ public class InitManager {
try {
this.interval = Integer.parseInt(intervalValue);
} catch (NumberFormatException e) {
log.error("Interval paramater [{}] is not an integer", intervalValue);
log.error("Interval parameter [{}] is not an integer", intervalValue);
}
}
@ -221,6 +221,12 @@ public class InitManager {
}
public void runInitializer() {
Thread thread = new Thread(new Executor(this));
thread.setContextClassLoader(Thread.currentThread().getContextClassLoader());
thread.start();
}
public void setCallback() {
BundleWiring wiring = getBundle().adapt(BundleWiring.class);
ClassLoader cl = wiring.getClassLoader();
@ -230,7 +236,7 @@ public class InitManager {
log.info("Loaded class {}", clazz.getName());
Constructor<?> constructor = clazz.getConstructor();
Initializer initializer = (Initializer) constructor.newInstance();
initializer.setCalllback(this);
initializer.setCallback(this);
} catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
@ -241,7 +247,8 @@ public class InitManager {
synchronized (this.dependsOn) {
this.dependsOn.remove(meta.id);
if (!this.executed && this.canExecute())
this.execute();
// this.execute();
this.runInitializer();
}
}
@ -251,7 +258,7 @@ public class InitManager {
InitManager.this.updateById(id, true);
this.executed = true;
this.notifyDependent();
owner.setCalllback(null);
owner.setCallback(null);
}
};
@ -367,10 +374,12 @@ public class InitManager {
bundle.getBundleId(), bundle.getSymbolicName());
InitializerMeta meta = createMeta(initializerClass, bundle);
meta.runInitializer();
Thread thread = new Thread(new Executor(meta));
thread.setContextClassLoader(Thread.currentThread().getContextClassLoader());
thread.start();
// Thread thread = new Thread(new Executor(meta));
// thread.setContextClassLoader(Thread.currentThread().getContextClassLoader());
// thread.start();
}

View File

@ -53,7 +53,7 @@ public abstract class AbstractInitializer implements Initializer {
}
@Override
public void setCalllback(Callback callback) {
public void setCallback(Callback callback) {
// Ignore it by default
}
}

View File

@ -61,5 +61,5 @@ public interface Initializer {
public void setInitializerId(String id);
public String getInitializerId();
public void setCalllback(Initializer.Callback callback);
public void setCallback(Initializer.Callback callback);
}

View File

@ -3,7 +3,7 @@
<parent>
<groupId>ru.entaxy.esb.platform.runtime</groupId>
<artifactId>core</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
<artifactId>initializer</artifactId>

View File

@ -6,7 +6,7 @@
<parent>
<artifactId>storage-initializer</artifactId>
<groupId>ru.entaxy.esb.platform.runtime.core.initializer</groupId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<groupId>ru.entaxy.esb.platform.runtime.core.initializer.storage.initializer</groupId>

View File

@ -6,7 +6,7 @@
<parent>
<artifactId>storage-initializer</artifactId>
<groupId>ru.entaxy.esb.platform.runtime.core.initializer</groupId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<groupId>ru.entaxy.esb.platform.runtime.core.initializer.storage.initializer</groupId>

View File

@ -25,7 +25,7 @@
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<property name="blob_type" value="bytea" dbms="postgresql"/>
<property name="blob_type" value="oid" dbms="postgresql"/>
<property name="blob_type" value="blob"/>
<property name="text" value="varchar(1024)" dbms="h2"/>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>storage-initializer</artifactId>
<groupId>ru.entaxy.esb.platform.runtime.core.initializer</groupId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
<artifactId>initializer</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -3,7 +3,7 @@
<parent>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
<artifactId>management</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<groupId>ru.entaxy.esb.platform.runtime.core.management</groupId>
<artifactId>blueprint-generator-service</artifactId>

View File

@ -3,7 +3,7 @@
<parent>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
<artifactId>management</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<groupId>ru.entaxy.esb.platform.runtime.core.management</groupId>
<artifactId>cluster-node-management</artifactId>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
<artifactId>management</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<groupId>ru.entaxy.esb.platform.runtime.core.management</groupId>

View File

@ -19,7 +19,9 @@
*/
package ru.entaxy.esb.platform.core.management.connection;
public interface ConnectionMBean {
import ru.entaxy.esb.platform.base.management.core.api.RuntimeTypedMBean;
public interface ConnectionMBean extends RuntimeTypedMBean {
public static final String CONNECTION_KEY = "connection";

View File

@ -25,8 +25,11 @@ import javax.management.StandardMBean;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import ru.entaxy.esb.platform.base.management.core.api.EntaxyRuntimeTyped;
import ru.entaxy.esb.platform.core.management.connection.ConnectionMBean;
//@TODO move string to constant
@EntaxyRuntimeTyped(name = "entaxy.runtime.connection")
public class ConnectionMBeanImpl extends StandardMBean implements ConnectionMBean {
protected ManagedConnection connection;

View File

@ -91,7 +91,7 @@ public class ConnectionsMBeanImpl extends StandardMBean
}
@Override
public void addded(ManagedConnections connections) {
public void added(ManagedConnections connections) {
Hashtable props = new Hashtable<>();
// String jmxObjectName = "jmx.objectname";
// String objectName = "ru.entaxy.esb:group=platform,category=connections,connection=";
@ -108,6 +108,7 @@ public class ConnectionsMBeanImpl extends StandardMBean
descriptor.registration = bundleContext.registerService(ConnectionMBean.class
, service
, props);
managed.put(connection.getName(), descriptor);
} catch (Exception e) {
log.error("Error adding connection [" + connection.getName() + "]", e);
}

View File

@ -21,7 +21,7 @@ package ru.entaxy.esb.platform.core.management.connection.impl;
public interface ManagedConnectionsListener {
public void addded(ManagedConnections connections);
public void added(ManagedConnections connections);
public void removed(ManagedConnections connections);
}

View File

@ -26,6 +26,8 @@ import org.osgi.framework.BundleEvent;
import org.osgi.framework.wiring.BundleCapability;
import org.osgi.framework.wiring.BundleRevision;
import org.osgi.util.tracker.BundleTrackerCustomizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.entaxy.esb.platform.core.management.connection.ConnectionsMBean;
import ru.entaxy.esb.platform.core.management.connection.impl.ManagedConnection;
@ -35,6 +37,8 @@ import ru.entaxy.platform.base.support.CommonUtils;
public class DeployedConnectionCustomizer implements BundleTrackerCustomizer<ManagedConnections> {
private static final Logger log = LoggerFactory.getLogger(DeployedConnectionCustomizer.class);
protected ManagedConnectionsListener listener;
public DeployedConnectionCustomizer(ManagedConnectionsListener listener) {
@ -43,16 +47,20 @@ public class DeployedConnectionCustomizer implements BundleTrackerCustomizer<Man
@Override
public ManagedConnections addingBundle(Bundle bundle, BundleEvent event) {
log.debug("INSPECTING: " + bundle.getBundleId());
BundleRevision revision = bundle.adapt(BundleRevision.class);
if (revision == null)
return null;
log.debug("REVISION FOUND: " + bundle.getBundleId());
List<BundleCapability> capabilities = revision.getDeclaredCapabilities(ConnectionsMBean.CAPABILITY_NAMESPACE);
if ((capabilities==null) || (capabilities.size()==0))
return null;
log.debug("CAPABILITIES FOUND: " + bundle.getBundleId());
ManagedConnections result = new ManagedConnections();
for (BundleCapability capability: capabilities) {
Object val = capability.getAttributes().get("name");
String name = val==null?"":val.toString();
log.debug("CAPABILITIES/NAME [" + name + "] : " + bundle.getBundleId());
if (!CommonUtils.isValid(name))
continue;
val = capability.getAttributes().get("platform");
@ -66,7 +74,7 @@ public class DeployedConnectionCustomizer implements BundleTrackerCustomizer<Man
.bundleId(bundle.getBundleId());
result.managedConnections.add(mc);
}
listener.addded(result);
listener.added(result);
return result;
}
@ -78,6 +86,7 @@ public class DeployedConnectionCustomizer implements BundleTrackerCustomizer<Man
@Override
public void removedBundle(Bundle bundle, BundleEvent event, ManagedConnections object) {
log.debug("BUNDLE [{}] REMOVING", bundle.getBundleId());
listener.removed(object);
}

View File

@ -7,7 +7,7 @@
<parent>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
<artifactId>management</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<groupId>ru.entaxy.esb.platform.runtime.core.management</groupId>

View File

@ -23,6 +23,7 @@ import ru.entaxy.esb.platform.runtime.base.connecting.connection.Connection;
import java.util.List;
@Deprecated
public interface ConnectionManager {
/*
@Deprecated

View File

@ -37,8 +37,11 @@ import ru.entaxy.esb.platform.runtime.base.connecting.generator.Generated;
import ru.entaxy.esb.platform.runtime.base.connecting.producer.connection.util.ConnectionProducerUtil;
import ru.entaxy.esb.platform.runtime.core.management.connection.api.ConnectionManager;
import ru.entaxy.platform.core.artifact.Artifact;
import ru.entaxy.platform.core.artifact.ArtifactManifest;
import ru.entaxy.platform.core.artifact.Artifacts;
import ru.entaxy.platform.core.artifact.DeployedArtifact;
import ru.entaxy.platform.core.artifact.Manifested;
import ru.entaxy.platform.core.artifact.capabilities.ManifestCapabilityHelper;
import ru.entaxy.platform.core.artifact.installer.builder.Installer;
import ru.entaxy.platform.core.artifact.installer.builder.typed.BlueprintInstaller;
import ru.entaxy.platform.core.artifact.service.ArtifactService;
@ -155,9 +158,16 @@ public class ConnectionManagerImpl implements ConnectionManager {
.timestampedVersion(version)
.groupId(Artifact.DEFAULT_RUNTIME_GROUP_ID + "." + type)
.artifactId(type + "-" + name);
artifact.provideCapability(artifact.getCoordinates().getGroupId())
.attribute("name",connection.getName())
.attribute("platform", connection.isPlatform()?"true":"false");
if (artifact.isManifested()) {
ArtifactManifest manifest = ((Manifested)artifact).getManifest();
ManifestCapabilityHelper capabilityHelper = new ManifestCapabilityHelper(manifest);
capabilityHelper.provideCapability(artifact.getCoordinates().getGroupId())
.attribute("name",connection.getName())
.attribute("platform", connection.isPlatform()?"true":"false");
capabilityHelper.save();
}
log.info("Artifact of category [{}] is prepared: [{}]", artifact.getCategory(), artifact.getCoordinates());
return artifact;
} else {

View File

@ -3,11 +3,10 @@
<parent>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
<artifactId>management</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<groupId>ru.entaxy.esb.platform.runtime.core.management</groupId>
<artifactId>node-management</artifactId>
<version>1.8.1</version>
<packaging>bundle</packaging>
<name>ENTAXY :: PLATFORM :: RUNTIME :: CORE :: MANAGEMENT :: NODE MANAGEMENT </name>
<description>ENTAXY :: PLATFORM :: RUNTIME :: CORE :: MANAGEMENT :: NODE MANAGEMENT </description>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>ru.entaxy.esb.platform.runtime</groupId>
<artifactId>core</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
<artifactId>management</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<groupId>ru.entaxy.esb.platform.runtime.core.management</groupId>

View File

@ -52,14 +52,14 @@ public class ConnectorManagerAdapter implements ru.entaxy.esb.platform.core.mana
ConnectorService connectorService;
@Override
public void addConnector(String idOrName, String connectorFactoryId, Map<String, String> paramaters)
public void addConnector(String idOrName, String connectorFactoryId, Map<String, String> parameters)
throws Exception {
System system = getSystemByIdOrName(idOrName);
if (system == null)
throw new IllegalArgumentException("System not found by Id or Name [" + idOrName + "]");
ConnectorDto connectorDto = new ConnectorDto();
connectorDto.setConnectorParams(paramaters);
connectorDto.setConnectorParams(parameters);
connectorDto.setSystemUuid(system.getUuid());
connectorDto.setTemplateName(connectorFactoryId);

View File

@ -85,7 +85,7 @@ public class PermissionManagerAdapter implements ru.entaxy.esb.platform.core.man
}
@Override
public void createPremission(String objectId, String subjectId) throws Exception {
public void createPermission(String objectId, String subjectId) throws Exception {
PermissionDto dto = new PermissionDto(objectId, subjectId);
permissionManager.createPermission(dto);
}

View File

@ -7,7 +7,7 @@
<parent>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
<artifactId>management</artifactId>
<version>1.8.1</version>
<version>1.8.2</version>
</parent>
<groupId>ru.entaxy.esb.platform.runtime.core.management</groupId>

View File

@ -24,10 +24,11 @@ import ru.entaxy.esb.platform.base.management.core.api.Attribute;
import ru.entaxy.esb.platform.base.management.core.api.MBeanAnnotated;
import ru.entaxy.esb.platform.base.management.core.api.MBeanExportPolicy;
import ru.entaxy.esb.platform.base.management.core.api.Operation;
import ru.entaxy.esb.platform.base.management.core.api.RuntimeTypedMBean;
import ru.entaxy.esb.platform.base.management.core.utils.BundleAwareMBean;
@MBeanAnnotated(policy = MBeanExportPolicy.ANNOTATION_ENRICH)
public interface ConnectorMBean extends BundleAwareMBean {
public interface ConnectorMBean extends BundleAwareMBean, RuntimeTypedMBean {
public static interface Helper {

View File

@ -20,9 +20,10 @@
package ru.entaxy.esb.platform.core.management.profile;
import ru.entaxy.esb.platform.base.management.core.Qualifier;
import ru.entaxy.esb.platform.base.management.core.api.RuntimeTypedMBean;
import ru.entaxy.esb.platform.base.management.core.utils.BundleAwareMBean;
public interface DefaultRouteMBean extends BundleAwareMBean {
public interface DefaultRouteMBean extends BundleAwareMBean, RuntimeTypedMBean {
public static interface Helper {

View File

@ -30,10 +30,11 @@ import ru.entaxy.esb.platform.base.management.core.api.MBeanAnnotated;
import ru.entaxy.esb.platform.base.management.core.api.MBeanExportPolicy;
import ru.entaxy.esb.platform.base.management.core.api.Operation;
import ru.entaxy.esb.platform.base.management.core.api.Parameter;
import ru.entaxy.esb.platform.base.management.core.api.RuntimeTypedMBean;
import ru.entaxy.esb.platform.base.management.core.utils.BundleAwareMBean;
@MBeanAnnotated(policy = MBeanExportPolicy.ANNOTATION_ENRICH)
public interface ProfileMBean extends BundleAwareMBean {
public interface ProfileMBean extends BundleAwareMBean, RuntimeTypedMBean {
public static interface Helper {
@ -66,7 +67,7 @@ public interface ProfileMBean extends BundleAwareMBean {
@Operation(desc = "Adds connector to profile")
public void addConnector(
@Parameter(name = "factoryId", desc = "Connector factory ID") String connectorFactoryId
, @Parameter(name = "parameters", desc = "Connector parameters") Map<String, String> paramaters) throws Exception;
, @Parameter(name = "parameters", desc = "Connector parameters") Map<String, String> parameters) throws Exception;
@Operation(desc = "Removes connector from profile")
public void removeConnector(

View File

@ -23,7 +23,7 @@ import java.util.Map;
public interface ConnectorManager {
public void addConnector(String idOrName, String connectorFactoryId, Map<String, String> paramaters) throws Exception;
public void addConnector(String idOrName, String connectorFactoryId, Map<String, String> parameters) throws Exception;
public void removeConnector(String idOrName, String connectorName) throws Exception;

View File

@ -27,6 +27,6 @@ public interface PermissionManager {
public List<String> getSubjectPermissions(String subjectId) throws Exception;
public void createPremission(String objectId, String subjectId) throws Exception;
public void createPermission(String objectId, String subjectId) throws Exception;
}

View File

@ -30,6 +30,7 @@ import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.entaxy.esb.platform.base.management.core.api.EntaxyRuntimeTyped;
import ru.entaxy.esb.platform.base.management.core.utils.BundleAwareMBeanImpl;
import ru.entaxy.esb.platform.core.management.profile.ProfileMBean;
import ru.entaxy.esb.platform.core.management.profile.impl.helper.Helpers;
@ -37,6 +38,8 @@ import ru.entaxy.esb.system.auth.basic.jpa.api.entity.BasicAuthAccount;
import ru.entaxy.esb.system.jpa.entity.System;
import ru.entaxy.platform.base.support.CommonUtils;
// @TODO move string to constant
@EntaxyRuntimeTyped(name = "entaxy.runtime.profile")
public class ProfileMBeanImpl extends BundleAwareMBeanImpl<ManagedProfile, ProfileMBean> implements ProfileMBean {
private static final Logger log = LoggerFactory.getLogger(ProfileMBeanImpl.class);
@ -88,8 +91,8 @@ public class ProfileMBeanImpl extends BundleAwareMBeanImpl<ManagedProfile, Profi
}
@Override
public void addConnector(String connectorFactoryId, Map<String, String> paramaters) throws Exception {
this.helpers.connectorHelper.addConnector(getName(), connectorFactoryId, paramaters);
public void addConnector(String connectorFactoryId, Map<String, String> parameters) throws Exception {
this.helpers.connectorHelper.addConnector(getName(), connectorFactoryId, parameters);
}
@Override
@ -129,12 +132,12 @@ public class ProfileMBeanImpl extends BundleAwareMBeanImpl<ManagedProfile, Profi
@Override
public void allowSource(String idOrName) throws Exception {
helpers.permissionHelper.createPremission(idOrName, getUuid());
helpers.permissionHelper.createPermission(idOrName, getUuid());
}
@Override
public void allowTarget(String idOrName) throws Exception {
helpers.permissionHelper.createPremission(getUuid(), idOrName);
helpers.permissionHelper.createPermission(getUuid(), idOrName);
}

View File

@ -67,7 +67,7 @@ public class ConnectorHelperImpl implements ConnectorHelper {
}
@Override
public void addConnector(String idOrName, String connectorFactoryId, Map<String, String> paramaters)
public void addConnector(String idOrName, String connectorFactoryId, Map<String, String> parameters)
throws Exception {
throw new OperationNotSupportedException(EXPLANATION);
}
@ -95,9 +95,9 @@ public class ConnectorHelperImpl implements ConnectorHelper {
@Override
public void addConnector(String idOrName, String connectorFactoryId, Map<String, String> paramaters)
public void addConnector(String idOrName, String connectorFactoryId, Map<String, String> parameters)
throws Exception {
getEffectiveConnectorManager().addConnector(idOrName, connectorFactoryId, paramaters);
getEffectiveConnectorManager().addConnector(idOrName, connectorFactoryId, parameters);
}
@Override

View File

@ -23,10 +23,13 @@ import javax.management.NotCompliantMBeanException;
import org.osgi.framework.BundleContext;
import ru.entaxy.esb.platform.base.management.core.api.EntaxyRuntimeTyped;
import ru.entaxy.esb.platform.base.management.core.utils.BundleAwareMBeanImpl;
import ru.entaxy.esb.platform.core.management.profile.ConnectorMBean;
import ru.entaxy.esb.platform.core.management.profile.impl.helper.Helpers;
//@TODO move string to constant
@EntaxyRuntimeTyped(name = "entaxy.runtime.connector")
public class ConnectorMBeanImpl extends BundleAwareMBeanImpl<ManagedConnector, ConnectorMBean> implements ConnectorMBean {
protected Helpers helpers;

View File

@ -59,7 +59,7 @@ public class PermissionHelperImpl implements PermissionHelper {
throw new OperationNotSupportedException(EXPLANATION); }
@Override
public void createPremission(String objectId, String subjectId) throws Exception {
public void createPermission(String objectId, String subjectId) throws Exception {
throw new OperationNotSupportedException(EXPLANATION); }
};
}
@ -96,8 +96,8 @@ public class PermissionHelperImpl implements PermissionHelper {
}
@Override
public void createPremission(String objectId, String subjectId) throws Exception {
getEffectivePermissionManager().createPremission(objectId, subjectId);
public void createPermission(String objectId, String subjectId) throws Exception {
getEffectivePermissionManager().createPermission(objectId, subjectId);
}
}

View File

@ -23,9 +23,12 @@ import javax.management.NotCompliantMBeanException;
import org.osgi.framework.BundleContext;
import ru.entaxy.esb.platform.base.management.core.api.EntaxyRuntimeTyped;
import ru.entaxy.esb.platform.base.management.core.utils.BundleAwareMBeanImpl;
import ru.entaxy.esb.platform.core.management.profile.DefaultRouteMBean;
//@TODO move string to constant
@EntaxyRuntimeTyped(name = "entaxy.runtime.default-route")
public class DefaultRouteMBeanImpl extends BundleAwareMBeanImpl<ManagedRoute, DefaultRouteMBean> implements DefaultRouteMBean {

View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,18 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
<artifactId>object-producing</artifactId>
<version>1.8.2</version>
</parent>
<groupId>ru.entaxy.esb.platform.runtime.core.object-producing</groupId>
<artifactId>object-producer-api</artifactId>
<packaging>bundle</packaging>
<name>ENTAXY :: PLATFORM :: CORE :: OBJECT PRODUCING :: PRODUCER API</name>
<description>ENTAXY :: PLATFORM :: CORE :: OBJECT PRODUCING :: PRODUCER API</description>
<properties>
<bundle.osgi.export.pkg>ru.entaxy.platform.core.producer.api</bundle.osgi.export.pkg>
</properties>
</project>

View File

@ -0,0 +1,46 @@
/*-
* ~~~~~~licensing~~~~~~
* test-producers
* ==========
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.producer.api;
import java.util.List;
import ru.entaxy.platform.base.objects.factory.EntaxyFactory;
public interface EntaxyProducer {
public interface EntaxyProducerListener {
public void factoryAdded(String factoryId, String factoryType, EntaxyProducer producer);
public void factoryRemoved(String factoryId, String factoryType, EntaxyProducer producer);
}
public void addListener(EntaxyProducerListener listener);
public void removeListener(EntaxyProducerListener listener);
public String getProducerId();
public List<String> getSupportedTypes();
public List<EntaxyFactory> getAllFactories();
public List<EntaxyFactory> getFactoriesForType(String factoryType);
public EntaxyFactory getFactoryById(String factoryId);
}

View File

@ -0,0 +1,58 @@
/*-
* ~~~~~~licensing~~~~~~
* test-producers
* ==========
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.producer.api;
import java.util.List;
import com.google.gson.JsonObject;
import ru.entaxy.platform.base.objects.factory.EntaxyFactory;
public interface EntaxyProducerService {
public static interface INSTRUCTIONS {
public static final String PRINT_OUTPUT = "printOutput";
public static final String SKIP = "skip";
public static interface ARTIFACT {
public static final String VERSION = "artifact.version";
public static final String TIMESTAMP = "artifact.timestamp";
public static final String VERSION_POLICY = "artifact.version.policy";
}
};
public ProducerResult produce(String configuration);
public ProducerResult produce(JsonObject configuration);
public ProducerResult produce(String configuration, String instructions);
public ProducerResult produce(JsonObject configuration, String instructions);
public List<EntaxyProducer> getAllProducers();
public EntaxyProducer getProducerForType(String type);
public EntaxyFactory findFactoryById(String factoryId);
public List<ProducingCommandExecutor> getAvailableCommands();
public void registerCommand(ProducingCommandExecutor commandExecutor);
public ProducingCommandExecutor getCommandById(String id);
}

View File

@ -0,0 +1,89 @@
/*-
* ~~~~~~licensing~~~~~~
* object-producer-api
* ==========
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.producer.api;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
public class EntaxyProducerUtils {
protected static Gson sharedGson = new Gson();
protected static class InstructionsItemBuilder {
protected JsonObject instructionsJson;
protected InstructionsItemBuilder(JsonObject jsonObject) {
this.instructionsJson = jsonObject;
}
}
public static class InstructionsBuilder extends InstructionsItemBuilder {
protected InstructionsBuilder(JsonObject jsonObject) {
super(jsonObject);
}
public CommandBuilder command(String commandName) {
if (!instructionsJson.has(commandName))
instructionsJson.add(commandName, new JsonObject());
return new CommandBuilder(instructionsJson, instructionsJson.get(commandName).getAsJsonObject());
}
public CommandBuilder any() {
return this.command("*");
}
public JsonObject getInstructions() {
return this.instructionsJson;
}
public String getInstructionsString() {
return getInstructions().toString();
}
}
public static class CommandBuilder extends InstructionsBuilder {
protected JsonObject commandJson;
protected CommandBuilder(JsonObject instructionsObject, JsonObject commandObject) {
super(instructionsObject);
commandJson = commandObject;
}
public CommandBuilder set(String name, Object value) {
this.commandJson.remove(name);
this.commandJson.add(name, sharedGson.toJsonTree(value));
return this;
}
}
public static InstructionsBuilder instructions() {
return instructions(new JsonObject());
}
public static InstructionsBuilder instructions(JsonObject jsonObject) {
return new InstructionsBuilder(jsonObject);
}
}

View File

@ -0,0 +1,28 @@
/*-
* ~~~~~~licensing~~~~~~
* test-producers
* ==========
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.producer.api;
import ru.entaxy.platform.base.objects.factory.EntaxyFactory;
public interface EntaxyWrappedFactory extends EntaxyFactory {
public EntaxyFactory getOrigin();
}

View File

@ -0,0 +1,172 @@
/*-
* ~~~~~~licensing~~~~~~
* test-producers
* ==========
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.producer.api;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import ru.entaxy.platform.base.support.CommonUtils;
import ru.entaxy.platform.core.producer.api.ExecutionPlan.ExecutionPlanUpdate.OPERATIONS;
public class ExecutionPlan implements Iterable<ExecutionTask> {
public List<ExecutionTask> tasks = new ArrayList<>();
public ExecutionPlan(List<ExecutionTask> tasks) {
this.tasks = tasks;
}
protected Iterator<ExecutionTask> currentIterator;
protected ExecutionPlanIterator iterator = null;
@Override
public Iterator<ExecutionTask> iterator() {
this.currentIterator = this.tasks.listIterator();
if (this.iterator == null)
this.iterator = new ExecutionPlanIterator();
return this.iterator;
}
public List<ExecutionPlanUpdate.OPERATIONS> applyUpdate(ExecutionPlanUpdate planUpdate) throws Exception {
List<ExecutionPlanUpdate.OPERATIONS> result = new LinkedList<>();
for (ExecutionPlanUpdate.ExecutionPlanUpdateRecord record: planUpdate.records) {
if (ExecutionPlanUpdate.OPERATIONS.RESET.equals(record.operation)) {
String target = record.target;
reset(target);
result.add(OPERATIONS.RESET);
continue;
}
if (ExecutionPlanUpdate.OPERATIONS.UPDATE_INSTRUCTIONS.equals(record.operation)) {
String target = record.target;
synchronized (tasks) {
for (ExecutionTask task: tasks)
if (task.commandId.equals(target)) {
if ((task.instructions == null) || task.instructions.isEmpty())
task.instructions = new HashMap<>();
task.instructions.putAll(record.values);
result.add(OPERATIONS.UPDATE_INSTRUCTIONS);
continue;
}
}
}
}
return result;
}
protected void reset(String commandId) throws Exception {
synchronized (tasks) {
if (CommonUtils.isValid(commandId)) {
for (int i=0; i<tasks.size(); i++)
if (tasks.get(i).commandId.equals(commandId)) {
this.currentIterator = tasks.listIterator(i);
return;
}
} else {
this.currentIterator = tasks.listIterator();
}
}
}
protected Iterator<ExecutionTask> getCurrentIterator(){
return this.currentIterator;
}
protected class ExecutionPlanIterator implements Iterator<ExecutionTask>{
@Override
public boolean hasNext() {
return ExecutionPlan.this.getCurrentIterator().hasNext();
}
@Override
public ExecutionTask next() {
return ExecutionPlan.this.getCurrentIterator().next();
}
}
public static class ExecutionPlanUpdate {
public static enum OPERATIONS {
RESET,
UPDATE_INSTRUCTIONS
}
protected List<ExecutionPlanUpdateRecord> records = new LinkedList<>();
public static class ExecutionPlanUpdateRecord {
protected ExecutionPlanUpdate planUpdate;
protected OPERATIONS operation;
protected String target;
protected Map<String, Object> values = new LinkedHashMap<>();
protected ExecutionPlanUpdateRecord(ExecutionPlanUpdate planUpdate) {
this.planUpdate = planUpdate;
}
public ExecutionPlanUpdateRecord target(String value) {
this.target = value;
return this;
}
public ExecutionPlanUpdateRecord value(String name, Object value) {
this.values.put(name, value);
return this;
}
public ExecutionPlanUpdate complete() {
return this.planUpdate;
}
}
public static ExecutionPlanUpdate create() {
return new ExecutionPlanUpdate();
}
public ExecutionPlanUpdateRecord reset() {
ExecutionPlanUpdateRecord record = new ExecutionPlanUpdateRecord(this);
record.operation = OPERATIONS.RESET;
this.records.add(record);
return record;
}
public ExecutionPlanUpdateRecord updateInstructions() {
ExecutionPlanUpdateRecord record = new ExecutionPlanUpdateRecord(this);
record.operation = OPERATIONS.UPDATE_INSTRUCTIONS;
this.records.add(record);
return record;
}
}
}

View File

@ -0,0 +1,42 @@
/*-
* ~~~~~~licensing~~~~~~
* test-producers
* ==========
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.producer.api;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ExecutionTask {
public String commandId;
public ProducingCommandExecutor executor;
public Map<String, Object> instructions = new HashMap<>();
public List<ExecutionTask> dependsOn = new ArrayList<>();
public ExecutionTask() {
super();
}
public ExecutionTask(String id) {
super();
this.commandId = id;
}
}

View File

@ -0,0 +1,124 @@
/*-
* ~~~~~~licensing~~~~~~
* test-producers
* ==========
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.producer.api;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.entaxy.platform.core.producer.api.ExecutionPlan.ExecutionPlanUpdate;
public class ProducerResult {
private static final Logger log = LoggerFactory.getLogger(ProducerResult.class);
public static class CommandResult {
public String commandId;
public boolean result = true;
public boolean skipped = false;
public List<Exception> exceptions = new ArrayList<>();
public Object resultObject = null;
public ExecutionPlanUpdate planUpdate = null;
public CommandResult(String id) {
this.commandId = id;
}
public ProducerResult.CommandResult result(boolean resultValue) {
this.result = resultValue;
return this;
};
public ProducerResult.CommandResult resultObject(Object resultObjectValue) {
this.resultObject = resultObjectValue;
return this;
};
public ProducerResult.CommandResult exception(Exception exceptionValue) {
this.exceptions.add(exceptionValue);
return this;
};
}
public static ProducerResult createFailed(Exception e) {
ProducerResult result = new ProducerResult();
result.commandResult("#").exception(e).result(false);
return result;
}
protected List<CommandResult> commandResults = new LinkedList<>();
public Object getLastObject() {
if (commandResults.isEmpty())
return null;
return commandResults.get(commandResults.size()-1).resultObject;
}
public CommandResult getLastCommandResult() {
if (commandResults.isEmpty())
return null;
return commandResults.get(commandResults.size()-1);
}
public Map<String, List<Exception>> getAllExceptions(){
Map<String, List<Exception>> result = new LinkedHashMap<>();
for (CommandResult cr: commandResults)
if (!cr.exceptions.isEmpty())
result.put(cr.commandId, cr.exceptions);
return result;
}
public List<CommandResult> getCommandResults() {
return commandResults;
}
public <T> T findResultObject(Class<T> clazz){
log.debug("findResultObject : " + clazz.getName());
ListIterator<CommandResult> listIterator = commandResults.listIterator(commandResults.size());
while (listIterator.hasPrevious()) {
CommandResult cr = listIterator.previous();
log.debug("Inspecting : " + cr.commandId);
if ((cr.resultObject != null) && (clazz.isInstance(cr.resultObject))) {
log.debug("... found");
return clazz.cast(cr.resultObject);
}
log.debug("... not found");
}
return null;
}
public CommandResult commandResult(String id) {
CommandResult commandResult = new CommandResult(id);
this.commandResults.add(commandResult);
return commandResult;
}
public void addCommandResult(CommandResult commandResult) {
this.commandResults.add(commandResult);
}
}

View File

@ -0,0 +1,32 @@
/*-
* ~~~~~~licensing~~~~~~
* test-producers
* ==========
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.producer.api;
import java.util.List;
import java.util.Map;
public interface ProducingCommandExecutor {
public String getId();
public List<String> getRequiredPredecessors();
public List<String> getDescendants();
public List<Class<?>> getAcceptedInputClasses();
public List<Class<?>> getProducedOutputClasses();
public ProducerResult execute(ProducerResult currentResult, Map<String, Object> parameters);
}

View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,32 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
<artifactId>object-producing</artifactId>
<version>1.8.2</version>
</parent>
<groupId>ru.entaxy.esb.platform.runtime.core.object-producing</groupId>
<artifactId>object-producer-core</artifactId>
<packaging>bundle</packaging>
<name>ENTAXY :: PLATFORM :: CORE :: OBJECT PRODUCING :: PRODUCER CORE</name>
<description>ENTAXY :: PLATFORM :: CORE :: OBJECT PRODUCING :: PRODUCER CORE</description>
<properties>
<bundle.osgi.export.pkg>ru.entaxy.platform.core.producer.*</bundle.osgi.export.pkg>
</properties>
<dependencies>
<dependency>
<groupId>
ru.entaxy.esb.platform.runtime.core.object-producing
</groupId>
<artifactId>object-producer-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
<artifactId>artifact-management</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,162 @@
/*-
* ~~~~~~licensing~~~~~~
* test-producers
* ==========
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.producer.executor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.entaxy.platform.core.producer.api.EntaxyProducerService;
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;
public abstract class AbstractCommandExecutor implements ProducingCommandExecutor {
private static final Logger log = LoggerFactory.getLogger(AbstractCommandExecutor.class);
public static String SKIP_INSTRUSTION = "skip";
public static String PRINT_OUTPUT_INSTRUSTION = "printOutput";
protected EntaxyProducerService entaxyProducerService;
protected String id;
protected List<String> requiredPredecessors = new ArrayList<>();
protected List<String> descendants = new ArrayList<>();
protected List<Class<?>> acceptedInputClasses = new ArrayList<>();
protected List<Class<?>> producedOutputClasses = new ArrayList<>();
protected boolean isPrintOutput = false;
protected Map<String, Object> instructions;
protected AbstractCommandExecutor(EntaxyProducerService entaxyProducerService) {
this.entaxyProducerService = entaxyProducerService;
if (this.getClass().isAnnotationPresent(CommandExecutor.class)) {
CommandExecutor commandExecutorAnnotation = this.getClass().getAnnotation(CommandExecutor.class);
this.id = commandExecutorAnnotation.id();
this.requiredPredecessors = Arrays.asList(commandExecutorAnnotation.predecessors());
this.descendants = Arrays.asList(commandExecutorAnnotation.descendants());
this.acceptedInputClasses = Arrays.asList(commandExecutorAnnotation.inputs());
this.producedOutputClasses = Arrays.asList(commandExecutorAnnotation.outputs());
}
}
@Override
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public List<String> getRequiredPredecessors() {
return requiredPredecessors;
}
public void setRequiredPredecessors(List<String> requiredPredecessors) {
this.requiredPredecessors = requiredPredecessors;
}
@Override
public List<String> getDescendants() {
return descendants;
}
public void setDescendants(List<String> descendants) {
this.descendants = descendants;
}
@Override
public List<Class<?>> getAcceptedInputClasses() {
return acceptedInputClasses;
}
public void setAcceptedInputClasses(List<Class<?>> acceptedInputClasses) {
this.acceptedInputClasses = acceptedInputClasses;
}
@Override
public List<Class<?>> getProducedOutputClasses() {
return this.producedOutputClasses;
}
public void setProducedOutputClasses(List<Class<?>> producedOutputClasses) {
this.producedOutputClasses = producedOutputClasses;
}
@Override
public ProducerResult execute(ProducerResult currentResult, Map<String, Object> instructions) {
CommandResult cr = new CommandResult(getId());
this.instructions = instructions;
setPrintOutput(instructions);
if (isSkipped(instructions))
cr.skipped = true;
else
try {
cr.result = doExecute(currentResult, cr, instructions);
} catch (Exception e) {
log.error("Error executing [" + getId() + "]", e);
cr.exception(e).result(false);
}
currentResult.addCommandResult(cr);
return currentResult;
}
protected void setPrintOutput(Map<String, Object> parameters) {
if (parameters.containsKey(PRINT_OUTPUT_INSTRUSTION)) {
Object val = parameters.get(PRINT_OUTPUT_INSTRUSTION);
if (val == null)
return;
if (val instanceof Boolean)
this.isPrintOutput = (Boolean)val;
}
}
protected void printOutput(String message) {
if (this.isPrintOutput)
// OUTPUT TO CONSOLE
System.out.println(message);
}
protected boolean isSkipped(Map<String, Object> parameters) {
if (!parameters.containsKey(SKIP_INSTRUSTION))
return false;
Object obj = parameters.get(SKIP_INSTRUSTION);
if (obj instanceof Boolean)
return (Boolean)obj;
if (obj instanceof String)
return "true".equalsIgnoreCase((String)obj);
if (obj instanceof Number)
return ((Number)obj).intValue() > 0;
return false;
}
protected abstract boolean doExecute(ProducerResult currentResult
, CommandResult commandResult
, Map<String, Object> instructions) throws Exception;
}

View File

@ -0,0 +1,35 @@
/*-
* ~~~~~~licensing~~~~~~
* test-producers
* ==========
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.producer.executor;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface CommandExecutor {
String id();
String[] predecessors() default {};
String[] descendants() default {};
Class<?>[] inputs() default {};
Class<?>[] outputs() default {};
}

View File

@ -0,0 +1,86 @@
/*-
* ~~~~~~licensing~~~~~~
* object-producer-core
* ==========
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.producer.executor;
import java.util.HashMap;
import java.util.Map;
public class CommandInstructions {
protected Map<String, Object> instructionsMap = new HashMap<>();
public CommandInstructions() {
super();
}
public CommandInstructions(Map<String, Object> instructionsMap) {
super();
load(instructionsMap);
}
public void load(Map<String, Object> instructionsMap) {
this.instructionsMap = instructionsMap;
}
public boolean has(String name) {
return this.instructionsMap.containsKey(name);
}
public Boolean getBoolean(String name) {
if (!this.has(name))
return null;
Object value = this.instructionsMap.get(name);
if (value instanceof Boolean)
return (Boolean)value;
if (value instanceof String)
return "true".equals(((String)value).toLowerCase());
if (value instanceof Number)
return ((Number)value).longValue() > 0;
if (value instanceof Long)
return ((Long)value).longValue() > 0;
return value!=null;
}
public Object get(String name) {
return this.instructionsMap.get(name);
}
public String getString(String name) {
if (!has(name))
return null;
Object value = instructionsMap.get(name);
return value!=null?value.toString():"";
}
public Long getLong(String name) {
if (!has(name))
return null;
Object value = instructionsMap.get(name);
if (value instanceof Number)
return ((Number)value).longValue();
return (long)-1;
}
}

View File

@ -0,0 +1,209 @@
/*-
* ~~~~~~licensing~~~~~~
* test-producers
* ==========
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.producer.executor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import ru.entaxy.platform.base.support.CommonUtils;
import ru.entaxy.platform.base.support.DependencySorter;
import ru.entaxy.platform.base.support.JSONUtils;
import ru.entaxy.platform.core.producer.api.EntaxyProducerService;
import ru.entaxy.platform.core.producer.api.ExecutionPlan;
import ru.entaxy.platform.core.producer.api.ExecutionPlan.ExecutionPlanUpdate;
import ru.entaxy.platform.core.producer.api.ExecutionPlan.ExecutionPlanUpdate.OPERATIONS;
import ru.entaxy.platform.core.producer.api.ExecutionTask;
import ru.entaxy.platform.core.producer.api.ProducerResult;
import ru.entaxy.platform.core.producer.api.ProducerResult.CommandResult;
public class ProducingExecutor {
private static final Logger log = LoggerFactory.getLogger(ProducingExecutor.class);
protected static final String DEFAULT_EXECUTION_PLAN = "{'validate':{}}";
protected static final String ANY_COMMAND = "*";
protected JsonObject configuration;
protected EntaxyProducerService producerService;
protected JsonObject executionPlanJSON = JSONUtils.getJsonRootObject(DEFAULT_EXECUTION_PLAN);
protected ExecutionPlan executionPlan = null;
public ProducingExecutor(JsonObject configuration, String buildInstructions
, EntaxyProducerService producerService) throws Exception {
this.configuration = configuration;
this.producerService = producerService;
if (CommonUtils.isValid(buildInstructions)) {
executionPlanJSON = JSONUtils.getJsonRootObject(buildInstructions);
if (executionPlanJSON.entrySet().isEmpty())
executionPlanJSON = JSONUtils.getJsonRootObject(DEFAULT_EXECUTION_PLAN);
}
buildPlan();
}
protected ExecutionTask createExecutionTask(String id, Map<String, Object> parameters) {
ExecutionTask result = new ExecutionTask();
result.commandId = id;
result.instructions = parameters;
result.executor = producerService.getCommandById(result.commandId);
return result;
}
protected ExecutionTask createExecutionTask(Map<String, ExecutionTask> taskMap, String id, Map<String, Object> commandInstructions) {
if (!taskMap.containsKey(id))
taskMap.put(id, new ExecutionTask(id));
ExecutionTask result = taskMap.get(id);
result.instructions = commandInstructions;
result.executor = producerService.getCommandById(result.commandId);
return result;
}
protected void createDependency(Map<String, ExecutionTask> taskMap, String masterId, String slaveId) {
taskMap.get(slaveId).dependsOn.add(taskMap.get(masterId));
}
protected void buildPlan() throws Exception {
log.debug("building plan for execution on: \n" + configuration.toString());
log.debug("execution plan: \n" + executionPlanJSON.toString());
Map<String, ExecutionTask> taskMap = new HashMap<>();
Map<String, Object> anyCommandInstructions = new HashMap<>();
if (executionPlanJSON.has(ANY_COMMAND))
anyCommandInstructions = JSONUtils.element2map(executionPlanJSON.get(ANY_COMMAND));
List<String> neededCommands = new ArrayList<>();
for (String id: executionPlanJSON.keySet()) {
if (ANY_COMMAND.equals(id))
continue;
JsonElement jsonElement = executionPlanJSON.get(id);
Map<String, Object> commandInstructions = new HashMap<>(anyCommandInstructions);
commandInstructions.putAll(JSONUtils.element2map(jsonElement));
neededCommands.add(id);
if (createExecutionTask(taskMap, id, commandInstructions).executor == null) {
log.error("Command [{}] not found", id);
throw new Exception("Command not found: " + id);
}
}
List<String> commandsToCheck = List.copyOf(neededCommands);
List<String> newCommandsToCheck = new ArrayList<>();
// add required commands
while (!commandsToCheck.isEmpty()) {
newCommandsToCheck.clear();
for (String command: commandsToCheck) {
log.debug("Checking command [{}]", command);
for (String s: taskMap.get(command).executor.getRequiredPredecessors()) {
if (!neededCommands.contains(s)) {
log.debug("Adding command [{}]", s);
newCommandsToCheck.add(s);
neededCommands.add(s);
if (createExecutionTask(taskMap, s, anyCommandInstructions).executor == null) {
log.error("Command [{}] not found", s);
throw new Exception("Command not found: " + s);
}
}
createDependency(taskMap, s, command);
}
}
commandsToCheck = List.copyOf(newCommandsToCheck);
}
// create backward dependencies by descendants
for (String s: taskMap.keySet()) {
for (String descendant: taskMap.get(s).executor.getDescendants()) {
if (taskMap.containsKey(descendant))
createDependency(taskMap, s, descendant);
}
}
// arrange commands
executionPlan = new ExecutionPlan(new LinkedList<>(taskMap.values()));
List<ExecutionTask> sorted = DependencySorter.getSortedList(
executionPlan.tasks,
new DependencySorter.DependencyProvider<ExecutionTask>() {
@Override
public List<ExecutionTask> getDependencies(ExecutionTask inspectedObject) {
return inspectedObject.dependsOn;
}
});
executionPlan.tasks = sorted;
}
public ProducerResult execute() {
ProducerResult producerResult = new ProducerResult();
producerResult.commandResult("#plan").result(true).resultObject(executionPlan);
producerResult.commandResult("#init").result(true).resultObject(configuration);
return execute(producerResult);
}
protected ProducerResult execute(ProducerResult producerResult) {
Iterator<ExecutionTask> taskIterator = executionPlan.iterator();
while (taskIterator.hasNext()) {
ExecutionTask task = taskIterator.next();
task.executor.execute(producerResult, task.instructions);
CommandResult cr = producerResult.getLastCommandResult();
if (cr.planUpdate != null) {
try {
log.debug("Applying plan update");
List<ExecutionPlanUpdate.OPERATIONS> result = executionPlan.applyUpdate(cr.planUpdate);
producerResult.commandResult("#planUpdate").result(true).resultObject(cr.planUpdate);
if (result.contains(OPERATIONS.RESET))
producerResult.commandResult("#reset").result(true).resultObject(cr.planUpdate);
} catch (Exception e) {
log.error("Error applying plan update", e);
producerResult.commandResult("#planUpdate").result(false).resultObject(cr.planUpdate).exception(e);
}
}
}
return producerResult;
}
}

View File

@ -0,0 +1,79 @@
/*-
* ~~~~~~licensing~~~~~~
* test-producers
* ==========
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.producer.executor.commands;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.JsonObject;
import ru.entaxy.platform.core.producer.api.EntaxyProducerService;
import ru.entaxy.platform.core.producer.api.ProducerResult;
import ru.entaxy.platform.core.producer.api.ProducerResult.CommandResult;
import ru.entaxy.platform.core.producer.executor.AbstractCommandExecutor;
import ru.entaxy.platform.core.producer.executor.CommandExecutor;
import ru.entaxy.platform.core.producer.executor.objectmodel.FactoredObject;
import ru.entaxy.platform.core.producer.executor.objectmodel.FactoredObjectRef;
import ru.entaxy.platform.core.producer.executor.objectmodel.ObjectModel;
@CommandExecutor(id = "analyze", inputs = {JsonObject.class}, predecessors = {})
public class Analyze extends AbstractCommandExecutor {
private static final Logger log = LoggerFactory.getLogger(Analyze.class);
public Analyze(EntaxyProducerService entaxyProducerService) {
super(entaxyProducerService);
}
@Override
protected boolean doExecute(ProducerResult currentResult, CommandResult commandResult,
Map<String, Object> instructions) throws Exception {
log.info("Executing command [{}]", getId());
JsonObject jo = currentResult.findResultObject(JsonObject.class);
printOutput("\n\n\t== ANALYZE == \n\n");
printOutput("\n\tIncoming JSON ::\n\n");
printOutput(jo.toString());
ObjectModel om = new ObjectModel();
om.load(jo);
om.checkRefs();
printOutput("\n\tObjectModel ::\n\n");
for (FactoredObject fo: om.objects)
printOutput("Object :: [" + fo.getObjectId() + "/" + fo.factoryId + ":" + fo.getObjectType() + "]");
for (FactoredObjectRef fo: om.refs)
printOutput("Reference :: [" + fo.definedIn.getObjectId() + " -> " + fo.getTargetId()
+ "; isLink=" + fo.isLink()
+ "; isExternal=" + fo.isExternal()
+ "]");
commandResult.resultObject(om);
printOutput("\n\tOutgoing JSON ::\n\n");
printOutput(om.getJsonCurrent().toString());
return true;
}
}

View File

@ -0,0 +1,151 @@
/*-
* ~~~~~~licensing~~~~~~
* test-producers
* ==========
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.producer.executor.commands;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.entaxy.esb.platform.runtime.base.connecting.generator.Generated;
import ru.entaxy.platform.base.support.CommonUtils;
import ru.entaxy.platform.core.artifact.Artifact;
import ru.entaxy.platform.core.artifact.ArtifactManifest;
import ru.entaxy.platform.core.artifact.Artifacts;
import ru.entaxy.platform.core.artifact.Manifested;
import ru.entaxy.platform.core.artifact.capabilities.ManifestCapabilityHelper;
import ru.entaxy.platform.base.objects.EntaxyObject.FIELDS;
import ru.entaxy.platform.base.objects.EntaxyObject.HEADERS;
import ru.entaxy.platform.core.producer.api.EntaxyProducerService;
import ru.entaxy.platform.core.producer.api.ProducerResult;
import ru.entaxy.platform.core.producer.api.ProducerResult.CommandResult;
import ru.entaxy.platform.core.producer.executor.AbstractCommandExecutor;
import ru.entaxy.platform.core.producer.executor.CommandExecutor;
import ru.entaxy.platform.core.producer.executor.generationmodel.GeneratedHeaders;
import ru.entaxy.platform.core.producer.executor.generationmodel.GeneratedList;
import ru.entaxy.platform.core.producer.executor.support.ArtifactList;
@CommandExecutor(id = "build", predecessors = {"generate"})
public class Build extends AbstractCommandExecutor {
private static final Logger log = LoggerFactory.getLogger(Build.class);
public Build(EntaxyProducerService entaxyProducerService) {
super(entaxyProducerService);
}
@Override
protected boolean doExecute(ProducerResult currentResult, CommandResult commandResult,
Map<String, Object> instructions) throws Exception {
printOutput("\n\t == BUILDING ==\n");
GeneratedList generated = currentResult.findResultObject(GeneratedList.class);
if (generated == null) {
log.info("Nothing to generate");
return true;
}
ArtifactList artifactList = new ArtifactList();
for (Generated g: generated) {
if (g == null)
continue;
Artifact artifact = Artifacts.fromGenerated(g);
if ((artifact == null) || Artifact.ARTIFACT_CATEGORY_UNKNOWN.equals(artifact.getCategory())
|| !CommonUtils.isValid(artifact.getCategory())) {
log.info("Artifact is not buildable");
continue;
}
log.info("Built artifact of category [{}]", artifact.getCategory());
Map<String, String> headers = GeneratedHeaders.getHeaders(g.getProperties()).getAsStringMap();
String mainObjectValue = headers.get(HEADERS.MAIN_OBJECT);
if (!CommonUtils.isValid(mainObjectValue))
throw new Exception("Main object not found");
String[] mainObjectData = mainObjectValue.split(":");
if (mainObjectData.length<2)
throw new Exception("Main object not complete: [" + mainObjectValue + "]");
String versionPolicy = g.getProperties().getOrDefault(
EntaxyProducerService.INSTRUCTIONS.ARTIFACT.VERSION_POLICY,
instructions.getOrDefault(
EntaxyProducerService.INSTRUCTIONS.ARTIFACT.VERSION_POLICY
, ""))
.toString();
String timestamp = g.getProperties().getOrDefault(
EntaxyProducerService.INSTRUCTIONS.ARTIFACT.TIMESTAMP,
instructions.getOrDefault(
EntaxyProducerService.INSTRUCTIONS.ARTIFACT.TIMESTAMP
, ""))
.toString();
artifact.getCoordinates()
.groupId(mainObjectData[1])
.artifactId(mainObjectData[0])
.version("1")
.versionPolicy(versionPolicy)
.timestamp(timestamp);
if (artifact instanceof Manifested) {
ArtifactManifest manifest = ((Manifested)artifact).getManifest();
manifest.getCustomAttributes().putAll(headers);
// Generate provided capabilities for every included object
ManifestCapabilityHelper helper = new ManifestCapabilityHelper(manifest);
String objectsValue = headers.getOrDefault(HEADERS.GENERATED_OBJECTS, "");
if (CommonUtils.isValid(objectsValue)) {
String[] objects = objectsValue.split(",");
for (int i=0; i<objects.length; i++) {
String[] objectData = objects[i].split(":");
if (objectData.length<2)
continue;
String objectId = objectData[0];
String objectType = objectData[1];
if (!CommonUtils.isValid(objectId) || !CommonUtils.isValid(objectType))
continue;
objectId = objectId.trim();
objectType = objectType.trim();
Map<String, Object> attributes = null;
if (g.getProperties().containsKey(FIELDS.FIELDS_TO_PUBLISH)) {
Object map = g.getProperties().get(FIELDS.FIELDS_TO_PUBLISH);
if (map != null) {
attributes = (Map<String, Object>)((Map<String, Object>)map).get(objectId);
}
}
helper.provideCapability(objectType).attributes(attributes);
}
helper.save();
}
}
artifact.getProperties().putAll(g.getProperties());
artifactList.add(artifact);
printOutput("\n\t == " + artifact.getCoordinates().toString() + " ==\n");
printOutput(new String(artifact.asByteArray()));
printOutput("\n\t == \n");
}
commandResult.resultObject(artifactList);
return true;
}
}

View File

@ -0,0 +1,79 @@
/*-
* ~~~~~~licensing~~~~~~
* test-producers
* ==========
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.producer.executor.commands;
import java.util.Map;
import java.util.stream.Collectors;
import ru.entaxy.platform.core.artifact.Artifact;
import ru.entaxy.platform.core.artifact.DeployedArtifact;
import ru.entaxy.platform.core.artifact.service.ArtifactService;
import ru.entaxy.platform.core.producer.api.EntaxyProducerService;
import ru.entaxy.platform.core.producer.api.ProducerResult;
import ru.entaxy.platform.core.producer.api.ProducerResult.CommandResult;
import ru.entaxy.platform.core.producer.executor.AbstractCommandExecutor;
import ru.entaxy.platform.core.producer.executor.CommandExecutor;
import ru.entaxy.platform.core.producer.executor.support.ArtifactList;
import ru.entaxy.platform.core.producer.executor.support.ArtifactsHelper;
import ru.entaxy.platform.core.producer.executor.support.DeployedArtifactList;
@CommandExecutor(id = "deploy", predecessors = {"build"})
public class Deploy extends AbstractCommandExecutor {
public static final String DEPLOY_LOCAL_INSTRUCTION = "deployLocal";
public Deploy(EntaxyProducerService entaxyProducerService) {
super(entaxyProducerService);
}
@Override
protected boolean doExecute(ProducerResult currentResult, CommandResult commandResult,
Map<String, Object> instructions) throws Exception {
boolean deployLocal = false;
Object deployLocalValue = instructions.get(DEPLOY_LOCAL_INSTRUCTION);
if (deployLocalValue != null)
if (deployLocalValue instanceof Boolean)
deployLocal = (Boolean)deployLocalValue;
ArtifactList artifactList = currentResult.findResultObject(ArtifactList.class);
DeployedArtifactList deployedArtifactList = new DeployedArtifactList();
ArtifactService artifactService = ArtifactsHelper.getInstance().getArtifactService();
for (Artifact artifact: artifactList) {
DeployedArtifact da = deployLocal
?artifactService.deployLocal(artifact)
:artifactService.deployShared(artifact);
deployedArtifactList.add(da);
}
printOutput("\n\n\t== DEPLOY ==\n");
printOutput("DEPLOYED: ["
+ deployedArtifactList.stream().map(da->da.getLocation()).collect(Collectors.joining(","))
+ "]");
commandResult.resultObject(deployedArtifactList);
return true;
}
}

View File

@ -0,0 +1,548 @@
/*-
* ~~~~~~licensing~~~~~~
* test-producers
* ==========
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.producer.executor.commands;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import ru.entaxy.platform.base.support.CommonUtils;
import ru.entaxy.platform.base.support.JSONUtils;
import ru.entaxy.platform.base.objects.EntaxyObject.FIELDS;
import ru.entaxy.platform.base.objects.factory.EntaxyFactory;
import ru.entaxy.platform.base.objects.factory.EntaxyFactory.CONFIGURATION.OUTPUTS;
import ru.entaxy.platform.base.objects.factory.EntaxyFactory.FieldInfo;
import ru.entaxy.platform.base.objects.factory.EntaxyFactory.RefFieldInfo;
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.executor.AbstractCommandExecutor;
import ru.entaxy.platform.core.producer.executor.CommandExecutor;
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;
import ru.entaxy.platform.core.producer.impl.FieldInfoImpl;
import ru.entaxy.platform.core.producer.impl.RefFieldInfoImpl;
@CommandExecutor(id = "enrich", predecessors = {"layout"})
public class Enrich extends AbstractCommandExecutor {
private static final Logger log = LoggerFactory.getLogger(Enrich.class);
public Enrich(EntaxyProducerService entaxyProducerService) {
super(entaxyProducerService);
// TODO Auto-generated constructor stub
}
// TODO move to FieldInfo
protected boolean isLookup(FieldInfo fi) {
if (fi.getJsonOrigin().has("lookup")) {
String lookup = fi.getJsonOrigin().get("lookup").getAsString();
return CommonUtils.isValid(lookup);
}
return false;
}
// TODO move to FieldInfo
public String getLookup(FieldInfo fi) {
return fi.getJsonOrigin().has("lookup")
?fi.getJsonOrigin().get("lookup").getAsString()
:null;
}
@Override
protected boolean doExecute(ProducerResult currentResult, CommandResult commandResult,
Map<String, Object> instructions) throws Exception {
int count = 15;
if (!instructions.containsKey("_count")) {
instructions.put("_count", count);
}
if (instructions.get("_count") instanceof Integer)
count = (Integer)instructions.get("_count");
else if (instructions.get("_count") instanceof Number)
count = ((Number)instructions.get("_count")).intValue();
count--;
printOutput("\n\n\t== ENRICH == #" + count + " ==\n\n");
ObjectModel objectModel = currentResult.findResultObject(ObjectModel.class);
objectModel.startTracking();
JsonObject incomingJson = objectModel.getJsonCurrent().deepCopy();
Gson gson = new Gson();
// enrich type to ensure we can resolve refs
for (FactoredObject fo: objectModel.objects) {
// skip proxies
if (fo instanceof FactoredObjectProxy)
continue;
String factoryId = fo.factoryId;
EntaxyFactory factory = entaxyProducerService.findFactoryById(factoryId);
if (factory == null)
throw new Exception("Factory not found: [" + factoryId + "]");
String objectType = fo.getObjectType();
if (!CommonUtils.isValid(objectType)) {
fo.setObjectType(factory.getFactoryType());
objectModel.setDirty();
}
}
// enrich fields
for (FactoredObject fo: objectModel.objects) {
// skip proxies
if (fo instanceof FactoredObjectProxy)
continue;
String factoryId = fo.factoryId;
EntaxyFactory factory = entaxyProducerService.findFactoryById(factoryId);
List<FieldInfo> delayed = new LinkedList<>();
List<String> processedFieldNames = new LinkedList<>();
JsonObject objectOrigin = fo.origin;
if (JSONUtils.setValue(objectOrigin, FIELDS.PROPERTIES, new JsonObject(), true)) {
printOutput("[DIRTY] CREATED 'properties' for [" + fo.getObjectId() + "/" + fo.getObjectType() + "]");
objectModel.setDirty();
}
JsonObject objectProperties = objectOrigin.get(FIELDS.PROPERTIES).getAsJsonObject();
List<FieldInfo> factoryFields = factory.getFields(OUTPUTS.OUTPUT_TYPE_INIT);
for (FieldInfo fi: factoryFields) {
FieldInfo fieldInfo = fi;
log.info("\n ITERATING FOR FIELD: " + fi.getName() + "\n" + fi.getJsonOrigin());
if (FIELDS.OBJECT_ID.equals(fi.getName())
|| FIELDS.OBJECT_TYPE.equals(fi.getName()))
continue;
// check if lookup
if (isLookup(fi)) {
String lookup = getLookup(fi);
log.info("\n LOOKUP FIELD: " + fi.getName() + " -> " + lookup);
// replace lookup with corresponding ref
Optional<FieldInfo> toLookupOpt = factoryFields.stream()
.filter(f -> lookup.equals(f.getName()))
.findFirst();
if (!toLookupOpt.isPresent()) {
// field to lookup not found
log.error("Factory configuration error: loooked up field [{}] referenced by [{}] not found in factory [{}]"
, lookup
, fi.getName()
, factory.getFactoryId());
continue;
}
FieldInfo toLookup = toLookupOpt.get();
RefFieldInfoImpl fieldInfoImpl = new RefFieldInfoImpl();
fieldInfoImpl.name(fi.getName())
.description(fi.getDescription())
.displayName(fi.getDisplayName())
.immutable(fi.isImmutable())
.required(fi.isRequired());
fieldInfoImpl.refField(
fi.getJsonOrigin().has(FIELDS.REF_FIELD)
?fi.getJsonOrigin().get(FIELDS.REF_FIELD).getAsString()
:""
)
.refByValueOnly(true)
.backRef(false);
fieldInfoImpl.setConditional(fi.isConditional());
fieldInfoImpl.setCondition(fi.getCondition());
fieldInfoImpl.setRef(true);
fieldInfoImpl.setType(toLookup.getType());
JsonObject lookupJson = fi.getJsonOrigin().deepCopy();
JsonObject lookedUpJson = toLookup.getJsonOrigin();
for (Entry<String, JsonElement> entry: lookedUpJson.entrySet()) {
if (lookupJson.has(entry.getKey()))
lookupJson.remove(entry.getKey());
lookupJson.add(entry.getKey(), entry.getValue());
}
fieldInfoImpl.setJsonOrigin(lookupJson);
log.info("\n LOOKUP FIELD JSON: \n" + lookupJson.toString());
fieldInfo = fieldInfoImpl;
if (!processedFieldNames.contains(lookup) || fi.isConditional()) {
delayed.add(fieldInfo);
continue;
}
}
// check if conditional
if (fi.isConditional()) {
delayed.add(fi);
continue;
}
processField(objectModel, fieldInfo, fo, gson);
processedFieldNames.add(fieldInfo.getName());
}
int delayedCount = 0;
while (delayedCount != delayed.size()) {
List<FieldInfo> toRemove = new ArrayList<>();
delayedCount = delayed.size();
for (FieldInfo fi: delayed) {
// first check conditionals
if (fi.isConditional()) {
String condition = fi.getCondition();
if (condition.startsWith("${"))
condition = condition.substring(2, condition.lastIndexOf("}"));
if (!objectProperties.has(condition))
continue;
Object conditionValue = JSONUtils.element2object(objectProperties.get(condition));
if (conditionValue == null) {
continue;
} else if (conditionValue instanceof String) {
if (!"true".equalsIgnoreCase((String)conditionValue)) {
toRemove.add(fi);
continue;
}
} else if (conditionValue instanceof Number) {
if (((Number)conditionValue).doubleValue()<=0) {
toRemove.add(fi);
continue;
}
} else if (conditionValue instanceof Boolean) {
if (!(Boolean)conditionValue) {
toRemove.add(fi);
continue;
}
}
}
// then check lookups
if (isLookup(fi)) {
if (!processedFieldNames.contains(getLookup(fi))) {
continue;
}
}
// we're still here so process
processField(objectModel, fi, fo, gson);
processedFieldNames.add(fi.getName());
}
delayed.removeAll(toRemove);
}
}
if (objectModel.stopTracking() && count>0) {
// 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();
}
instructions.put("_count", count);
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;
}
protected boolean processField(ObjectModel objectModel, FieldInfo fi, FactoredObject fo, Gson gson) {
log.info("\nPROCESSING FIELD: " + fi.getName());
if (fi.isRef()) {
log.info("\nPROCESSING REF: " + fi.getName());
return processRef(objectModel, (RefFieldInfo)fi, fo, gson);
}
boolean result = false;
JsonObject objectOrigin = fo.origin;
JsonObject objectProperties = objectOrigin.get(FIELDS.PROPERTIES).getAsJsonObject();
boolean exists = objectProperties.has(fi.getName());
if (!exists) {
if (fi.isRequired()) {
printOutput("[DIRTY] CREATED " + fi.getName() + " for [" + fo.getObjectId() + "/" + fo.getObjectType() + "]");
objectProperties.add(fi.getName(), fi.getJsonOrigin().get(FIELDS.DEFAULT_VALUE));
objectModel.setDirty();
result = true;
}
}
return result;
}
protected boolean processRef(ObjectModel objectModel, RefFieldInfo fi, FactoredObject fo, Gson gson) {
boolean result = false;
JsonObject objectOrigin = fo.origin;
JsonObject objectProperties = objectOrigin.get(FIELDS.PROPERTIES).getAsJsonObject();
boolean exists = objectProperties.has(fi.getName());
if (!exists) {
if (fi.isRequired()) {
if (fi.isBackRef()) {
// it's a backRef, so we'll try to find object of the given type
// referencing current object
List<FactoredObject> candidates = fo.references.stream()
.filter(ref->!ref.isBackRef())
.map(ref->ref.definedIn)
.filter(obj->fi.getType().equals(obj.getObjectType()))
.collect(Collectors.toList());
if (candidates.size()>0) {
// we found candidates, so just add ref to first one
// no matter what object is there
// 'cause the ref being backRef won't be ever generated
FactoredObjectRef ref = new FactoredObjectRef(objectModel, candidates.get(0));
ref.definedIn = fo;
fo.embed(ref);
ref.setBackRef(true);
ref.setResolved(true);
printOutput("[DIRTY] CREATED " + fi.getName() + " for [" + fo.getObjectId() + "/" + fo.getObjectType() + "]");
objectProperties.add(fi.getName(), ref.origin);
result = true;
} else {
// try to use default value
printOutput("[DIRTY] CREATED " + fi.getName() + " for [" + fo.getObjectId() + "/" + fo.getObjectType() + "]");
objectProperties.add(fi.getName(), fi.getJsonOrigin().get(FIELDS.DEFAULT_VALUE));
objectModel.setDirty();
result = true;
}
} else {
// it's a direct ref
FactoredObject candidate = null;
// try to find by backRef
List<FactoredObjectRef> backrefs = objectModel.refs.stream()
.filter(ref->
(ref.isBackRef()
&& (ref.getTargetObject().equals(fo))
&& (ref.definedIn.getObjectType().equals(fi.getType()))
)
)
.collect(Collectors.toList());
if (backrefs.size()>0) {
// we can use any
candidate = backrefs.get(0).definedIn;
} else {
// try to find objects of required type defined in current
List<FactoredObject> candidates = objectModel.objects
.stream()
.filter(
obj->((obj != fo) && (obj.getObjectType().equals(fi.getType())))
)
.collect(Collectors.toList());
// we can use the only one
if (candidates.size() == 1)
candidate = candidates.get(0);
else if (candidates.size()>1) {
// search for defined in current
candidates = candidates.stream().filter(c->c.isDefinedIn(fo))
.collect(Collectors.toList());
if (candidates.size()==1)
candidate = candidates.get(0);
}
}
if (candidate != null) {
FactoredObjectRef ref = new FactoredObjectRef(objectModel, candidate);
ref.definedIn = fo;
fo.embed(ref);
ref.origin.addProperty(FIELDS.IS_REF_BY_VALUE_ONLY, fi.isRefByValueOnly());
ref.origin.addProperty(FIELDS.REF_FIELD, fi.getRefField());
printOutput("[DIRTY] CREATED " + fi.getName() + " for [" + fo.getObjectId() + "/" + fo.getObjectType() + "]");
objectProperties.add(fi.getName(), ref.origin);
objectModel.setDirty();
result = true;
} else {
/*
if (fi.getJsonOrigin().has(FIELDS.DEFAULT_VALUE)) {
printOutput("[DIRTY] CREATED " + fi.getName() + " for [" + fo.getObjectId() + "/" + fo.getObjectType() + "]");
objectProperties.add(fi.getName(), fi.getJsonOrigin().get(FIELDS.DEFAULT_VALUE));
objectModel.setDirty();
result = true;
} else { */
// we just create a ref to nothing
// hoping it will be enriched next time
JsonObject refCopy = fi.getJsonOrigin().deepCopy();
if (isLookup(fi)) {
// remove default targetId, 'cause it will be resolved on next enrich
refCopy.remove(FactoredObjectRef.TARGET_ID_FIELD);
}
printOutput("[DIRTY] CREATED " + fi.getName() + " for [" + fo.getObjectId() + "/" + fo.getObjectType() + "]");
printOutput("\t" + refCopy.toString());
objectProperties.add(fi.getName(), refCopy);
objectModel.setDirty();
result = true;
//}
}
}
}
} else {
// we found something where must be ref
JsonElement currentValue = objectProperties.get(fi.getName());
JsonObject refCopy = fi.getJsonOrigin().deepCopy();
if (currentValue.isJsonObject()) {
// this is some object
printOutput("CURRENT VALUE [" + currentValue.toString() + "] IS OBJECT IN " + fi.getName() + " for [" + fo.getObjectId() + "/" + fo.getObjectType() + "]");
JsonObject currentObject = currentValue.getAsJsonObject();
if (currentObject.has(FIELDS.IS_REF)) {
String targetType = currentObject.has(FactoredObjectRef.TARGET_TYPE_FIELD)
?currentObject.get(FactoredObjectRef.TARGET_TYPE_FIELD).getAsString()
:null;
if (!CommonUtils.isValid(targetType)){
String refType = fi.getType();
targetType = CommonUtils.isValid(refType)?refType:"*";
currentObject.remove(FactoredObjectRef.TARGET_TYPE_FIELD);
currentObject.addProperty(FactoredObjectRef.TARGET_TYPE_FIELD, targetType);
objectModel.setDirty();
}
if (!currentObject.has(FIELDS.IS_REF_BY_VALUE_ONLY)
|| !currentObject.has(FIELDS.REF_FIELD)
|| !currentObject.has(FIELDS.IS_BACK_REF))
{
currentObject.addProperty(FIELDS.IS_REF_BY_VALUE_ONLY, fi.isRefByValueOnly());
currentObject.addProperty(FIELDS.REF_FIELD, fi.getRefField());
currentObject.addProperty(FIELDS.IS_BACK_REF, fi.isBackRef());
printOutput("[DIRTY] UPDATED " + fi.getName() + " for [" + fo.getObjectId() + "/" + fo.getObjectType() + "]");
objectModel.setDirty();
}
if (isLookup(fi)) {
String lookup = getLookup(fi);
JsonElement lookupValue = objectProperties.get(lookup);
if (lookupValue.isJsonObject()) {
JsonObject lookupObject = lookupValue.getAsJsonObject();
if (lookupObject.has(FactoredObjectRef.TARGET_ID_FIELD)) {
String lookupTargetId = lookupObject.get(FactoredObjectRef.TARGET_ID_FIELD).getAsString();
String lookupTargetType = lookupObject.get(FactoredObjectRef.TARGET_TYPE_FIELD).getAsString();
String currentTargetId = currentObject.has(FactoredObjectRef.TARGET_ID_FIELD)
?currentObject.get(FactoredObjectRef.TARGET_ID_FIELD).getAsString()
:"";
String currentTargetType = currentObject.has(FactoredObjectRef.TARGET_TYPE_FIELD)
?currentObject.get(FactoredObjectRef.TARGET_TYPE_FIELD).getAsString()
:"";
if (
(!lookupTargetId.equals(currentTargetId) && currentTargetType.equals(lookupTargetType))
|| !CommonUtils.isValid(currentTargetId)
) {
currentObject.remove(FactoredObjectRef.TARGET_ID_FIELD);
currentObject.add(FactoredObjectRef.TARGET_ID_FIELD, lookupObject.get(FactoredObjectRef.TARGET_ID_FIELD));
printOutput("[DIRTY] UPDATED " + fi.getName() + " for [" + fo.getObjectId() + "/" + fo.getObjectType() + "]"
+ "\n\tSET LOOKUP TARGET ID TO ["
+ lookupObject.get(FactoredObjectRef.TARGET_ID_FIELD).toString()
+ "]");
objectModel.setDirty();
}
}
}
}
result = true;
} else if (currentObject.has(FIELDS.FACTORY_ID)) {
// it will be replaced with reference on next layout
printOutput("[DIRTY] FOUND OBJECT " + fi.getName() + " for [" + fo.getObjectId() + "/" + fo.getObjectType() + "]");
objectModel.setDirty();
result = true;
}
} else {
printOutput("CURRENT VALIE [" + currentValue.toString() + "] IS NOT OBJECT IN " + fi.getName() + " for [" + fo.getObjectId() + "/" + fo.getObjectType() + "]");
}
if (!result) {
// we have something which is not a ref and not a object to produce
// we'll treat it as resolved ref value
refCopy.remove(FIELDS.DEFAULT_VALUE);
refCopy.add(FactoredObjectRef.TARGET_VALUE_FIELD, currentValue);
refCopy.addProperty(FactoredObjectRef.IS_RESOLVED_FIELD, true);
printOutput("[DIRTY] CONSIDER VALUE [" + currentValue.toString() + "] AS RESOLVED " + fi.getName() + " for [" + fo.getObjectId() + "/" + fo.getObjectType() + "]");
objectModel.setDirty();
result = true;
}
}
return result;
}
}

View File

@ -0,0 +1,78 @@
/*-
* ~~~~~~licensing~~~~~~
* test-producers
* ==========
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.producer.executor.commands;
import java.util.Map;
import ru.entaxy.esb.platform.runtime.base.connecting.generator.Generated;
import ru.entaxy.platform.core.producer.api.EntaxyProducerService;
import ru.entaxy.platform.core.producer.api.ProducerResult;
import ru.entaxy.platform.core.producer.api.ProducerResult.CommandResult;
import ru.entaxy.platform.core.producer.executor.AbstractCommandExecutor;
import ru.entaxy.platform.core.producer.executor.CommandExecutor;
import ru.entaxy.platform.core.producer.executor.generationmodel.AbstractTask;
import ru.entaxy.platform.core.producer.executor.generationmodel.GeneratedList;
import ru.entaxy.platform.core.producer.executor.generationmodel.GenerationModel;
@CommandExecutor(id = "generate", predecessors = {"validate", "pre-generate"})
public class Generate extends AbstractCommandExecutor {
public Generate(EntaxyProducerService entaxyProducerService) {
super(entaxyProducerService);
// TODO Auto-generated constructor stub
}
@Override
protected boolean doExecute(ProducerResult currentResult, CommandResult commandResult,
Map<String, Object> instructions) throws Exception {
GenerationModel generationModel = currentResult.findResultObject(GenerationModel.class);
// generate
this.printOutput("\n\t == Execution ==\n");
for (AbstractTask at: generationModel.getTasks()) {
at.setPrintOutput(isPrintOutput);
at.execute(currentResult, commandResult, entaxyProducerService, instructions);
this.printOutput("\n :: Result ::\n");
if (at.getGeneratedResult()==null)
this.printOutput("-> NOTHING");
else {
Generated g = at.getGeneratedResult();
this.printOutput("\tTYPE :: [" + g.getType() + "]");
this.printOutput("\tCONTENT :: \n\n");
if (g.getObject() == null)
this.printOutput("-> EMPTY\n\n");
else
this.printOutput(g.getObject().toString());
}
this.printOutput("\n ::\n");
}
this.printOutput("\n\t ==\n");
// collect result
GeneratedList resultObject = new GeneratedList();
for (AbstractTask at: generationModel.getTasks())
resultObject.add(at.getGeneratedResult());
commandResult.resultObject(resultObject);
return true;
}
}

View File

@ -0,0 +1,145 @@
/*-
* ~~~~~~licensing~~~~~~
* test-producers
* ==========
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.producer.executor.commands;
import java.util.Map;
import org.osgi.framework.Constants;
import ru.entaxy.platform.base.support.CommonUtils;
import ru.entaxy.platform.core.artifact.Blueprint;
import ru.entaxy.platform.core.artifact.DeployedArtifact;
import ru.entaxy.platform.core.artifact.installer.builder.ClusterInstaller;
import ru.entaxy.platform.core.artifact.installer.builder.InstallationResult;
import ru.entaxy.platform.core.artifact.installer.builder.Installer;
import ru.entaxy.platform.core.artifact.installer.builder.LocalInstaller;
import ru.entaxy.platform.core.artifact.installer.builder.typed.BlueprintInstaller;
import ru.entaxy.platform.core.artifact.service.ArtifactService;
import ru.entaxy.platform.core.producer.api.EntaxyProducerService;
import ru.entaxy.platform.core.producer.api.ProducerResult;
import ru.entaxy.platform.core.producer.api.ProducerResult.CommandResult;
import ru.entaxy.platform.core.producer.executor.AbstractCommandExecutor;
import ru.entaxy.platform.core.producer.executor.CommandExecutor;
import ru.entaxy.platform.core.producer.executor.CommandInstructions;
import ru.entaxy.platform.core.producer.executor.support.ArtifactsHelper;
import ru.entaxy.platform.core.producer.executor.support.DeployedArtifactList;
import ru.entaxy.platform.core.producer.executor.support.InstallationResultList;
@CommandExecutor(id = "install", predecessors = "deploy")
public class Install extends AbstractCommandExecutor {
public static final String INSTALL_LOCAL_INSTRUCTION = "installLocal";
public static final String UPDATE_INSTRUCTION = "update";
public static final String INSTALL_ONLY_IF_MISSING_INSTRUCTION = "installOnlyIfMissing";
public Install(EntaxyProducerService entaxyProducerService) {
super(entaxyProducerService);
}
@Override
protected boolean doExecute(ProducerResult currentResult, CommandResult commandResult,
Map<String, Object> instructions) throws Exception {
CommandInstructions commandInstructions = new CommandInstructions(instructions);
boolean installLocal =
commandInstructions.has(INSTALL_LOCAL_INSTRUCTION)
?commandInstructions.getBoolean(INSTALL_LOCAL_INSTRUCTION)
:false;
boolean installOnlyIfMissing =
commandInstructions.has(INSTALL_ONLY_IF_MISSING_INSTRUCTION)
?commandInstructions.getBoolean(INSTALL_ONLY_IF_MISSING_INSTRUCTION)
:false;
String update =
commandInstructions.has(UPDATE_INSTRUCTION)
?commandInstructions.getString(UPDATE_INSTRUCTION)
:null;
Object installLocalValue = instructions.get(INSTALL_LOCAL_INSTRUCTION);
if (installLocalValue != null)
if (installLocalValue instanceof Boolean)
installLocal = (Boolean)installLocalValue;
DeployedArtifactList deployedArtifactList = currentResult.findResultObject(DeployedArtifactList.class);
InstallationResultList installationResultList = new InstallationResultList();
ArtifactService artifactService = ArtifactsHelper.getInstance().getArtifactService();
for (DeployedArtifact da: deployedArtifactList) {
InstallationResult result = null;
Installer<?> installer = null;
printOutput("-> Installing artifact: [" + da.getArtifact().getCoordinates().toString() + "]");
if (installLocal) {
LocalInstaller localInstaller = artifactService.installers().local()
.artifact(da);
installer = localInstaller;
printOutput("-> Installing locally");
} else {
ClusterInstaller clusterInstaller = artifactService.installers().cluster()
.artifact(da);
installer = clusterInstaller;
printOutput("-> Installing clustered");
}
// TODO add support for other types when they appear
if (da.getArtifact().getCategory().equals(Blueprint.ARTIFACT_CATEGORY_BLUEPRINT)) {
// we're installing blueprint
printOutput("-> Installing: " + da.getArtifact().getCategory());
BlueprintInstaller blueprintInstaller = installer.typed(BlueprintInstaller.class);
if (installOnlyIfMissing)
blueprintInstaller.installOnlyIfMissing();
if (update != null) {
if (!CommonUtils.isValid(update)) {
update = da
.getArtifact().getProperties()
.getOrDefault(Constants.BUNDLE_SYMBOLICNAME, "")
.toString();
}
blueprintInstaller.update(update);
}
result = blueprintInstaller.start().install();
} else {
printOutput("-> Unknown category: " + da.getArtifact().getCategory());
}
if (result != null) {
for (String key: da.getArtifact().getProperties().keySet())
result.getProperties().putIfAbsent(key, da.getArtifact().getProperties().get(key));
// TODO imrove Coordinates: add "asMap" method
result.getProperties().put("artifact.artifactId", da.getArtifact().getCoordinates().getArtifactId());
result.getProperties().put("artifact.groupId", da.getArtifact().getCoordinates().getGroupId());
result.getProperties().put("artifact.version", da.getArtifact().getCoordinates().getVersion());
result.getProperties().put("artifact.type", da.getArtifact().getCoordinates().getType());
result.getProperties().put("artifact.classifier", da.getArtifact().getCoordinates().getClassifier());
installationResultList.add(result);
}
}
commandResult.resultObject(installationResultList);
return true;
}
}

View File

@ -0,0 +1,64 @@
/*-
* ~~~~~~licensing~~~~~~
* test-producers
* ==========
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.producer.executor.commands;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.entaxy.platform.core.producer.api.EntaxyProducerService;
import ru.entaxy.platform.core.producer.api.ProducerResult;
import ru.entaxy.platform.core.producer.api.ProducerResult.CommandResult;
import ru.entaxy.platform.core.producer.executor.AbstractCommandExecutor;
import ru.entaxy.platform.core.producer.executor.CommandExecutor;
import ru.entaxy.platform.core.producer.executor.objectmodel.ObjectModel;
@CommandExecutor(id = "layout", predecessors = {"analyze"})
public class Layout extends AbstractCommandExecutor {
private static final Logger log = LoggerFactory.getLogger(Layout.class);
public Layout(EntaxyProducerService entaxyProducerService) {
super(entaxyProducerService);
}
@Override
protected boolean doExecute(ProducerResult currentResult, CommandResult commandResult,
Map<String, Object> instructions) throws Exception {
log.debug("Executing command [{}]", getId());
ObjectModel objectModel = currentResult.findResultObject(ObjectModel.class);
printOutput("\n\n\t== LAYOUT == \n\n");
printOutput("\n\tIncoming JSON ::\n\n");
printOutput(objectModel.getJsonCurrent().toString());
log.debug(" -- INCOMING JSON --\n" + objectModel.getJsonCurrent().toString());
objectModel.layout();
log.debug(" -- OUTGOING JSON --\n" + objectModel.getJsonCurrent().toString());
commandResult.resultObject(objectModel);
printOutput("\n\tOutgoing JSON ::\n\n");
printOutput(objectModel.getJsonCurrent().toString());
return true;
}
}

View File

@ -0,0 +1,58 @@
/*-
* ~~~~~~licensing~~~~~~
* test-producers
* ==========
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.producer.executor.commands;
import java.util.Map;
import ru.entaxy.platform.core.producer.api.EntaxyProducerService;
import ru.entaxy.platform.core.producer.api.ProducerResult;
import ru.entaxy.platform.core.producer.api.ProducerResult.CommandResult;
import ru.entaxy.platform.core.producer.executor.AbstractCommandExecutor;
import ru.entaxy.platform.core.producer.executor.CommandExecutor;
import ru.entaxy.platform.core.producer.executor.generationmodel.AbstractTask;
import ru.entaxy.platform.core.producer.executor.generationmodel.GenerationModel;
import ru.entaxy.platform.core.producer.executor.objectmodel.ObjectModel;
@CommandExecutor(id = "pre-generate", predecessors = {"validate"})
public class PrepareGenerate extends AbstractCommandExecutor {
public PrepareGenerate(EntaxyProducerService entaxyProducerService) {
super(entaxyProducerService);
}
@Override
protected boolean doExecute(ProducerResult currentResult, CommandResult commandResult,
Map<String, Object> instructions) throws Exception {
ObjectModel objectModel = currentResult.findResultObject(ObjectModel.class);
GenerationModel generationModel = new GenerationModel(objectModel);
generationModel.load();
// print plan
this.printOutput("\n\t == Generation plan ==\n");
for (AbstractTask at: generationModel.getTasks())
this.printOutput(at.getInfo());
commandResult.resultObject(generationModel);
return true;
}
}

View File

@ -0,0 +1,112 @@
/*-
* ~~~~~~licensing~~~~~~
* test-producers
* ==========
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.producer.executor.commands;
import java.util.Map;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.entaxy.platform.base.objects.EntaxyObject;
import ru.entaxy.platform.base.objects.EntaxyObjectStorage;
import ru.entaxy.platform.base.objects.EntaxyObjectStorageService;
import ru.entaxy.platform.base.support.osgi.OSGIUtils;
import ru.entaxy.platform.core.artifact.DeployedArtifact;
import ru.entaxy.platform.core.artifact.installer.builder.InstallationResult;
import ru.entaxy.platform.core.producer.api.EntaxyProducerService;
import ru.entaxy.platform.core.producer.api.ProducerResult;
import ru.entaxy.platform.core.producer.api.ProducerResult.CommandResult;
import ru.entaxy.platform.core.producer.executor.AbstractCommandExecutor;
import ru.entaxy.platform.core.producer.executor.CommandExecutor;
import ru.entaxy.platform.core.producer.executor.support.InstallationResultList;
@CommandExecutor(id = "store", predecessors = "install")
public class Store extends AbstractCommandExecutor {
private static final Logger log = LoggerFactory.getLogger(Store.class);
protected EntaxyObjectStorageService objectStorageService;
public Store(EntaxyProducerService entaxyProducerService) {
super(entaxyProducerService);
try {
objectStorageService = OSGIUtils.services().ofClass(EntaxyObjectStorageService.class).get();
} catch (Exception e) {
log.warn("EntaxyObjectStorageService not found yet", e);
}
}
@Override
protected boolean doExecute(ProducerResult currentResult, CommandResult commandResult,
Map<String, Object> instructions) throws Exception {
InstallationResultList installationResultList = currentResult.findResultObject(InstallationResultList.class);
if (objectStorageService == null)
objectStorageService = OSGIUtils.services().ofClass(EntaxyObjectStorageService.class).get();
for (InstallationResult installationResult: installationResultList) {
printOutput("\n -- INSTALLATION RESULT ::"
+ "\n\t" + installationResult.getResult().toString()
+ "\n\tproperties:"
+ (installationResult.getProperties()==null
?"\n\t\t<EMPTY>"
:installationResult.getProperties().entrySet().stream()
.map(entry->
"\n\t\t[" + entry.getKey() + "] = ["
+ (entry.getValue()==null
?""
:(entry.getValue() instanceof DeployedArtifact
?"DeployedArtifact :: " + (
((DeployedArtifact)entry.getValue()).getArtifact()
.getProperties().entrySet().stream()
.map(e->
"\n\t\t\t[" + e.getKey() + "] = ["
+ (e.getValue()==null
?""
:e.getValue().toString()) + "]"
).collect(Collectors.joining())
)
:entry.getValue().toString()) + "]"
)
).collect(Collectors.joining())
)
);
EntaxyObjectStorage objectStorage = objectStorageService.getObjectStorage(
installationResult.getProperties()
.getOrDefault(EntaxyObject.FIELDS.OBJECT_TYPE, "").toString()
);
if (objectStorage == null) {
log.warn("Storage not found for type: [" + installationResult.getProperties()
.getOrDefault(EntaxyObject.FIELDS.OBJECT_TYPE, "").toString() + "]");
continue;
}
objectStorage.store(installationResult.getProperties());
}
return true;
}
}

View File

@ -0,0 +1,53 @@
/*-
* ~~~~~~licensing~~~~~~
* test-producers
* ==========
* Copyright (C) 2020 - 2022 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.producer.executor.commands;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.entaxy.platform.core.producer.api.EntaxyProducerService;
import ru.entaxy.platform.core.producer.api.ProducerResult;
import ru.entaxy.platform.core.producer.api.ProducerResult.CommandResult;
import ru.entaxy.platform.core.producer.executor.AbstractCommandExecutor;
import ru.entaxy.platform.core.producer.executor.CommandExecutor;
import ru.entaxy.platform.core.producer.executor.objectmodel.ObjectModel;
@CommandExecutor(id = "validate", predecessors = {"enrich", "layout"})
public class Validate extends AbstractCommandExecutor {
private static final Logger log = LoggerFactory.getLogger(Validate.class);
public Validate(EntaxyProducerService entaxyProducerService) {
super(entaxyProducerService);
}
@Override
protected boolean doExecute(ProducerResult currentResult, CommandResult commandResult,
Map<String, Object> instructions) throws Exception {
log.info("Executing command [{}]", getId());
ObjectModel objectModel = currentResult.findResultObject(ObjectModel.class);
// TODO check ObjectModel.objects & .refs for
// - factory exists
// - output supported
return true;
}
}

Some files were not shown because too many files have changed in this diff Show More