ENTAXY-374 release 1.8.2
This commit is contained in:
@ -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>
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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();
|
||||
|
||||
}
|
@ -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();
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
|
@ -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();
|
||||
|
||||
}
|
@ -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);
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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(","))
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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")
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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"/>
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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&repeat=true&depends-on=core,datasources</Entaxy-Initializer-Class>
|
||||
<Entaxy-Initializer-Class>ru.entaxy.esb.platform.runtime.core.initializer.connection.ConnectionInitializer?id=connections&repeat=true&retries=10&interval=2000&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>
|
@ -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);
|
||||
|
@ -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": {},
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -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": {}
|
||||
}
|
||||
]
|
||||
}
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -64,7 +64,7 @@ public class DataSourcesInitializer extends AbstractInitializer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCalllback(Callback callback) {
|
||||
public void setCallback(Callback callback) {
|
||||
DataSourcesInitializer.callback = callback;
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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();
|
||||
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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"/>
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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";
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
|
@ -23,6 +23,7 @@ import ru.entaxy.esb.platform.runtime.base.connecting.connection.Connection;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Deprecated
|
||||
public interface ConnectionManager {
|
||||
/*
|
||||
@Deprecated
|
||||
|
@ -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 {
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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(
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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 {
|
||||
|
||||
|
||||
|
201
platform/runtime/core/object-producing/LICENSE.txt
Normal file
201
platform/runtime/core/object-producing/LICENSE.txt
Normal 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.
|
@ -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.
|
@ -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>
|
@ -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);
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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();
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
@ -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.
|
@ -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>
|
@ -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;
|
||||
|
||||
}
|
@ -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 {};
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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
Reference in New Issue
Block a user